I'm trying to read a string of serial data
here is an example of the data coming in from the Soft serial port
N 1450556518 660 192.168.1.2 5 24.625 24.500 24.625 24.500 25.187
this is my complete code:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <AltSoftSerial.h>
#include <SoftwareSerial.h>
#include <Time.h>
#include <Streaming.h>
#define LCD_COLS 20 //LCD is 20x4
#define LCD_ROWS 4
//AltSoftSerial mySerial; //tx9 rx8
SoftwareSerial mySerial(8, 9); // RX, TX removed to use bidirectinal read.
LiquidCrystal_I2C lcd(0x27,LCD_COLS,LCD_ROWS);
char Ip_string[15];
unsigned long SerialStartTime = 0, time_UTC = 0; // storage for onset of serial data
bool firstChar = true; // if first char = or not.
uint8_t numberOfDevices; // get the actual number of temperatures per line of text. global as its used by many things.
float temps[8]; //up to 8 devices
const char *monthName[12] =
{
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
const char *dayName[7] =
{
"Sun","Mon","Tue","Wed","Thu","Fri","Sat"
};
//String to gather string of data that can be split up process.
//Flag to mark the end of the input string.
//need to used string because varible length.
tmElements_t tm;
char inputString[200] ="";
bool stringComplete = true;
void setup ()
{
if(timeStatus() == timeNotSet)
{
getDate(__DATE__); //get compile time update tm (tmElements)
getTime(__TIME__);
setTime(makeTime(tm)); //set the system time with it.
}
mySerial.begin(9600);
Serial.begin (115200);
Wire.begin(); // intitiate wire library
lcd.init();
lcd.backlight();
//state = NONE;
}
void serialEvent(void)
{
while(mySerial.available())
{
if (firstChar)
{
SerialStartTime = millis();
firstChar = false; //set the serialstart only once.
}
char d = mySerial.read();//convert d into char
char * str2 = &d;//convert into pointer and then obtain address
if (*str2 == '\n')
return;
if (*str2 == '\r' ) // look for the carriage return
{
strncat(inputString,char(0),1);
stringComplete = true; //set complete flag to true.
}
else
{
strncat(inputString,str2,1); //concantenate it
}
}
}
void processCstring()
{
//inputString contains formatted string
Serial.print(">>>");Serial.print(inputString);Serial.println("<<<");
char display_record[2]; //determine if N for display or R for record.
char temp_UTCString[12];
unsigned long time_UTC;
unsigned int time_DST;
char *ptr_inputString;
ptr_inputString = inputString;
uint8_t rem_string;
sscanf(inputString,"%s %s %d %s %d %n", display_record, temp_UTCString, &time_DST , Ip_string, &numberOfDevices , &rem_string);
time_UTC = atol(temp_UTCString);//convert string into long
float delay = 0.5 + (millis() - SerialStartTime) / 1000.0; //round up serial start time
unsigned long currTime = time_UTC + time_DST * 60 +1 ; //cant work out why the 1 is needed.
for (int n = 0; n < numberOfDevices; n++) //process the number of floating points.
{
ptr_inputString += rem_string;
char tempCString[10];
sscanf(ptr_inputString,"%s", tempCString);
Serial.print(">>");Serial.print(ptr_inputString);Serial.println("<<");
ptr_inputString += strlen(tempCString); // pointer is null terminated. and moves along by remstring.
Serial.print("tempCString ");
Serial.println(tempCString);
Serial.print("ptr_inputString ");
Serial.println((int)ptr_inputString);
Serial.println();
//temps[n] = atof(tempCString);
}
setTime(currTime);
Serial.println(now());
Serial.println();
firstChar = true; //set the first char for the next read to start millis counter.
}
void loop ()
{
serialEvent();
if(stringComplete)
{
//process input string.
//Serial.print(inputString);
processCstring();
inputString[0]=0;
stringComplete = false;
}
printLCDtime();
lcd.setCursor(0,1);
lcd.print(Ip_string);
// do other stuff in loop as required
} // end of loop
void printLCDtime(void)
{
char buffe[50];
sprintf(buffe,"%02d:%02d:%02d %3s %02d%03s%02d",hour(), minute(), second() ,dayName[weekday() - 1],day(), monthName[(month() - 1)], (year() % 100));
lcd.setCursor(0,0);
lcd.print(buffe);
}
//----- function to convert compile time to tm.element
bool getDate(const char *str)
{
char Month[12];
int Day, Year;
uint8_t monthIndex;
if (sscanf(str, "%s %d %d", Month, &Day, &Year) != 3) return false;
for (monthIndex = 0; monthIndex < 12; monthIndex++) {
if (strcmp(Month, monthName[monthIndex]) == 0) break;
}
if (monthIndex >= 12) return false;
tm.Day = Day;
tm.Month = monthIndex + 1;
tm.Year = CalendarYrToTm(Year);
return true;
}
bool getTime(const char *str)
{
int Hour, Min, Sec;
if (sscanf(str, "%d:%d:%d", &Hour, &Min, &Sec) != 3) return false;
tm.Hour = Hour;
tm.Minute = Min;
tm.Second = Sec;
return true;
}
as you will have worked out from looking at this far from elegant code I'm still a bit of noob.
the problem I am having is this section:
void processCstring()
{
//inputString contains formatted string
Serial.print(">>>");Serial.print(inputString);Serial.println("<<<");
char display_record[2]; //determine if N for display or R for record.
char temp_UTCString[12];
unsigned long time_UTC;
unsigned int time_DST;
char *ptr_inputString;
ptr_inputString = inputString;
uint8_t rem_string;
sscanf(inputString,"%s %s %d %s %d %n", display_record, temp_UTCString, &time_DST , Ip_string, &numberOfDevices , &rem_string);
time_UTC = atol(temp_UTCString);//convert string into long
float delay = 0.5 + (millis() - SerialStartTime) / 1000.0; //round up serial start time
unsigned long currTime = time_UTC + time_DST * 60 +1 ; //cant work out why the 1 is needed.
for (int n = 0; n < numberOfDevices; n++) //process the number of floating points.
{
ptr_inputString += rem_string;
char tempCString[10];
sscanf(ptr_inputString,"%s", tempCString);
Serial.print(">>");Serial.print(ptr_inputString);Serial.println("<<");
ptr_inputString += strlen(tempCString); // pointer is null terminated. and moves along by remstring.
Serial.print("tempCString ");
Serial.println(tempCString);
Serial.print("ptr_inputString ");
Serial.println((int)ptr_inputString);
Serial.println();
//temps[n] = atof(tempCString);
}
setTime(currTime);
Serial.println(now());
Serial.println();
firstChar = true; //set the first char for the next read to start millis counter.
}
Here is an example of my output to the hardware serial port. For some reason the pointer the to string now shows no characters for sscanf to read on the second pass and for the last 5 hours I can't work out why.
>>>N 1450557902 660 192.168.1.2 5 24.812 24.750 24.812 24.625 25.625 <<<
>>24.812 24.750 24.812 24.625 25.625 <<
tempCString 24.812
ptr_inputString 637
>><<
tempCString 24.812
ptr_inputString 674
>><<
tempCString 24.812
ptr_inputString 711
>><<
tempCString 24.812
ptr_inputString 748
>><<
tempCString 24.812
ptr_inputString 785
1450597503