Issue with raspberry pi serial port - python

I'm using raspberry pi 2 to control 2 types of printers. I found at this site how to send serial commands in hexadecimal format using python, like:
cmdTest=b"\x12\x02\x42"
ser.write(cmdTest)
This code works true for one printer but fail for another!
knowing that:
I test both devices using a normal computer and both works.
Both are from same manufacturer (ELTRASISTEMI).
I am using the appropriate commands for every printer
I am specifying the correct baud rate knowing that both are of the same baud rate.

My problem solved, Although something still not clear.
The commands were correct the problem is something related to the serial convertor I were using. Now I used a usb to serial convertor instead of a shield convertor and it works great with same code and same commands. Although it worked, I'm still confused why a printer worked with RS232 shield and other not.

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?

Failing to communicate with digital dial indicator via USB serial python library

I have this digital dial indicator : Helios-Preisser Digimet 1722-502". It comes with a capacity to output its reading over a USB serial cable. The USB cable is a special 4 pin connector on the end that plugs into the calipers and a normal USB on the other end.
Although the device comes with special software, I am trying to write a basic python library to communicate with it. Below is the snippet of the manuel which explains the data communication protocol
I am using the python Serial library and have managed to get some communication going with it. Here's what I have so far
import serial
ser = serial.Serial(port ='/dev/tty.usbserial-MA4LOCLF', baudrate=4800,parity=serial.PARITY_EVEN, bytesize=serial.SEVENBITS,stopbits=serial.STOPBITS_TWO, dsrdtr=True, xonxoff=True)
# press the small red button on the cable. This generates a data entry
In [77]: ser.inWaiting()
Out[77]: 8
In [78]: ser.read(8)
Out[78]: '+000.00\r'
So this works great when using the mode the data is being requested by the pressing of the small red button on the cable plugged into the dial indicator
However, there is another mode where one can request a data entry. This is the mode described in the manual as "data transmission by request of peripheral" where one has to pulse the DataRequest pin low for T1 (100ms<T1<1000ms).
I have tried mostly randomly all possible combinations I could think to get this data request working but to no avail. All attempts at using the write function from the serial library have not worked
In [79]: ser.write('0\r')
Out[79]: 2
In [80]: ser.inWaiting()
Out[80]: 0
I am a bit out of ideas. I know this mode works because when you download (in Windows only) the software which comes with the device, you have the ability to send that request. SO there must be a way of emulating this request with the python serial library but I'm stuck and I'm not even sure how to proceed.
Any help would be appreciated.
Thanks
pyserial supports (or it should, but at the end of the day that would depend on the driver and not on pyserial itself) a function to change the state of the port's control lines.
You need to do something like this:
ser.setDTR(False)
time.sleep(0.5)
ser.setDTR(True)
If you read from the port right after you should get the value you are looking for.
To get the timing more or less right you should run your code as a script instead of line by line.
Ok, well after much "messing around", I was able to debug this problem and find the solution but it was certainly not a linear process. I should point out that I was placed on the right path thanks to the suggestions by Marcos G. who pointed out that you can indeed control the dtr lines directly with pyserial.
Here's the answer.
After some more searching the web, I found this link which provided a suggestion for how to troubleshoot your serial connection on a mac. This Coolterm software was immensely helpful.
I downloaded it and it allows you to monitor the state of the various RTS and DTS (and other) lines while you are communicating in a real time with you device. Super useful!
This showed me that:
When "sending" a reading from the device by pressing the red button, the DTR line was True and the RTS line was irrelevant. This is indeed what is shown in the documentation.
In order to "request" a reading from the device the DTR line needed to be False and the RTS line needed to be pulsed from False to True back to False with the precise timing. This worked and indeed produced a reading waiting on the USB line.
Here's the code below
import time
import serial
ser = serial.Serial(port ='/dev/tty.usbserial-MA4LOCLF', baudrate=4800,parity=serial.PARITY_EVEN, bytesize=serial.SEVENBITS,stopbits=serial.STOPBITS_TWO, dsrdtr=True)
ser.dtr=False
ser.rts=False
# request one reading every second
while(1):
ser.rts=True
time.sleep(0.1)
ser.rts=False
time.sleep(0.1)
print ser.read(ser.inWaiting())
time.sleep(1)

