I am getting multiple messages from a GPS device at different frequencies. After getting strings I have to save this data on the SD card. It works well when we have the same frequencies messages but if the frequencies are not same the saved data gets some blank spaces. I am using the split strings method.
CR1A = String1.indexOf(13); //finds location of first
String1A = String1.substring(0, CR1A + 2 ); //captures first data String
CR1B = String1.indexOf(13, CR1A + 2 ); //finds location of second ,
String1B = String1.substring(CR1A , CR1B + 2 ); //captures second data String
CR1C = String1.indexOf(13, CR1B + 2 );
String1C = String1.substring(CR1B , CR1C + 2 );
CR1D = String1.indexOf(13, CR1C + 2 );
String1D = String1.substring(CR1C , CR1D + 2 );
CR1E = String1.indexOf(13, CR1D + 2 );
String1E = String1.substring(CR1D , CR1E + 2 );
CR1F = String1.indexOf(13, CR1E + 2 );
String1F = String1.substring(CR1E , CR1F + 2 );
strID = (String1A.substring(0, 2));
if (strID == "$G") {
File dataFile = SD.open("GPS1.txt", FILE_WRITE);
// if the file is available, write to it:
strID = (String1A.substring(0, 5));
if (strID == "$GPGG") {
dataFile.print(dt);
dataFile.print(" ");
dataFile.print(tm);
dataFile.print(msec);
dataFile.print(",");
dataFile.print(String1A);
String1A = "";
}
strID = (String1D.substring(4, 6));
if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
dataFile.print(String1B);
String1B = "";
}
strID = (String1C.substring(4, 6));
if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
dataFile.print(String1C);
String1C = "";
}
strID = (String1D.substring(4, 6));
if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
dataFile.print(String1D);
String1D = "";
}
strID = (String1E.substring(4, 6));
if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
dataFile.print(String1E);
String1E = "";
}
strID = (String1F.substring(4, 6));
if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
dataFile.print(String1F);
String1F = "";
}
dataFile.close();
}
EDIT:
This is the code now I am using. I have turned off all the commands which extract strings from my available data received at the serial port. I am just using an interrupt timer for it.. and it is working perfectly. But I didn't like this simple method and I don't know it's a good way to get strings like this or not as I am not a good programmer.
#include <TimerOne.h>
#define RxTimeOut 5
/*
** MEGA MINI **
** MOSI - pin 51
** MISO - pin 50
** CLK - pin 52
** CS - pin 53 (for MKRZero SD: SDCARD_SS_PIN)
** SDA - pin 20
** SCL - pin 21
*/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <EEPROM.h>
#include "math.h"
#include <SPI.h>
#include <SD.h>
#include "RTClib.h"
#define DS1307_CTRL_ID 0x68
unsigned long int ticks = 0;
RTC_DS1307 rtc;
bool flag = false;
String GPSmessage = "";
const int chipSelect = 53;
String dataString = "";
//String dataString1 = "";
//String dataString2 = "";
//String dataString3 = "";
bool stringComplete = false;
bool string1Complete = false;
bool string2Complete = false;
bool string3Complete = false;
String strID = "";
unsigned long msec;
const long interval = 500;
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
unsigned long CurrentBaudRate = 9600;
unsigned long x = 0;
int Up = 3;
int Dn = 4;
int Mnu = 5;
String String1;
String inputString1 = ""; // a String to hold incoming data
boolean NewDataFlag1 = 0;
unsigned int Serial1TimeOut = 0;
String String2;
String inputString2 = ""; // a String to hold incoming data
boolean NewDataFlag2 = 0;
unsigned int Serial2TimeOut = 0;
String String3;
String inputString3 = ""; // a String to hold incoming data
boolean NewDataFlag3 = 0;
unsigned int Serial3TimeOut = 0;
void timerIsr()
{
serial1Event();
serial2Event();
serial3Event();
if (Serial1TimeOut > 0)Serial1TimeOut--;
if (Serial1TimeOut == 0 && NewDataFlag1 == 1)
{
String1 = inputString1;
inputString1 = "";
NewDataFlag1 = 0;
}
if (Serial2TimeOut > 0)Serial2TimeOut--;
if (Serial2TimeOut == 0 && NewDataFlag2 == 1)
{
String2 = inputString2;
inputString2 = "";
NewDataFlag2 = 0;
}
if (Serial3TimeOut > 0)Serial3TimeOut--;
if (Serial3TimeOut == 0 && NewDataFlag3 == 1)
{
String3 = inputString3;
inputString3 = "";
NewDataFlag3 = 0;
}
}
void setup() {
Timer1.initialize(5000); // Timer event time
Timer1.attachInterrupt( timerIsr );
Serial.println("Sonay di nathli");
//========================================= SD Card =======================================================//
// Serial.println("Initializing SD card...");
// see if the card is not present:
if (!SD.begin(chipSelect)) {
// Serial.println("Card failed, or not present");
// don't do anything more:
return;
}
// Serial.println("SD card Ready");
//====================================================== RTC =============================================//
if (!rtc.begin())
{
// Serial.println("Couldn't find RTC");
Serial.flush();
abort();
}
if (!rtc.isrunning()) {
// Serial.println("RTC is NOT running, let's set the time!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
//================================================ OLED Baudrate selection ====================================================//
pinMode(Up, INPUT_PULLUP);
pinMode(Dn, INPUT_PULLUP);
pinMode(Mnu, INPUT_PULLUP);
unsigned char bdindx = EEPROM.read(0);
if (bdindx > 3) bdindx = 0;
if (bdindx == 0) CurrentBaudRate = 4800;
if (bdindx == 1) CurrentBaudRate = 9600;
if (bdindx == 2) CurrentBaudRate = 19200;
if (bdindx == 3) CurrentBaudRate = 115200;
delay (500);
while (!Serial) { }// wait for serial port to connect
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(CurrentBaudRate);
Serial1.begin(CurrentBaudRate);
Serial2.begin(CurrentBaudRate);
Serial3.begin(CurrentBaudRate);
Serial.println(CurrentBaudRate);
delay (1000);
display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.display();
}
String String1A, String1B, String1C, String1D, String1E, String1F;
String String2A, String2B, String2C, String2D, String2E, String2F;
String String3A, String3B, String3C, String3D, String3E, String3F;
int CR1A, CR1B, CR1C, CR1D, CR1E, CR1F;
int CR2A, CR2B, CR2C, CR2D, CR2E, CR2F;
int CR3A, CR3B, CR3C, CR3D, CR3E, CR3F;
// ============================================ Showing baud rate on screen (position) ===========================================//
void DrawBaudRate(unsigned long BdRt)
{
unsigned char Xoffset = 0;
if (BdRt >= 0 && BdRt < 10000) Xoffset = 37;
if (BdRt >= 10000 && BdRt < 100000) Xoffset = 30;
if (BdRt >= 100000 ) Xoffset = 25;
// display.drawRect(0,0,128,64,SSD1306_WHITE);
// display.setTextSize(2);
// display.setCursor(15,10);
// display.println("Baudrate");
// display.setTextSize(2);
// display.setCursor(15,10);
// display.println(tm);
// display.setCursor(Xoffset,37);// 6 digit
// display.println(BdRt);
// display.display();
// delay(10);
}
// ================================================== Selection of Baud Rate ========================================================//
unsigned long SelectBaudRate(unsigned long BdRt)
{
unsigned char BdRtIndx = 0;
unsigned int FlashCnt = 0;
if (BdRt == 4800) BdRtIndx = 0;
if (BdRt == 9600) BdRtIndx = 1;
if (BdRt == 19200) BdRtIndx = 2;
if (BdRt == 115200) BdRtIndx = 3;
unsigned char Xoffset = 0;
if (BdRt >= 0 && BdRt < 10000) Xoffset = 37;
if (BdRt >= 10000 && BdRt < 100000) Xoffset = 30;
if (BdRt >= 100000 ) Xoffset = 25;
display.drawRect(0, 0, 128, 64, SSD1306_WHITE);
display.setTextSize(1);
display.setCursor(15, 10); display.println("Select Baudrate");
display.setCursor(15, 20); display.println("by Up/Dn Buttons");
display.setTextSize(2);
display.setCursor(Xoffset, 37); // 6 digit
display.println(BdRt);
display.display();
delay(10);
while (digitalRead(Mnu) == 0) delay(10);
delay(100);
while (digitalRead(Mnu) == 1)
{
delay(10);
FlashCnt++;
if (digitalRead(Up) == 0)
{
if (BdRtIndx < 3) BdRtIndx++;
}
if (digitalRead(Dn) == 0)
{
if (BdRtIndx > 0) BdRtIndx--;
}
if (BdRtIndx == 0) BdRt = 4800;
if (BdRtIndx == 1) BdRt = 9600;
if (BdRtIndx == 2) BdRt = 19200;
if (BdRtIndx == 3) BdRt = 115200;
if (BdRt >= 0 && BdRt < 10000) Xoffset = 37;
if (BdRt >= 10000 && BdRt < 100000) Xoffset = 30;
if (BdRt >= 100000 ) Xoffset = 25;
display.clearDisplay();
display.drawRect(0, 0, 128, 64, SSD1306_WHITE);
display.setTextSize(1);
display.setCursor(15, 10); display.println("Select Baudrate");
display.setCursor(15, 20); display.println("by Up/Dn Buttons");
display.setTextSize(2);
display.setCursor(Xoffset, 37); // 6 digit
if (FlashCnt > 1) display.println(BdRt);
if (FlashCnt > 2) FlashCnt = 0;
display.display();
delay(250);
//while(digitalRead(Up)==0 || digitalRead(Dn)==0) delay(10);
}
while (digitalRead(Mnu) == 0) delay(10);
display.clearDisplay();
display.drawRect(0, 0, 128, 64, SSD1306_WHITE);
display.setTextSize(2);
display.setCursor(20, 10); display.println("Saving");
display.setCursor(20, 35); display.println("Changes");
display.display();
delay(2000);
EEPROM.write(0, BdRtIndx);
return (BdRt);
}
//=================================================== OLED showing time ===============================================//
char Time[] = " : : ";
byte i, second, minute, hour;
void DS3231_display() {
// Convert BCD to decimal
second = (second >> 4) * 10 + (second & 0x0F);
minute = (minute >> 4) * 10 + (minute & 0x0F);
hour = (hour >> 4) * 10 + (hour & 0x0F);
// End conversion
Time[7] = second % 10 + 48;
Time[6] = second / 10 + 48;
Time[4] = minute % 10 + 48;
Time[3] = minute / 10 + 48;
Time[1] = hour % 10 + 48;
Time[0] = hour / 10 + 48;
display.drawRect(0, 0, 128, 64, SSD1306_WHITE);
draw_text(16, 25, Time, 2); // Display the time
}
void blink_parameter() {
byte j = 1;
while (j < 10 && digitalRead(Up) && digitalRead(Dn)) {
j++;
delay(25);
}
}
byte edit(byte x_pos, byte y_pos, byte parameter) {
char text[3];
sprintf(text, "%02u", parameter);
while (!digitalRead(Up)); // Wait until button B1 released
while (true) {
while (!digitalRead(Dn)) { // If button B2 is pressed
display.clearDisplay();
parameter++;
if (i == 0 && parameter > 23) // If hours > 23 ==> hours = 0
parameter = 0;
if (i == 1 && parameter > 59) // If minutes > 59 ==> minutes = 0
parameter = 0;
sprintf(text, "%02u", parameter);
draw_text(x_pos, y_pos, text, 2);
delay(200); // Wait 200ms
}
display.drawRect(0, 0, 128, 64, SSD1306_WHITE);
draw_text(x_pos, y_pos, " ", 2);
blink_parameter();
draw_text(x_pos, y_pos, text, 2);
blink_parameter();
if (!digitalRead(Up)) { // If button B1 is pressed
i++; // Increament 'i' for the next parameter
// display.clearDisplay();
return parameter; // Return parameter value and exit
}
}
}
void draw_text(byte x_pos, byte y_pos, char *text, byte text_size) {
display.setCursor(x_pos, y_pos);
display.setTextSize(text_size);
display.print(text);
display.display();
}
//---------------------------------------------
void loop() {
// ========================================= Editing time and displaying on OLED ============================================//
if (!digitalRead(Up)) { // If button B1 is pressed
i = 0;
while (!digitalRead(Up)); // Wait for button B1 release
hour = edit(16, 25, hour); // Edit hours
minute = edit(52, 25, minute); // Edit minutes
// Convert decimal to BCD
minute = ((minute / 10) << 4) + (minute % 10);
hour = ((hour / 10) << 4) + (hour % 10);
// End conversion
// Write data to DS3231 RTC
Wire.beginTransmission(0x68); // Start I2C protocol with DS3231 address
Wire.write(0); // Send register address
Wire.write(0); // Reset sesonds and start oscillator
Wire.write(minute); // Write minute
Wire.write(hour); // Write hour
Wire.endTransmission(); // Stop transmission and release the I2C bus
delay(200); // Wait 200ms
}
Wire.beginTransmission(0x68); // Start I2C protocol with DS3231 address
Wire.write(0); // Send register address
Wire.endTransmission(false); // I2C restart
Wire.requestFrom(0x68, 7); // Request 7 bytes from DS3231 and release I2C bus at end of reading
second = Wire.read(); // Read seconds from register 0
minute = Wire.read(); // Read minutes from register 1
hour = Wire.read(); // Read hour from register 2
Wire.beginTransmission(0x68); // Start I2C protocol with DS3231 address
Wire.write(0x11); // Send register address
Wire.endTransmission(false); // I2C restart
Wire.requestFrom(0x68, 2); // Request 2 bytes from DS3231 and release I2C bus at end of reading
DS3231_display(); // Diaplay time & calendar
delay(50); // Wait 50ms
{ display.clearDisplay();
if (digitalRead(Mnu) == 0) CurrentBaudRate = SelectBaudRate(CurrentBaudRate);
// DrawBaudRate(CurrentBaudRate);
delay(10);
x++;
if (x > 123456) x = 0;
}
// ======================================= Reading Date and Time from RTC =============================================//
DateTime now = rtc.now();
char dt[16];
char tm[16];
char buffer [16];
uint8_t thisSec, thisMin, thisHour;
thisSec = now.second();
thisMin = now.minute();
thisHour = now.hour();
sprintf(dt, "%02d-%02d-%02d", now.year(), now.month(), now.day());
sprintf(tm, "%02d%02d%02d", now.hour(), now.minute(), now.second());
sprintf (buffer, "%02d:%02d:%02d", thisHour, thisMin, thisSec);
msec = millis() % 1000; //TO USE LAST 3 DIGITS OF MILLIS OF ARDUINO
//SERIAL_PORT_1
// if (string1Complete)
{ Serial.print (String1);
// CR1A = String1.indexOf(13); //finds location of first
// String1A = String1.substring(0, CR1A + 2 ); //captures first data String
// CR1B = String1.indexOf(13, CR1A + 2 ); //finds location of second ,
// String1B = String1.substring(CR1A , CR1B + 2 ); //captures second data String
// CR1C = String1.indexOf(13, CR1B + 2 );
// String1C = String1.substring(CR1B , CR1C + 2 );
// CR1D = String1.indexOf(13, CR1C + 2 );
// String1D = String1.substring(CR1C , CR1D + 2 );
// CR1E = String1.indexOf(13, CR1D + 2 );
// String1E = String1.substring(CR1D , CR1E + 2 );
// CR1F = String1.indexOf(13, CR1E + 2 );
// String1F = String1.substring(CR1E , CR1F + 2 );
//
// strID = (String1A.substring(0, 5));
// if (strID == "$GPGG") {
// Serial.println(String1);
// }
// strID = (String1B.substring(0, 5));
// if (strID == "$GPVT") {
// Serial.println(String1B);
// }
// strID = (String1C.substring(0, 5));
// if (strID == "$GPZD") {
// Serial.println(String1C);
// }
// strID = (String1D.substring(0, 5));
// if (strID == "$GPGL") {
// Serial.println(String1D);
// }
// strID = (String1E.substring(0, 5));
// if (strID == "$GPGN") {
// Serial.println(String1E);
// }
// strID = (String1F.substring(0, 5));
// if (strID == "$GPGR") {
// Serial.println(String1F);
// }
// strID = (String1.substring(0, 2));
// if (strID == "$") {
File dataFile = SD.open("GPS1.txt", FILE_WRITE);
// if the file is available, write to it:
strID = (String1A.substring(0, 5));
if (strID == "$GPGG") {
dataFile.print(dt);
dataFile.print(" ");
dataFile.print(tm);
dataFile.print(msec);
dataFile.print(",");
dataFile.print(String1);
Serial.print (String1);
String1 = "";
Serial.print (String1);
dataFile.close();
}
// }
// strID = (String1D.substring(4, 6));
// if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
// dataFile.print(String1B);
// String1B = "";
// }
// strID = (String1C.substring(4, 6));
// if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
// dataFile.print(String1C);
// String1C = "";
// }
// strID = (String1D.substring(4, 6));
// if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
// dataFile.print(String1D);
// String1D = "";
// }
// strID = (String1E.substring(4, 6));
// if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
// dataFile.print(String1E);
// String1E = "";
// }
// strID = (String1F.substring(4, 6));
// if (strID == "TG" || "DA" || "LL" || "NS" || "RS") {
// dataFile.print(String1F);
// String1F = "";
// }
// }
else {
File dataFile = SD.open("ES2.txt", FILE_WRITE);
if (dataFile) {
dataFile.print(dt);
dataFile.print(" ");
dataFile.print(tm);
dataFile.print(msec);
dataFile.print(",");
dataFile.println(String1);
Serial.print (String1);
// dataFile.println(String1B);
String1A = "";
String1B = "";
dataFile.close();
}
}
// }
string1Complete = false;
}
}
//-----------------------------------------------------------------------------------------------------------------
void serial1Event() {
while (Serial1.available()) {
char inChar1 = (char)Serial1.read();
inputString1 += inChar1;
Serial1TimeOut = RxTimeOut;
NewDataFlag1 = 1;
if (NewDataFlag1 == 1) {
string1Complete = true;
}
}
}
indexOf()
does find the'\r'
. Why do you try to process five messages at a time instead of processing them one by one?"DA"
,"LL"
, and"NS"
are all truthy in C++. So, the above mentioned nonsense is functionally equivalent toif (true)
.