Is there an easy way for these values to go to "0" or "error" if the Tx goes offline?
The design of your program is somewhat based on the original conditions where the transmission was faster than the display and there was run on and jumbled data.
Now with the tx every 30 seconds, and the display taking 24 seconds the can be some clean up. Setting newData = false and newData = true can be done in one location for each. I have added another boolean variable to control the display, so that you still only parse once and are ready for the next packet.
Try this. It untested, but I think the code will display the 6 data screens and then a "Waiting new data" screen until there is a new packet received and parsed.
#include <SoftwareSerial.h>
SoftwareSerial XBee(2, 3); // RX, TX
#include <Wire.h>
#include <LiquidCrystal.h>
const int rs = 12, en = 11, d4 = 7, d5 = 6, d6 = 5, d7 = 4;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
#include <string.h>
#include <stdio.h>
const byte numChars = 64; //This means 64 characters are expected.
char receivedChars[numChars]; // array that is received
char tempChars [numChars]; // temporary array for use when parsing
//variables to hold the parsed data
int TempCbmp = 0;
int TempFbmp = 0;
int TempCdht = 0;
int TempFdht = 0;
int HICdht = 0;
int HIFdht = 0;
float H1dht = 00.00;
float DPdht = 00.00;
long P1bmp = 000000;
float P2bmp = 000.00;
float P3bmp = 00.00;
boolean newData = false;
boolean displayNewData = false;//add new control variable
//non blocking display control variables
unsigned long lastDisplaySwitch;
unsigned long interval = 4000; //4 seconds for each lcd screen
byte count = 0;// for display screen
//============
void setup()
{
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
lcd.clear ();
lcd.setCursor(0, 0);
lcd.print("Waiting New Data"); //should be 16 chars and fill 1st row
// Set up both ports at 9600 baud. This value is most important
// for the XBee. Make sure the baud rate matches the config
// setting of your XBee.
XBee.begin(9600);
Serial.begin(9600);
}
void loop() {
recvWithEndMarker();
if (newData == true) {
//this temporary copy is necessary to protect the original data
//because strtok() used in parseData() replaces the commas with \0
memset(tempChars, '\0', 64); //clear tempChars
strcpy(tempChars, receivedChars);
memset(receivedChars, '\0', 64);//clear receivedChars
parseData();
}
if(displayNewData == true)
showDisplay();
}
//========
void recvWithEndMarker() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (XBee.available() > 0 && newData == false) { // If Xbee is receiving data AND newData is false, THEN "rc" is the XBee data
rc = XBee.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc; //if rc is NOT the endMarker, then index "rc" to the "receivedChars" array.
ndx++; // go to the next character and index it as well
if (ndx >= numChars) { // what does this mean? why would ndx ever be greater than 64?
ndx = numChars - 1; // what does this do?
}
}
else {
receivedChars[ndx] = '\0'; //terminate the string when the endMarker is received
recvInProgress = false; // and mark as NOT recvInProgress
ndx = 0; // move index back to 0 position?
newData = true; // why is new data here marked as true? shouldn't it be above the "ndx=0"?
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
//=======
void parseData() { // split the data into it's parts
char * strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(tempChars, ","); // get the first part - the string
TempCbmp = atoi(strtokIndx); // copy it to TempCbmp
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
TempFbmp = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
TempCdht = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
TempFdht = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
HICdht = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
HIFdht = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ",");
H1dht = atof(strtokIndx); // convert this part to a float
strtokIndx = strtok(NULL, ",");
DPdht = atof(strtokIndx); // convert this part to a float
strtokIndx = strtok(NULL, ",");
P1bmp = atol(strtokIndx); // convert this part to a long
strtokIndx = strtok(NULL, ",");
P2bmp = atof(strtokIndx); // convert this part to a float
strtokIndx = strtok(NULL, ",");
P3bmp = atof(strtokIndx); // convert this part to a float
newData = false;
displayNewData = true;
}
//======
void showDisplay()
{
if (millis() - lastDisplaySwitch > interval)
{
lastDisplaySwitch += interval;
count++;
switch (count) {
case 1:
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("TempC(bmp): ");
lcd.print(TempCbmp);
lcd.setCursor(0, 1);
lcd.print("TempF(bmp): ");
lcd.print(TempFbmp); // Round 1 of data display complete
break;
case 2:
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("TempC(dht): ");
lcd.print(TempCdht);
lcd.setCursor(0, 1);
lcd.print("TempF(dht): ");
lcd.print(TempFdht); // Round 2 of data display complete
break;
case 3:
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("HIC: ");
lcd.print(HICdht);
lcd.setCursor(0, 1);
lcd.print("HIF: ");
lcd.print(HIFdht); // Round 3 of data display complete
break;
case 4:
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("H: ");
lcd.print(H1dht);
lcd.setCursor(0, 1);
lcd.print("DP: ");
lcd.print(DPdht); // Round 4 of data display complete
break;
case 5:
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("P(Pa): ");
lcd.print(P1bmp);
lcd.setCursor(0, 1);
lcd.print("P(mm): ");
lcd.print(P2bmp);
break;
case 6:
lcd.setCursor(0, 1);
lcd.print("P(in): ");
lcd.print(P3bmp);
break;
case 7:
displayNewData = false;
count = 0; //reset display counter
lcd.setCursor(0, 0);
lcd.print("Waiting New Data"); //should be 16 chars and fill 1st row
lcd.setCursor(0, 1);
lcd.print(" "); //16 spaces to clear second row
break;
default:
// if nothing else matches, do the default
// default is optional
break;
}
}
}