@@ -1 +0,0 @@
|
||||
|
||||
|
||||
+2449
-1699
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+330
-203
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
insert header here
|
||||
insert header here
|
||||
|
||||
*/
|
||||
#ifndef _____OpenBCI_32bit__
|
||||
@@ -8,238 +8,365 @@
|
||||
|
||||
#include <DSPI.h>
|
||||
#include <Arduino.h>
|
||||
#include <OpenBCI_Wifi_Master.h>
|
||||
#include <OpenBCI_Wifi_Master_Definitions.h>
|
||||
#include "OpenBCI_32bit_Library_Definitions.h"
|
||||
|
||||
void __USER_ISR ADS_DRDY_Service(void);
|
||||
class OpenBCI_32bit_Library {
|
||||
|
||||
public:
|
||||
// ENUMS
|
||||
typedef enum ACCEL_MODE {
|
||||
ACCEL_MODE_ON,
|
||||
ACCEL_MODE_OFF
|
||||
};
|
||||
|
||||
// Start up functions
|
||||
OpenBCI_32bit_Library();
|
||||
boolean accelHasNewData(void);
|
||||
void accelUpdateAxisData(void);
|
||||
void accelWriteAxisData(void);
|
||||
void begin(void);
|
||||
void beginDebug(void);
|
||||
boolean beginSecondarySerial(void);
|
||||
char getCharSerial0(void);
|
||||
char getCharSerial1(void);
|
||||
boolean hasDataSerial0(void);
|
||||
boolean hasDataSerial1(void);
|
||||
typedef enum TIME_SYNC_MODE {
|
||||
TIME_SYNC_MODE_ON,
|
||||
TIME_SYNC_MODE_OFF
|
||||
};
|
||||
|
||||
typedef enum MARKER_MODE {
|
||||
MARKER_MODE_ON,
|
||||
MARKER_MODE_OFF
|
||||
};
|
||||
|
||||
void writeSerial(char *data, int len);
|
||||
typedef enum BOARD_MODE {
|
||||
BOARD_MODE_DEFAULT,
|
||||
BOARD_MODE_DEBUG,
|
||||
BOARD_MODE_ANALOG,
|
||||
BOARD_MODE_DIGITAL,
|
||||
BOARD_MODE_MARKER,
|
||||
BOARD_MODE_BLE,
|
||||
BOARD_MODE_END_OF_MODES // This must be the last entry-insert any new board modes above this line
|
||||
};
|
||||
|
||||
boolean isADSDataAvailable(void);
|
||||
typedef enum MULTI_CHAR_COMMAND {
|
||||
MULTI_CHAR_CMD_NONE,
|
||||
MULTI_CHAR_CMD_PROCESSING_INCOMING_SETTINGS_CHANNEL,
|
||||
MULTI_CHAR_CMD_PROCESSING_INCOMING_SETTINGS_LEADOFF,
|
||||
MULTI_CHAR_CMD_SERIAL_PASSTHROUGH,
|
||||
MULTI_CHAR_CMD_SETTINGS_BOARD_MODE,
|
||||
MULTI_CHAR_CMD_SETTINGS_SAMPLE_RATE,
|
||||
MULTI_CHAR_CMD_INSERT_MARKER
|
||||
};
|
||||
|
||||
typedef enum PACKET_TYPE {
|
||||
PACKET_TYPE_ACCEL,
|
||||
PACKET_TYPE_RAW_AUX,
|
||||
PACKET_TYPE_USER_DEFINED,
|
||||
PACKET_TYPE_ACCEL_TIME_SET,
|
||||
PACKET_TYPE_ACCEL_TIME_SYNC,
|
||||
PACKET_TYPE_RAW_AUX_TIME_SET,
|
||||
PACKET_TYPE_RAW_AUX_TIME_SYNC
|
||||
};
|
||||
|
||||
typedef enum SAMPLE_RATE {
|
||||
SAMPLE_RATE_16000,
|
||||
SAMPLE_RATE_8000,
|
||||
SAMPLE_RATE_4000,
|
||||
SAMPLE_RATE_2000,
|
||||
SAMPLE_RATE_1000,
|
||||
SAMPLE_RATE_500,
|
||||
SAMPLE_RATE_250
|
||||
};
|
||||
|
||||
void writeTimeCurrent(void);
|
||||
void writeZeroAux(void);
|
||||
void activateAllChannelsToTestCondition(byte testInputCode, byte amplitudeCode, byte freqCode);
|
||||
// STRUCTS
|
||||
typedef struct {
|
||||
uint32_t baudRate;
|
||||
boolean rx;
|
||||
boolean tx;
|
||||
} SerialInfo;
|
||||
|
||||
void channelSettingsArraySetForAll(void);
|
||||
void channelSettingsArraySetForChannel(byte N);
|
||||
void channelSettingsSetForChannel(byte channelNumber, byte powerDown, byte gain, byte inputType, byte bias, byte srb2, byte srb1);
|
||||
typedef struct {
|
||||
boolean rx;
|
||||
boolean tx;
|
||||
} SpiInfo;
|
||||
|
||||
void leadOffConfigureSignalForAll(byte amplitudeCode, byte freqCode);
|
||||
void leadOffConfigureSignalForTargetSS(byte targetSS, byte amplitudeCode, byte freqCode);
|
||||
typedef struct {
|
||||
uint8_t sampleNumber;
|
||||
uint8_t data[BLE_TOTAL_DATA_BYTES];
|
||||
boolean ready;
|
||||
uint8_t bytesLoaded;
|
||||
} BLE;
|
||||
|
||||
void leadOffSetForAllChannels(void);
|
||||
void leadOffSetForChannel(byte channelNumber, byte pInput, byte nInput);
|
||||
// Start up functions
|
||||
OpenBCI_32bit_Library();
|
||||
boolean accelHasNewData(void);
|
||||
void accelUpdateAxisData(void);
|
||||
void accelWriteAxisDataSerial(void);
|
||||
void activateAllChannelsToTestCondition(byte testInputCode, byte amplitudeCode, byte freqCode);
|
||||
void activateChannel(byte); // enable the selected channel
|
||||
void ADS_writeChannelData(void);
|
||||
void ADS_writeChannelDataAvgDaisy(void);
|
||||
void ADS_writeChannelDataNoAvgDaisy(void);
|
||||
void attachDaisy(void);
|
||||
void begin(void);
|
||||
void beginDebug(void);
|
||||
void beginDebug(uint32_t);
|
||||
void beginPinsAnalog(void);
|
||||
void beginPinsDebug(void);
|
||||
void beginPinsDefault(void);
|
||||
void beginPinsDigital(void);
|
||||
void beginSerial0(void);
|
||||
void beginSerial0(uint32_t);
|
||||
void beginSerial1(void);
|
||||
void beginSerial1(uint32_t);
|
||||
void boardReset(void);
|
||||
void changeChannelLeadOffDetect();
|
||||
void changeChannelLeadOffDetect(byte N);
|
||||
void channelSettingsArraySetForAll(void);
|
||||
void channelSettingsArraySetForChannel(byte N);
|
||||
void channelSettingsSetForChannel(byte, byte, byte, byte, byte, byte, byte);
|
||||
boolean checkMultiCharCmdTimer(void);
|
||||
void csLow(int);
|
||||
void csHigh(int);
|
||||
void configureInternalTestSignal(byte,byte);
|
||||
void configureLeadOffDetection(byte, byte);
|
||||
void deactivateChannel(byte); // disable given channel 1-8(16)
|
||||
void disable_accel(void); // stop data acquisition and go into low power mode
|
||||
void enable_accel(byte); // start acceleromoeter with default settings
|
||||
void endMultiCharCmdTimer(void);
|
||||
void endSerial0(void);
|
||||
void endSerial1(void);
|
||||
const char* getBoardMode(void);
|
||||
char getChannelCommandForAsciiChar(char);
|
||||
char getCharSerial0(void);
|
||||
char getCharSerial1(void);
|
||||
char getConstrainedChannelNumber(byte);
|
||||
byte getDefaultChannelSettingForSetting(byte);
|
||||
char getDefaultChannelSettingForSettingAscii(byte);
|
||||
char getGainForAsciiChar(char);
|
||||
uint8_t * getGains(void);
|
||||
char getMultiCharCommand(void);
|
||||
char getNumberForAsciiChar(char);
|
||||
const char* getSampleRate(void);
|
||||
char getTargetSSForConstrainedChannelNumber(byte);
|
||||
char getYesOrNoForAsciiChar(char);
|
||||
boolean hasDataSerial0(void);
|
||||
boolean hasDataSerial1(void);
|
||||
boolean isADSDataAvailable(void);
|
||||
boolean isProcessingMultibyteMsg(void);
|
||||
void leadOffConfigureSignalForAll(byte, byte);
|
||||
void leadOffConfigureSignalForTargetSS(byte, byte, byte);
|
||||
void leadOffSetForAllChannels(void);
|
||||
void leadOffSetForChannel(byte, byte, byte);
|
||||
void ledFlash(int);
|
||||
void loop(void);
|
||||
void printAll(char);
|
||||
void printAll(const char *);
|
||||
void printlnAll(void);
|
||||
void printlnAll(const char *);
|
||||
void printlnSerial(void);
|
||||
void printlnSerial(char);
|
||||
void printlnSerial(int);
|
||||
void printlnSerial(int, int);
|
||||
void printlnSerial(const char *);
|
||||
void printSerial(int);
|
||||
void printSerial(char);
|
||||
void printSerial(int, int);
|
||||
void printSerial(const char *);
|
||||
boolean processChar(char);
|
||||
boolean processCharWifi(char);
|
||||
void processIncomingBoardMode(char);
|
||||
void processIncomingSampleRate(char);
|
||||
void processInsertMarker(char);
|
||||
void processIncomingChannelSettings(char);
|
||||
void processIncomingLeadOffSettings(char);
|
||||
void reportDefaultChannelSettings(void);
|
||||
void removeDaisy(void);
|
||||
void resetADS(int); // reset all the ADS1299's settings
|
||||
void resetChannelSettingsArrayToDefault(byte channelSettingsArray[][OPENBCI_NUMBER_OF_CHANNEL_SETTINGS]);
|
||||
void resetLeadOffArrayToDefault(byte leadOffArray[][OPENBCI_NUMBER_OF_LEAD_OFF_SETTINGS]);
|
||||
void startADS(void);
|
||||
void stopADS(void);
|
||||
void sendChannelData(void);
|
||||
void sendChannelData(PACKET_TYPE);
|
||||
void setBoardMode(uint8_t);
|
||||
void setChannelsToDefault(void);
|
||||
void setCurPacketType(void);
|
||||
void setSampleRate(uint8_t newSampleRateCode);
|
||||
void sendEOT(void);
|
||||
void setSerialInfo(SerialInfo, boolean, boolean, uint32_t);
|
||||
boolean smellDaisy(void);
|
||||
void startMultiCharCmdTimer(char);
|
||||
void streamSafeChannelDeactivate(byte);
|
||||
void streamSafeChannelActivate(byte);
|
||||
void streamSafeChannelSettingsForChannel(byte, byte, byte, byte, byte, byte, byte);
|
||||
void streamSafeSetAllChannelsToDefault(void);
|
||||
void streamSafeReportAllChannelDefaults(void);
|
||||
void streamSafeLeadOffSetForChannel(byte, byte, byte);
|
||||
void streamSafeTimeSendSyncSetPacket(void);
|
||||
void streamStart(void);
|
||||
void streamStop(void);
|
||||
void tryMultiAbort(void);
|
||||
void updateBoardData(void);
|
||||
void updateBoardData(boolean);
|
||||
void updateChannelData(void); // retrieve data from ADS
|
||||
void updateDaisyData(void);
|
||||
void updateDaisyData(boolean);
|
||||
void useAccel(boolean);
|
||||
void useTimeStamp(boolean);
|
||||
void write(uint8_t);
|
||||
void writeAuxDataSerial(void);
|
||||
void writeChannelSettings(void);
|
||||
void writeChannelSettings(byte);
|
||||
void writeSerial(uint8_t);
|
||||
void writeSpi(uint8_t);
|
||||
void writeTimeCurrent(void);
|
||||
void writeTimeCurrentSerial(uint32_t newTime);
|
||||
void writeZeroAux(void);
|
||||
void zeroAuxData(void);
|
||||
|
||||
boolean processChar(char character);
|
||||
void processIncomingBoardMode(char character);
|
||||
void processIncomingChannelSettings(char character);
|
||||
void processIncomingLeadOffSettings(char character);
|
||||
// Variables
|
||||
boolean boardUseSRB1; // used to keep track of if we are using SRB1
|
||||
boolean daisyPresent;
|
||||
boolean daisyUseSRB1;
|
||||
boolean streaming;
|
||||
boolean useInBias[OPENBCI_NUMBER_OF_CHANNELS_DAISY]; // used to remember if we were included in Bias before channel power down
|
||||
boolean useSRB2[OPENBCI_NUMBER_OF_CHANNELS_DAISY];
|
||||
boolean verbosity; // turn on/off Serial verbosity
|
||||
|
||||
void resetChannelSettingsArrayToDefault(byte channelSettingsArray[][OPENBCI_NUMBER_OF_CHANNEL_SETTINGS]);
|
||||
void resetLeadOffArrayToDefault(byte leadOffArray[][OPENBCI_NUMBER_OF_LEAD_OFF_SETTINGS]);
|
||||
byte boardChannelDataRaw[OPENBCI_NUMBER_BYTES_PER_ADS_SAMPLE]; // array to hold raw channel data
|
||||
byte channelSettings[OPENBCI_NUMBER_OF_CHANNELS_DAISY][OPENBCI_NUMBER_OF_CHANNEL_SETTINGS]; // array to hold current channel settings
|
||||
byte daisyChannelDataRaw[OPENBCI_NUMBER_BYTES_PER_ADS_SAMPLE];
|
||||
byte defaultChannelSettings[OPENBCI_NUMBER_OF_CHANNEL_SETTINGS]; // default channel settings
|
||||
byte lastBoardDataRaw[OPENBCI_NUMBER_BYTES_PER_ADS_SAMPLE];
|
||||
byte lastDaisyDataRaw[OPENBCI_NUMBER_BYTES_PER_ADS_SAMPLE];
|
||||
byte leadOffSettings[OPENBCI_NUMBER_OF_CHANNELS_DAISY][OPENBCI_NUMBER_OF_LEAD_OFF_SETTINGS]; // used to control on/off of impedance measure for P and N side of each channel
|
||||
byte meanBoardDataRaw[OPENBCI_NUMBER_BYTES_PER_ADS_SAMPLE];
|
||||
byte meanDaisyDataRaw[OPENBCI_NUMBER_BYTES_PER_ADS_SAMPLE];
|
||||
byte sampleCounter;
|
||||
|
||||
void sendChannelDataWithAccel(void);
|
||||
void sendChannelDataWithRawAux(void);
|
||||
void sendChannelDataWithTimeAndAccel(void);
|
||||
void sendChannelDataWithTimeAndRawAux(void);
|
||||
int boardChannelDataInt[OPENBCI_NUMBER_CHANNELS_PER_ADS_SAMPLE]; // array used when reading channel data as ints
|
||||
int daisyChannelDataInt[OPENBCI_NUMBER_CHANNELS_PER_ADS_SAMPLE]; // array used when reading channel data as ints
|
||||
int lastBoardChannelDataInt[OPENBCI_NUMBER_CHANNELS_PER_ADS_SAMPLE];
|
||||
int lastDaisyChannelDataInt[OPENBCI_NUMBER_CHANNELS_PER_ADS_SAMPLE];
|
||||
int meanBoardChannelDataInt[OPENBCI_NUMBER_CHANNELS_PER_ADS_SAMPLE];
|
||||
int meanDaisyChannelDataInt[OPENBCI_NUMBER_CHANNELS_PER_ADS_SAMPLE];
|
||||
int numChannels;
|
||||
|
||||
void streamSafeChannelDeactivate(byte channelNumber);
|
||||
void streamSafeChannelActivate(byte channelNumber);
|
||||
void streamSafeChannelSettingsForChannel(byte channelNumber, byte powerDown, byte gain, byte inputType, byte bias, byte srb2, byte srb1);
|
||||
void streamSafeSetAllChannelsToDefault(void);
|
||||
void streamSafeReportAllChannelDefaults(void);
|
||||
void streamSafeLeadOffSetForChannel(byte channelNumber, byte pInput, byte nInput);
|
||||
void streamSafeTimeSendSyncSetPacket(void);
|
||||
void streamStart(void);
|
||||
void streamStop(void);
|
||||
short auxData[3]; // This is user faceing
|
||||
short axisData[3];
|
||||
|
||||
// OLD CODE REVERT
|
||||
void writeChannelSettings();
|
||||
void writeChannelSettings(byte N);
|
||||
void changeChannelLeadOffDetect();
|
||||
void changeChannelLeadOffDetect(byte N);
|
||||
void configureLeadOffDetection(byte amplitudeCode, byte freqCode);
|
||||
unsigned long lastSampleTime;
|
||||
|
||||
boolean waitForNewChannelData(void);
|
||||
volatile boolean channelDataAvailable;
|
||||
|
||||
// Variables
|
||||
boolean daisy;
|
||||
boolean sniffMode;
|
||||
boolean streaming;
|
||||
boolean timeSynced;
|
||||
boolean sendTimeSyncUpPacket;
|
||||
boolean isProcessingIncomingSettingsChannel;
|
||||
boolean isProcessingIncomingSettingsLeadOff;
|
||||
boolean settingBoardMode;
|
||||
volatile boolean channelDataAvailable;
|
||||
// ENUMS
|
||||
ACCEL_MODE curAccelMode;
|
||||
BOARD_MODE curBoardMode;
|
||||
PACKET_TYPE curPacketType;
|
||||
SAMPLE_RATE curSampleRate;
|
||||
TIME_SYNC_MODE curTimeSyncMode;
|
||||
|
||||
boolean isProcessingMultibyteMsg(void);
|
||||
boolean isValidBoardType(char c);
|
||||
// STRUCTS
|
||||
BLE ble;
|
||||
SerialInfo iSerial0;
|
||||
SerialInfo iSerial1;
|
||||
|
||||
uint8_t curBoardMode;
|
||||
// Class Objects
|
||||
DSPI0 spi; // use DSPI library
|
||||
|
||||
int numberOfIncomingSettingsProcessedChannel;
|
||||
int numberOfIncomingSettingsProcessedLeadOff;
|
||||
char streamPacketType;
|
||||
char currentChannelSetting;
|
||||
// #ifdef __OpenBCI_Wifi_Master__
|
||||
void accelWriteAxisDataWifi(void);
|
||||
void ADS_writeChannelDataWifi(boolean daisy);
|
||||
void writeAuxDataWifi(void);
|
||||
void writeTimeCurrentWifi(uint32_t newTime);
|
||||
// #endif
|
||||
|
||||
// Getters
|
||||
char getChannelCommandForAsciiChar(char asciiChar);
|
||||
char getConstrainedChannelNumber(byte channelNumber);
|
||||
byte getDefaultChannelSettingForSetting(byte setting);
|
||||
char getDefaultChannelSettingForSettingAscii(byte setting);
|
||||
char getGainForAsciiChar(char asciiChar);
|
||||
char getNumberForAsciiChar(char asciiChar);
|
||||
char getTargetSSForConstrainedChannelNumber(byte channelNumber);
|
||||
char getYesOrNoForAsciiChar(char asciiChar);
|
||||
private:
|
||||
|
||||
DSPI0 spi; // use DSPI library
|
||||
byte ADS_getDeviceID(int);
|
||||
void boardBeginADSInterrupt(void);
|
||||
boolean boardBegin(void);
|
||||
boolean boardBeginDebug(void);
|
||||
boolean boardBeginDebug(int);
|
||||
void changeInputType(byte);
|
||||
int getX(void);
|
||||
int getY(void);
|
||||
int getZ(void);
|
||||
void initialize(void);
|
||||
void initialize_accel(byte); // initialize
|
||||
void initialize_ads(void);
|
||||
void initializeSerialInfo(SerialInfo);
|
||||
void initializeVariables(void);
|
||||
void initializeSpiInfo(SpiInfo);
|
||||
byte LIS3DH_getDeviceID(void);
|
||||
byte LIS3DH_read(byte); // read a register on LIS3DH
|
||||
int LIS3DH_read16(byte); // read two bytes, used to get axis data
|
||||
void LIS3DH_write(byte,byte); // write a register on LIS3DH
|
||||
boolean LIS3DH_DataReady(void); // check LIS3DH_DRDY pin
|
||||
boolean LIS3DH_DataAvailable(void); // check LIS3DH STATUS_REG2
|
||||
void LIS3DH_readAllRegs(void);
|
||||
void LIS3DH_writeAxisDataSerial(void);
|
||||
void LIS3DH_writeAxisDataForAxisSerial(uint8_t);
|
||||
void LIS3DH_updateAxisData(void);
|
||||
void LIS3DH_zeroAxisData(void);
|
||||
void printADSregisters(int);
|
||||
void printAllRegisters(void);
|
||||
void printFailure();
|
||||
void printHex(byte);
|
||||
void printlnHex(byte);
|
||||
void printRegisterName(byte);
|
||||
void printSuccess();
|
||||
void RDATA(int); // read data one-shot
|
||||
void RDATAC(int); // go into read data continuous mode
|
||||
void RESET(int); // set all register values to default
|
||||
byte RREG(byte,int); // read one ADS register
|
||||
void RREGS(byte,byte,int); // read multiple ADS registers
|
||||
void SDATAC(int); // get out of read data continuous mode
|
||||
void sendChannelDataSerial(PACKET_TYPE);
|
||||
void sendChannelDataSerialBLE(PACKET_TYPE packetType);
|
||||
void sendTimeWithAccelSerial(void);
|
||||
void sendTimeWithRawAuxSerial(void);
|
||||
void STANDBY(int); // go into low power mode
|
||||
void START(int); // start data acquisition
|
||||
void STOP(int); // stop data acquisition
|
||||
void WAKEUP(int); // get out of low power mode
|
||||
void WREG(byte,byte,int); // write one ADS register
|
||||
void WREGS(byte,byte,int); // write multiple ADS registers
|
||||
byte xfer(byte); // SPI Transfer function
|
||||
|
||||
// BOARD
|
||||
boolean useAccel;
|
||||
boolean useAux;
|
||||
void initialize(void);
|
||||
void initializeVariables(void);
|
||||
void printAllRegisters(void);
|
||||
void sendChannelData(void); // send the current data with sample number
|
||||
|
||||
|
||||
// ADS1299
|
||||
void initialize_ads(void);
|
||||
void setChannelsToDefault(void);
|
||||
void reportDefaultChannelSettings(void);
|
||||
void printADSregisters(int);
|
||||
void WAKEUP(int); // get out of low power mode
|
||||
void STANDBY(int); // go into low power mode
|
||||
void RESET(int); // set all register values to default
|
||||
void START(int); // start data acquisition
|
||||
void STOP(int); // stop data acquisition
|
||||
void RDATAC(int); // go into read data continuous mode
|
||||
void SDATAC(int); // get out of read data continuous mode
|
||||
void RDATA(int); // read data one-shot
|
||||
byte RREG(byte,int); // read one ADS register
|
||||
void RREGS(byte,byte,int); // read multiple ADS registers
|
||||
void WREG(byte,byte,int); // write one ADS register
|
||||
void WREGS(byte,byte,int); // write multiple ADS registers
|
||||
byte ADS_getDeviceID(int);
|
||||
void printRegisterName(byte); // used for verbosity
|
||||
void printHex(byte); // used for verbosity
|
||||
void updateChannelData(void); // retrieve data from ADS
|
||||
void updateBoardData(void);
|
||||
void updateDaisyData(void);
|
||||
byte xfer(byte); // SPI Transfer function
|
||||
void resetADS(int); // reset all the ADS1299's settings
|
||||
void startADS(void);
|
||||
void stopADS(void);
|
||||
void activateChannel(byte); // enable the selected channel
|
||||
void deactivateChannel(byte); // disable given channel 1-8(16)
|
||||
void configureInternalTestSignal(byte,byte);
|
||||
|
||||
void changeInputType(byte);
|
||||
|
||||
void ADS_writeChannelData(void);
|
||||
// void ADS_printDeviceID(int); //
|
||||
boolean smellDaisy(void);
|
||||
void removeDaisy(void);
|
||||
void attachDaisy(void);
|
||||
void writeAuxData(void);
|
||||
|
||||
short auxData[3]; // This is user faceing
|
||||
byte regData[24]; // array is used to mirror register data
|
||||
byte lastBoardDataRaw[24];
|
||||
byte boardChannelDataRaw[24]; // array to hold raw channel data
|
||||
byte meanBoardDataRaw[24];
|
||||
byte lastDaisyDataRaw[24];
|
||||
byte daisyChannelDataRaw[24];
|
||||
byte meanDaisyDataRaw[24];
|
||||
int boardStat; // used to hold the status register
|
||||
int daisyStat;
|
||||
int boardChannelDataInt[8]; // array used when reading channel data as ints
|
||||
int lastBoardChannelDataInt[8];
|
||||
int meanBoardChannelDataInt[8];
|
||||
int daisyChannelDataInt[8]; // array used when reading channel data as ints
|
||||
int lastDaisyChannelDataInt[8];
|
||||
int meanDaisyChannelDataInt[8];
|
||||
int numChannels;
|
||||
byte channelSettings[OPENBCI_NUMBER_OF_CHANNELS_DAISY][OPENBCI_NUMBER_OF_CHANNEL_SETTINGS]; // array to hold current channel settings
|
||||
byte defaultChannelSettings[OPENBCI_NUMBER_OF_CHANNEL_SETTINGS]; // default channel settings
|
||||
byte leadOffSettings[OPENBCI_NUMBER_OF_CHANNELS_DAISY][OPENBCI_NUMBER_OF_LEAD_OFF_SETTINGS]; // used to control on/off of impedance measure for P and N side of each channel
|
||||
boolean useInBias[OPENBCI_NUMBER_OF_CHANNELS_DAISY]; // used to remember if we were included in Bias before channel power down
|
||||
boolean useSRB2[OPENBCI_NUMBER_OF_CHANNELS_DAISY];
|
||||
boolean boardUseSRB1; // used to keep track of if we are using SRB1
|
||||
boolean daisyUseSRB1;
|
||||
boolean verbosity; // turn on/off Serial verbosity
|
||||
boolean daisyPresent;
|
||||
boolean firstDataPacket;
|
||||
byte sampleCounter;
|
||||
|
||||
// LIS3DH
|
||||
short axisData[3];
|
||||
void initialize_accel(byte); // initialize
|
||||
void enable_accel(byte); // start acceleromoeter with default settings
|
||||
void disable_accel(void); // stop data acquisition and go into low power mode
|
||||
byte LIS3DH_getDeviceID(void);
|
||||
byte LIS3DH_read(byte); // read a register on LIS3DH
|
||||
void LIS3DH_write(byte,byte); // write a register on LIS3DH
|
||||
int LIS3DH_read16(byte); // read two bytes, used to get axis data
|
||||
int getX(void);
|
||||
int getY(void);
|
||||
int getZ(void);
|
||||
boolean LIS3DH_DataReady(void); // check LIS3DH_DRDY pin
|
||||
boolean LIS3DH_DataAvailable(void); // check LIS3DH STATUS_REG2
|
||||
void LIS3DH_readAllRegs(void);
|
||||
void LIS3DH_writeAxisData(void);
|
||||
void LIS3DH_writeAxisDataForAxis(uint8_t axis);
|
||||
void LIS3DH_updateAxisData(void);
|
||||
|
||||
void csLow(int);
|
||||
void csHigh(int);
|
||||
|
||||
//
|
||||
boolean boardBegin(void);
|
||||
boolean boardBeginDebug(void);
|
||||
boolean boardBeginDebug(int);
|
||||
void boardReset(void);
|
||||
void ledFlash(int numberOfFlashes);
|
||||
void sendEOT(void);
|
||||
|
||||
char buffer[1];
|
||||
|
||||
// ADS1299
|
||||
boolean isRunning;
|
||||
// LIS3DH
|
||||
int DRDYpinValue;
|
||||
int lastDRDYpinValue;
|
||||
|
||||
// Time sync Variables
|
||||
unsigned long timeOffset;
|
||||
unsigned long timeSetCharArrived;
|
||||
unsigned long timeComputer;
|
||||
unsigned long timeCurrent;
|
||||
// Time sync Methods
|
||||
// unsigned long timeGet(void);
|
||||
// void timeSet(char character);
|
||||
void timeSendSyncSetPacket(void);
|
||||
// Variables
|
||||
boolean commandFromSPI;
|
||||
boolean firstDataPacket;
|
||||
boolean isMultiCharCmd; // A multi char command is in progress
|
||||
boolean isRunning;
|
||||
boolean settingBoardMode;
|
||||
boolean settingSampleRate;
|
||||
boolean newMarkerReceived; // flag to indicate a new marker has been received
|
||||
byte bufferBLEPosition;
|
||||
byte regData[24]; // array is used to mirror register data
|
||||
char buffer[1];
|
||||
char markerValue;
|
||||
char multiCharCommand; // The type of command
|
||||
char currentChannelSetting;
|
||||
char optionalArgBuffer5[5];
|
||||
char optionalArgBuffer6[6];
|
||||
char optionalArgBuffer7[7];
|
||||
int boardStat; // used to hold the status register
|
||||
int daisyStat;
|
||||
int DRDYpinValue;
|
||||
int lastDRDYpinValue;
|
||||
int numberOfIncomingSettingsProcessedChannel;
|
||||
int numberOfIncomingSettingsProcessedLeadOff;
|
||||
int numberOfIncomingSettingsProcessedBoardType;
|
||||
uint8_t optionalArgCounter;
|
||||
unsigned long multiCharCmdTimeout; // the timeout in millis of the current multi char command
|
||||
unsigned long timeOfLastRead;
|
||||
unsigned long timeOfMultiByteMsgStart;
|
||||
|
||||
#ifdef __OpenBCI_Wifi_Master__
|
||||
// functions
|
||||
void LIS3DH_writeAxisDataWifi(void);
|
||||
void LIS3DH_writeAxisDataForAxisWifi(uint8_t);
|
||||
void sendChannelDataWifi(PACKET_TYPE, boolean);
|
||||
void sendRawAuxWifi(void);
|
||||
void sendTimeWithAccelWifi(void);
|
||||
void sendTimeWithRawAuxWifi(void);
|
||||
#endif
|
||||
};
|
||||
|
||||
// This let's us call into the class from within the library if necessary
|
||||
|
||||
@@ -10,31 +10,30 @@
|
||||
#ifndef _____OpenBCI_32bit_Library_Definitions_h
|
||||
#define _____OpenBCI_32bit_Library_Definitions_h
|
||||
|
||||
// The default baud rate
|
||||
// Baud rates
|
||||
#define OPENBCI_BAUD_RATE 115200
|
||||
#define OPENBCI_BAUD_RATE_BLE 9600
|
||||
#define OPENBCI_BAUD_RATE_MIN_NO_AVG 200000
|
||||
|
||||
// File transmissions
|
||||
#define OPENBCI_BOP 'A' // Begining of stream packet
|
||||
#define OPENBCI_EOP_STND_ACCEL 0xC0 // End of standard stream packet
|
||||
#define OPENBCI_EOP_STND_RAW_AUX 0xC1 // End of stream packet with raw packet
|
||||
#define OPENBCI_EOP_USER_DEFINED 0xC2 // End of stream packet, user defined
|
||||
#define OPENBCI_EOP_ACCEL_TIME_SET 0xC3 // End of time sync up with accel stream packet
|
||||
#define OPENBCI_EOP_ACCEL_TIME_SYNCED 0xC4 // End of time synced stream packet
|
||||
#define OPENBCI_EOP_RAW_AUX_TIME_SET 0xC5 // End of time sync up stream packet
|
||||
#define OPENBCI_EOP_RAW_AUX_TIME_SYNCED 0xC6 // End of time synced stream packet
|
||||
|
||||
//PIN CONNECTIONS
|
||||
#define ADS_DRDY 9 // ADS data ready pin
|
||||
#define ADS_RST 4 // ADS reset pin
|
||||
#define BOARD_ADS 8 // ADS chip select
|
||||
#define DAISY_ADS 3 // ADS Daisy chip select
|
||||
#define BOTH_ADS 5 // Slave Select Both ADS chips
|
||||
#define SD_SS 2 // SD card chip select
|
||||
#define LIS3DH_SS 1 // LIS3DH chip select
|
||||
#define LIS3DH_DRDY 0 // LIS3DH data ready pin
|
||||
#define ADS_DRDY 9 // ADS data ready pin
|
||||
#define ADS_RST 4 // ADS reset pin
|
||||
#define BOARD_ADS 8 // ADS chip select
|
||||
#define DAISY_ADS 3 // ADS Daisy chip select
|
||||
#define BOTH_ADS 5 // Slave Select Both ADS chips
|
||||
#define SD_SS 2 // SD card chip select
|
||||
#define LIS3DH_SS 1 // LIS3DH chip select
|
||||
#define LIS3DH_DRDY 0 // LIS3DH data ready pin
|
||||
// #define WIFI_SS 13 // Wifi Chip Select
|
||||
#define OPENBCI_PIN_LED 11
|
||||
#define OPENBCI_PIN_PGC 12
|
||||
// #define WIFI_RESET 18
|
||||
|
||||
#define OPENBCI_PIN_SERIAL1_TX 11
|
||||
#define OPENBCI_PIN_SERIAL1_RX 12
|
||||
|
||||
//ADS1299 SPI Command Definition Byte Assignments
|
||||
#define _WAKEUP 0x02 // Wake-up from standby mode
|
||||
@@ -115,6 +114,9 @@
|
||||
#define ADSTESTSIG_DCSIG (0b00000011)
|
||||
#define ADSTESTSIG_NOCHANGE (0b11111111)
|
||||
|
||||
#define ADS1299_CONFIG1_DAISY (0b10110000)
|
||||
#define ADS1299_CONFIG1_DAISY_NOT (0b10010000)
|
||||
|
||||
//Lead-off signal choices
|
||||
#define LOFF_MAG_6NA (0b00000000)
|
||||
#define LOFF_MAG_24NA (0b00000100)
|
||||
@@ -324,18 +326,24 @@
|
||||
#define OPENBCI_CHANNEL_MAX_NUMBER_8 'c'
|
||||
#define OPENBCI_CHANNEL_MAX_NUMBER_16 'C'
|
||||
|
||||
/** Set Packet Type */
|
||||
#define OPENBCI_BOARD_MODE_SET '/'
|
||||
#define OPENBCI_BOARD_MODE_DEFAULT '0'
|
||||
#define OPENBCI_BOARD_MODE_DEBUG '1'
|
||||
#define OPENBCI_BOARD_MODE_WIFI '2'
|
||||
#define OPENBCI_BOARD_MODE_INPUT_ANALOG '3'
|
||||
#define OPENBCI_BOARD_MODE_INPUT_DIGITAL '4'
|
||||
|
||||
/** Set sample rate */
|
||||
#define OPENBCI_SAMPLE_RATE_SET '~'
|
||||
|
||||
/** Insert marker into the stream */
|
||||
#define OPENBCI_INSERT_MARKER '`'
|
||||
|
||||
/** Sync Clocks */
|
||||
#define OPENBCI_TIME_SET '<'
|
||||
#define OPENBCI_TIME_STOP '>'
|
||||
|
||||
/** Wifi Stuff */
|
||||
#define OPENBCI_WIFI_ATTACH '{'
|
||||
#define OPENBCI_WIFI_REMOVE '}'
|
||||
#define OPENBCI_WIFI_STATUS ':'
|
||||
#define OPENBCI_WIFI_RESET ';'
|
||||
|
||||
/** Possible number of channels */
|
||||
#define OPENBCI_NUMBER_OF_CHANNELS_DAISY 16
|
||||
#define OPENBCI_NUMBER_OF_CHANNELS_DEFAULT 8
|
||||
@@ -349,20 +357,19 @@
|
||||
#define OPENBCI_SAMPLE_RATE_125 125
|
||||
#define OPENBCI_SAMPLE_RATE_250 250
|
||||
|
||||
/** Time out for multi char commands **/
|
||||
#define MULTI_CHAR_COMMAND_TIMEOUT_MS 1000
|
||||
|
||||
/** Packet Size */
|
||||
#define OPENBCI_PACKET_SIZE 33
|
||||
|
||||
#define OPENBCI_NUMBER_BYTES_PER_ADS_SAMPLE 24
|
||||
#define OPENBCI_NUMBER_CHANNELS_PER_ADS_SAMPLE 24
|
||||
|
||||
/** Impedance Calculation Variables */
|
||||
#define OPENBCI_LEAD_OFF_DRIVE_AMPS 0.000000006
|
||||
#define OPENBCI_LEAD_OFF_FREQUENCY_HZ 31
|
||||
|
||||
/** Raw data packet types/codes */
|
||||
#define OPENBCI_PACKET_TYPE_V3 0 // 0000
|
||||
#define OPENBCI_PACKET_TYPE_TIME_SYNCED 1 // 0001
|
||||
#define OPENBCI_PACKET_TYPE_TIME_SET 2 // 0010
|
||||
#define OPENBCI_PACKET_TYPE_USER_DEFINED 3 // 0011
|
||||
#define OPENBCI_PACKET_TYPE_RAW_AUX 4 // 0100
|
||||
|
||||
#define OPENBCI_TIME_OUT_MS_1 1
|
||||
#define OPENBCI_TIME_OUT_MS_3 3
|
||||
|
||||
@@ -374,4 +381,13 @@
|
||||
#define OPENBCI_FIRMWARE_VERSION_V1 1
|
||||
#define OPENBCI_FIRMWARE_VERSION_V2 1
|
||||
|
||||
#define OPENBCI_ADS_BYTES_PER_CHAN 3
|
||||
#define OPENBCI_ADS_CHANS_PER_BOARD 8
|
||||
|
||||
/** BLE Packet Information */
|
||||
#define BLE_BYTES_PER_PACKET 20
|
||||
#define BLE_BYTES_PER_SAMPLE 6
|
||||
#define BLE_SAMPLES_PER_PACKET 3
|
||||
#define BLE_TOTAL_DATA_BYTES 18
|
||||
|
||||
#endif
|
||||
|
||||
+106
-76
@@ -1,8 +1,7 @@
|
||||
[](https://waffle.io/OpenBCI/OpenBCI_32bit_Library)
|
||||
# OpenBCI 32bit Library
|
||||
|
||||
The (soon to be) official library for the OpenBCI 32bit Board.
|
||||
|
||||
The official library for the OpenBCI 32bit Board.
|
||||
|
||||
## Table of Contents:
|
||||
|
||||
@@ -17,7 +16,7 @@ The (soon to be) official library for the OpenBCI 32bit Board.
|
||||
4. [System Overview](#systemOverview)
|
||||
5. [Reference Guide](#referenceGuide)
|
||||
1. [Functions](#functions)
|
||||
2. [Constants](#constants)
|
||||
2. [Enums](#enums)
|
||||
|
||||
## <a name="minimums"></a> Minimums:
|
||||
|
||||
@@ -88,7 +87,7 @@ You do not need to declare any variables...
|
||||
```Arduino
|
||||
void setup() {
|
||||
board.begin(); // Bring up the OpenBCI Board
|
||||
board.useAccel = true; // Notify the board we want to use accel data, this effects `::sendChannelData()`
|
||||
// The board will use accel data by default
|
||||
}
|
||||
```
|
||||
|
||||
@@ -96,14 +95,7 @@ void setup() {
|
||||
```Arduino
|
||||
void setup() {
|
||||
board.begin(); // Bring up the OpenBCI Board
|
||||
board.useAux = true; // Notify the board we want to use aux data, this effects `::sendChannelData()`
|
||||
}
|
||||
```
|
||||
|
||||
#### Bare board
|
||||
```Arduino
|
||||
void setup() {
|
||||
board.begin(); // Bring up the OpenBCI Board
|
||||
board.useAccel(false); // Notify the board we want to use aux data, this effects `::sendChannelData()`
|
||||
}
|
||||
```
|
||||
|
||||
@@ -114,17 +106,13 @@ We will start with the basics here, and work our way up... The loop function can
|
||||
A bare board, not using the SD, accel, or aux data must have the following:
|
||||
```Arduino
|
||||
void loop() {
|
||||
board.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();
|
||||
}
|
||||
board.sendChannelData();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,8 +125,12 @@ void loop() {
|
||||
```
|
||||
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](https://github.com/OpenBCI/OpenBCI_32bit_Library/issues/22). 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.
|
||||
|
||||
|
||||
## <a name="systemOverview"></a> System Overview:
|
||||
|
||||
### Sending Channel Data
|
||||
In the OpenBCI system, and with most wireless systems, we are restricted by the rate at which we can send data.
|
||||
|
||||
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.
|
||||
|
||||
# <a name="referenceGuide"></a> Reference Guide:
|
||||
@@ -185,6 +177,14 @@ Called in every `loop()` and checks `Serial0`.
|
||||
|
||||
`true` if there is data ready to be read.
|
||||
|
||||
### hasDataSerial1()
|
||||
|
||||
Called in every `loop()` and checks `Serial1`.
|
||||
|
||||
**_Returns_** {boolean}
|
||||
|
||||
`true` if there is data ready to be read.
|
||||
|
||||
### processChar(character)
|
||||
|
||||
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.
|
||||
@@ -205,87 +205,117 @@ If `hasDataSerial0()` is `true` then this function is called. Reads from `Serial
|
||||
|
||||
The character from the serial port.
|
||||
|
||||
### getCharSerial1()
|
||||
|
||||
If `hasDataSerial1()` is `true` then this function is called. Reads from `Serial1` which comes from the external serial port. 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.
|
||||
|
||||
### sendChannelData()
|
||||
|
||||
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.
|
||||
Writes channel data, aux data, and footer to serial port or over wifi. Based on global variables `useAux` and `useAccel` Must keep for portability.
|
||||
|
||||
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.
|
||||
|
||||
### sendChannelDataWithAccel()
|
||||
|
||||
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.
|
||||
|
||||
### sendChannelDataWithRawAux()
|
||||
|
||||
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.
|
||||
|
||||
### sendChannelDataWithTimeAndAccel()
|
||||
|
||||
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`
|
||||
|
||||
### sendChannelDataWithTimeAndRawAux()
|
||||
|
||||
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`
|
||||
If `curAccelMode` is ACCEL_MODE_OFF then then sends data from `auxData` array and sets the contents of `auxData` to `0` after send. `board.useAccel(false)`
|
||||
If `curAccelMode` is ACCEL_MODE_ON then then sends data from `axisData` array and sets the contents of `axisData` to `0` after send. `board.useAccel(true)`
|
||||
|
||||
### updateChannelData()
|
||||
|
||||
Called when the board ADS1299 has new data available. If there is a daisy module attached, that data is also fetched here.
|
||||
|
||||
### waitForNewChannelData()
|
||||
## <a name="enums"></a> ENUMS:
|
||||
|
||||
Check status register to see if data is available from the ADS1299.
|
||||
### BOARD_MODE
|
||||
|
||||
**_Returns_** {boolean}
|
||||
Board mode changes the hardware pins.
|
||||
|
||||
`true` if data is available.
|
||||
#### BOARD_MODE_DEFAULT
|
||||
|
||||
## <a name="constants"></a> Constants:
|
||||
`0` - Board will operate leave all pins in default mode.
|
||||
|
||||
### OPENBCI_EOP_STND_ACCEL
|
||||
#### BOARD_MODE_DEBUG
|
||||
|
||||
`0xC0` - End of standard stream packet.
|
||||
`1` - Board will output serial debug data out of the external serial port.
|
||||
|
||||
### OPENBCI_EOP_STND_RAW_AUX
|
||||
#### BOARD_MODE_ANALOG
|
||||
|
||||
`0xC1` - End of stream packet with raw packet.
|
||||
`2` - Board will read from `A6` (`D11`), `A7` (`D12`), and `A8` (`D13`). `A8` is only is use when there is no wifi present. The analog to digital converter is 10bits and the data will be in .
|
||||
|
||||
### OPENBCI_EOP_USER_DEFINED
|
||||
|Pin|Aux Bytes|Notes|
|
||||
|----|----|----|
|
||||
|`A6`|0:1|`D11`|
|
||||
|`A7`|2:3|`D12`|
|
||||
|`A8`|4:5|`D13` - If wifi not present|
|
||||
|
||||
`0xC2` - End of stream packet, user defined.
|
||||
#### BOARD_MODE_DIGITAL
|
||||
|
||||
### OPENBCI_EOP_ACCEL_TIME_SET
|
||||
`3` - Board will read from `D11`, `D12`, `D13` (if wifi not present), `D17`, and `D18` (if wifi not present).
|
||||
|
||||
`0xC3` - End of time sync up with accelerometer stream packet.
|
||||
|Pin|Aux Byte|Notes|
|
||||
|----|----|----|
|
||||
|`D11`|0||
|
||||
|`D11`|1||
|
||||
|`D13`|2|If wifi not present|
|
||||
|`D17`|3||
|
||||
|`D18`|4|If wifi not present|
|
||||
|
||||
### OPENBCI_EOP_ACCEL_TIME_SYNCED
|
||||
### PACKET_TYPE
|
||||
|
||||
`0xC4` - End of time synced stream packet.
|
||||
#### PACKET_TYPE_ACCEL
|
||||
|
||||
### OPENBCI_EOP_RAW_AUX_TIME_SET
|
||||
`0` - End of standard stream packet.
|
||||
|
||||
`0xC5` - End of time sync up stream packet.
|
||||
#### PACKET_TYPE_RAW_AUX
|
||||
|
||||
### OPENBCI_EOP_RAW_AUX_TIME_SYNCED
|
||||
`1` - End of stream packet with raw packet.
|
||||
|
||||
`0xC6` - End of time synced stream packet.
|
||||
#### PACKET_TYPE_USER_DEFINED
|
||||
|
||||
`2` - End of stream packet, user defined.
|
||||
|
||||
#### PACKET_TYPE_ACCEL_TIME_SET
|
||||
|
||||
`3` - End of time sync up with accelerometer stream packet.
|
||||
|
||||
#### PACKET_TYPE_ACCEL_TIME_SYNC
|
||||
|
||||
`4` - End of time synced stream packet.
|
||||
|
||||
#### PACKET_TYPE_RAW_AUX_TIME_SET
|
||||
|
||||
`5` - End of time sync up stream packet.
|
||||
|
||||
#### PACKET_TYPE_RAW_AUX_TIME_SYNC
|
||||
|
||||
`6` - End of time synced stream packet.
|
||||
|
||||
### SAMPLE_RATE
|
||||
|
||||
#### SAMPLE_RATE_16000
|
||||
|
||||
`0` - Sample rate 16000Hz
|
||||
|
||||
#### SAMPLE_RATE_8000
|
||||
|
||||
`1` - Sample rate 8000Hz
|
||||
|
||||
#### SAMPLE_RATE_4000
|
||||
|
||||
`2` - Sample rate 4000Hz
|
||||
|
||||
#### SAMPLE_RATE_2000
|
||||
|
||||
`3` - Sample rate 2000Hz
|
||||
|
||||
#### SAMPLE_RATE_1000
|
||||
|
||||
`4` - Sample rate 1000Hz
|
||||
|
||||
#### SAMPLE_RATE_500
|
||||
|
||||
`5` - Sample rate 500Hz
|
||||
|
||||
#### SAMPLE_RATE_250
|
||||
|
||||
`6` - Sample rate 250Hz
|
||||
|
||||
+33
-1
@@ -1,6 +1,38 @@
|
||||
# OpenBCI 32bit Upgrade Guide
|
||||
|
||||
The purpose of this document is to provide instruction, resources, and advice for upgrading an OpenBCI 32bit 8-16 channel board firmware.
|
||||
The purpose of this document is to provide instruction, resources, and advice for upgrading an OpenBCI Cyton 8-16 channel board firmware.
|
||||
|
||||
## Upgrading to 3.0.0
|
||||
|
||||
### Upgrading from 2.x.x
|
||||
|
||||
Flash the `Pic` with [`DefaultBoard`](https://github.com/OpenBCI/OpenBCI_32bit_Library/blob/master/examples/DefaultBoard/DefaultBoard.ino)
|
||||
|
||||
#### Awesome New Features
|
||||
|
||||
* Wifi shield support
|
||||
* Read from analog or digital ports in a single line or command. (board mode)
|
||||
* Simplified user experience
|
||||
* Variable sample rate with wifi shield or Serial1 (with baud of 468000)
|
||||
|
||||
#### What this update set out to solve
|
||||
|
||||
* Have a single `.sendChannelData()` data function to call that manages the stop byte behind the scenes. I.e. if accel data should be added to aux bytes vs. reading from analog input pins and putting that in the aux bytes.
|
||||
* Add wifi support without breaking any firmware v2.0.0 or v1.0.0 features.
|
||||
* Prevent users from having to upload custom code to the pic
|
||||
|
||||
#### In depth tutorials
|
||||
* [How to get/install/upload code to Pic32 `Board`](http://docs.openbci.com/tutorials/02-Upload_Code_to_OpenBCI_Board#upload-code-to-openbci-board-32bit-upload-how-to-firmware-version-2xx-fall-2016)
|
||||
|
||||
#### New commands
|
||||
|
||||
* [Set Board Mode]()
|
||||
* [Set sample rate]()
|
||||
* [Wifi attach/remove/status]()
|
||||
|
||||
### Upgrading from 1.x.x
|
||||
|
||||
Read *Upgrading to 2.0.0* below:
|
||||
|
||||
## Upgrading to 2.0.0
|
||||
|
||||
|
||||
+143
@@ -1,3 +1,146 @@
|
||||
# v3.0.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Add wifi shield support.
|
||||
* Simply add [OpenBCI_Wifi_Master](https://github.com/OpenBCI/OpenBCI_Wifi_Master_Library) to your `DefaultBoard.ino` and add `wifi.loop()` to your loop function. If you want to read from it checkout the `DefaultBoard.ino` for it's simple interface.
|
||||
* Send channel gains to wifi shield at start of stream
|
||||
* takes ~4 seconds for the wifi shield to be reachable
|
||||
* Add ability to turn external serial port `Serial1` on through commands.
|
||||
* Change board types on the fly! No longer do you have to upload new code to the Cyton's Pic32 just to do an analog read. You can now read from analog or digital pins with the press send of a code! `'/x'` now sets the board mode, where x can be one of the following:
|
||||
* BOARD_MODE_DEFAULT is `0`
|
||||
* BOARD_MODE_DEBUG is `1`
|
||||
* BOARD_MODE_ANALOG is `2`
|
||||
* BOARD_MODE_DIGITAL is `3`
|
||||
* BOARD_MODE_MARKER is `4`
|
||||
* BOARD_MODE_BLE is `5`
|
||||
* A new board mode called MARKER. In this mode, if a command in the format of ``'`n'`` (where n is ASCII '0':'9') is received by the Cyton over any of the serial streams (including wifi) then a marker of int(n) is inserted in the AUX1 channel. Note that this mode is mutually exclusive to the DEFAULT (accelerometer mode) as it uses the AUX1/ACCELX channel.
|
||||
* A new board mode called BLE. In this mode, the board will switch `Serial0` to `9600` and will downsample 2 channels to 125Hz and send them 3 samples in a packet for a total of 18 data bytes. The RFduino would then take this packet and send it over BLE.
|
||||
* Add loop function for internal timing operations related to power on reset for wifi shield, remove `loop` to free up pins and such and remove wifi capability.
|
||||
* Add function to turn time stamps on `useTimeStamp(true)`, time stamps are disabled by default. Note the Wifi shield will use NTP time stamps.
|
||||
* Add wifi commands:
|
||||
* _OpenBCI Wifi Attach_ - `{`
|
||||
* _OpenBCI Wifi Remove_ - `}`
|
||||
* _OpenBCI Wifi Status_ - `:`
|
||||
* _OpenBCI Wifi Reset_ - `;`
|
||||
* Variable sample rate in the format of **~(COMMAND)**. This works similar to the Channel Settings commands, however, there is no latching character. Changing the sample rate requires sending a `v` or soft-reset to ensure all systems are correct. Power cycling the OpenBCI board will cause the sample rate to reset back to default of 250Hz. **IMPORTANT!** The Cyton cannot and will not stream data over 250SPS. Plug in the wifi shield to get speeds over 250SPS streaming. You may still write to an SD card though, the firmware will not send EEG data over the Bluetooth radios. Check out the new commands:
|
||||
* 0 = 16000 Hz
|
||||
* 1 = 8000 Hz
|
||||
* 2 = 4000 Hz
|
||||
* 3 = 2000 Hz
|
||||
* 4 = 1000 Hz
|
||||
* 5 = 500 Hz
|
||||
* 6 = 250 Hz
|
||||
* ~ = Get current sample rate
|
||||
* **EXAMPLE**
|
||||
* First, user sends **~~**
|
||||
* **returns** `Sample rate is 250Hz$$$`
|
||||
* Then, user sends **~5**
|
||||
* **returns** Sample rate set to 500Hz$$$
|
||||
|
||||
### Enhancements
|
||||
|
||||
* `hasDataSerial0` and `hasDataSerial1` use new properties `SerialInfo` to determine if data should be received. Now safe to call every loop.
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* Removed boolean `useAccel` in support of new mode paradigm. To use the accel, do nothing, it's enabled by default, to not use the accel simply call `useAccel(false)` and this library will automatically send the contents of `auxData` array each packet.
|
||||
* Removed `OPENBCI_EOP_STND_ACCEL`, `OPENBCI_EOP_STND_RAW_AUX`, `OPENBCI_EOP_USER_DEFINED`, `OPENBCI_EOP_ACCEL_TIME_SET`, `OPENBCI_EOP_ACCEL_TIME_SYNCED`, `OPENBCI_EOP_RAW_AUX_TIME_SET`, and `OPENBCI_EOP_RAW_AUX_TIME_SYNCED` in place of `enum` support replacement: `PACKET_TYPE_ACCEL`, `PACKET_TYPE_RAW_AUX`, `PACKET_TYPE_USER_DEFINED`, `PACKET_TYPE_ACCEL_TIME_SET`, `PACKET_TYPE_ACCEL_TIME_SYNC`, `PACKET_TYPE_RAW_AUX_TIME_SET`, and `PACKET_TYPE_RAW_AUX_TIME_SYNC`.
|
||||
* Removed `sniffMode` in place for `curBoardMode == OPENBCI_BOARD_MODE_DEBUG`
|
||||
* Removed public `waitForNewChannelData()`
|
||||
* Removed public `timeSynced` and private `sendTimeSyncUpPacket`
|
||||
* Setting internal test signal now, when not streaming, returns a success message, with EOT `$$$`
|
||||
* Sending multi char messages now times out after a second of not completing the multichar message.
|
||||
|
||||
## Release Candidate 7
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Sending data for register query took too long to send, removed delay when command came from wifi.
|
||||
* Setting board mode restarted board for no real reason.
|
||||
|
||||
### New Features
|
||||
|
||||
* Marker mode, where you can store markers to the stream. Send a `/4` to engage this mode.
|
||||
|
||||
## Release Candidate 6
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Even when command came from wifi, library printed to `Serial0`, which resulted in overflow of radio buffer which led to a reset.
|
||||
|
||||
## Release Candidate 5
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Calling `boardBeginDebug(void)` would result in debug not working.
|
||||
* Closes #69 with once second timeout on multi byte messages.
|
||||
|
||||
## Release Candidate 4
|
||||
|
||||
### Enhancements
|
||||
|
||||
* Can now send long messages to Wifi shield which will allow for the GUI to understand the the channel settings for each channel on the Cyton. Required changing a ton of `Serial0.print` to `printAll` and `Serial0.println` to `printlnAll`.
|
||||
* Send response when stopping and starting streaming to wifi shield if present, will not send to Serial ever.
|
||||
|
||||
## Release Candidate 3
|
||||
|
||||
Fix the library.properties file again...
|
||||
|
||||
## Release Candidate 2
|
||||
|
||||
Had to fix the library.properties file
|
||||
|
||||
## Release Candidate 1
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* Stop sending wifi connection status on connect
|
||||
|
||||
## Beta5
|
||||
|
||||
### New Features
|
||||
|
||||
* Send gains after connecting to Wifi shield
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* Don't send streaming data over bluetooth when wifi is present and attached
|
||||
|
||||
## Beta4
|
||||
|
||||
The overall goal was to clean the wifi code out of the library so it would not be needed when you are building a bare board.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed the `BoardWithAnalogSensor.ino`, `BoardWithDigitalRead.ino` and `BoardWithCustomData.ino` examples.
|
||||
* Board did not send serial data with allowed sample rates over bluetooth.
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* Removed all wifi code and put into [new library](https://github.com/OpenBCI/OpenBCI_Wifi_Master_Library) that must be included! The new library is a called [OpenBCI_Wifi_Master_Library](https://github.com/OpenBCI/OpenBCI_Wifi_Master_Library). It is simply included when wifi is wanted.
|
||||
* Removed `.loop()` function from library.
|
||||
|
||||
### Files
|
||||
|
||||
* Add `BoardWithWifi.ino` example that shows a bare board with just wifi. No SD or ACCEL for example.
|
||||
|
||||
## Beta3
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixes erroneous print out on seeking wifi overall `Serial0`.
|
||||
|
||||
## Beta2
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* Setting internal test signal now, when not streaming, returns a success message, with EOT $$$
|
||||
|
||||
## Beta1
|
||||
|
||||
* Initial Release
|
||||
|
||||
# v2.0.1
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
#include <DSPI.h>
|
||||
#include <OpenBCI_32bit_Library.h>
|
||||
#include <OpenBCI_32Bit_Library_Definitions.h>
|
||||
|
||||
void setup() {
|
||||
// Bring up the OpenBCI Board
|
||||
board.beginDebug();
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
if (board.hasDataSerial1()) {
|
||||
// Read one char and process it
|
||||
board.processChar(board.getCharSerial1());
|
||||
}
|
||||
}
|
||||
+8
-13
@@ -5,26 +5,21 @@
|
||||
void setup() {
|
||||
// Bring up the OpenBCI Board
|
||||
board.begin();
|
||||
// Don't use the accel
|
||||
board.useAccel(false);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
// Send that channel data
|
||||
board.sendChannelData();
|
||||
}
|
||||
}
|
||||
// Check the serial port for new data
|
||||
if (board.hasDataSerial0()) {
|
||||
// Read one char and process it
|
||||
board.processChar(board.getCharSerial0());
|
||||
}
|
||||
// Check the serial ports for new data
|
||||
if (board.hasDataSerial0()) board.processChar(board.getCharSerial0());
|
||||
if (board.hasDataSerial1()) board.processChar(board.getCharSerial1());
|
||||
board.loop();
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <DSPI.h>
|
||||
#include <OpenBCI_32bit_Library.h>
|
||||
#include <OpenBCI_32Bit_Library_Definitions.h>
|
||||
|
||||
void setup() {
|
||||
// Bring up the OpenBCI Board
|
||||
board.beginDebug();
|
||||
// don't use accel
|
||||
board.useAccel(false);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (board.streaming) {
|
||||
if (board.channelDataAvailable) {
|
||||
// Read from the ADS(s), store data, set channelDataAvailable flag to false
|
||||
board.updateChannelData();
|
||||
// Send channel data
|
||||
board.sendChannelData();
|
||||
}
|
||||
}
|
||||
|
||||
// Check the serial ports for new data
|
||||
if (board.hasDataSerial0()) board.processChar(board.getCharSerial0());
|
||||
if (board.hasDataSerial1()) board.processChar(board.getCharSerial1());
|
||||
board.loop();
|
||||
}
|
||||
@@ -26,11 +26,8 @@ void setup() {
|
||||
// Bring up the OpenBCI Board
|
||||
board.begin();
|
||||
|
||||
// Notify the board we don't want to use accel data
|
||||
board.useAccel = false;
|
||||
|
||||
// Notify the board we want to use aux data, this effects `::sendChannelData()`
|
||||
board.useAux = true;
|
||||
// Notify the board we don't want to use accel data and use aux
|
||||
board.useAccel(false);
|
||||
|
||||
// Configure two external triggers
|
||||
pinMode(leftButton, INPUT); // set the button pin direction
|
||||
@@ -73,7 +70,7 @@ void loop() {
|
||||
writeDataToSDcard(board.sampleCounter);
|
||||
}
|
||||
|
||||
// Send standard packet with channel data and accel data
|
||||
// Send standard packet with channel data and aux data
|
||||
// includes aux data because we set told the board to add it
|
||||
board.sendChannelData();
|
||||
}
|
||||
@@ -106,4 +103,5 @@ void loop() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
board.loop();
|
||||
}
|
||||
|
||||
@@ -7,11 +7,10 @@ void setup() {
|
||||
board.begin();
|
||||
|
||||
// Notify the board we want to use accel data
|
||||
board.useAccel = true;
|
||||
board.useAccel(true);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
// The main dependency of this single threaded microcontroller is to
|
||||
// stream data from the ADS.
|
||||
if (board.streaming) {
|
||||
@@ -26,17 +25,12 @@ void loop() {
|
||||
}
|
||||
|
||||
// Send standard packet with channel data
|
||||
if (board.timeSynced) {
|
||||
board.sendChannelDataWithTimeAndAccel();
|
||||
} else {
|
||||
board.sendChannelDataWithAccel();
|
||||
}
|
||||
board.sendChannelData();
|
||||
}
|
||||
}
|
||||
|
||||
// Check the serial port for new data
|
||||
if (board.hasDataSerial0()) {
|
||||
// Read one char and process it
|
||||
board.processChar(board.getCharSerial0());
|
||||
}
|
||||
// Check the serial ports for new data
|
||||
if (board.hasDataSerial0()) board.processChar(board.getCharSerial0());
|
||||
if (board.hasDataSerial1()) board.processChar(board.getCharSerial1());
|
||||
board.loop();
|
||||
}
|
||||
|
||||
@@ -2,16 +2,22 @@
|
||||
#include <OpenBCI_32bit_Library.h>
|
||||
#include <OpenBCI_32Bit_Library_Definitions.h>
|
||||
|
||||
// NOTE: THIS DOES NOT HAVE SD
|
||||
|
||||
void setup() {
|
||||
// Bring up the OpenBCI Board
|
||||
board.begin();
|
||||
|
||||
// Notify the board we want to use aux data, this effects `::sendChannelData()`
|
||||
board.useAux = true;
|
||||
// Read from the analog sensor and store auxiliary position 0
|
||||
// take a reading from the ADC. Result range from 0 to 1023
|
||||
// Will put 10 bits from:
|
||||
// Aux 1:2 D11 (A5)
|
||||
// Aux 3:4 D12 (A6)
|
||||
// Aux 5:6 D17 (A7)
|
||||
board.setBoardMode(board.BOARD_MODE_ANALOG);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
// The main dependency of this single threaded microcontroller is to
|
||||
// stream data from the ADS.
|
||||
if (board.streaming) {
|
||||
@@ -19,24 +25,13 @@ void loop() {
|
||||
// Read from the ADS(s), store data, set channelDataAvailable flag to false
|
||||
board.updateChannelData();
|
||||
|
||||
// Read from the analog sensor and store auxiliary position 0
|
||||
// take a reading from the ADC. Result range from 0 to 1023
|
||||
board.auxData[0] = analogRead(A7);
|
||||
|
||||
// Send standard packet with channel data and accel data
|
||||
// includes aux data because we set `useAux` in setup()
|
||||
if (board.timeSynced) {
|
||||
board.sendChannelDataWithTimeAndRawAux();
|
||||
} else {
|
||||
// Send standard packet with channel data
|
||||
board.sendChannelDataWithRawAux();
|
||||
}
|
||||
// Send standard packet with channel data and aux data
|
||||
board.sendChannelData();
|
||||
}
|
||||
}
|
||||
|
||||
// Check the serial port for new data
|
||||
if (board.hasDataSerial0()) {
|
||||
// Read one char and process it
|
||||
board.processChar(board.getCharSerial0());
|
||||
}
|
||||
// Check the serial ports for new data
|
||||
if (board.hasDataSerial0()) board.processChar(board.getCharSerial0());
|
||||
if (board.hasDataSerial1()) board.processChar(board.getCharSerial1());
|
||||
board.loop();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#include <DSPI.h>
|
||||
#include <OpenBCI_32bit_Library.h>
|
||||
#include <OpenBCI_32Bit_Library_Definitions.h>
|
||||
|
||||
void setup() {
|
||||
// Bring up the OpenBCI Board
|
||||
board.begin();
|
||||
// Put it in BLE mode
|
||||
board.setBoardMode(board.BOARD_MODE_BLE);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (board.streaming) {
|
||||
if (board.channelDataAvailable) {
|
||||
// Read from the ADS(s), store data, set channelDataAvailable flag to false
|
||||
board.updateChannelData();
|
||||
// Send that channel data
|
||||
board.sendChannelData();
|
||||
}
|
||||
}
|
||||
// Check the serial ports for new data
|
||||
if (board.hasDataSerial0()) board.processChar(board.getCharSerial0());
|
||||
if (board.hasDataSerial1()) board.processChar(board.getCharSerial1());
|
||||
board.loop();
|
||||
}
|
||||
@@ -17,7 +17,6 @@ void setup() {
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
// Downsample
|
||||
if ((millis() - timer) > 10) {
|
||||
// Save new time
|
||||
@@ -49,7 +48,7 @@ void sendLEDStatus() {
|
||||
Serial0.write(LEDState); // 1 byte
|
||||
// Fill the rest with fake data
|
||||
for (int i = 0; i < 30; i++) {
|
||||
Serial0.write(0x00);
|
||||
Serial0.write((uint8_t)0x00);
|
||||
}
|
||||
// Send a stop byte with an `B` or `1011` in the last nibble to indicate a
|
||||
// different packet type.
|
||||
|
||||
@@ -3,43 +3,32 @@
|
||||
#include <OpenBCI_32Bit_Library_Definitions.h>
|
||||
|
||||
void setup() {
|
||||
// Bring up the OpenBCI Board
|
||||
board.begin();
|
||||
// Bring up the OpenBCI Board
|
||||
board.begin();
|
||||
|
||||
// Notify the board we want to use aux data, this effects `::sendChannelData()`
|
||||
board.useAux = true;
|
||||
|
||||
// Set pin to input A0-A5 can be digital input
|
||||
pinMode(17, INPUT);
|
||||
// Read from digital input and store auxiliary position 0
|
||||
// take a reading from the ADC. Result range from 0 to 1023
|
||||
// Will put 10 bits from:
|
||||
// Aux 1:2 D11
|
||||
// Aux 3:4 D12
|
||||
// Aux 5:6 D17
|
||||
board.setBoardMode(board.BOARD_MODE_DIGITAL);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// The main dependency of this single threaded microcontroller is to
|
||||
// stream data from the ADS.
|
||||
if (board.streaming) {
|
||||
if (board.channelDataAvailable) {
|
||||
// Read from the ADS(s), store data, set channelDataAvailable flag to false
|
||||
board.updateChannelData();
|
||||
|
||||
// The main dependency of this single threaded microcontroller is to
|
||||
// stream data from the ADS.
|
||||
if (board.streaming) {
|
||||
if (board.channelDataAvailable) {
|
||||
// Read from the ADS(s), store data, set channelDataAvailable flag to false
|
||||
board.updateChannelData();
|
||||
|
||||
// Read from the analog sensor and store auxiliary position 0
|
||||
// take a reading from the ADC. Result range from 0 to 1023
|
||||
board.auxData[0] = digitalRead(17);
|
||||
|
||||
// Send standard packet with channel data and accel data
|
||||
// includes aux data because we set `useAux` in setup()
|
||||
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());
|
||||
// Send packet with channel data and auxData contents
|
||||
board.sendChannelData();
|
||||
}
|
||||
}
|
||||
// Check the serial ports for new data
|
||||
if (board.hasDataSerial0()) board.processChar(board.getCharSerial0());
|
||||
if (board.hasDataSerial1()) board.processChar(board.getCharSerial1());
|
||||
board.loop();
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ void setup() {
|
||||
board.begin();
|
||||
|
||||
// Notify the board we want to use aux data, this effects `::sendChannelData()`
|
||||
board.useAux = true;
|
||||
board.useAccel(false);
|
||||
|
||||
// make an 'I'm alive' blink
|
||||
for(int i=0; i<3; i++){
|
||||
@@ -46,7 +46,6 @@ void setup() {
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
// The main dependency of this single threaded microcontroller is to
|
||||
// stream data from the ADS.
|
||||
if (board.streaming) {
|
||||
@@ -63,9 +62,8 @@ void loop() {
|
||||
board.sendChannelData();
|
||||
}
|
||||
}
|
||||
// Check the serial port for new data
|
||||
if (board.hasDataSerial0()) {
|
||||
// Read one char and process it
|
||||
board.processChar(board.getCharSerial0());
|
||||
}
|
||||
// Check the serial ports for new data
|
||||
if (board.hasDataSerial0()) board.processChar(board.getCharSerial0());
|
||||
if (board.hasDataSerial1()) board.processChar(board.getCharSerial1());
|
||||
board.loop();
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
#include <DSPI.h>
|
||||
#include <OBCI32_SD.h>
|
||||
#include <EEPROM.h>
|
||||
#include <OpenBCI_32bit_Library.h>
|
||||
#include <OpenBCI_32bit_Library_Definitions.h>
|
||||
|
||||
// Booleans Required for SD_Card_Stuff.ino
|
||||
boolean addAccelToSD = false; // On writeDataToSDcard() call adds Accel data to SD card write
|
||||
boolean addAuxToSD = false; // On writeDataToSDCard() call adds Aux data to SD card write
|
||||
boolean SDfileOpen = false; // Set true by SD_Card_Stuff.ino on successful file open
|
||||
|
||||
void setup() {
|
||||
// Bring up the OpenBCI Board
|
||||
board.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (board.streaming) {
|
||||
if (board.channelDataAvailable) {
|
||||
// Read from the ADS(s), store data, set channelDataAvailable flag to false
|
||||
board.updateChannelData();
|
||||
|
||||
// Verify the SD file is open
|
||||
if(SDfileOpen) {
|
||||
// Write to the SD card
|
||||
writeDataToSDcard(board.sampleCounter);
|
||||
}
|
||||
|
||||
// Send standard packet with channel data
|
||||
board.sendChannelData();
|
||||
}
|
||||
}
|
||||
|
||||
// Check the serial port for new data
|
||||
if (board.hasDataSerial0()) {
|
||||
// Read one char from the serial port
|
||||
char newChar = board.getCharSerial0();
|
||||
|
||||
// Send to the sd library for processing
|
||||
sdProcessChar(newChar);
|
||||
|
||||
// Send to the board library
|
||||
board.processChar(newChar);
|
||||
}
|
||||
}
|
||||
@@ -1,423 +0,0 @@
|
||||
|
||||
#define BLOCK_5MIN 11000
|
||||
#define BLOCK_15MIN 33000
|
||||
#define BLOCK_30MIN 66000
|
||||
#define BLOCK_1HR 131000
|
||||
#define BLOCK_2HR 261000
|
||||
#define BLOCK_4HR 521000
|
||||
#define BLOCK_12HR 1561000
|
||||
#define BLOCK_24HR 3122000
|
||||
|
||||
#define OVER_DIM 20 // make room for up to 20 write-time overruns
|
||||
|
||||
|
||||
char fileSize = '0'; // SD file size indicator
|
||||
int blockCounter = 0;
|
||||
|
||||
uint32_t BLOCK_COUNT;
|
||||
SdFile openfile; // want to put this before setup...
|
||||
Sd2Card card(&board.spi,SD_SS);// SPI needs to be init'd before here
|
||||
SdVolume volume;
|
||||
SdFile root;
|
||||
uint8_t* pCache; // array that points to the block buffer on SD card
|
||||
uint32_t MICROS_PER_BLOCK = 2000; // block write longer than this will get flaged
|
||||
uint32_t bgnBlock, endBlock; // file extent bookends
|
||||
int byteCounter = 0; // used to hold position in cache
|
||||
//int blockCounter; // count up to BLOCK_COUNT with this
|
||||
boolean openvol;
|
||||
boolean cardInit = false;
|
||||
boolean fileIsOpen = false;
|
||||
|
||||
struct {
|
||||
uint32_t block; // holds block number that over-ran
|
||||
uint32_t micro; // holds the length of this of over-run
|
||||
} over[OVER_DIM];
|
||||
uint32_t overruns; // count the number of overruns
|
||||
uint32_t maxWriteTime; // keep track of longest write time
|
||||
uint32_t minWriteTime; // and shortest write time
|
||||
uint32_t t; // used to measure total file write time
|
||||
|
||||
byte fileTens, fileOnes; // enumerate succesive files on card and store number in EEPROM
|
||||
char currentFileName[] = "OBCI_00.TXT"; // file name will enumerate in hex 00 - FF
|
||||
prog_char elapsedTime[] PROGMEM = {"\n%Total time mS:\n"}; // 17
|
||||
prog_char minTime[] PROGMEM = { "%min Write time uS:\n"}; // 20
|
||||
prog_char maxTime[] PROGMEM = { "%max Write time uS:\n"}; // 20
|
||||
prog_char overNum[] PROGMEM = { "%Over:\n"}; // 7
|
||||
prog_char blockTime[] PROGMEM = { "%block, uS\n"}; // 11 74 chars + 2 32(16) + 2 16(8) = 98 + (n 32x2) up to 24 overruns...
|
||||
prog_char stopStamp[] PROGMEM = { "%STOP AT\n"}; // used to stamp SD record when stopped by PC
|
||||
prog_char startStamp[] PROGMEM = { "%START AT\n"}; // used to stamp SD record when started by PC
|
||||
|
||||
|
||||
char sdProcessChar(char character) {
|
||||
|
||||
switch (character) {
|
||||
case 'A': // 5min
|
||||
case 'S': // 15min
|
||||
case 'F': // 30min
|
||||
case 'G': // 1hr
|
||||
case 'H': // 2hr
|
||||
case 'J': // 4hr
|
||||
case 'K': // 12hr
|
||||
case 'L': // 24hr
|
||||
case 'a': // 512 blocks
|
||||
fileSize = character;
|
||||
SDfileOpen = setupSDcard(character);
|
||||
break;
|
||||
case 'j': // close the file, if it's open
|
||||
if(SDfileOpen){
|
||||
SDfileOpen = closeSDfile();
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
if(SDfileOpen) {
|
||||
stampSD(ACTIVATE);
|
||||
}
|
||||
break;
|
||||
case 'b':
|
||||
if(SDfileOpen) {
|
||||
stampSD(DEACTIVATE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return character;
|
||||
|
||||
}
|
||||
|
||||
|
||||
boolean setupSDcard(char limit){
|
||||
|
||||
if(!cardInit){
|
||||
if(!card.init(SPI_FULL_SPEED, SD_SS)) {
|
||||
if(!board.streaming) {
|
||||
Serial0.println("initialization failed. Things to check:");
|
||||
Serial0.println("* is a card is inserted?");
|
||||
}
|
||||
// card.init(SPI_FULL_SPEED, SD_SS);
|
||||
} else {
|
||||
if(!board.streaming) {
|
||||
Serial0.println("Wiring is correct and a card is present.");
|
||||
}
|
||||
cardInit = true;
|
||||
}
|
||||
if (!volume.init(card)) { // Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
|
||||
if(!board.streaming) {
|
||||
Serial0.println("Could not find FAT16/FAT32 partition. Make sure you've formatted the card");
|
||||
board.sendEOT();
|
||||
}
|
||||
return fileIsOpen;
|
||||
}
|
||||
}
|
||||
|
||||
// use limit to determine file size
|
||||
switch(limit){
|
||||
case 'h':
|
||||
BLOCK_COUNT = 50; break;
|
||||
case 'a':
|
||||
BLOCK_COUNT = 512; break;
|
||||
case 'A':
|
||||
BLOCK_COUNT = BLOCK_5MIN; break;
|
||||
case 'S':
|
||||
BLOCK_COUNT = BLOCK_15MIN; break;
|
||||
case 'F':
|
||||
BLOCK_COUNT = BLOCK_30MIN; break;
|
||||
case 'G':
|
||||
BLOCK_COUNT = BLOCK_1HR; break;
|
||||
case 'H':
|
||||
BLOCK_COUNT = BLOCK_2HR; break;
|
||||
case 'J':
|
||||
BLOCK_COUNT = BLOCK_4HR; break;
|
||||
case 'K':
|
||||
BLOCK_COUNT = BLOCK_12HR; break;
|
||||
case 'L':
|
||||
BLOCK_COUNT = BLOCK_24HR; break;
|
||||
default:
|
||||
if(!board.streaming) {
|
||||
Serial0.println("invalid BLOCK count");
|
||||
board.sendEOT(); // Write end of transmission because we exit here
|
||||
}
|
||||
return fileIsOpen;
|
||||
}
|
||||
|
||||
incrementFileCounter();
|
||||
openvol = root.openRoot(volume);
|
||||
openfile.remove(root, currentFileName); // if the file is over-writing, let it!
|
||||
|
||||
if (!openfile.createContiguous(root, currentFileName, BLOCK_COUNT*512UL)) {
|
||||
if(!board.streaming) {
|
||||
Serial0.print("createfdContiguous fail");
|
||||
}
|
||||
cardInit = false;
|
||||
}//else{Serial0.print("got contiguous file...");delay(1);}
|
||||
// get the location of the file's blocks
|
||||
if (!openfile.contiguousRange(&bgnBlock, &endBlock)) {
|
||||
if(!board.streaming) {
|
||||
Serial0.print("get contiguousRange fail");
|
||||
}
|
||||
cardInit = false;
|
||||
}//else{Serial0.print("got file range...");delay(1);}
|
||||
// grab the Cache
|
||||
pCache = (uint8_t*)volume.cacheClear();
|
||||
// tell card to setup for multiple block write with pre-erase
|
||||
if (!card.erase(bgnBlock, endBlock)){
|
||||
if(!board.streaming) {
|
||||
Serial0.println("erase block fail");
|
||||
}
|
||||
cardInit = false;
|
||||
}//else{Serial0.print("erased...");delay(1);}
|
||||
if (!card.writeStart(bgnBlock, BLOCK_COUNT)){
|
||||
if(!board.streaming) {
|
||||
Serial0.println("writeStart fail");
|
||||
}
|
||||
cardInit = false;
|
||||
} else{
|
||||
fileIsOpen = true;
|
||||
delay(1);
|
||||
}
|
||||
board.csHigh(SD_SS); // release the spi
|
||||
// initialize write-time overrun error counter and min/max wirte time benchmarks
|
||||
overruns = 0;
|
||||
maxWriteTime = 0;
|
||||
minWriteTime = 65000;
|
||||
byteCounter = 0; // counter from 0 - 512
|
||||
blockCounter = 0; // counter from 0 - BLOCK_COUNT;
|
||||
if(fileIsOpen == true){ // send corresponding file name to controlling program
|
||||
if(!board.streaming) {
|
||||
Serial0.print("Corresponding SD file ");
|
||||
Serial0.println(currentFileName);
|
||||
}
|
||||
}
|
||||
if(!board.streaming) {
|
||||
board.sendEOT();
|
||||
}
|
||||
return fileIsOpen;
|
||||
}
|
||||
|
||||
boolean closeSDfile(){
|
||||
if(fileIsOpen){
|
||||
board.csLow(SD_SS); // take spi
|
||||
card.writeStop();
|
||||
openfile.close();
|
||||
board.csHigh(SD_SS); // release the spi
|
||||
fileIsOpen = false;
|
||||
if(!board.streaming){ // verbosity. this also gets insterted as footer in openFile
|
||||
Serial0.print("Total Elapsed Time: ");Serial0.print(t);Serial0.println(" mS"); //delay(10);
|
||||
Serial0.print("Max write time: "); Serial0.print(maxWriteTime); Serial0.println(" uS"); //delay(10);
|
||||
Serial0.print("Min write time: ");Serial0.print(minWriteTime); Serial0.println(" uS"); //delay(10);
|
||||
Serial0.print("Overruns: "); Serial0.print(overruns); Serial0.println(); //delay(10);
|
||||
if (overruns) {
|
||||
uint8_t n = overruns > OVER_DIM ? OVER_DIM : overruns;
|
||||
Serial0.println("fileBlock,micros");
|
||||
for (uint8_t i = 0; i < n; i++) {
|
||||
Serial0.print(over[i].block); Serial0.print(','); Serial0.println(over[i].micro);
|
||||
}
|
||||
}
|
||||
board.sendEOT();
|
||||
}
|
||||
}else{
|
||||
if(!board.streaming) {
|
||||
Serial0.println("No open file to close");
|
||||
board.sendEOT();
|
||||
}
|
||||
}
|
||||
// delay(100); // cool down
|
||||
return fileIsOpen;
|
||||
}
|
||||
|
||||
void writeDataToSDcard(byte sampleNumber){
|
||||
boolean addComma = true;
|
||||
// convert 8 bit sampleCounter into HEX
|
||||
convertToHex(sampleNumber, 1, addComma);
|
||||
// convert 24 bit channelData into HEX
|
||||
for (int currentChannel = 0; currentChannel < 8; currentChannel++){
|
||||
convertToHex(board.boardChannelDataInt[currentChannel], 5, addComma);
|
||||
if(board.daisyPresent == false){
|
||||
if(currentChannel == 6){
|
||||
addComma = false;
|
||||
if(addAuxToSD || addAccelToSD) {addComma = true;} // format CSV
|
||||
}
|
||||
}
|
||||
}
|
||||
if(board.daisyPresent){
|
||||
for (int currentChannel = 0; currentChannel < 8; currentChannel++){
|
||||
convertToHex(board.daisyChannelDataInt[currentChannel], 5, addComma);
|
||||
if(currentChannel == 6){
|
||||
addComma = false;
|
||||
if(addAuxToSD || addAccelToSD) {addComma = true;} // format CSV
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(addAuxToSD == true){
|
||||
// convert auxData into HEX
|
||||
for(int currentChannel = 0; currentChannel < 3; currentChannel++){
|
||||
convertToHex(board.auxData[currentChannel], 3, addComma);
|
||||
if(currentChannel == 1) addComma = false;
|
||||
}
|
||||
addAuxToSD = false;
|
||||
}// end of aux data log
|
||||
else if(addAccelToSD == true){ // if we have accelerometer data to log
|
||||
// convert 16 bit accelerometer data into HEX
|
||||
for (int currentChannel = 0; currentChannel < 3; currentChannel++){
|
||||
convertToHex(board.axisData[currentChannel], 3, addComma);
|
||||
if(currentChannel == 1) addComma = false;
|
||||
}
|
||||
addAccelToSD = false; // reset addAccel
|
||||
}// end of accelerometer data log
|
||||
|
||||
// add aux data logging...
|
||||
}
|
||||
|
||||
|
||||
void writeCache(){
|
||||
if(blockCounter > BLOCK_COUNT) return;
|
||||
uint32_t tw = micros(); // start block write timer
|
||||
board.csLow(SD_SS); // take spi
|
||||
if(!card.writeData(pCache)) {
|
||||
if (!board.streaming) {
|
||||
Serial0.println("block write fail");
|
||||
board.sendEOT();
|
||||
}
|
||||
} // write the block
|
||||
board.csHigh(SD_SS); // release spi
|
||||
tw = micros() - tw; // stop block write timer
|
||||
if (tw > maxWriteTime) maxWriteTime = tw; // check for max write time
|
||||
if (tw < minWriteTime) minWriteTime = tw; // check for min write time
|
||||
if (tw > MICROS_PER_BLOCK) { // check for overrun
|
||||
if (overruns < OVER_DIM) {
|
||||
over[overruns].block = blockCounter;
|
||||
over[overruns].micro = tw;
|
||||
}
|
||||
overruns++;
|
||||
}
|
||||
byteCounter = 0; // reset 512 byte counter for next block
|
||||
blockCounter++; // increment BLOCK counter
|
||||
if(blockCounter == BLOCK_COUNT-1){
|
||||
t = millis() - t;
|
||||
board.streamStop();
|
||||
// stopRunning();
|
||||
board.disable_accel();
|
||||
writeFooter();
|
||||
}
|
||||
if(blockCounter == BLOCK_COUNT){
|
||||
closeSDfile();
|
||||
BLOCK_COUNT = 0;
|
||||
} // we did it!
|
||||
}
|
||||
|
||||
|
||||
void incrementFileCounter(){
|
||||
fileTens = EEPROM.read(0);
|
||||
fileOnes = EEPROM.read(1);
|
||||
// if it's the first time writing to EEPROM, seed the file number to '00'
|
||||
if(fileTens == 0xFF | fileOnes == 0xFF){
|
||||
fileTens = fileOnes = '0';
|
||||
}
|
||||
fileOnes++; // increment the file name
|
||||
if (fileOnes == ':'){fileOnes = 'A';}
|
||||
if (fileOnes > 'F'){
|
||||
fileOnes = '0'; // hexify
|
||||
fileTens++;
|
||||
if(fileTens == ':'){fileTens = 'A';}
|
||||
if(fileTens > 'F'){fileTens = '0';fileOnes = '1';}
|
||||
}
|
||||
EEPROM.write(0,fileTens); // store current file number in eeprom
|
||||
EEPROM.write(1,fileOnes);
|
||||
currentFileName[5] = fileTens;
|
||||
currentFileName[6] = fileOnes;
|
||||
// // send corresponding file name to controlling program
|
||||
// Serial0.print("Corresponding SD file ");Serial0.println(currentFileName);
|
||||
}
|
||||
|
||||
void stampSD(boolean state){
|
||||
unsigned long time = millis();
|
||||
if(state){
|
||||
for(int i=0; i<10; i++){
|
||||
pCache[byteCounter] = pgm_read_byte_near(startStamp+i);
|
||||
byteCounter++;
|
||||
if(byteCounter == 512){
|
||||
writeCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
for(int i=0; i<9; i++){
|
||||
pCache[byteCounter] = pgm_read_byte_near(stopStamp+i);
|
||||
byteCounter++;
|
||||
if(byteCounter == 512){
|
||||
writeCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
convertToHex(time, 7, false);
|
||||
}
|
||||
|
||||
void writeFooter(){
|
||||
for(int i=0; i<17; i++){
|
||||
pCache[byteCounter] = pgm_read_byte_near(elapsedTime+i);
|
||||
byteCounter++;
|
||||
}
|
||||
convertToHex(t, 7, false);
|
||||
|
||||
for(int i=0; i<20; i++){
|
||||
pCache[byteCounter] = pgm_read_byte_near(minTime+i);
|
||||
byteCounter++;
|
||||
}
|
||||
convertToHex(minWriteTime, 7, false);
|
||||
|
||||
for(int i=0; i<20; i++){
|
||||
pCache[byteCounter] = pgm_read_byte_near(maxTime+i);
|
||||
byteCounter++;
|
||||
}
|
||||
convertToHex(maxWriteTime, 7, false);
|
||||
|
||||
for(int i=0; i<7; i++){
|
||||
pCache[byteCounter] = pgm_read_byte_near(overNum+i);
|
||||
byteCounter++;
|
||||
}
|
||||
convertToHex(overruns, 7, false);
|
||||
for(int i=0; i<11; i++){
|
||||
pCache[byteCounter] = pgm_read_byte_near(blockTime+i);
|
||||
byteCounter++;
|
||||
}
|
||||
if (overruns) {
|
||||
uint8_t n = overruns > OVER_DIM ? OVER_DIM : overruns;
|
||||
for (uint8_t i = 0; i < n; i++) {
|
||||
convertToHex(over[i].block, 7, true);
|
||||
convertToHex(over[i].micro, 7, false);
|
||||
}
|
||||
}
|
||||
for(int i=byteCounter; i<512; i++){
|
||||
pCache[i] = NULL;
|
||||
}
|
||||
writeCache();
|
||||
}
|
||||
|
||||
// CONVERT RAW BYTE DATA TO HEX FOR SD STORAGE
|
||||
void convertToHex(long rawData, int numNibbles, boolean useComma){
|
||||
|
||||
for (int currentNibble = numNibbles; currentNibble >= 0; currentNibble--){
|
||||
byte nibble = (rawData >> currentNibble*4) & 0x0F;
|
||||
if (nibble > 9){
|
||||
nibble += 55; // convert to ASCII A-F
|
||||
}
|
||||
else{
|
||||
nibble += 48; // convert to ASCII 0-9
|
||||
}
|
||||
pCache[byteCounter] = nibble;
|
||||
byteCounter++;
|
||||
if(byteCounter == 512){
|
||||
writeCache();
|
||||
}
|
||||
}
|
||||
if(useComma == true){
|
||||
pCache[byteCounter] = ',';
|
||||
}else{
|
||||
pCache[byteCounter] = '\n';
|
||||
}
|
||||
byteCounter++;
|
||||
if(byteCounter == 512){
|
||||
writeCache();
|
||||
}
|
||||
}// end of byteToHex converter
|
||||
@@ -0,0 +1,49 @@
|
||||
#include <DSPI.h>
|
||||
#include <EEPROM.h>
|
||||
#include <OpenBCI_Wifi_Master_Definitions.h>
|
||||
#include <OpenBCI_Wifi_Master.h>
|
||||
#include <OpenBCI_32bit_Library.h>
|
||||
#include <OpenBCI_32bit_Library_Definitions.h>
|
||||
|
||||
void setup() {
|
||||
// Bring up the OpenBCI Board
|
||||
board.begin();
|
||||
// Bring up wifi with rx/tx both true
|
||||
wifi.begin(true, true);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (board.streaming) {
|
||||
if (board.channelDataAvailable) {
|
||||
// Read from the ADS(s), store data, set channelDataAvailable flag to false
|
||||
board.updateChannelData();
|
||||
// Send the channel data
|
||||
board.sendChannelData();
|
||||
}
|
||||
}
|
||||
|
||||
// Check the serial ports for new data
|
||||
if (board.hasDataSerial0()) board.processChar(board.getCharSerial0());
|
||||
if (board.hasDataSerial1()) board.processChar(board.getCharSerial1());
|
||||
board.loop();
|
||||
|
||||
// Call to wifi loop
|
||||
wifi.loop();
|
||||
|
||||
if (wifi.hasData()) {
|
||||
// Read one char from the wifi shield
|
||||
char newChar = wifi.getChar();
|
||||
|
||||
// Send to the sd library for processing
|
||||
sdProcessChar(newChar);
|
||||
|
||||
// Send to the board library
|
||||
board.processCharWifi(newChar);
|
||||
}
|
||||
|
||||
if (!wifi.sentGains) {
|
||||
if(wifi.present && wifi.tx) {
|
||||
wifi.sendGains(board.numChannels, board.getGains());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
#include <DSPI.h>
|
||||
#include <OBCI32_SD.h>
|
||||
#include <EEPROM.h>
|
||||
#include <OpenBCI_Wifi_Master_Definitions.h>
|
||||
#include <OpenBCI_Wifi_Master.h>
|
||||
#include <OpenBCI_32bit_Library.h>
|
||||
#include <OpenBCI_32bit_Library_Definitions.h>
|
||||
|
||||
@@ -12,9 +14,8 @@ boolean SDfileOpen = false; // Set true by SD_Card_Stuff.ino on successful file
|
||||
void setup() {
|
||||
// Bring up the OpenBCI Board
|
||||
board.begin();
|
||||
|
||||
// Notify the board we want to use accel data
|
||||
board.useAccel = true;
|
||||
// Bring up wifi
|
||||
wifi.begin(true, true);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
@@ -24,12 +25,16 @@ void loop() {
|
||||
board.updateChannelData();
|
||||
|
||||
// Check to see if accel has new data
|
||||
if(board.accelHasNewData()) {
|
||||
// Get new accel data
|
||||
board.accelUpdateAxisData();
|
||||
if (board.curAccelMode == board.ACCEL_MODE_ON) {
|
||||
if(board.accelHasNewData()) {
|
||||
// Get new accel data
|
||||
board.accelUpdateAxisData();
|
||||
|
||||
// Tell the SD_Card_Stuff.ino to add accel data in the next write to SD
|
||||
addAccelToSD = true; // Set false after writeDataToSDcard()
|
||||
// Tell the SD_Card_Stuff.ino to add accel data in the next write to SD
|
||||
addAccelToSD = true; // Set false after writeDataToSDcard()
|
||||
}
|
||||
} else {
|
||||
addAuxToSD = true;
|
||||
}
|
||||
|
||||
// Verify the SD file is open
|
||||
@@ -37,18 +42,11 @@ void loop() {
|
||||
// Write to the SD card, writes aux data
|
||||
writeDataToSDcard(board.sampleCounter);
|
||||
}
|
||||
if (board.timeSynced) {
|
||||
// Send time synced packet with channel data, current board time, and an accel reading
|
||||
// X axis is sent on sampleCounter % 10 == 7
|
||||
// Y axis is sent on sampleCounter % 10 == 8
|
||||
// Z axis is sent on sampleCounter % 10 == 9
|
||||
board.sendChannelDataWithTimeAndAccel();
|
||||
} else {
|
||||
// Send standard packet with channel data
|
||||
board.sendChannelDataWithAccel();
|
||||
}
|
||||
|
||||
board.sendChannelData();
|
||||
}
|
||||
}
|
||||
|
||||
// Check serial 0 for new data
|
||||
if (board.hasDataSerial0()) {
|
||||
// Read one char from the serial 0 port
|
||||
@@ -60,4 +58,38 @@ void loop() {
|
||||
// Send to the board library
|
||||
board.processChar(newChar);
|
||||
}
|
||||
|
||||
if (board.hasDataSerial1()) {
|
||||
// Read one char from the serial 1 port
|
||||
char newChar = board.getCharSerial1();
|
||||
|
||||
// Send to the sd library for processing
|
||||
sdProcessChar(newChar);
|
||||
|
||||
// Read one char and process it
|
||||
board.processChar(newChar);
|
||||
}
|
||||
|
||||
// Call the loop function on the board
|
||||
board.loop();
|
||||
|
||||
// Call to wifi loop
|
||||
wifi.loop();
|
||||
|
||||
if (wifi.hasData()) {
|
||||
// Read one char from the wifi shield
|
||||
char newChar = wifi.getChar();
|
||||
|
||||
// Send to the sd library for processing
|
||||
sdProcessChar(newChar);
|
||||
|
||||
// Send to the board library
|
||||
board.processCharWifi(newChar);
|
||||
}
|
||||
|
||||
if (!wifi.sentGains) {
|
||||
if(wifi.present && wifi.tx) {
|
||||
wifi.sendGains(board.numChannels, board.getGains());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+22
-14
@@ -14,29 +14,37 @@ board KEYWORD1
|
||||
accelHasNewData KEYWORD2
|
||||
accelUpdateAxisData KEYWORD2
|
||||
begin KEYWORD2
|
||||
beginDebug KEYWORD2
|
||||
beginDebug KEYWORD2
|
||||
getCharSerial0 KEYWORD2
|
||||
getCharSerial1 KEYWORD2
|
||||
hasDataSerial0 KEYWORD2
|
||||
hasDataSerial1 KEYWORD2
|
||||
isADSDataAvailable KEYWORD2
|
||||
isProcessingMultibyteMsg KEYWORD2
|
||||
loop KEYWORD2
|
||||
processChar KEYWORD2
|
||||
sendChannelData KEYWORD2
|
||||
sendChannelDataWithAccel KEYWORD2
|
||||
sendChannelDataWithRawAux KEYWORD2
|
||||
sendChannelDataWithTimeAndAccel KEYWORD2
|
||||
sendChannelDataWithTimeAndRawAux KEYWORD2
|
||||
tryMultiAbort KEYWORD2
|
||||
updateChannelData KEYWORD2
|
||||
waitForNewChannelData KEYWORD2
|
||||
useAccel KEYWORD2
|
||||
useTimeStamp KEYWORD2
|
||||
sendChannelData KEYWORD2
|
||||
streaming KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
|
||||
OPENBCI_EOP_STND_ACCEL KEYWORD2
|
||||
OPENBCI_EOP_STND_RAW_AUX KEYWORD2
|
||||
OPENBCI_EOP_USER_DEFINED KEYWORD2
|
||||
OPENBCI_EOP_ACCEL_TIME_SET KEYWORD2
|
||||
OPENBCI_EOP_ACCEL_TIME_SYNCED KEYWORD2
|
||||
OPENBCI_EOP_RAW_AUX_TIME_SET KEYWORD2
|
||||
OPENBCI_EOP_RAW_AUX_TIME_SYNCED KEYWORD2
|
||||
PACKET_TYPE_ACCEL LITERAL1
|
||||
PACKET_TYPE_RAW_AUX LITERAL1
|
||||
PACKET_TYPE_USER_DEFINED LITERAL1
|
||||
PACKET_TYPE_ACCEL_TIME_SET LITERAL1
|
||||
PACKET_TYPE_ACCEL_TIME_SYNC LITERAL1
|
||||
PACKET_TYPE_RAW_AUX_TIME_SET LITERAL1
|
||||
PACKET_TYPE_RAW_AUX_TIME_SYN LITERAL1
|
||||
SAMPLE_RATE_16000 LITERAL1
|
||||
SAMPLE_RATE_8000 LITERAL1
|
||||
SAMPLE_RATE_4000 LITERAL1
|
||||
SAMPLE_RATE_2000 LITERAL1
|
||||
SAMPLE_RATE_1000 LITERAL1
|
||||
SAMPLE_RATE_500 LITERAL1
|
||||
SAMPLE_RATE_250 LITERAL1
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
name=OpenBCI_32bit_Library
|
||||
version=3.0.0
|
||||
author=Joel Murphy <joel@openbci.com>, Conor Russomanno <conor@openbci.com>, Leif Percifield <lpercifield@gmail.com>, AJ Keller <pushtheworldllc@gmail.com>
|
||||
maintainer=Joel Murphy <joel@openbci.com>, AJ Keller <pushtheworldllc@gmail.com>
|
||||
sentence=The library for controlling OpenBCI Cyton (32bit) boards. The Cyton is the main one.
|
||||
paragraph=The to be ran on the Pic 32. Use the DefaultBoard.ino for the firmware that ships with every Cyton order. See the examples for stipped down versions of the board. See the learning pages at openbci.com for more info!
|
||||
category=Device Control
|
||||
url=https://github.com/OpenBCI/OpenBCI_32bit_Library
|
||||
architectures=pic32
|
||||
Arquivo binário não exibido.
-126
@@ -1,126 +0,0 @@
|
||||
# vim: set noexpandtab:
|
||||
# A sample Makefile for building Google Test and using it in user
|
||||
# tests. Please tweak it to suit your environment and project. You
|
||||
# may want to move it to your project's root directory.
|
||||
#
|
||||
# SYNOPSIS:
|
||||
#
|
||||
# make [all] - makes everything.
|
||||
# make TARGET - makes the given target.
|
||||
# make test - Run all tests
|
||||
# make clean - removes all files generated by make.
|
||||
|
||||
# Please tweak the following variable definitions as needed by your
|
||||
# project, except GTEST_HEADERS, which you can use in your own targets
|
||||
# but shouldn't modify.
|
||||
|
||||
# Points to the root of Google Test, relative to where this file is.
|
||||
# Remember to tweak this if you move this file.
|
||||
GTEST_DIR = ./googletest/googletest
|
||||
|
||||
# Points to the root of Google Mock, relative to where this file is.
|
||||
# Remember to tweak this if you move this file.
|
||||
GMOCK_DIR = ./googletest/googlemock
|
||||
|
||||
# Points to the root of Arduino mock, relative to where this file is.
|
||||
# Remember to tweak this if you move this file.
|
||||
ARDUINO_MOCK_DIR = ./arduino-mock
|
||||
|
||||
# Where to find user code.
|
||||
TEST_DIR = .
|
||||
|
||||
# Flags passed to the preprocessor.
|
||||
# Set Google Test's header directory as a system directory, such that
|
||||
# the compiler doesn't generate warnings in Google Test headers.
|
||||
CPPFLAGS += -isystem $(GTEST_DIR)/include -isystem $(GMOCK_DIR)/include \
|
||||
-I$(ARDUINO_MOCK_DIR)/include/arduino-mock
|
||||
|
||||
# Flags passed to the C++ compiler.
|
||||
CXXFLAGS += -g -Wall -Wextra -pthread \
|
||||
-Wno-missing-field-initializers \
|
||||
-Wno-missing-braces \
|
||||
-Wno-unused-command-line-argument
|
||||
|
||||
# All tests produced by this Makefile. Remember to add new tests you
|
||||
# created to the list.
|
||||
TESTS = unittest
|
||||
|
||||
|
||||
# All Google Test headers. Usually you shouldn't change this
|
||||
# definition.
|
||||
GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \
|
||||
$(GTEST_DIR)/include/gtest/internal/*.h
|
||||
|
||||
# All Google Mock headers. Note that all Google Test headers are
|
||||
# included here too, as they are included by Google Mock headers.
|
||||
# Usually you shouldn't change this definition.
|
||||
GMOCK_HEADERS = $(GMOCK_DIR)/include/gmock/*.h \
|
||||
$(GMOCK_DIR)/include/gmock/internal/*.h \
|
||||
$(GTEST_HEADERS)
|
||||
|
||||
# Arduino Mock headers.
|
||||
# Usually you shouldn't change this definition.
|
||||
ARDUINO_MOCK_HEADERS = $(ARDUINO_MOCK_DIR)/include/arduino-mock/*.h
|
||||
|
||||
# House-keeping build targets.
|
||||
|
||||
all : $(TESTS)
|
||||
|
||||
test : $(TESTS)
|
||||
for t in $(TESTS); do ./$$t; done;
|
||||
|
||||
clean :
|
||||
rm -f $(TESTS) gmock.a gtest_main.a gmock_main.a \
|
||||
arduino_mock_all.a *.o
|
||||
|
||||
# Builds gtest.a and gtest_main.a.
|
||||
|
||||
# Usually you shouldn't tweak such internal variables, indicated by a
|
||||
# trailing _.
|
||||
GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS)
|
||||
GMOCK_SRCS_ = $(GMOCK_DIR)/src/*.cc $(GMOCK_HEADERS)
|
||||
ARDUINO_MOCK_SRCS_ = $(ARDUINO_MOCK_DIR)/src/*.cc $(ARDUINO_MOCK_HEADERS)
|
||||
|
||||
# For simplicity and to avoid depending on implementation details of
|
||||
# Google Mock and Google Test, the dependencies specified below are
|
||||
# conservative and not optimized. This is fine as Google Mock and
|
||||
# Google Test compile fast and for ordinary users their source rarely
|
||||
# changes.
|
||||
gtest-all.o : $(GTEST_SRCS_)
|
||||
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -I$(GMOCK_DIR) $(CXXFLAGS) \
|
||||
-c $(GTEST_DIR)/src/gtest-all.cc
|
||||
|
||||
gmock-all.o : $(GMOCK_SRCS_)
|
||||
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -I$(GMOCK_DIR) $(CXXFLAGS) \
|
||||
-c $(GMOCK_DIR)/src/gmock-all.cc
|
||||
|
||||
gmock_main.o : $(GMOCK_SRCS_)
|
||||
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -I$(GMOCK_DIR) $(CXXFLAGS) \
|
||||
-c $(GMOCK_DIR)/src/gmock_main.cc
|
||||
|
||||
gmock.a : gmock-all.o gtest-all.o
|
||||
$(AR) $(ARFLAGS) $@ $^
|
||||
|
||||
gmock_main.a : gmock-all.o gtest-all.o gmock_main.o
|
||||
$(AR) $(ARFLAGS) $@ $^
|
||||
|
||||
# Builds Arduino mocks.
|
||||
ArduinoMockAll.o : $(ARDUINO_MOCK_SRCS_)
|
||||
$(CXX) $(CPPFLAGS) -I$(ARDUINO_MOCK_DIR) $(CXXFLAGS) -c \
|
||||
$(ARDUINO_MOCK_DIR)/src/ArduinoMockAll.cc
|
||||
|
||||
arduino_mock_all.a : ArduinoMockAll.o
|
||||
$(AR) $(ARFLAGS) $@ $^
|
||||
|
||||
# Builds a test. A test should link with either gtest.a or
|
||||
# gtest_main.a, depending on whether it defines its own main()
|
||||
# function.
|
||||
|
||||
unittest.o : $(TEST_DIR)/unittest.cc \
|
||||
$(GTEST_HEADERS)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(TEST_DIR)/unittest.cc
|
||||
|
||||
unittest : unittest.o \
|
||||
gmock_main.a \
|
||||
arduino_mock_all.a
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@
|
||||
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Submodule test/googletest deleted from d225acc90b
Arquivo binário não exibido.
@@ -1,15 +0,0 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include "Arduino.h"
|
||||
#include "DSPI.h"
|
||||
#include "Serial.h"
|
||||
#include "../OpenBCI_32bit_Library_Definitions.h"
|
||||
#include "../OpenBCI_32bit_Library.h"
|
||||
|
||||
|
||||
// using ::testing::Return;
|
||||
|
||||
TEST(cmds, getChannel) {
|
||||
OpenBCI_32bit_Library bciBoard;
|
||||
|
||||
// EXPECT_EQ(bciBoard.getChannelCommandForAsciiChar('1'), 0x00) << "Channel 1 cmd incorrect ";
|
||||
}
|
||||
Arquivo binário não exibido.
@@ -176,7 +176,7 @@ void testSendChannelData() {
|
||||
// A call to send channel data should send 34 bytes, so we should be
|
||||
// able to verify this by counting how many bytes are returned by
|
||||
// '::sendChannelData()'
|
||||
byte expectedNumberOfBytes = 34;
|
||||
byte expectedNumberOfBytes = 33;
|
||||
|
||||
byte acutalNumberOfBytes = board.sendChannelData();
|
||||
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário