I'm working on an Arduino project, and I am interfacing it with a Python script due to memory limitations. On the Python side I have a 2 dimensional matrix containing respective x, y values for coordinates, and in this list is 26000 coordinate pairs. So, in interest of clarifying the data structure for all of you, pathlist[0][0]
, would return the X value of the first coordinate of my list. Performing different operations, etc. on this list in Python is posing no problems. Where I am running into trouble however is sending these values to Arduino over serial, in a way that is useful.
Due to the nature of serial communication (at least I think this is the case) I must send each each integer as a string, and only one digit at a time. So, a number like 345 would be sent over as 3 individual characters, those being of course, 3, 4, then 5.
What I am struggling with is finding a way to rebuild those integers on the Arduino.
Whenever I send a value over, it's receiving the data and outputting it like so:
//Python is sending over the number '25'
2ÿÿ52
//Python is sending the number 431.
4ÿÿ321ÿÿÿ2
The Arduino code is:
String str;
int ds = 4;
void setup() {
Serial.begin(9600);
}
void loop(){
if (Serial.available()>0) {
for (int i=0; i<4; i=i+1) {
char d= Serial.read();
str.concat(d);
}
char t[str.length()+1];
str.toCharArray(t, (sizeof(t)));
int intdata = atoi(t);
Serial.print(intdata);
}
}
And the Python code looks like this:
import serial
s = serial.Serial(port='/dev/tty.usbmodemfd131', baudrate=9600)
s.write(str(25))
I'm almost certain that the problem isn't stemming from the output method (Serial.print
), seeing as when I declare another int, it formats fine on output, so I am assuming the problem lies in how the intdata
variable is constructed.
One thing of note that may help diagnose this problem is that if I change Serial.print(intdata)
to Serial.print(intdata+5)
my result is 2ÿÿ57
, where I would expect 30 (25+5). This 7 is present regardless of the input. For instance I could write 271 to the serial and my result would look as follows:
//For input 271.
2ÿÿ771ÿÿÿ7
It appears to me that Arduino is chunking the values into pairs of two and appending the length to the end. I can't understand why that would happen though.
It also seems to me that the ÿ
are being added in the for loop. Meaning that they are added because nothing is being sent at that current moment. But even fixing that by adding yet another if(Serial.available()>0)
conditional, the result is still not treated like an integer.
Also, would using Pickle be appropriate here? What am I doing wrong?
You should wait a bit for the serial data to arrive.
The Arduino code should be:
if (Serial.available()){
delay(100); // Wait for all data.
while (Serial.available()) {
char d = Serial.read();
str.concat(d);
}
}
Also you have to clear your string before re-using it.
[Edit]
I forgot to mention ÿ == -1 == 255 which means Serial.read()
it is saying it can't read anything.
I would change the communication so python sends newlines between numbers, so you're not as dependent on the timing:
s.write(str(25)+'\n')
and then on the receiving side:
void loop(){
while (Serial.available() > 0) {
char d = Serial.read();
if (d == '\n') {
char t[str.length()+1];
str.toCharArray(t, (sizeof(t)));
int intdata = atoi(t);
Serial.print(intdata);
str = String();
}
else {
str.concat(d);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With