PySerial receiving strange data - pyserial

I've connected my smart meter with a serial cable. However, when retrieving the data using PySerial I always get these lines:
b'\x00\n'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00
Eventually, I do get some data, but not even all.
Output should be like:
/ISk5\2ME382-1003
0-0:96.1.1(4B414C37303035313039)
1-0:1.8.1(00180.724*kWh)
1-0:1.8.2(00001.416*kWh)
1-0:2.8.1(00000.000*kWh)
1-0:2.8.2(00000.000*kWh)
[...]
!
My script:
import sys
import serial
ser = serial.Serial()
ser.baudrate = 9600
ser.bytesize=serial.SEVENBITS
ser.parity=serial.PARITY_EVEN
ser.stopbits=serial.STOPBITS_ONE
ser.xonxoff=0
ser.rtscts=0
ser.timeout=None
ser.port="/dev/ttyUSB0"
ser.open()
count=0
stack=[]
while count < 25:
p1_raw = str(ser.readline())
print(p1_raw)
count=count+1
ser.close()
exit
The problem seems to be with Python/PySerial. When using cu or minicom the data is received properly.
Any ideas?

After trying various settings, this seems to have solved the problem:
ser.xonxoff=1

Related

Reading Serial Data Using a Raspberry Pi Pico

I have a Spektrum Radio transmitter, along with its receiver. What I am currently trying to do is by using microPython and a Raspberry Pi Pico, I want to read the data coming into the receiver, and convert that into servo commands. All I know is that the protocol used by the transmitter/receiver is DSMX. How can I go about doing this? I only need to receive, I don't need to transfer any data back from the Raspberry Pi Pico.
I'm using Thonny, and all I've done is try to use the UART module and ustruct module and create a variable using that
uart = UART(1, baudrate = 115200)
data = uart.read()
header,id,data,error_checking,trailer = ustruct.unpack('>BBHHB',data)
When trying to run this, I get thrown the error
TypeError: object with buffer protocol required
I didn't expect anything, as I don't really know what I'm doing.
Any help would be really appreciated.
You're getting that TypeError exception because your call to uart.read() is returning None (meaning that there was no data available on the serial port). I don't know anything about the DSMX protocol, but to avoid that error in your code you probably want something like:
format = 'BBHHB'
required_size = ustruct.calcsize(format)
if uart.any() >= required_size:
data = uart.read(required_size)
header,id,data,error_checking,trailer = ustruct.unpack(f'>{format}',data)
...and the above probably needs to live in some sort of loop.

How to use read data from computer using a pi pico running micropython

I have looked everywhere on the internet, sadly i couldn't find anything. Is there anyway i could read data from my computer to the raspberry pi pico running micropython? Any help would be appreciated. I use pyserial to send and receive data on my computer.
I also had this issue and from this link I was able to figure it out. To read data from the usb port use "sys.stdin.buffer.read(8)".
Here is a short code that you can upload to the pico to do this.
import time
import sys
while True:
print("hello")
data = sys.stdin.buffer.read(8)
# to convert to string use data = sys.stdin.buffer.read(8).decode("utf-8")
print(data)
time.sleep(1)
With this code it will wait until 8 bytes come in, until then it will idle. I'm sure there is a way around it, just haven't tried yet.
I used the Arduino IDE serial monitor to send data. Upload this code in Thonny (save it as main.py so it starts on power up), then disconnect the pico, plug it back in, and open the Arduino serial monitor. Send something like '12345678' and it should spit it back out.
EDIT:
The above code will idle until you send it data. To have the pico continue running if no data is sent, use the following (source):
import time
import sys
import select
while True:
print("hello")
res = select.select([sys.stdin], [], [], 0)
data = ""
while res[0]:
data = data + sys.stdin.read(1)
res = select.select([sys.stdin], [], [], 0)
print(data, end = "")
time.sleep(1)
And you can just use Thonny to send the data, you don't need the Arduino IDE.

Can't read serial response using pyserial

Trying to use pyserial to talk to a Korad KD3005P power supply. (Using Python 3.6)
import serial
ser = serial.Serial('/dev/ttyACM0', baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=1)
ser.write(b'VSET1:2')
ser.write(b'VOUT1?')
response = ser.readline()
print(response)
VSET1:2 sets the voltage to 2 volts
VOUT1? tells the device to return the current voltage.
But all I get from the VOUT1? part seems to be:
b''
Stuff I've checked or tried without success:
The device works - I can talk to the device and get responses successfully with these commands through a serial terminal like CuteCom
Pyserial is kinda working - if I run the above program, the VSET1:2 does change the voltage.
I've tried different timeouts
I've tried ser.read() instead with various bit lengths
I've tried putting the read commands in a while loop
Any suggestions?
Oh.
It's a timing thing of some kind. Removing the VSET command or putting a time.sleep() command in between them and voila.. I get a response.
I'm going to mark this resolved but if anyone can enlighten me as to the nuances of this, thanks.

Python split data from arduino serial to raspberry

i have an output from serial arduino like this on raspberry
30.27|34.00\n
30.27|32.00\n
30.21|33.00\n
code on raspberry:
import serial
ser = serial.Serial('/dev/ttyACM0', 9600)
while 1 :
ser.readline()
i want to spit like this
x=30.21
y=33.00
is this possible if data send in real time,
thanks..
Using the same code you already have, try:
import serial
ser = serial.Serial('/dev/ttyACM0', 9600)
while 1 :
data=ser.readline()
x=data.split("|")[0]
y=data.split("|")[1]
print "x=",x
print "y=",y
You can streamline the code some more but wanted to make it step by step for easier reading.

Pyserial processing data from microcontroller

I am new to Pyserial, I'm trying to use it for communication between my computer and a microcontroller, I need to receive the data and put it into variables so that I can plot with those variables. Is there any way to do this? I have currently figured out reading data from input signals.
import serial
import sys
import Queue
import threading
ser = serial.Serial(port='COM6',timeout=None, baudrate= 57600)
# opening the port 'ser' that was just created to receive data
flag = ser.isOpen()
print flag
while 1:
data = ser.read(1)
n = ser.inWaiting()
if n:
data = data + ser.read(n)
data = data.split()
for item in data:
item = str(item)
sys.stdout.write(item + '\n')
I'm doing it like the following: to transfer data to and fro my AVR and Beagle running UBuntu.
serial = serial.Serial("/dev/ttyO1", baudrate=9600)
then after opening the serial port at a particualr set baudrate you just need to:
while True:
while serial.inWaiting() > 0:
inChar = serial.read() # Read a character inChar has that byte what is sent over the UART
and to send over to the microcontroller just do serial.write("") that's it.
but make sure while you do all these commands the serial line is open()