The slowness is because of the python line ser.readline(). readline() is blocking (meaning it takes prevents anything else from happening) until either it hits a timeout, or it gets an end-of-line (EOL) character. In the case of PySerial, the EOL character is \n. The timeout is set when python initializes the serial port. If you have
ser = serial.Serial('COM16',115200,timeout=5)
then anytime ser.readline() is run, the command will wait for up to 5 seconds to get an EOL character.
In your Quarto code, when a command is sent, the returned data does not have a \n at the end to mark the end of line, to python keeps waiting for it until it times out each time readline() is run.
There are two solutions. One is add a terminal line to your sends, so replace
if (incoming == 'A') {
toggleLEDGreen();
Serial.print(ch1_data, 8);
}
with
if (incoming == 'A') {
toggleLEDGreen();
Serial.print(ch1_data, 8);
Serial.print('\n')
}
Alternatively, you can replace Serial.print(ch1_data, 8);
with Serial.println(ch1_data, 8);
to do it on one line. That uses the Arduino's Serial print line command, which ends each line with a \r\n. This will work fine with PySerial's readline, but you'll see \r\n and the end of each line instead of just \n.
The second solution is to not use readline, but instead read by fixed number of bytes you want to read and then you do not need to change the Quarto code to add line termination. This can be tricky because you have to make sure the Quarto always sends the same number of bytes. Serial.print(512,HEX) will send out "200" (3 bytes) but Serial.print(16384) will send out 4000 (4 bytes). But if your Quarto code does send out fixed bytes (let's say 4) then you can replace ser.readline()
with ser.read(4)
to read exactly 4 bytes.