I'm trying to make simple serial communication between python and arduino. But it seems like I can't send data to arduino without receiving data after writing data to arduino in while loop. Or arduino isn't receiving that data, because python code doesn't freeze between those write commands
python code
import numpy as np
from mss import mss
import time
import serial
ser = serial.Serial(
port='COM14',
baudrate=515200,
timeout=5,
)
time.sleep(2)
bounding_box = {'top': int(2160/3), 'left': 0, 'width': 3840, 'height': int(2160/3)}
sct = mss()
count = 1
while True:
sct_img = sct.grab(bounding_box)
average = np.mean(np.array(sct_img), axis=(0, 1))
averageString = str(int(average[0])).zfill(3) + "%" + str(int(average[1])).zfill(3) + "%" + str(int(average[2])).zfill(3) # + "" + str("A")
ser.write(averageString.encode('utf-8'))
print(averageString)
# have to do this to send more data to arduino, but it's slowing down too much communication
#msg = ser.readline()
#msg = msg.decode('utf-8')
#msg = msg.rstrip()
#print("Message from arduino: ")
#print(msg)
arduino code
int r = 9;
int g = 10;
int b = 11;
void setup() {
Serial.begin(515200);
delay(500);
}
void loop() {
String data;
while (Serial.available() == 0) {}
data = Serial.readString();
data.trim();
//delay(100);
Serial.println("data" + data);
int delimiter, delimiter_1, delimiter_2, delimiter_3;
delimiter = data.indexOf("%");
delimiter_1 = data.indexOf("%", delimiter + 1);
delimiter_2 = data.indexOf("%", delimiter_1 + 1);
delimiter_3 = data.indexOf("%", delimiter_2 + 1);
String second = data.substring(delimiter + 1, delimiter_1);
String first = data.substring(delimiter_1 + 1, delimiter_2);
String third = data.substring(delimiter_2 + 1, delimiter_3);
analogWrite(r, 255 - first.toInt());
analogWrite(g, 255 - second.toInt());
analogWrite(b, 255 - third.toInt());
}
I have tested many different speeds and they don't effect. I just found out it need one second sleep between sends to work correctly at speed of 115200. But why It need that one second delay. I would like to update between 10-100ms
you need to start off with some code that's very simple like ( adjust the sleep timer in the code )
while True:
dataToSend = 'data from python'
dataToSend.encode()
ser.write(dataToSend)
time.sleep(0.2) # 0.2 secs == 200 milliseconds
and on arduino side you have this ( please use 115200 as baud at both ends )
void loop() {
if (Serial.available()) {
String buffer = "";
while(Serial.available()) {
delay(1); // slow down a bit
char c = Serial.read();
buffer += c;
} // end while
if ( buffer.length() > 1 ) {
Serial.println("data: "+ buffer);
}
} // end if
}
If all is good then you can proceed injecting the rest of your code slowly
by the way you can have your own millis() in Python so that you won't have to use time.sleep()
readString() will read characters and if no more characters have been received in 1 second (default timeout) returns the string read
this may be where your 1 second delays comes frome
if the Python program terminates the transmitted string with a newline '\n' you could use readStringUntil()
Serial.readStringUntil('\n');
will read characters into the String until a '\n' is received or timeout occures (1 second)
I used millis() from arduino to measure how long it take to read sent data from pc. When sending from arduino ide serial port it takes about 1ms to run that code but when I sent it from python it took 1052ms. That 1000ms is that serial.readStringUntil() function timeout. I'm using 'A' as the end of data so '\n' won't mess up my python console. I think problem is that arduino doesn't understand ser.writelines(averageString.encode('utf-8')) encode to utf-8. So what decoding does arduino use?