Why can't I read my data from my serial port? - python

Why is this code not working?
import serial
s = serial.Serial('/dev/ttyUSB1')
#s.open()
s.write(b"1234")
print(s.read())
print(s.read_all())
When I run this code, I get this output:
b'1'
b''

Since there is on Information about any device connected and the output is empty the second time I assume you need a delay or some kind of waiting in your code. This is because the machine you are running the python script on executes much faster than your baudrate of the serial device.
Try this for example:
import serial
import time
s = serial.Serial('/dev/ttyUSB1')
s.write(b'1234')
time.sleep(1)
print(s.read_all())

Related

Is it possible to call the Python serial library as a function in an imported module when communicating with an Arduino?

I am writing a program to communicate between my laptop (Python) and an Arduino. The Arduino code, with which I have no issue, reads the serial data form my laptop and returns a reply. The code below works when I am calling the function which starts the serial communication from within the same file. However, when I import the file as a module in another file, using lal the same commands, it does not work!
To provide more detail, although Python thinks it has connected and even prints out the correct port number, it does not really connect. I know this because in the scenario that does work, when the serial communication is open, the Arduino IDE cannot speak to the Arduino as the Arduino is busy. However in the scenario which is not working, even after Python thinks it has opened serial communication, the Arduino IDE can still communicate with the Arduino.
Is there a way to pass the ser variable when called from a function in an imported module?
def connect():
for n in range(0,21):
try:
ser = serial.Serial('COM'+str(n), 115200 ,timeout=0.1)
status=1
port=n
return ser,port,status
except:
pass
time.sleep(0.05)
return 0, 0, 0
if __name__ == "__main__":
ser,port,status=connect()
n=0
while n<3:
num = input("Enter a word: ") # Taking input from user
ser.write(bytes(num, 'utf-8'))
time.sleep(0.05)
data = ser.readline()
print(data) # printing the value
n+=1
ser.close()
print('closed')
I have found the reason my code was not working! Notice in the code I posted, I use the input function to get a user input which is sent to the Arduino. This effectively results in a delay. In the scenario that was not working, I did not use the input function and so my code went straight from serial.serial to serial.write. The Arduino runs at 16 MHz and just couldn't keep up! All I needed to do was add a delay and now it works!

PySerial: writing to microcontroller using a while loop adds 100ms to the loop time

I'm trying to do actuator control with values calculated from Python. I am at a point where I want to send the calculated data to a microcontroller in an infinite loop. It seems like ser.write() adds 100ms (total loop execution time of 120ms)
Right now I'm sending the value obtained by my Python code to a microcontroller using PySerial.
Python's data processing side isn't the problem because I checked that the data was being calculated every 20ms.
Below is the code I am using.
import serial as ser
COM = 'COM4'
brate = 115200
ser = ser.Serial()
ser.baudrate=brate
ser.port = COM
while(1):
##Data Calculation Code###
ser.open()
send = bytearray([int(calculated_data)])
ser.write(send)
if(i !=0):
ser.close()
Thank you for your time
I just figured it out after searching a little bit more.
Seems like the serial port doesn't have to be opened and closed everytime.
from serial import Serial
ser = ser.Serial(COM, brate)
Did the trick.

Python Serial not outputting full string

I have the following code running on one computer, and another computer with RS232 DataLogger by Eltima Software reading the serial connection.
When I run the python file on the one computer, only a few characters show up on the other computer, not the full "hellobob"
I have the monitoring computer set at 9600 baud rate, 8 data bits, no parity, one stop bit.
The monitoring computer only picks up "he". I have monitored lots of other devices with the same software, so I know that is working.
This is the python code.
import serial
import io
from time import sleep
ser = serial.Serial('/dev/tty.usbserial-A505VSLL')
sio = io.TextIOWrapper(io.BufferedRWPair(ser, ser))
sio.write(unicode("hellobob\n"))
sleep(5)
sio.flush()
ser.close()
It may be encoding issue. You may simply try following without io module:
import serial
ser = serial.Serial('/dev/tty.usbserial-A505VSLL')
ser.write(b"hellobob\n") # send bytes
ser.close()

Pyserial can't read device

I'm trying to read data off of a sensor that I bought, using a conversion module (SSI to RS232). I have the module plugged into my Windows laptop via USB/serial converter.
When I use Putty in Serial mode, I can send the command $2RD and receive the appropriate response from the sensor unit. When I run a script to try to do the same thing, the unit returns: ''
Here is the code I am using:
import sys
import serial
import time
ser = serial.Serial(
port='COM4',
baudrate=9600,
timeout=1,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
)
while True:
ser.write('$2RD'.encode())
#time.sleep(1)
s = ser.read(26)
print s
A few other notes:
I've tried some variations using flushInput, flushOutput, sleeping, waiting, etc...nothing seems to help.
I know I have the COM ports right/the hardware all works in Putty, so pretty sure this is something with my code.
I've also tries 13,400 BAUD with no difference in outcome.
If I connect the TX and RX lines from the USB, I can read the command I'm sending...so it should be at least getting to the RS232/SSI conversion device.
s = ser.read(26) should probably be ser.read(size=26) since it takes keyword argument and not positional argument.
Also, you can try to set a timeout to see what was sent after a specific time because otherwise the function can block if 26 bytes aren't sent as specified in the read docs of pyserial :
Read size bytes from the serial port. If a timeout is set it may return less characters as requested. With no timeout it will block until the requested number of bytes is read.

Errors in the data received through serial using Python

I want to send data to a peripheral using PySerial. However, errors sometime appear in the data received.
import serial
dongle = serial.Serial("/dev/ttyUSB0", 9600)
dongle.write("Some data\n")
And then, Some data\n is transmitted to the peripheral.
Sometime it works great, but sometime, errors appear in the data received: Somata\n, Som a\n, etc…
How to fix that issue?
I suspect you need to add an inter-char delay to your serial write. Unfortunately, such a thing is not available in PySerial. There is an inter_byte_timeout, but that's for reads.
Something like:
import serial
import time
def write_with_delay(command):
while len(command)>0: # Loop till all of string has been sent
char_to_tx = command[0] # Get a
dongle.write(char_to_tx)
command = command[1:] # Remove sent character
time.sleep(0.01)
dongle = serial.Serial("/dev/ttyUSB0", 9600)
write_with_delay('Some data\n')
Which will send the string with a 10ms (0.01s) delay between each character. Ordinarily, adding arbitrary delays into code is a bad thing, but for serial comms it is sometimes necessary.

Categories