What did I do wrong when building receiver with pyserial? - python

I am using XBee modem to make mutual remote communication system.
Initially I tried using Arduino, however, I figured out that using two single board computer with python would be much more convenient. I am using pyserial right now.
This is the code which I made. It is really simple, and I don't see there would be something cause error.
Transmitter
import serial
import time
Xserial=serial.Serial('COM4',9600)
for i in range(10):
print(i)
Xserial.write(b"Test2")
time.sleep(3)
Xserial.close()
Receiver
import serial
import time
XSerial=serial.Serial('COM10',9600)
while (True):
line=XSerial.read(1)
print(line)
XSerial.close()
I think transmitter is working, however, receiver does not seem to receive what I send.
I am sure that it was working yesterday, but it is not working today. I checked XCTU and the connection is fine. I can communicate with each other by XCTU.

Related

How to parse specific data from a serial input on a Raspberry Pi?

I am using a GPS module for precise positioning. It's going to be autonomous and we need to make a fail-safe in case the GPS loses its rtk fix.
To do that, I am employing a Raspberry Pi 4b connected via UART to the GPS module. The GPS sends a message, GNGGA, where one of the parameters informs the status of the fix, then the Raspberry Pi monitors these parameters and keeps checking if the fix type stays as rtk fixed and sends an alert if not.
So far I have the code below that connects the Raspberry Pi to the module
#!/usr/bin/env python
import time
import serial
ser=serial.Serial(
port='/dev/serial/serial01'
baudrate=460800
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=1
)
counter=0
while 1:
x=ser.readline()
If I print x, I get something like this:
�6ȶ< �>�r�%���a���5��PFpx���� zR�b�qI��#ǃy�v����$p���`X�w�?Ĉ*�����>��G;
A���
O���������r[���nlB>X$GNGGA,202538.90,2156.26451,S,04753.49406,W,1,12,0.52,751.9,M,-6.2,M,,*53
The unreadable part of the code is some other messages the GPS needs, while the readable part is the part I want to extract.
I believe I know the logic behind what needs to be done: I need to recognize the start of this string, and since the size of this is fixed, I should be able to use its length to extract the whole string or just the parameter I need.
I don't have much experience dealing with serial communication with python so I don't know how to employ this logic. After a few hours of trial and error, I managed to find the start of the string with a few if's, but I don't how to go from here.
Can anyone give some advice?

How to send one gcode command over USB?

I am trying to write a simple python script that sends a gcode command to my wanhao D9 motherboard printer, running Marlin. I am running the python script on a raspberry pi that is connected to the printer via USB.
import serial
ser = serial.Serial("/dev/ttyUSB0", 115200)
ser.write("G28\n")
I have read over 20 forum pages with simular problems and tried their answers such as changing the baud rate to 250000 and the following changes to the write function parameter:
ser.write("G28\r\n")
ser.write(b'G28\r\n')
ser.write(b'G28\n')
ser.write(b'G28')
ser.write("G28")
I have tried all these combinations, and I have also added:
time.sleep(5)
along with the relevant import statement for the time module at the top of my file. I added this line of code between my ser declaration and my ser.write function call.
I have also tried adding:
ser.close()
to see if that would make a difference but it has not, as I know this is best practice anyway.
No matter what combination of this code I used, when I run my python script my printer seems to restart (the screen changes from the home page to the opening wanhao logo and back to the home page)
I look forward to any help anyone can give me in regards to my code and what I may be doing wrong.
Adding an extra sleep period after my command fixed my issue. I can also now read back the initial set up feedback from the printer.
My final code without this is:
import serial
import time
ser = serial.Serial('/dev/ttyUSB0', 115200)
time.sleep(2)
ser.write("G28\r\n")
time.sleep(1)
ser.close()
Thank you, to the users in this post for guiding me in the right direction Full examples of using pySerial package
This code works for me, I hope someone else finds it useful in the future too.

PySerial does not receive data correctly

I have a little problem receiving data correctly via pySerial: it often does not read the full data or too much of it. Sometimes and sometimes more often, there are additional characters or some characters/parts of the sended data are missing. It seems, PC and the emitter of the data are not synchronised correctly.
In the current example I use a arduino, sending 'Hello World' to the serial port of my PC (os is Ubuntu 14.04), with the following simple code:
void setup(){
Serial.begin(9600);
Serial.print("Programme initiated\n");
}
I use the following python3 code to receive the data:
import serial
import time
arduino = serial.Serial(port, baudrate=9600, timeout=2)
print(arduino.isOpen)
print(arduino)
time.sleep(1)
while True:
print(arduino.readline())
This is pretty much a simple tutorial example, and here is what I receive (apart from the correct stuff):
b'PrProgramme initiated\n'
or
b'PProgramme initiated\n'
or
b'ProgProgramme initiated\n'
or
b'ogramme initiated\n'
I moved on with more complex problems in my code, but still I didn't solved that problem. When sending a message in a loop from the arduino (the standard hello world code), it often needs time to stabilise (while that, it again does only show the middle fragment of the data) and after that running quite stable, but even then it sometimes breaks down single lines.
I faced the same difficulties when communicating with a multimeter device. There, it often does not read the first characters or mixes up with previous data.
Did anyone faced that problem before? I think it is a question of synchronisation, but I don't know how to solve it. And what puzzles me, is that I really only used tutorial stuff and it doesn't seem to work properly. Or is it a configuration problem of my PC?
What you are looking at is happening because some different things are going on.
First of all every time you open the serial port, you are causing what is called and "autoreset" and the Arduino reboot. That can be avoided in hardware or even in software by explicitly disabling RST signal on open. How to do that may vary and is out of scope of the question.
Then we have to understand that serial does NOT wait for the other part to be listening to send data; so if you disable the autoreset and connecting to the Arduino you should see random part of output of the program, depending of its current state.
Finally we have some buffer capability on pc (and sometimes even on the UART to USB side), so its not true that if you are not listening that data get lost, it may be still in the buffer.
We could say the first 3 artifact may be given by buffered data + reboot (this happen a lot when you send a lot of data, and that break the autoupload of code and you have to do a manual procedure), while the last one may be something that prevented the buffer to fill, maybe it was disabled by you, maybe some weird timing opening the serial, maybe you disabled the autoreset, maybe time that the arduino got enumerated part of the message was gone.

Reading from serial port with pyserial only works if terminal app is open in background

I am using pyserial to communicate with my Multimeter (Keithley2000) over an FTDI based usb-to-rs232 adapter (Using the Mac OS X built-in driver).
Before I started with Pyserial I verified that the Hardware & Driver works by using a terminal app (Serial.app) to communicate with the Multimeter.
This works just fine.
But if I try the same thing with the simple program below, it doesn't work.
Writing works fine (I can for example reset the instrument), but I can't read anything back.
import serial
import io
port = serial.Serial("/dev/cu.usbserial-FT8VXG35", 9600, timeout=1)
port.write("*idn?\r")
print(port.readline())
Now here comes the weird part. If i leave Serial.app open in den background, the program actually works.
Does anyone know the reason for this behaviour?
Here are my settings in Serial.app
Some peripherals need the flow control lines (RTC/CTS, DSR/DTR) set to specific levels - maybe having serial.app running the background sets these lines the way your multimeter needs?

Sending hex data over RS-232 between an Arduino and a Mac OS X system

I'm using Voice Recognition Module -- Arduino Compatible. It says there to use AccessPort, but since I'm on Mac OS X it won't work. I don't know of any other solution but to write my own in Python while I'm open to any other language that works.
I found some solutions over here about pySerial but as of now it doesn't seem to work.
import serial
import struct
def C(val):
return struct.pack('H', val)
ser = serial.Serial(port='/dev/tty.PL2303-00001004', baudrate=9600, timeout=1)
ser.nonblocking()
ser.write(C(0xaa11))
print ser.read().__repr__()
ser.close()
It opens, write two bytes and doesn't read anything. 0xaa11 is used to start recording. My device seems to be in waiting mode since the red LEDs flash rapidly. Even if I do 0xaa00, it doesn't do much either. I even tried to change the byte order to 0x00aa, 0x11aa and so on, but I never receive my 0xcc or 0xe0 error code.
In the documentation it says to send it as hex, so my guess is that accessport converts hex to a Short which use two bytes. 0xaa00 is a two bytes number. I even tried to change the baud rate to 38400 in case someone before me did set that to this speed.
I'd be happy to read anything from that serial port because as of now I can write, it does nothing and reads nothing...
As of now, I'll try to install AccessPort with crossover. If it still doesn't work, I'll have to find a Windows box. I could even write my own bridge with my Arduino board since the driver I'm using might be buggy.
In case it matters, I'm using a USB to Serial PL2303.
Edit
I plugged my output and input pin to test my USB-to-serial. I do read what I write so the driver is working fine.
I'll try to set it up directly with Arduino and test directly from there.
Sending 0xaa11 is different than sending 0xaa and then 0x11. The serial seems to reverse the byte order.
On the other hand, the documentation doesn't tell about bit endianess, so it might be the problem too.
I kind of solved my problem while it was pretty dumb after all.
Here is my final script:
import serial
import struct
from time import sleep
def C(val):
return struct.pack('!H', val)
ser = serial.Serial(port='/dev/tty.PL2303-00002006', baudrate=9600)
sleep(2)
ser.write(C(0xaa00))
sleep(1)
ser.write(C(0xaa36))
sleep(1)
ser.write(C(0xaa11))
sleep(1)
while True:
print ser.readline()
If someone ever want to use that module, it works. It will switch to a mode where it puts to output words instead of bytes so you can read it using readline...
I used in struct.pack "!H" to use network endianess it change 0xaa00 to 0xaa 0x00 like it should be.
But the real problem here wasn't in the script. Since the usb to serial did work I thought that it was strange that the module didn't respond anything... not even a byte for errors. Every command in this module must return something. That's why I looked back at my cable and checked the pins... gnd to gnd, power supply to power supply and then rxd to txd, txd to rxd... While everything seems ok... I should receive something... And then I really thought... what if it's not supposed to use a cross cable and txd should be plugged to txd and rxd to rxd... Apparently it does.
I switch the cable and now data is sent and received.
So anyone using that module should check that it's correctly plugged in. If it doesn't work, switch the data pins.

Categories

Resources