Notifications
Clear all

How to parse the String variables strlat1 & strlon1 from the Data Frames of the I2C Slave message received:

13 Posts
3 Users
0 Reactions
565 Views
(@do_not_give_up)
Member
Joined: 2 years ago
Posts: 8
Topic starter  

My project is passing live, real-time GPS coordinnates from a I2C Master TTGO T7 V1.3 ESP32-Wrover Mini) to a I2C Slave (ILI9488 3.5 in. TFT ESP32-Wrover LCD Display). I have successfully established communication between both micros. The Sring message received by the Slave prints to the Serial Monitor exactly as configured by the Master. However, I cannot print the individual Sring variables stored value from the received message to the Serial Monitor?

These print requests returned a blank

Serial.print("strlat1 ");Serial.println(strlat1);
Serial.print("strlon1 ");Serial.println(strlon1);

How do I parse the String variables strlat1 & strlon1 values from the Data Frames of the I2C Slave message to be able to utilize the String's variable values else where in the project?

Serial Monitor of the Master

21:15:29.550 -> requestFrom: 16
21:15:30.395 -> 44.241032, -85.942070
21:15:30.395 -> endTransmission: 0
21:15:30.429 -> requestFrom: 16
21:15:30.531 -> 44.241032, -85.942070
21:15:30.531 -> endTransmission: 0

Serial Monitor of the Slave

21:08:28.517 -> 44.241135, -85.941811
21:08:28.517 ->
21:08:28.517 -> onRequest
21:08:29.392 ->
21:08:29.392 -> 44.241135, -85.941811
21:08:29.392 ->
21:08:29.392 -> onRequest

(Slightly different time stamps, I am too slow!)

Screenshot:  I2C Slave message received.png

https://imgur.com/a/g1cyx6p

 

Arduino Sketches 


   
Quote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 4 years ago
Posts: 7728
 

@do_not_give_up   You need to show what these print statements produce.

These print requests returned a blank

Serial.print("strlat1 ");Serial.println(strlat1);
Serial.print("strlon1 ");Serial.println(strlon1);

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.


   
ReplyQuote
Will
 Will
(@will)
Member
Joined: 3 years ago
Posts: 2585
 

@do_not_give_up

Since you don't specify the contents of the message received, we can't give you a precise answer. However, the general procedure is to locate the part(s) of the message that you need to extract; make a not of the starting and ending indices of each. Then use substring() to extract the values from the message string.

Remember that indices start from zero and the substring end index is the character just past the end of the desired part.

