Hello,
thanks to your help. It works now very reliable. The poll mode did not work for me.
I had a bug in the function "void recvWithStartEndMarkers()".
Additionally I installed the mentioned level shifter.
That's what my code looks like now:
#include <SoftwareSerial.h>
/*
sensor Pin3(TX) to Arduino Pin 10(RX)
sensor Pin4(RX) to Arduino Pin 11(TX)
*/
SoftwareSerial mySerial(10, 11); // RX, TX
const byte numChars = 41;
char receivedChars[numChars];
char tempChars[numChars]; // temporary array for use when parsing
float oxygen = 0.0; // variables to hold the parsed data
float temperature = 0.0;
int pressure = 0;
float percentage = 0.0;
boolean newData = false;
unsigned long currentMillis = 0;
unsigned long previousReadOxySenMillis = 0;
//unsigned long previousReadDHTMillis = 0;
const long ReadOxySenInterval = 10000;
//============
void setup() {
Serial.begin(9600);
mySerial.begin(9600);
}
//============
void loop() {
currentMillis = millis(); // capture the latest value of millis()
updateReadOxySen();
}
//============
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = 'O';
char endMarker = 'e';
char rc;
while (mySerial.available() > 0 && newData == false) {
rc = mySerial.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
//============
void parseData() { // split the data into its parts
char * strtokIndx; // this is used by strtok() as an index
//data from sensor send looks like: "O xxxx.x T yxx.x P xxxx % xxx.xx e xxxx\r\n"
//e.g. "O 0020.1 T +19.3 P 1013 % 020.16 e 0001\r\n"
strtokIndx = strtok(tempChars,"T"); // get the first part - the string
oxygen = atof(strtokIndx); // copy it to oxygen
strtokIndx = strtok(NULL, "P"); // this continues where the previous call left off
temperature = atof(strtokIndx); // convert this part to a float
strtokIndx = strtok(NULL, "%"); // this continues where the previous call left off
pressure = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, "e"); // this continues where the previous call left off
percentage = atof(strtokIndx); // convert this part to a float
}
//============
void showParsedData() {
Serial.print("Oxygen ");
Serial.println(oxygen);
Serial.print("Temperature ");
Serial.println(temperature);
Serial.print("Pressure ");
Serial.println(pressure);
Serial.print("Percent ");
Serial.println(percentage);
}
void updateReadOxySen() {
if (currentMillis - previousReadOxySenMillis >= ReadOxySenInterval) {
// time is up, so make anew read
recvWithStartEndMarkers();
if (newData == true) {
strcpy(tempChars, receivedChars);
// this temporary copy is necessary to protect the original data
// because strtok() used in parseData() replaces the commas with \0
parseData();
showParsedData();
newData = false;
}
// and save the time of change
previousReadOxySenMillis += ReadOxySenInterval;
}
}