I have modified Robin2's Serial code for bluetooth serial send and receive, in the function below. At times, I will see btwrite|initGUI=trqe instead of btwrite|initGUI=true and I'm not sure what could cause that. It's unfortunately sporadic and not reproduceable consistently.
The app and the Arduino and the hc05 are all using a baud rate of 9600. The app bluetooth client has character encoding of UTF-8, a delimiter byte of 10 and a polling rate of 10mS.
What could be causing a "u" to be interpreted by my function as a "q" ? This serial out snippet is from the bottom of the function recvWithStartEndMarkersBT() , with the line of code that is Serial.print("serialInCharsBT: "); Serial.println(serialInCharsBT); . Does anything in the code stick out as problematic, that could cause this issue? I'll entertain theoretical thoughts if not, I need to overcome this unreliability if so, even if a CRC is the only answer.
(I'm happy to post a more complete sample project if that is helpful, however given that it is communicating with an app on a phone, narrowing it down to the function may be more useful?)
Hi, thanks for the reply. For my own knowledge/learning, can you explain why moving the char rc inside of the loop and removing newDataBT and removing the strlcpy will fix my issue, or what is the root cause is? Does the extra code create a timing issue or does char rc need to be reinstantiated each time for reliability?
I updated to your code and I am still getting errant characters. One strange thing I've noticed, although the reproduction is inconsistent, the pattern on the characters that are wrong always has the 6th bit flipped for that byte/character?
It's a Mega2560. I'm using the hardware setup as pictured below. The HC-05 is currently set up for AT+UART=9600,1,0 . I have also tried AT+UART=9600,0,0 . Data is being sent back and forth between over the HC-05 between the 2560 and an Android application.
//#define analogVin A3 // Analog voltage input to A0
int readAdcBitValue(int analogVin){
int adcReadBitValue = analogRead(analogVin);
return adcReadBitValue;
} // readAdcBitValue
No it isn't my goal. This forum stops you from editing your posts after a time period and there are a few people that are trying to do what I'm doing and that's ok as long as they aren't plagiarizing my 100s of hours of work.
The link works for anyone that has the direct link, I hope it's understandable.
I think I have made the changes you've suggested with this function, I will paste a new version of the code (with the old code commented out for reference) to ensure I understood correctly.
This was eye opening, I was able to remove a lot of code with this. It is for your review below.
I also thought I was using more memory than the size and complexity of my program, but was not sure. Dynamic memory is at 19% usage.
I believe I was able to eliminate all of that, per your strtok suggestion.
The only part I wasn't sure about was when you said " You could be working directly with receivedChars or receivedCharsBT " . Did you mean that I could elimated using char* serialInChars in the function void processSerialIn(char* serialInChars) { ... } ?
#include <EEPROM.h>
#include <FreqMeasure.h> // uses pin 49 as an rpm/frequency input
#include <Adafruit_MCP4725.h>
//#include <SoftwareSerial.h> // required to use the TX and RX pins of the Mega2560
#define BTSerial Serial1
#define DAC_RESOLUTION (8)
Adafruit_MCP4725 MCP4725;
#pragma region Troubleshooting
bool ts = false; // global troubleshooting variable
void whatCharacterAmI(char chr)
{
for (int i = 0; i < 513; i++)
{
if (chr == i)
{
Serial.print(" *** (whatCharacterAmI) Character match found to digit: "); Serial.print(i); Serial.println(" *** ");
break;
}
}
}
#pragma endregion Troubleshooting
#pragma region Variable instantiation
// uC Input pins
int id_engineRpm = 49;
// Variables
unsigned long currentTimeStamp;
unsigned long serialLastWriteTimeStamp;
unsigned long sendBluetoothDataTimeStamp;
unsigned long getRPMTimeStamp;
//char settingNameArr[100];
int aODV = 0;
bool vOE = true;
bool vCC = true;
#pragma endregion Variable instantiation
#pragma region Engine RPM
unsigned long lastRpmUpdateTime;
double sum = 0;
int count = 0;
int lastRpmUpdateTimeOut = 2000; // equates to zero rpm if more than two seconds elapse without a frequency
bool engineRunning = false;
int engineRpm = 0;
int globalEngineRpm = 0;
int getRpm()
{
//Serial.println("Inside of getRpm()");
int rpmHz = 0;
int rpm = 0;
if (FreqMeasure.available())
{
//Serial.print(" Inside of FreqMeasure.available(), count is: "); Serial.println(count);
sum = sum + FreqMeasure.read();
count = count + 1;
if (count > 10) // when set to 100, at 400rpm, the update was too slow for the timeout period
{
rpmHz = FreqMeasure.countToFrequency(sum / count);
sum = 0;
count = 0;
lastRpmUpdateTime = (millis() + lastRpmUpdateTimeOut);
//Serial.print("getRpm(): "); Serial.println(millis());
//Serial.print("getRpm() lastRpmUpdateTime: "); Serial.println(lastRpmUpdateTime);
rpm = (rpmHz * 5);
//Serial.print("(getRpm()) rpm: "); Serial.println(rpm);
globalEngineRpm = rpm;
//return rpm;
}
}
else if ((currentTimeStamp - lastRpmUpdateTimeOut) < 1500)
{
Serial.println("(getRpm) Waiting");
}
else
{
Serial.print(" ** FreqMeasure NOT available, count is: "); Serial.println(count); // USE THIS FOR TROUBLESHOOTING
lastRpmUpdateTime = 0;
globalEngineRpm = rpm;
}
return rpm;
}
#pragma endregion Engine RPM
#pragma region Serial data
boolean newData = false;
const byte numChars = 100;
char receivedChars[numChars];
void recvWithStartEndMarkers()
{
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (Serial.available() > 0 && newData == false)
{
rc = Serial.read();
if (recvInProgress == true)
{
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars)
{
ndx = numChars - 1;
}
}
else
{
receivedChars[ndx] = '\0';
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker)
{
recvInProgress = true;
}
}
if (newData == true)
{
//Serial.print("receivedChars length: "); Serial.println(strlen(receivedChars));
char serialInChars[strlen(receivedChars)];
strlcpy(serialInChars, receivedChars, (strlen(receivedChars) + 1));
//Serial.print("This just in ... ");
//Serial.println(receivedChars);
//Serial.print("serialInChars length: "); Serial.println(strlen(serialInChars));
//Serial.print("serialInChars: "); Serial.println(serialInChars);
newData = false;
processSerialIn(serialInChars);
}
} // void recvWithStartEndMarkers
const byte numCharsBT = 100;
char receivedCharsBT[numCharsBT];
bool newDataBT = false;
void recvWithStartEndMarkersBT()
{
static boolean recvInProgress = false;
static byte ndx = 0;
const char startMarker = '<';
const char endMarker = '>';
while (BTSerial.available() > 0 && newDataBT == false)
{
char rc = BTSerial.read();
if (recvInProgress == true)
{
if (rc != endMarker)
{
receivedCharsBT[ndx] = rc;
ndx++;
if (ndx >= numCharsBT)ndx = numCharsBT - 1;
}
else
{
receivedCharsBT[ndx] = '\0';
recvInProgress = false;
ndx = 0;
if (ts == true) { Serial.print("receivedCharsBT length: "); Serial.println(strlen(receivedCharsBT)); }
char serialInCharsBT[strlen(receivedCharsBT)];
//strlcpy(serialInCharsBT, receivedCharsBT, (strlen(receivedCharsBT) + 1));
strncpy(serialInCharsBT, receivedCharsBT, (strlen(receivedCharsBT) + 1));
//Serial.print("This just in ... ");
//Serial.println(receivedCharsBT);
if (ts == true) { Serial.print("serialInCharsBT length: "); Serial.println(strlen(serialInCharsBT)); }
Serial.print("serialInCharsBT: "); Serial.println(serialInCharsBT);
Serial.print("receivedCharsBT: "); Serial.println(receivedCharsBT);
processSerialIn(receivedCharsBT);
}
}
else if (rc == startMarker)recvInProgress = true;
}
}
void processSerialIn(char* serialInChars) // examples: <read=automation> or <write:automation=off>
{
Serial.print(" (processSerialIn) serialInChars: "); Serial.println(serialInChars);
Serial.print(" strlen(serialInChars): "); Serial.println(strlen(serialInChars));
char *token;
const char *delimiter ="|=";
token = strtok(serialInChars, delimiter);
char settingCmdArr[100] = {0};
char settingNameArr[100] = {0};
char settingValueArr[100] = {0};
int whileLoopCount = 0;
while (token != NULL)
{
switch (whileLoopCount)
{
case 0:
strncpy(settingCmdArr, token, strlen(token));
break;
case 1:
strncpy(settingNameArr, token, strlen(token));
break;
case 2:
strncpy(settingValueArr, token, strlen(token));
break;
default:
// statements
Serial.println(" *** (processSerialIn) while(token != NULL failure) default:");
break;
}
token = strtok(NULL, delimiter);
whileLoopCount++;
}
if(strcmp(settingCmdArr, "write") == 0)
{
// I know this is verbose, I will condense this later on after some thought
}
else if(strcmp(settingCmdArr, "btwrite") == 0)
{
// I know this is verbose, I will condense this later on after some thought
}
else if(strcmp(settingCmdArr, "send") == 0)
{
// I know this is verbose, I will condense this later on after some thought
}
else if(strcmp(settingCmdArr, "btsend") == 0)
{
// I know this is verbose, I will condense this later on after some thought
}
else if(strcmp(settingCmdArr, "read") == 0)
{
// I know this is verbose, I will condense this later on after some thought
}
else if(strcmp(settingCmdArr, "btread") == 0)
{
// I know this is verbose, I will condense this later on after some thought
}
else
{
Serial.println(" *** Unknown command ***");
Serial.println(settingCmdArr);
//Serial.println(serialInChars[i]);
//whatCharacterAmI(serialInChars[i]);
}
processSerialCmd(settingCmdArr, settingNameArr, settingValueArr);
} // void processSerialIn
/*
void processSerialIn(char* serialInChars) // examples: <read=automation> or <write:automation=off>
{
Serial.print(" (processSerialIn) serialInChars: "); Serial.println(serialInChars);
Serial.print(" strlen(serialInChars): "); Serial.println(strlen(serialInChars));
char settingTempArr[100];
memset(settingTempArr, '\0', strlen(settingTempArr));
char settingNameArr[100];
memset(settingNameArr, '\0', strlen(settingNameArr));
char settingValueArr[100];
memset(settingValueArr, '\0', strlen(settingValueArr));
char temp[100];
bool containsDelimiter = false;
bool readCommand = false; // not needed? disabled 6/21/24
char command[15];
int commandLength = 0;
int charIndexer = 0;
for(int i = 0; i < (strlen(serialInChars) + 1); i++)
{
settingTempArr[charIndexer] = serialInChars[i];
//Serial.print("initial settingTempArr: "); Serial.println(settingTempArr);
if (serialInChars[i] == '|')
{
settingTempArr[charIndexer + 1] = '\0'; // overwrite the deliniating character
if(strcmp(settingTempArr, "write|") == 0)
{
//writeCommand = true; // not needed? disabled 6/21/24
settingTempArr[charIndexer] = '\0'; // overwrite the deliniating character
strcpy(command, settingTempArr);
commandLength = strlen(command);
memset(settingTempArr, '\0', strlen(settingTempArr));
charIndexer = -1; // the charIndexer++ at the bottom of the for loop will put this to 0
settingTempArr[100];
}
else if(strcmp(settingTempArr, "btwrite|") == 0)
{
//btWriteCommand = true; // not needed? disabled 6/21/24
settingTempArr[charIndexer] = '\0'; // overwrite the deliniating character
strcpy(command, settingTempArr);
commandLength = strlen(command);
memset(settingTempArr, '\0', strlen(settingTempArr));
charIndexer = -1; // the charIndexer++ at the bottom of the for loop will put this to 0
settingTempArr[100];
}
else if(strcmp(settingTempArr, "send|") == 0)
{
//sendCommand = true; // not needed? disabled 6/21/24
settingTempArr[charIndexer] = '\0'; // overwrite the deliniating character
strcpy(command, settingTempArr);
commandLength = strlen(command);
memset(settingTempArr, '\0', strlen(settingTempArr));
charIndexer = -1; // the charIndexer++ at the bottom of the for loop will put this to 0
settingTempArr[100];
}
else if(strcmp(settingTempArr, "btsend|") == 0)
{
//btSendCommand = true; // not needed? disabled 6/21/24
settingTempArr[charIndexer] = '\0'; // overwrite the deliniating character
strcpy(command, settingTempArr);
commandLength = strlen(command);
memset(settingTempArr, '\0', strlen(settingTempArr));
charIndexer = -1; // the charIndexer++ at the bottom of the for loop will put this to 0
settingTempArr[100];
}
else if(strcmp(settingTempArr, "read|") == 0)
{
readCommand = true; // not needed? disabled 6/21/24
settingTempArr[charIndexer] = '\0'; // overwrite the deliniating character
strcpy(command, settingTempArr);
commandLength = strlen(command);
memset(settingTempArr, '\0', strlen(settingTempArr));
charIndexer = -1; // the charIndexer++ at the bottom of the for loop will put this to 0
settingTempArr[100];
}
else if(strcmp(settingTempArr, "btread|") == 0)
{
readCommand = true; // not needed? disabled 6/21/24
settingTempArr[charIndexer] = '\0'; // overwrite the deliniating character
strcpy(command, settingTempArr);
commandLength = strlen(command);
memset(settingTempArr, '\0', strlen(settingTempArr));
charIndexer = -1; // the charIndexer++ at the bottom of the for loop will put this to 0
settingTempArr[100];
}
else
{
Serial.println(" *** Unknown command ***");
Serial.println(settingTempArr);
Serial.println(serialInChars[i]);
whatCharacterAmI(serialInChars[i]);
}
}
else if (serialInChars[i] == '=')
{
settingTempArr[charIndexer] = '\0'; // overwrite the deliniating character
strcpy(settingNameArr, settingTempArr);
int settingNameArrLength = strlen(settingNameArr);
memset(settingTempArr, '\0', strlen(settingTempArr));
charIndexer = -1; // the charIndexer++ at the bottom of the for loop will put this to 0
settingTempArr[100];
}
else if (serialInChars[i] == '\f')
{
Serial.print(" \ f was found: "); Serial.print(i); Serial.print(" - "); Serial.println(serialInChars[i]);
}
else if (serialInChars[i] == '\n')
{
Serial.print(" \ n was found: "); Serial.print(i); Serial.print(" - "); Serial.println(serialInChars[i]);
}
else if (serialInChars[i] == '\0')
{
settingTempArr[charIndexer] = '\0'; // overwrite the deliniating character
if (readCommand == true)
{
strcpy(settingNameArr, settingTempArr);
int settingNameArrLength = strlen(settingNameArr);
}
else
{
strcpy(settingValueArr, settingTempArr);
int settingValueArrLength = strlen(settingValueArr);
}
memset(settingTempArr, '\0', strlen(settingTempArr));
charIndexer = -1; // the charIndexer++ at the bottom of the for loop will put this to 0
settingTempArr[100];
}
else
{
if (ts == true) { Serial.print(i); Serial.print(" - "); Serial.println(serialInChars[i]); }
}
charIndexer++; // allows a different indexing than the for loop, for when string splits occur
}
processSerialCmd(command, settingNameArr, settingValueArr);
} // void processSerialIn
*/
void processSerialCmd(char* cmdType, char* cmdName, char* cmdValue) // examples: <read|automation> or <write|automation=off> or <send|test=true>
{
Serial.println("");
Serial.print(" cmdType: "); Serial.print(cmdType); Serial.print(", cmdType strlen: "); Serial.println(strlen(cmdType));
Serial.print(" cmdName: "); Serial.print(cmdName); Serial.print(", cmdName strlen: "); Serial.println(strlen(cmdName));
Serial.print(" cmdValue: "); Serial.print(cmdValue); Serial.print(", cmdValue strlen: "); Serial.println(strlen(cmdValue));
Serial.println("");
if (strcmp(cmdType,"btsend") == 0)
{
bluetoothSendCmd(cmdName, cmdValue);
}
if (strcmp(cmdType,"btread") == 0)
{
bluetoothReadCmd(cmdName, cmdValue);
}
if (strcmp(cmdType,"btwrite") == 0)
{
bluetoothWriteCmd(cmdName, cmdValue);
}
} // void processSerialCmd
void bluetoothSendCmd(char* btSendCmdName, char* btSendCmdValue)
{
BTSerial.print(btSendCmdName); BTSerial.print("="); BTSerial.println(btSendCmdValue);
Serial.print(" (bluetoothSendCmd) btSendCmdName: "); Serial.print(btSendCmdName); Serial.print(", btSendCmdValue: "); Serial.println(btSendCmdValue);
} // void bluetoothSendCmd(char* btSendCmdName, char* btSendCmdValue)
void bluetoothReadCmd(char* btReadCmdName, char* btReadCmdValue) // btReadCmdValue is not currently used
{
if (strcmp(btReadCmdName,"vOE") == 0)
{
if ((vOE != 0) && (vOE != NULL))
{
BTSerial.print("vOE="); BTSerial.println(vOE);
}
Serial.print(" (bluetoothReadCmd) btReadCmdName: "); Serial.print(btReadCmdName); Serial.print(", value: "); Serial.println(vOE);
}
else if (strcmp(btReadCmdName,"aODV") == 0)
{
if ((aODV != 0) && (aODV != NULL))
{
BTSerial.print("aODV="); BTSerial.println(aODV);
}
Serial.print(" (bluetoothReadCmd) btReadCmdName: "); Serial.print(btReadCmdName); Serial.print(", value: "); Serial.println(aODV);
}
} // void bluetoothReadCmd(char* btReadCmdName, char* btReadCmdValue)
void bluetoothWriteCmd(char* btWriteCmdName, char* btWriteCmdValue)
{
if (((strcmp(btWriteCmdName,"initializeGUI") == 0) && (strcmp(btWriteCmdValue,"true") == 0)) || ((strcmp(btWriteCmdName,"initGUI") == 0) && (strcmp(btWriteCmdValue,"true") == 0)))
{
initializeGui();
}
if ((strcmp(btWriteCmdName,"vCC") == 0) && (strcmp(btWriteCmdValue,"true") == 0))
{
vCC = true;
Serial.println("(bluetoothWriteCmd) vCC = true");
}
else if ((strcmp(btWriteCmdName,"vCC") == 0) && (strcmp(btWriteCmdValue,"false") == 0))
{
vCC = false;
Serial.println("(bluetoothWriteCmd) vCC = false");
}
} // void bluetoothWriteCmd(char* btWriteCmdName, char* btWriteCmdValue)
#pragma endregion Serial data
#pragma region Bluetooth Send
void initializeGui()
{
BTSerial.print("currentRpm="); BTSerial.println("Init_1234");
BTSerial.print("manualControlState="); BTSerial.println("Init_disabled");
Serial.println(" initializeGui() complete");
} // initializeGui()
void sendBluetoothData()
{
//engineRpm = getRpm(); // needs a timer to throttle data being sent
if (engineRpm >= 400)
{
//BTSerial.print("currentRpm="); BTSerial.println(engineRpm);
}
if (globalEngineRpm >= 400)
{
BTSerial.print("currentRpm="); BTSerial.println(globalEngineRpm);
}
else
{
BTSerial.print("currentRpm="); BTSerial.println("0");
}
//}
} // sendBluetoothData()
#pragma endregion Bluetooth Send
void setup()
{
Serial.begin(9600);
BTSerial.begin(9600);
while (!Serial)
{
; // Wait for serial to connect
}
while (!BTSerial)
{
; // Wait for BTSerial to connect
}
if (BTSerial)
{
Serial.println("BTSerial connected");
}
MCP4725.begin(0x60); // could be 0x61 or 0x62
delay(1000);
serialLastWriteTimeStamp = millis();
sendBluetoothDataTimeStamp = millis();
// engine rpm
FreqMeasure.begin();
lastRpmUpdateTime = 0;
engineRpm = 0;
// Input pins
pinMode(id_engineRpm, INPUT);
char* serialInChars = "write|w_name=value";
processSerialIn(serialInChars);
serialInChars = "read|r_name=value";
processSerialIn(serialInChars);
serialInChars = "send|s_name=value";
processSerialIn(serialInChars);
serialInChars = "btwrite|btw_name=value";
processSerialIn(serialInChars);
serialInChars = "btread|btr_name=value";
processSerialIn(serialInChars);
serialInChars = "btsend|bts_name=value";
processSerialIn(serialInChars);
}
void loop()
{
currentTimeStamp = millis();
recvWithStartEndMarkers();
recvWithStartEndMarkersBT();
if ((currentTimeStamp - serialLastWriteTimeStamp) > 7000)
{
//Serial.print("getExhaustValveAngleADC: "); Serial.println(getExhaustValveAngleADC());
//engineRpm = getRpm();
//Serial.print("\tglobalEngineRpm: "); Serial.println(globalEngineRpm);
serialLastWriteTimeStamp = millis();
}
}
I tried void processSerialIn(char[] serialInChars) (which didn't work) to try to call the processSerialIn function and then blank out receivedCharsBT inside of recvWithStartEndMarkersBT() after calling the function processSerialIn, and the same for recWithStartEndMarkers().
However I'm not sure how I can call processSerialIn() without a parameter, if I'm calling processSerialIn from both functions void recvWithStartEndMarkers() and void recvWithStartEndMarkersBT() ? Can you give me a hint as to what to websearch so I can learn?
As an update, I did what I think you were advising, however I created a second function so that I could handle the global variables , so void processSerialIn will handle receivedChars and void processSerialInBT will handle receivedCharsBT .
An interesting thing happened supporting what you speculated. The characters came in correctly via char rc = BTSerial.read(); and printed to the terminal, however even with me initializing the char array with receivedCharsBT[100] = {0};, even though within the same function, there was an extra "b" at the beginning of the command. Should I try and figure out the memory address of each variable?
17:10:45.995 -> globalEngineRpm: 0
17:10:52.993 -> globalEngineRpm: 0
17:10:57.321 -> rc: <
17:10:57.321 -> rc: b
17:10:57.321 -> rc: t
17:10:57.321 -> rc: w
17:10:57.321 -> rc: r
17:10:57.321 -> rc: i
17:10:57.321 -> rc: t
17:10:57.321 -> rc: e
17:10:57.321 -> rc: |
17:10:57.321 -> rc: m
17:10:57.321 -> rc: C
17:10:57.321 -> rc: =
17:10:57.321 -> rc: f
17:10:57.781 -> rc: a
17:10:57.781 -> rc: l
17:10:57.781 -> rc: s
17:10:57.781 -> rc: e
17:10:57.781 -> rc: >
17:10:57.781 -> receivedCharsBT: bbtwrite|mC=false
17:10:57.781 -> (processSerialInBT) receivedCharsBT: bbtwrite|mC=false
17:10:57.781 -> strlen(receivedCharsBT): 17
17:10:57.781 -> *** Unknown command ***
17:10:57.781 -> bbtwrite
17:10:57.781 ->
17:10:57.781 -> cmdType: bbtwrite, cmdType strlen: 8
17:10:57.781 -> cmdName: mC, cmdName strlen: 2
17:10:57.781 -> cmdValue: false, cmdValue strlen: 5
17:10:57.781 ->
17:11:00.648 -> globalEngineRpm: 0
17:11:07.685 -> globalEngineRpm: 0
void processSerialIn()
{
Serial.print(" (processSerialIn) receivedChars: "); Serial.println(receivedChars);
Serial.print(" strlen(receivedChars): "); Serial.println(strlen(receivedChars));
char *token;
const char *delimiter ="|=";
token = strtok(receivedChars, delimiter);
char settingCmdArr[100] = {0};
char settingNameArr[100] = {0};
char settingValueArr[100] = {0};
int whileLoopCount = 0;
while (token != NULL)
{
switch (whileLoopCount)
{
case 0:
strncpy(settingCmdArr, token, strlen(token));
break;
case 1:
strncpy(settingNameArr, token, strlen(token));
break;
case 2:
strncpy(settingValueArr, token, strlen(token));
break;
default:
// statements
Serial.println(" *** (processSerialIn) while(token != NULL failure) default:");
break;
}
token = strtok(NULL, delimiter);
whileLoopCount++;
}
if(strcmp(settingCmdArr, "write") == 0)
{
// I know this is verbose, I will condense this later on after some thought
}
else if(strcmp(settingCmdArr, "send") == 0)
{
// I know this is verbose, I will condense this later on after some thought
}
else if(strcmp(settingCmdArr, "read") == 0)
{
// I know this is verbose, I will condense this later on after some thought
}
else
{
Serial.println(" *** Unknown command ***");
Serial.println(settingCmdArr);
//Serial.println(receivedChars[i]);
//whatCharacterAmI(receivedChars[i]);
}
processSerialCmd(settingCmdArr, settingNameArr, settingValueArr);
} // void processSerialIn
void processSerialInBT()
{
Serial.print(" (processSerialInBT) receivedCharsBT: "); Serial.println(receivedCharsBT);
Serial.print(" strlen(receivedCharsBT): "); Serial.println(strlen(receivedCharsBT));
char *token;
const char *delimiter ="|=";
token = strtok(receivedCharsBT, delimiter);
char settingCmdArr[100] = {0};
char settingNameArr[100] = {0};
char settingValueArr[100] = {0};
int whileLoopCount = 0;
while (token != NULL)
{
switch (whileLoopCount)
{
case 0:
strncpy(settingCmdArr, token, strlen(token));
break;
case 1:
strncpy(settingNameArr, token, strlen(token));
break;
case 2:
strncpy(settingValueArr, token, strlen(token));
break;
default:
// statements
Serial.println(" *** (processSerialInBT) while(token != NULL failure) default:");
break;
}
token = strtok(NULL, delimiter);
whileLoopCount++;
}
if(strcmp(settingCmdArr, "btwrite") == 0)
{
// I know this is verbose, I will condense this later on after some thought
}
else if(strcmp(settingCmdArr, "btsend") == 0)
{
// I know this is verbose, I will condense this later on after some thought
}
else if(strcmp(settingCmdArr, "btread") == 0)
{
// I know this is verbose, I will condense this later on after some thought
}
else
{
Serial.println(" *** Unknown command ***");
Serial.println(settingCmdArr);
//Serial.println(receivedCharsBT[i]);
//whatCharacterAmI(receivedCharsBT[i]);
}
processSerialCmd(settingCmdArr, settingNameArr, settingValueArr);
} // void processSerialInBT
I tried another troubleshooting test where I print the received the incoming test bluetooth character rc and then also print as it builds receivedCharsBT
The third one down looks like it did not erase the memory addresses, but maybe starts to replace the first 7 characters with the same characters? Does that lead towards any clue on what is happening? Or there is two instances of the function competing against itself?
01:05:12.568 -> rc: < -
01:05:12.568 -> rc: b -
01:05:12.568 -> rc: t - b
01:05:12.599 -> rc: w - bt
01:05:12.599 -> rc: r - btw
01:05:12.633 -> rc: i - btwr
01:05:12.633 -> rc: t - btwri
01:05:12.666 -> rc: e - btwrit
01:05:12.666 -> rc: | - btwrite
01:05:12.699 -> rc: m - btwrite|
01:05:12.731 -> rc: C - btwrite|m
01:05:12.731 -> rc: = - btwrite|mC
01:05:12.764 -> rc: f - btwrite|mC=
01:05:12.797 -> rc: a - btwrite|mC=f
01:05:12.797 -> rc: l - btwrite|mC=fa
01:05:12.830 -> rc: s - btwrite|mC=fal
01:05:12.862 -> rc: e - btwrite|mC=fals
01:05:12.895 -> rc: > - btwrite|mC=false
01:05:12.927 -> ndx: 16
01:05:12.927 -> receivedCharsBT: btwrite|mC=false
01:05:12.961 -> (processSerialInBT) receivedCharsBT: btwrite|mC=false
01:05:13.060 -> strlen(receivedCharsBT): 16
01:05:13.061 ->
01:05:13.061 -> cmdType: btwrite, cmdType strlen: 7
01:05:13.125 -> cmdName: mC, cmdName strlen: 2
01:05:13.158 -> cmdValue: false, cmdValue strlen: 5
01:05:13.952 -> rc: < -
01:05:13.952 -> rc: b -
01:05:13.985 -> rc: t - b
01:05:13.985 -> rc: w - bt
01:05:13.985 -> rc: r - btw
01:05:14.020 -> rc: i - btwr
01:05:14.020 -> rc: t - btwri
01:05:14.090 -> rc: e - btwrit
01:05:14.090 -> rc: | - btwrite
01:05:14.124 -> rc: m - btwrite|
01:05:14.124 -> rc: C - btwrite|m
01:05:14.124 -> rc: = - btwrite|mC
01:05:14.157 -> rc: t - btwrite|mC=
01:05:14.194 -> rc: r - btwrite|mC=t
01:05:14.194 -> rc: u - btwrite|mC=tr
01:05:14.226 -> rc: e - btwrite|mC=tru
01:05:14.260 -> rc: > - btwrite|mC=true
01:05:14.292 -> ndx: 15
01:05:14.292 -> receivedCharsBT: btwrite|mC=true
01:05:14.324 -> (processSerialInBT) receivedCharsBT: btwrite|mC=true
01:05:14.393 -> strlen(receivedCharsBT): 15
01:05:14.423 ->
01:05:14.423 -> cmdType: btwrite, cmdType strlen: 7
01:05:14.490 -> cmdName: mC, cmdName strlen: 2
01:05:14.523 -> cmdValue: true, cmdValue strlen: 4
01:05:14.622 -> rc: < - btwrite
01:05:14.653 -> rc: b - btwrite
01:05:14.653 -> rc: t - btwrite
01:05:14.689 -> rc: w - btwrite
01:05:14.720 -> rc: r - btwrite
01:05:14.754 -> rc: i - btwrite
01:05:14.754 -> rc: t - btwrite
01:05:14.790 -> rc: e - btwrite
01:05:14.790 -> rc: | - btwrite
01:05:14.790 -> rc: m - btwrite|mC
01:05:14.823 -> rc: C - btwrite|mC
01:05:14.858 -> rc: = - btwrite|mC
01:05:14.858 -> rc: f - btwrite|mC=true
01:05:14.891 -> rc: a - btwrite|mC=frue
01:05:14.925 -> rc: l - btwrite|mC=faue
01:05:14.962 -> rc: s - btwrite|mC=fale
01:05:15.039 -> rc: e - btwrite|mC=fals
01:05:15.039 -> rc: > - btwrite|mC=false
01:05:15.039 -> ndx: 16
01:05:15.077 -> receivedCharsBT: btwrite|mC=false
01:05:15.218 -> (processSerialInBT) receivedCharsBT: btwrite|mC=false
01:05:15.218 -> strlen(receivedCharsBT): 16
01:05:15.288 ->
01:05:15.288 -> cmdType: btwrite, cmdType strlen: 7
01:05:15.389 -> cmdName: mC, cmdName strlen: 2
01:05:15.389 -> cmdValue: false, cmdValue strlen: 5
01:05:15.389 ->
01:08:10.585 -> globalEngineRpm: 0
01:08:39.083 -> rc: < -
01:08:39.116 -> rc: b -
01:08:39.116 -> rc: t - b
01:08:39.116 -> rc: w - bt
01:08:39.149 -> rc: r - btw
01:08:39.149 -> rc: i - btwr
01:08:39.182 -> rc: t - btwri
01:08:39.182 -> rc: e - btwrit
01:08:39.217 -> rc: | - btwrite
01:08:39.249 -> rc: m - btwrite|
01:08:39.249 -> rc: C - btwrite|m
01:08:39.284 -> rc: = - btwrite|mC
01:08:39.328 -> rc: t - btwrite|mC=
01:08:39.366 -> rc: r - btwrite|mC=t
01:08:39.366 -> rc: u - btwrite|mC=tr
01:08:39.366 -> rc: e - btwrite|mC=tru
01:08:39.406 -> rc: > - btwrite|mC=true
01:08:39.440 -> ndx: 15
Ok, I understand what you mean now. I thought putting it outside of the loop was the way to handle it when it was finishing receiving data, however I didn't consider that it was being called every time the main loop was cycling.
I ran the test 101 times and all 101 times it was accurate. I'm going to continue to test and ensure it stays consistent, but that is promising, I appreciate your critique and I've learned a lot here.
Do you think anything else needs addressing? I'd like to put the serial and bluetooth code somewhere for others if it is acceptable, and hopefully save someone else from the mistakes I made.