For example, if you r desired field runs from the 5th to 7th characters in the original string (let's call it 'theMessage'), then you'd use theMessage.substring(4,7) to extract the part.

Anything seems possible when you don't know what you're talking about.


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 4 years ago
Posts: 7728
 

@do_not_give_up To add a bit to Wills (@will) description, if memory serves GPS data comes in NMEA 'sentences'. Within the sentence the data elements are comma delimited.

Normally clicking the 'more' on the library entry will get you the documentation, but that page is 404 (missing). I then checked the Arduino.cc Library pages and again the documentation is 404. Finally a check of github and again 404.

Maybe there is a newer or at least a documented library to use?

The following may be helpful https://stackoverflow.com/questions/48486952/parsing-a-nmea-string-using-strok-in-c

 

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.


   
ReplyQuote
(@do_not_give_up)
Member
Joined: 2 years ago
Posts: 8
Topic starter  

 

Thank you for the prompt reply, still not able to print the variable values of strlat1 & strlon1 to the serial monitor?

Screenshot of the Serial Monitor:

 

Error with the changed code
//Libraries I2C Edit on GitHub I2C

// https://espressif-docs.readthedocs-hosted.com/projects/arduino-esp32/en/latest/api/i2c.html#arduino-esp32-i2c-api 

#include <SoftwareSerial.h>

#include "Wire.h"
#include "String.h"

#define I2C_DEV_ADDR 0x55//ESP32-Wrover - Hex = 0055 - Dec = 85 - Elecrow ILI9488 3.5 in. TFT display 

float flat1, flon1;
String strlat1, strlon1;

int i, b;

void onRequest(){
  Wire.print(" Packets.");
  Serial.println("onRequest");
}

void onReceive(int len){

  while(Wire.available()){
    Serial.write(Wire.read());
  }
  Serial.println();
}

void setup() {
  Serial.begin(115200);

Serial.println("Step_3_I2C_com_with_a_ESP32-Wrover_Slave_3.ino");
Serial.println("ILI9488 3.5in. ESP32-32 TFT Display");
Serial.println("06_09_2024");

  Serial.setDebugOutput(true);
  Wire.onReceive(onReceive);
  Wire.onRequest(onRequest);
  Wire.begin((uint8_t)I2C_DEV_ADDR);

}

void loop() {

#if CONFIG_IDF_TARGET_ESP32
  char message[64];
//  snprintf(message, 64, "%lu Packets.", i++);
  snprintf(message, 64, "%lu Packets.");
  Wire.slaveWrite((uint8_t *)message, strlen(message));
//  size_t slaveWrite(const unit_t *, size_t);

  int i;
  for ( i = 0; 1 < sizeof(message); i++) {
    if (message[i] == ',')break;
    }
  int b;
  for ( b = 0; b < i; b++) strlat1 = strlat1 + message[b];
  i = i + 2;
  for ( b = 0; b < (sizeof(message) - 1); b++) strlon1 = strlon1 +  message[b = i];

/*
Serial.println("************************************");
Serial.print("strlat1 ");Serial.println(strlat1);
Serial.print("strlon1 ");Serial.println(strlon1);
Serial.println("************************************");
*/

#endif

Serial.println("************************************");
Serial.print("strlat1 ");Serial.println(strlat1);
Serial.print("strlon1 ");Serial.println(strlon1);
Serial.println("************************************");

}

   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 4 years ago
Posts: 7728
 

@do_not_give_up Sorry, that's more than an 82 yo can handle at least quickly, but my 50+ yrs of experience tells me you are possibly missing a /0 terminator needed for a string. Perhaps use a function that has a length argument as well as looking for the /0. IIRC, they are of the general form strn.... where n is some 'not to exceed' number if the /0 is missing.

Does that make sense, help?

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 4 years ago
Posts: 7728
 

@do_not_give_up One other hint, if you use real variable names instead of i, b etc, then the code is self documenting. Also I see one bit of code that looks strange when I look at it quickly, it ends with 

message[b = i];

I have no idea what element of message will be referenced with the term b=i. Maybe I will learn something new today or ????

 

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 4 years ago
Posts: 7728
 

@do_not_give_up Just noticed another possible typo

for ( i = 0; 1 < sizeof(message); i++) {

did you mean

for (i = 0; i < sizeof(message); i++) {

 

 

 

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 4 years ago
Posts: 7728
 

@do_not_give_up I think this is the general solution for string tokenization such as in NEMEA GPS Sentences. I am not sure if this solution deals with null terms as in term1,term2,,term 4. Ifg it does not, there are code samples that show hor to do that and in fact there is a GPS NMEA tokenizing library somewhere.

https://www.geeksforgeeks.org/string-tokenization-in-c/

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.


   
ReplyQuote
(@do_not_give_up)
Member
Joined: 2 years ago
Posts: 8
Topic starter  

@will, The structure of the Master's original message was as follows;

Wire.beginTransmission(I2C_DEV_ADDR);
  
    Wire.println();
  
    Wire.println((strlat1) + (", ") + (strlon1));
  
    Serial.println((strlat1) + (", ") + (strlon1));

 

Master's Serial Monitor printout:

12:03:14.058 -> requestFrom: 16
12:03:14.160 -> 44.240974, -85.942001
12:03:14.160 -> endTransmission: 0

 

Slave's Messsage received Serial Monitor printout:

12:03:14.046 -> onRequest
12:03:14.148 ->
12:03:14.148 -> 44.240974, -85.942001

 

Counting positions of the message:

((strlat1) + (", ") + (strlon1)) 

(strlat1) = 44.240974 = 0 - 8 = 9 bits 

(", ")  =  9 -10 = 2 bits

(strlon1) = -85.942001 =  11 - 20 = 10 - bits

Will get busy researching the Message.substring(0,8), etc.! 

 


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 4 years ago
Posts: 7728
 

@do_not_give_up Bits? Don't you mean bytes. As @will said several posts back, just use strtok. I think I gave you some links on how to do that earlier. Using that will then get rid of your erroneous code BUT research the null term problem just in case. Null term is the term,,term where term 2 is NULL.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.


   
ReplyQuote
Will
 Will
(@will)
Member
Joined: 3 years ago
Posts: 2585
 

Posted by: @do_not_give_up

@will, The structure of the Master's original message was as follows;

Wire.beginTransmission(I2C_DEV_ADDR);
  
    Wire.println();
  
    Wire.println((strlat1) + (", ") + (strlon1));
  
    Serial.println((strlat1) + (", ") + (strlon1));

Since there are only two values separated by a comma, use this to separate them ...

void setup() {
  Serial.begin(9600);
}

void loop() {
  String    test = "9876.54321, 12345.6789";
  //
  int       comma = test.indexOf(",");
  //
  String    v1 = test.substring(0,comma);
  String    v2 = test.substring(comma+1,test.length());
  float     r1 = v1.toDouble();
  float     r2 = v2.toDouble();
  //
  Serial.println(" first value is "+v1);
  Serial.println(" second value is "+v2);
  Serial.print(" first float value is ");
  Serial.println(r1);
  Serial.print(" second float value is ");
  Serial.println(r2);
  delay(100000);
}

 

Anything seems possible when you don't know what you're talking about.


   
ReplyQuote
(@do_not_give_up)
Member
Joined: 2 years ago
Posts: 8
Topic starter  

@will I will play with your code, looks like it is the anwser, Thank you! Will keep you informed.


   
ReplyQuote