Pyserial cannot send all characters to arduino, but can do it on another PC terminal

I am working on an existing project.
Until now, a PC software controls an Arduino Due.
The PC software sends serial commands to the Arduino Due.
What I am trying to do, is to replace the PC software with a python script. Python 3.5.
So I am working with pyserial.
The problem seems to be that the python script does not send all the characters to the Arduino Due. It misses some final characters.
The difficult parts to understand are the following:
When I am sending the characters, from the python script, to another PC terminal instead of the Arduino, then I can successfully collect all the characters from the terminal, I am using Bray's terminal.
When I am sending the same string from my terminal to the Arduino Due, the Arduino Due successfully collects the data sent.
It seems as if only the Python to Arduino does not work, while
Python to PC termimal is working and
PC terminal to Arduino is working
I open the serial port like this:
my_port = serial.Serial('COM6', 115200)
while connected != True:
if my_port.is_open == 1:
connected = True
Can anyone provide any insight?
Thanks.
edit: I just noticed that when the python script sends the data, then the debug serial port I am using sends corrupted data.
Solved it.
I noticed that the debug serial was also sending less characters and I thought that there maybe a reset going on.
So I am now sending my arrays from a thread after each button press.
What I was doing, is that I was sending it directly after connection.

How to get live plot data from headless Raspberry Pi?

I'm new to using a RaspberryPi. Until now I was experimenting with an Arduino.
If I connect an Arduino by usb it is recognized as COM device and with the Arduino serial plot software it was easily possible to live plot sensor data.
For my next project I want to work with an Raspberry Pi Zero W and Python.
Is it possible to send serial data from a python script over the charging usb-cable like with the Arduino? If not, what would be the easiest way to send sensor data e.g. to matplotlib to plot the data directly?
It is possible. However I would not recommend using the USB serial port profile. While it works, it is severely limited in comparison to the alternative. Which is using one of the various ethernet gadget modes.
One tutorial for setting this up is e.g. http://www.circuitbasics.com/raspberry-pi-zero-ethernet-gadget/
The result of this is a full network interface that you can not only use to transfer data over a TCP/IP socket but at the same time run a SSH-connection to start and monitor your application. Even to develop by using a SSH-enabled editor such as Emacs. So the possibilities are much bigger than over the single-stream serial setup.
If it absolutely has to be serial, that's of course possible too - follow e.g. this tutorial: https://learn.adafruit.com/turning-your-raspberry-pi-zero-into-a-usb-gadget/serial-gadget

Pyserial microcontroller to host communication

I am using a Beaglebone Black (BBB) with Python and pyserial to communicate with an OBD-II reader. I am essentially trying to build a customizable digital gauge panel. Ideally I would like to use Flash for the GUI. Sadly Linux support for Flash is pretty weak. I would like to be able to send data from the BBB using Python to a OSX host computer.
I am currently using terminal to shell into the BBB to run code. I would need to be able to send data from the BBB via a USB/serial interface to the OSX computer running Flash. What would be the best method of accomplishing this?
I have not used beaglebone. I have worked with arduino's serial I/O. But this post says you have multiple serial I/O ports on BBB. Find appropriate connectors/convertors for serial to USB.
Then use the pyserial python module.
On OSX, you will find your device when connected on a path like /dev/ttyo1 where dev is my system name and ttyo1 or something similar will be your device.
import serial as s
device = "/dev/tty01"
bbb = s.Serial(device, 4800) #the second param is baudrate
while(True):
bbb.readline()
# do what you want with the output.
bbb.write('input')
This will read till the end of line character and give you a string. and then write "input" to the serial io on bbb. You will need a similar program running on BBB to read this input and do what you want to do with it.
So there will be two python programs. One on the OSX and the other on the BBB
That way you can give commands from OSX.py, let your BBB.py process and send a response. Which the OSX.py will read and do what is to be done.
You will have to design the input/output cycle properly.
Also if flash is not really necessary you can check out pyside.

Categories

Resources