I wrote a basic two way python and serial communication script that sends an integer to the arduino. Then, the arduino increments the integer and sends it back over serial.
comm.py
from time import sleep
from pySerialTransfer import pySerialTransfer as txfer
class struct:
control = 0
class receivestruct:
status = 0
if __name__ == '__main__':
try:
testStruct = struct
rstruct =receivestruct
link = txfer.SerialTransfer('COM7')
link.open()
sleep(2)
counter = 0
while True:
sendSize = 0
testStruct.control = counter
sendSize = link.tx_obj(testStruct.control, start_pos=sendSize)
link.send(sendSize)
print('sent')
#sleep(0.5)
read_correctly = False
while (read_correctly == False):
try:
if not (link.available()):
pass
recSize = 0
# this section returns errors with can't read str as int
rstruct.status = link.rx_obj(obj_type='i', start_pos=recSize)
counter = rstruct.status
recSize += txfer.STRUCT_FORMAT_LENGTHS['i']
print(rstruct.status)
read_correctly = True
except:
pass
except KeyboardInterrupt:
link.close()
arduino.ino
#include "SerialTransfer.h"
SerialTransfer myTransfer;
uint32_t rcontrol;
uint32_t control;
void setup()
{
Serial.begin(115200);
myTransfer.begin(Serial);
}
void loop()
{
if(myTransfer.available())
{
// use this variable to keep track of how many
// bytes we've processed from the receive buffer
uint16_t recSize = 0;
recSize = myTransfer.rxObj(rcontrol, recSize);
control = rcontrol + 1;
uint16_t sendSize = 0;
sendSize = myTransfer.txObj(control, sendSize);
myTransfer.sendData(sendSize);
}
}
Now, I thought this would work properly. However, here is the console log, where it seems like python is not reading the incremented value properly, and only reads the correct incremented value every n attempts:
115
sent
115
sent
116
sent
116
sent
116
sent
116
sent
116
sent
116
sent
116
sent
116
sent
116
sent
117
sent
117
sent
117
sent
117
sent
117
sent
117
sent
117
sent
117
sent
117
sent
118
sent
118
sent
118
sent
118
sent
118
sent
118
sent
118
sent
118
sent
118
sent
119
sent
119
sent
119
sent
119
sent
119
sent
119
sent
119
sent
119
sent
I tried the two way example for pySerialTransfer here, but it appears to use an outdated version of the library that is no longer supported. Any idea why I am seeing these issue with two way serial communication?
Thank you for the tutorial. I just ran your code, and I'm getting utf-8 decode errors:
PORT DEVICE MANUFACTURER
0 COM7 Arduino Srl (www.arduino.org)
➜ Select your port: 0
selecting: COM7
Waiting for Arduino
Exception in thread Thread-1 (listenToArduino):
Traceback (most recent call last):
File "C:\Users\sshen\AppData\Local\Programs\Python\Python312\Lib\threading.py", line 1073, in _bootstrap_inner
self.run()
File "C:\Users\sshen\AppData\Local\Programs\Python\Python312\Lib\threading.py", line 1010, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\sshen\OneDrive - ICI\Desktop\alt-min\comm.py", line 60, in listenToArduino
arduinoQueue.put(message.decode('utf-8').strip().upper())
^^^^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf0 in position 0: unexpected end of data
I'm not quite sure why this is happening. Do you know why?
void setup() {
Serial.begin(115200);
Serial.println(1);
}
void loop() {
static uint32_t oldMil = 0;
static int16_t num = 1;
if (Serial.available() > 0) {
byte pEek = Serial.peek();
if (pEek < 32 || pEek > 127) {
Serial.read();
return;
}
int i = Serial.parseInt();
if (i == 0)return;
num = i + 1;
Serial.print(num);
Serial.write(0xA);
oldMil = millis();
}
if (millis() - oldMil > 2000) {
oldMil = millis();
Serial.println(num);
}
}
import serial, time
from time import sleep
Arduino = serial.Serial("COM4", "115200", timeout=1)
Arduino.setDTR(False)
sleep(1)
Arduino.flushInput()
Arduino.setDTR(True)
sleep(3)
num = 0
print("start")
while True:
if (Arduino.isOpen() == False):
Arduino.open()
if Arduino.inWaiting() > 0:
try:
income = Arduino.readline().decode().strip()
i = int(income)
if(i==0):
break;
num = i + 1
line = str(num)
Arduino.write(line.encode())
print("sent " + line)
time.sleep(1)
except:
pass