diff --git a/OpenBCI_32bit_Library.cpp b/OpenBCI_32bit_Library.cpp index 6303da2..cdd2613 100644 --- a/OpenBCI_32bit_Library.cpp +++ b/OpenBCI_32bit_Library.cpp @@ -139,6 +139,20 @@ boolean OpenBCI_32bit_Library::isProcessingMultibyteMsg(void) { return isProcessingIncomingSettingsChannel || isProcessingIncomingSettingsLeadOff || settingBoardMode || settingSampleRate; } +/** + * Used to abort a multipack message + */ +void OpenBCI_32bit_Library::tryMultiAbort(void) { + if (millis() > timeOfMultiByteMsgStart + 1000) { + isProcessingIncomingSettingsChannel = false; + isProcessingIncomingSettingsLeadOff = false; + settingBoardMode = false; + settingSampleRate = false; + printAll("Timeout processing multi byte message - please send all commands at once as of v2"); + sendEOT(); + } +} + /** * @description Process one char at a time from serial port. This is the main * command processor for the OpenBCI system. Considered mission critical for @@ -286,12 +300,14 @@ boolean OpenBCI_32bit_Library::processChar(char character) { // CHANNEL SETTING COMMANDS case OPENBCI_CHANNEL_CMD_SET: // This is the first byte that tells us to expect more commands isProcessingIncomingSettingsChannel = true; + timeOfMultiByteMsgStart = millis(); numberOfIncomingSettingsProcessedChannel = 1; break; // LEAD OFF IMPEDANCE DETECTION COMMANDS case OPENBCI_CHANNEL_IMPEDANCE_SET: isProcessingIncomingSettingsLeadOff = true; + timeOfMultiByteMsgStart = millis(); numberOfIncomingSettingsProcessedLeadOff = 1; break; @@ -380,13 +396,14 @@ boolean OpenBCI_32bit_Library::processChar(char character) { // BOARD TYPE SET TYPE case OPENBCI_BOARD_MODE_SET: settingBoardMode = true; - numberOfIncomingSettingsProcessedBoardType = 0; + timeOfMultiByteMsgStart = millis(); optionalArgCounter = 0; break; // Sample rate set case OPENBCI_SAMPLE_RATE_SET: settingSampleRate = true; + timeOfMultiByteMsgStart = millis(); break; case OPENBCI_WIFI_ATTACH: @@ -546,7 +563,7 @@ boolean OpenBCI_32bit_Library::boardBeginDebug(int baudRate) { iSerial1.rx = true; iSerial1.baudRate = baudRate; // setSerialInfo(iSerial1, true, true, OPENBCI_BAUD_RATE); - Serial0.print("begin S1 tx "); Serial0.println(iSerial1.tx ? "on" : "off"); + // Serial0.print("begin S1 tx "); Serial0.println(iSerial1.tx ? "on" : "off"); Serial1.print("begin S1 tx "); Serial1.println(iSerial1.tx ? "on" : "off"); curBoardMode = BOARD_MODE_DEBUG; @@ -778,22 +795,23 @@ void OpenBCI_32bit_Library::processIncomingChannelSettings(char character) { currentChannelSetting = getChannelCommandForAsciiChar(character); break; case 2: // POWER_DOWN - channelSettings[currentChannelSetting][POWER_DOWN] = getNumberForAsciiChar(character); + optionalArgBuffer7[0] = getNumberForAsciiChar(character); break; case 3: // GAIN_SET - channelSettings[currentChannelSetting][GAIN_SET] = getGainForAsciiChar(character); + optionalArgBuffer7[1] = getGainForAsciiChar(character); break; case 4: // INPUT_TYPE_SET - channelSettings[currentChannelSetting][INPUT_TYPE_SET] = getNumberForAsciiChar(character); + optionalArgBuffer7[2] = getNumberForAsciiChar(character); break; case 5: // BIAS_SET - channelSettings[currentChannelSetting][BIAS_SET] = getNumberForAsciiChar(character); + optionalArgBuffer7[3] = getNumberForAsciiChar(character); break; case 6: // SRB2_SET - channelSettings[currentChannelSetting][SRB2_SET] = getNumberForAsciiChar(character); + optionalArgBuffer7[4] = getNumberForAsciiChar(character); + break; case 7: // SRB1_SET - channelSettings[currentChannelSetting][SRB1_SET] = getNumberForAsciiChar(character); + optionalArgBuffer7[5] = getNumberForAsciiChar(character); break; case 8: // 'X' latch if (character != OPENBCI_CHANNEL_CMD_LATCH) { @@ -805,8 +823,8 @@ void OpenBCI_32bit_Library::processIncomingChannelSettings(char character) { // We failed somehow and should just abort numberOfIncomingSettingsProcessedChannel = 0; - // put flag back down - isProcessingIncomingSettingsChannel = false; + // put flag back down + isProcessingIncomingSettingsChannel = false; } break; @@ -837,6 +855,13 @@ void OpenBCI_32bit_Library::processIncomingChannelSettings(char character) { sendEOT(); } + channelSettings[currentChannelSetting][POWER_DOWN] = optionalArgBuffer7[0]; + channelSettings[currentChannelSetting][GAIN_SET] = optionalArgBuffer7[1]; + channelSettings[currentChannelSetting][INPUT_TYPE_SET] = optionalArgBuffer7[2]; + channelSettings[currentChannelSetting][BIAS_SET] = optionalArgBuffer7[3]; + channelSettings[currentChannelSetting][SRB2_SET] = optionalArgBuffer7[4]; + channelSettings[currentChannelSetting][SRB1_SET] = optionalArgBuffer7[5]; + // Set channel settings streamSafeChannelSettingsForChannel(currentChannelSetting + 1, channelSettings[currentChannelSetting][POWER_DOWN], channelSettings[currentChannelSetting][GAIN_SET], channelSettings[currentChannelSetting][INPUT_TYPE_SET], channelSettings[currentChannelSetting][BIAS_SET], channelSettings[currentChannelSetting][SRB2_SET], channelSettings[currentChannelSetting][SRB1_SET]); @@ -877,10 +902,10 @@ void OpenBCI_32bit_Library::processIncomingLeadOffSettings(char character) { currentChannelSetting = getChannelCommandForAsciiChar(character); break; case 2: // pchannel setting - leadOffSettings[currentChannelSetting][PCHAN] = getNumberForAsciiChar(character); + optionalArgBuffer7[0] = getNumberForAsciiChar(character); break; case 3: // nchannel setting - leadOffSettings[currentChannelSetting][NCHAN] = getNumberForAsciiChar(character); + optionalArgBuffer7[1] = getNumberForAsciiChar(character); break; case 4: // 'Z' latch if (character != OPENBCI_CHANNEL_IMPEDANCE_LATCH) { @@ -893,8 +918,8 @@ void OpenBCI_32bit_Library::processIncomingLeadOffSettings(char character) { // reset numberOfIncomingSettingsProcessedLeadOff numberOfIncomingSettingsProcessedLeadOff = 0; - // put flag back down - isProcessingIncomingSettingsLeadOff = false; + // put flag back down + isProcessingIncomingSettingsLeadOff = false; } break; @@ -927,6 +952,9 @@ void OpenBCI_32bit_Library::processIncomingLeadOffSettings(char character) { sendEOT(); } + leadOffSettings[currentChannelSetting][PCHAN] = optionalArgBuffer7[0]; + leadOffSettings[currentChannelSetting][NCHAN] = optionalArgBuffer7[1]; + // Set lead off settings streamSafeLeadOffSetForChannel(currentChannelSetting + 1,leadOffSettings[currentChannelSetting][PCHAN],leadOffSettings[currentChannelSetting][NCHAN]); @@ -978,9 +1006,9 @@ void OpenBCI_32bit_Library::initializeVariables(void) { lastSampleTime = 0; numberOfIncomingSettingsProcessedChannel = 0; numberOfIncomingSettingsProcessedLeadOff = 0; - numberOfIncomingSettingsProcessedBoardType = 0; sampleCounter = 0; timeOfLastRead = 0; + timeOfMultiByteMsgStart = 0; // Enums curAccelMode = ACCEL_MODE_ON; diff --git a/OpenBCI_32bit_Library.h b/OpenBCI_32bit_Library.h index ac7e7f6..ddb9d78 100644 --- a/OpenBCI_32bit_Library.h +++ b/OpenBCI_32bit_Library.h @@ -161,6 +161,7 @@ public: 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 @@ -310,6 +311,7 @@ private: int numberOfIncomingSettingsProcessedBoardType; uint8_t optionalArgCounter; unsigned long timeOfLastRead; + unsigned long timeOfMultiByteMsgStart; #ifdef __OpenBCI_Wifi_Master__ // functions diff --git a/changelog.md b/changelog.md index 80e2d3c..8812b9e 100644 --- a/changelog.md +++ b/changelog.md @@ -52,6 +52,7 @@ ### Bug Fixes * Calling `boardBeginDebug(void)` would result in debug not working. +* Closes #69 with once second timeout on multi byte messages. ## Release Candidate 4 diff --git a/examples/BoardNoAccelSDWifi/BoardNoAccelSDWifi.ino b/examples/BoardNoAccelSDWifi/BoardNoAccelSDWifi.ino index 4f90300..c6a2e8e 100644 --- a/examples/BoardNoAccelSDWifi/BoardNoAccelSDWifi.ino +++ b/examples/BoardNoAccelSDWifi/BoardNoAccelSDWifi.ino @@ -23,4 +23,8 @@ void loop() { // Read one char and process it board.processChar(board.getCharSerial0()); } + // Used to abort multi part messages + if (board.isProcessingMultibyteMsg()) { + board.tryMultiAbort(); + } } diff --git a/examples/BoardNoAccelSDWifiDebug/BoardNoAccelSDWifiDebug.ino b/examples/BoardNoAccelSDWifiDebug/BoardNoAccelSDWifiDebug.ino index 1ede6aa..c7d5bfc 100644 --- a/examples/BoardNoAccelSDWifiDebug/BoardNoAccelSDWifiDebug.ino +++ b/examples/BoardNoAccelSDWifiDebug/BoardNoAccelSDWifiDebug.ino @@ -28,4 +28,8 @@ void loop() { // Read one char and process it board.processChar(board.getCharSerial1()); } + + if (board.isProcessingMultibyteMsg()) { + board.tryMultiAbort(); + } } diff --git a/examples/BoardWith2ButtonExternalTriggers/BoardWith2ButtonExternalTriggers.ino b/examples/BoardWith2ButtonExternalTriggers/BoardWith2ButtonExternalTriggers.ino index 6320674..ff23b05 100644 --- a/examples/BoardWith2ButtonExternalTriggers/BoardWith2ButtonExternalTriggers.ino +++ b/examples/BoardWith2ButtonExternalTriggers/BoardWith2ButtonExternalTriggers.ino @@ -103,4 +103,8 @@ void loop() { break; } } + // Used to abort multi part messages + if (board.isProcessingMultibyteMsg()) { + board.tryMultiAbort(); + } } diff --git a/examples/BoardWithAccel/BoardWithAccel.ino b/examples/BoardWithAccel/BoardWithAccel.ino index 107ae1c..a5fca4c 100644 --- a/examples/BoardWithAccel/BoardWithAccel.ino +++ b/examples/BoardWithAccel/BoardWithAccel.ino @@ -34,4 +34,9 @@ void loop() { // Read one char and process it board.processChar(board.getCharSerial0()); } + + // Used to abort multi part messages + if (board.isProcessingMultibyteMsg()) { + board.tryMultiAbort(); + } } diff --git a/examples/BoardWithAnalogSensor/BoardWithAnalogSensor.ino b/examples/BoardWithAnalogSensor/BoardWithAnalogSensor.ino index 651e040..acdabef 100644 --- a/examples/BoardWithAnalogSensor/BoardWithAnalogSensor.ino +++ b/examples/BoardWithAnalogSensor/BoardWithAnalogSensor.ino @@ -35,4 +35,9 @@ void loop() { // Read one char and process it board.processChar(board.getCharSerial0()); } + + // Used to abort multi part messages + if (board.isProcessingMultibyteMsg()) { + board.tryMultiAbort(); + } } diff --git a/examples/BoardWithDigitalRead/BoardWithDigitalRead.ino b/examples/BoardWithDigitalRead/BoardWithDigitalRead.ino index e1641f6..5fa6fc5 100644 --- a/examples/BoardWithDigitalRead/BoardWithDigitalRead.ino +++ b/examples/BoardWithDigitalRead/BoardWithDigitalRead.ino @@ -27,10 +27,13 @@ void loop() { board.sendChannelData(); } } - // Check the serial port for new data if (board.hasDataSerial0()) { // Read one char and process it board.processChar(board.getCharSerial0()); } + // Used to abort multi part messages + if (board.isProcessingMultibyteMsg()) { + board.tryMultiAbort(); + } } diff --git a/examples/BoardWithPulseSensor/BoardWithPulseSensor.ino b/examples/BoardWithPulseSensor/BoardWithPulseSensor.ino index b8d38b1..cf246f0 100644 --- a/examples/BoardWithPulseSensor/BoardWithPulseSensor.ino +++ b/examples/BoardWithPulseSensor/BoardWithPulseSensor.ino @@ -67,4 +67,8 @@ void loop() { // Read one char and process it board.processChar(board.getCharSerial0()); } + // Used to abort multi part messages + if (board.isProcessingMultibyteMsg()) { + board.tryMultiAbort(); + } } diff --git a/examples/BoardWithWifi/BoardWithWifi.ino b/examples/BoardWithWifi/BoardWithWifi.ino index ba1912a..93f5bee 100644 --- a/examples/BoardWithWifi/BoardWithWifi.ino +++ b/examples/BoardWithWifi/BoardWithWifi.ino @@ -22,6 +22,11 @@ void loop() { } } + // Used to abort multi part messages + if (board.isProcessingMultibyteMsg()) { + board.tryMultiAbort(); + } + // Call to wifi loop wifi.loop(); diff --git a/examples/DefaultBoard/DefaultBoard.ino b/examples/DefaultBoard/DefaultBoard.ino index 73a71a8..6fa4279 100644 --- a/examples/DefaultBoard/DefaultBoard.ino +++ b/examples/DefaultBoard/DefaultBoard.ino @@ -70,6 +70,11 @@ void loop() { board.processChar(newChar); } + // Used to abort multi part messages + if (board.isProcessingMultibyteMsg()) { + board.tryMultiAbort(); + } + // Call to wifi loop wifi.loop(); diff --git a/keywords.txt b/keywords.txt index 7e584c3..6bb5675 100755 --- a/keywords.txt +++ b/keywords.txt @@ -20,8 +20,10 @@ getCharSerial1 KEYWORD2 hasDataSerial0 KEYWORD2 hasDataSerial1 KEYWORD2 isADSDataAvailable KEYWORD2 +isProcessingMultibyteMsg KEYWORD2 loop KEYWORD2 processChar KEYWORD2 +tryMultiAbort KEYWORD2 updateChannelData KEYWORD2 useAccel KEYWORD2 useTimeStamp KEYWORD2