The (soon to be) official library for the OpenBCI 32bit Board.
- Minimums
- Installing
- Upgrading
- Downgrading
- General Overview
- Includes
- setup()
- loop()
- System Overview
- Reference Guide
- Functions
- Constants
You just opened your OpenBCI (congrats!) and want to get started programming the firmware right now?! Ok, ok do the following minimums!
- Install the dongle drivers from FTDI for your operating system.
- Download the latest Arduino IDE software from the Arduino site
- Follow the 2nd installation method "Manual install by copying ZIP file" to install the latest chipKIT-core hardware files from the chipKIT-core wiki
- Download this repository zip or clone this repo (we clone directly into the
libraries
folder for development) - Download OpenBCI_32bit_SD
- Move both of the folders into your
libraries
folder (please make a folder in Arduino named libraries if you don't have one)
- Mac OSX: User/Documents/Arduino/libraries
- Windows: /My Documents/Arduino/libraries
- Restart Arduino IDE
- Open
DefaultBoard.ino
for a full featured example. - Hack and make awesome stuff!
Checkout the upgrade guide!
Have a bunch of custom firmware based on the original firmware? Have no fear for previous releases are here and here for the radios if needed.
Your needs dictate what you need to include! This saves a ton of precious memory space!
In order to use the SD card write functionality, you must not only include the file SD_Card_Stuff.ino
located in examples/DefaultBoard, you must include the following:
Headers:
#include <OBCI32_SD.h>
#include <DSPI.h>
#include <EEPROM.h>
#include <OpenBCI_32bit_Library.h>
#include <OpenBCI_32bit_Library_Definitions.h>
Variables used by SD_Card_Stuff.ino
:
boolean addAccelToSD = false;
boolean addAuxToSD = false;
boolean SDfileOpen = false;
Headers:
#include <DSPI.h>
#include <OpenBCI_32bit_Library.h>
#include <OpenBCI_32bit_Library_Definitions.h>
You do not need to declare any variables...
void setup() {
board.begin(); // Bring up the OpenBCI Board
board.useAccel = true; // Notify the board we want to use accel data, this effects `::sendChannelData()`
}
void setup() {
board.begin(); // Bring up the OpenBCI Board
board.useAux = true; // Notify the board we want to use aux data, this effects `::sendChannelData()`
}
void setup() {
board.begin(); // Bring up the OpenBCI Board
}
We will start with the basics here, and work our way up... The loop function can be thought of as the meat and core executor of the OpenBCI_32bit_Library functionality. Keep in mind the main purpose of this library is to stream data from the ADS1299 to the computer, that's our focus, everything takes a back seat to that.
A bare board, not using the SD, accel, or aux data must have the following:
void loop() {
if (board.streaming) {
if (board.channelDataAvailable) {
// Read from the ADS(s), store data, set channelDataAvailable flag to false
board.updateChannelData();
if (board.timeSynced) {
board.sendChannelDataWithTimeAndRawAux();
} else {
// Send standard packet with channel data
board.sendChannelDataWithRawAux();
}
}
}
// Check the serial port for new data
if (board.hasDataSerial0()) {
// Read one char and process it
board.processChar(board.getCharSerial0());
}
}
The first if
statement is only true
if a b
command is ran through the processChar
function. The next if
statement exploits a volatile
interrupt driven boolean
called channelDataAvailable
. This interrupt driven system is new as of firmware version 2.0.0 a discussion of it can be found here. If the ADS1299 has signaled to the Board new data is ready, the function updateChannelData()
is executed. This function will grab new data from the Board's ADS1299 (and from the daisy's ADS1299) and store that data to the arrays: lastBoardDataRaw
, boardChannelDataRaw
, meanBoardDataRaw
, lastDaisyDataRaw
, daisyChannelDataRaw
, meanDaisyDataRaw
, which can be accessed to drive filters or whatever your heart desires.
If you send a packet from the Pic32 to the Device RFduino and you start it with 0x41
, write 31 bytes, and follow with 0xCX
(where X
can be 0-F
hex) then the packet will immediately be sent from the Device radio. This is counter to how if you want to send a message longer than 31 bytes (takes over two packets to transmit from Device radio to Host radio (Board to Dongle)) then you simply write the message, and that message will be sent in a multipacket format that allows it to be reassembled on the Dongle. This reassembling of data is critical to over the air programming.
Reads a status register to see if there is new accelerometer data.
Returns {boolean}
true
if the accelerometer has new data.
Reads from the accelerometer to get new X, Y, and Z data. Updates the global array axisData
.
The function the OpenBCI board will call in setup()
.
The function the OpenBCI board will call in setup. Turns sniff mode on and allows you to tap into the serial port that is broken out on the OpenBCI 32bit board.
You must alter Board_Defs.h
file located:
On Mac:
/Users/username/Documents/Arduino/hardware/chipkit-core/pic32/variants/openbci/Board_Defs.h
On Windows:
C:\Users\username\Documents\Arduino\hardware\chipkit-core\pic32\variants\openbci\Board_Defs.h
Specifically lines 311
and 313
, change 7
and 10
to 11
and 12
for _SER1_TX_PIN
and _SER1_RX_PIN
respectively. Check out this sweet gif if you are a visual person http://g.recordit.co/3jH01sMD6Y.gif
You will need to reflash your board! But now you can connect to pins 11
(TX
) and 12
(RX
) via any 3V3 serial to USB driver. Remember to use 3V3, 115200 baud, and have a common ground!
Called in every loop()
and checks Serial0
.
Returns {boolean}
true
if there is data ready to be read.
Process one char at a time from serial port. This is the main command processor for the OpenBCI system. Considered mission critical for normal operation.
character {char}
The character to process.
Returns {boolean}
true
if the command was recognized, false
if not.
If hasDataSerial0()
is true
then this function is called. Reads from Serial0
first and foremost, which comes from the RFduino. If no data is available then returns a 0x00
which is NOT a command that the system will recognize as a safe guard.
Returns {char}
The character from the serial port.
Writes channel data, aux data, and footer to serial port. This is the old way to send channel data. Based on global variables useAux
and useAccel
Must keep for portability. Will look to deprecate in 3.0.0.
If useAccel
is true
then sends data from axisData
array and sets the contents of axisData
to 0
.
If useAux
is true
then sends data from auxData
array and sets the contents of auxData
to 0
.
Adds stop byte OPENBCI_EOP_STND_ACCEL
. See Constants below for more info.
Writes channel data and axisData
array to serial port in the correct stream packet format.
Adds stop byte OPENBCI_EOP_STND_ACCEL
. See Constants below for more info.
Writes channel data and auxData
array to serial port in the correct stream packet format.
Adds stop byte OPENBCI_EOP_STND_RAW_AUX
. See Constants below for more info.
Writes channel data, axisData
array, and 4 byte unsigned time stamp in ms to serial port in the correct stream packet format.
axisData
will be split up and sent on the samples with sampleCounter
of 7, 8, and 9 for X, Y, and Z respectively. Driver writers parse accordingly.
If the global variable sendTimeSyncUpPacket
is true
(set by processChar
getting a time sync set <
command) then:
Adds stop byte OPENBCI_EOP_ACCEL_TIME_SET
and sets sendTimeSyncUpPacket
to false
.
Else if sendTimeSyncUpPacket
is false
then:
Adds stop byte OPENBCI_EOP_ACCEL_TIME_SYNCED
Writes channel data, auxData[0]
2 bytes, and 4 byte unsigned time stamp in ms to serial port in the correct stream packet format.
If the global variable sendTimeSyncUpPacket
is true
(set by processChar
getting a time sync set <
command) then:
Adds stop byte OPENBCI_EOP_RAW_AUX_TIME_SET
and sets sendTimeSyncUpPacket
to false
.
Else if sendTimeSyncUpPacket
is false
then:
Adds stop byte OPENBCI_EOP_RAW_AUX_TIME_SYNCED
Called when the board ADS1299 has new data available. If there is a daisy module attached, that data is also fetched here.
Check status register to see if data is available from the ADS1299.
Returns {boolean}
true
if data is available.
0xC0
- End of standard stream packet.
0xC1
- End of stream packet with raw packet.
0xC2
- End of stream packet, user defined.
0xC3
- End of time sync up with accelerometer stream packet.
0xC4
- End of time synced stream packet.
0xC5
- End of time sync up stream packet.
0xC6
- End of time synced stream packet.