I am working on a bigger project but I narrowed my problem down to this.
Its the basic of the basics but it does not work for me, I guess it has a simple
solution. Please help.
It would be much more reliable to interface Python with your Arduino using the compatible libraries: pySerialTransfer and SerialTransfer.h.
pySerialTransfer is pip-installable and cross-platform compatible. SerialTransfer.h runs on the Arduino platform and can be installed through the Arduino IDE's Libraries Manager.
Both of these libraries have highly efficient and robust packetizing/parsing algorithms with easy to use APIs.
Example Python Script:
import time
from pySerialTransfer import pySerialTransfer as txfer
if __name__ == '__main__':
try:
link = txfer.SerialTransfer('COM17')
link.open()
time.sleep(2) # allow some time for the Arduino to completely reset
while True:
send_size = 0
###################################################################
# Send a list
###################################################################
list_ = [1, 3]
list_size = link.tx_obj(list_)
send_size += list_size
###################################################################
# Send a string
###################################################################
str_ = 'hello'
str_size = link.tx_obj(str_, send_size) - send_size
send_size += str_size
###################################################################
# Send a float
###################################################################
float_ = 5.234
float_size = link.tx_obj(float_, send_size) - send_size
send_size += float_size
###################################################################
# Transmit all the data to send in a single packet
###################################################################
link.send(send_size)
###################################################################
# Wait for a response and report any errors while receiving packets
###################################################################
while not link.available():
if link.status < 0:
if link.status == -1:
print('ERROR: CRC_ERROR')
elif link.status == -2:
print('ERROR: PAYLOAD_ERROR')
elif link.status == -3:
print('ERROR: STOP_BYTE_ERROR')
###################################################################
# Parse response list
###################################################################
rec_list_ = link.rx_obj(obj_type=type(list_),
obj_byte_size=list_size,
list_format='i')
###################################################################
# Parse response string
###################################################################
rec_str_ = link.rx_obj(obj_type=type(str_),
obj_byte_size=str_size,
start_pos=list_size)
###################################################################
# Parse response float
###################################################################
rec_float_ = link.rx_obj(obj_type=type(float_),
obj_byte_size=float_size,
start_pos=(list_size + str_size))
###################################################################
# Display the received data
###################################################################
print('SENT: {} {} {}'.format(list_, str_, float_))
print('RCVD: {} {} {}'.format(rec_list_, rec_str_, rec_float_))
print(' ')
except KeyboardInterrupt:
link.close()
except:
import traceback
traceback.print_exc()
link.close()
Example Arduino Sketch:
#include "SerialTransfer.h"
SerialTransfer myTransfer;
void setup()
{
Serial.begin(115200);
myTransfer.begin(Serial);
}
void loop()
{
if(myTransfer.available())
{
// send all received data back to Python
for(uint16_t i=0; i < myTransfer.bytesRead; i++)
myTransfer.txBuff[i] = myTransfer.rxBuff[i];
myTransfer.sendData(myTransfer.bytesRead);
}
}
On the Arduino side, you can use myTransfer.txObj() and myTransfer.rxObj() to copy values to the library's RX buffer and parse multi-byte variables out of the library's TX buffer.