Store › Forums › Video Experimenter › Bugs/Problems › pserial with 3 parsed variables numbers
- This topic has 8 replies, 3 voices, and was last updated 2 years, 10 months ago by dan-dan.
-
AuthorPosts
-
April 16, 2019 at 5:41 pm #11007pedroeParticipant
Hi,
I have the video experimenter shield, and Im trying to communicate via pserial between 2 arduinos. To explain my issued, lets consider that the arduino master prints “1000,12,24.70” in the serial. Then the slave arduino which has the video experimenter shield has to read that info (“1000,12,24.70”) and then parse, so that the 1000, 12 and 24.70 becomes 3 diferente variables, 1 long 1 integer and 1 float.
Since my knowledge is very limited, Im not able to convert the char strings into numbers. At the moment, with all my internet search I was able to find some pieces of code that is working until the point of correct parsing, has follows:
TV.println(strings[0]); overlays 1000
TV.println(strings[1]); overlays 12
TV.println(strings[2]); overlays 24.70But now I would like to assign:
long int dist to strings[0]
int var to strings[1], and
float rad to strings[2]which I would ask for some help since Im not able to code a solution that works.
My slave arduino has the following code:
#include <TVout.h> #include <pollserial.h> #include <fontALL.h> TVout TV; pollserial pserial; char *strings[10]; char *ptr = NULL; void setup() { TV.begin(PAL,184,72); TV.select_font(font6x8); initOverlay(); TV.println("Serial Terminal"); TV.println("-- Version 0.1 --"); TV.set_hbi_hook(pserial.begin(4800)); } void initOverlay() { TCCR1A = 0; // Enable timer1. ICES0 is set to 0 for falling edge detection on input capture pin. TCCR1B = _BV(CS10); // Enable input capture interrupt TIMSK1 |= _BV(ICIE1); // Enable external interrupt INT0 on pin 2 with falling edge. EIMSK = _BV(INT0); EICRA = _BV(ISC01); } // Required to reset the scan line when the vertical sync occurs ISR(INT0_vect) { display.scanLine = 0; } void loop() { //Reads serial if (pserial.available()) { static char input[25]; static uint8_t i; char c = pserial.read (); if ( c != '\r' && i < 24 ) // assuming "Carriage Return" is chosen in the Serial monitor as the line ending character input[i++] = c; else { input[i] = '\0'; i = 0; //Parsing the input byte index = 0; ptr = strtok(input, ","); // takes a list of delimiters while(ptr != NULL) { strings[index] = ptr; index++; ptr = strtok(NULL, ","); // takes a list of delimiters } TV.println(strings[0]); TV.println(strings[1]); TV.println(strings[2]); }//if }//pserial available }//loop
The master arduino has the following code:
int long A=1000; int B=12; float C=24.7; void setup() { Serial.begin(4800); } void loop() { Serial.print(A); Serial.print(","); Serial.print(B); Serial.print(","); Serial.println(C); delay(2000); }
April 17, 2019 at 10:35 pm #11042MichaelKeymasterThe Arduino String object has methods to create integer and float types.
First create a String object from char array:String longString = String(strings[0]); String intString = String(strings[1]); String floatString = String(strings[2]);
Then use methods on String object to get primitive data types.
long int dist = longString.toInt(); // returns long int var = (int)intString.toInt(); // returns long, so cast to int float rad = floatString.toFloat();
That should work.
- This reply was modified 5 years, 8 months ago by Michael.
April 18, 2019 at 3:52 am #11044pedroeParticipantMichael I really appreciate your input! Thank you!
If i apply your suggestion using Serial instead of pserial and removing the TVout and the overlay, it outputs for the Serial monitor the correct values, parsed and in numbers:
char *strings[10]; char *ptr = NULL; void setup() { Serial.begin(4800); } void loop() { //Reads serial if (Serial.available()) { static char input[25]; static uint8_t i; char c = Serial.read (); if ( c != '\r' && i < 24 ) // assuming "Carriage Return" is chosen in the Serial monitor as the line ending character input[i++] = c; else { input[i] = '\0'; i = 0; //Parsing the input byte index = 0; ptr = strtok(input, ","); // takes a list of delimiters while(ptr != NULL) { strings[index] = ptr; index++; ptr = strtok(NULL, ","); // takes a list of delimiters // t0=atoi(strings[0]); // t1=atoi(strings[1]); // t2=atoi(strings[2]); } String longString = String(strings[0]); String intString = String(strings[1]); String floatString = String(strings[2]); long int dist = longString.toInt(); // returns long int var = (int)intString.toInt(); // returns long, so cast to int float rad = floatString.toFloat(); Serial.println(dist+1); Serial.println( var+1); Serial.println( rad+1); }//if }//pserial available }//loop
But using pserial and the tvout library with overlay it doesnt work. The overlayd output is:
0
0
0.00#include <TVout.h> #include <pollserial.h> #include <fontALL.h> TVout TV; pollserial pserial; char *strings[10]; char *ptr = NULL; void setup() { TV.begin(PAL,184,72); TV.select_font(font6x8); initOverlay(); TV.println("Serial Terminal"); TV.println("-- Version 0.1 --"); TV.set_hbi_hook(pserial.begin(4800)); } void initOverlay() { TCCR1A = 0; // Enable timer1. ICES0 is set to 0 for falling edge detection on input capture pin. TCCR1B = _BV(CS10); // Enable input capture interrupt TIMSK1 |= _BV(ICIE1); // Enable external interrupt INT0 on pin 2 with falling edge. EIMSK = _BV(INT0); EICRA = _BV(ISC01); } // Required to reset the scan line when the vertical sync occurs ISR(INT0_vect) { display.scanLine = 0; } void loop() { //Reads serial if (pserial.available()) { static char input[25]; static uint8_t i; char c = pserial.read (); if ( c != '\r' && i < 24 ) // assuming "Carriage Return" is chosen in the Serial monitor as the line ending character input[i++] = c; else { input[i] = '\0'; i = 0; //Parsing the input byte index = 0; ptr = strtok(input, ","); // takes a list of delimiters while(ptr != NULL) { strings[index] = ptr; index++; ptr = strtok(NULL, ","); // takes a list of delimiters // t0=atoi(strings[0]); // t1=atoi(strings[1]); // t2=atoi(strings[2]); } String longString = String(strings[0]); String intString = String(strings[1]); String floatString = String(strings[2]); long int dist = longString.toInt(); // returns long int var = (int)intString.toInt(); // returns long, so cast to int float rad = floatString.toFloat(); TV.print(0,20, dist); TV.print(0,30, var); TV.print(0,40, rad); }//if }//pserial available }//loop
- This reply was modified 5 years, 8 months ago by pedroe.
April 18, 2019 at 8:15 am #11046MichaelKeymasterHmm. Are the strings in the array still correct? That is, do strings[0] etc. contain the right values still?
You might be running out of memory for the String objects. Try reducing your resolution and remove these lines:TV.println("Serial Terminal"); TV.println("-- Version 0.1 --");
These string literals in the println() statements take up memory. Your video buffer is using 1656 bytes ((184/8) * 72). Try 128×72 and see if it works.
April 18, 2019 at 11:35 am #11047pedroeParticipantMichael,
Reducing to 128×72 WORKED!!! Thank you very much!
You have no idea how many hours i spent trying to solve this problem! Ready for the next one 🙂April 18, 2019 at 11:41 am #11048MichaelKeymasterWith a lot of experience, I have learned that when the behavior of an Arduino program doesn’t make sense, the problem is almost always a lack of memory!
April 19, 2019 at 9:20 am #11051pedroeParticipantMichael,
One more question;
The above solution worked fine, but i notice that frequently the pserial communication skips some characters/numbers.
For example, if the master arduino sends 245 through serial, the slave with the shield might only overlay 24 skipping a 5. In the next loop the value is corrected, but after a few seconds it happens again. Per my understanding is a communication problem, and the variable in the slave side actually only gets the value 24 instead of 245.Do you have any idea about this? Memory again? Sorry to bother.
April 20, 2019 at 9:40 am #11054MichaelKeymasterThis problem is due to the polling nature of the serial communication. It’s probably not going to be perfectly reliable. I haven’t seen this myself, though. Maybe try a lower speed?
February 16, 2022 at 11:17 am #14493dan-danParticipantЗдравствуйте! Вы решили эту проблему?
-
AuthorPosts
- You must be logged in to reply to this topic.