Beaglebone Black Wireless: UART isn't reading - python

I'm trying to have a Beaglebone Black Wireless(debian image 2017-07-01) communicate to another device using UART serial communication. In an example program, the bone waits for the device to send the letter "A", then, upon receiving the right letter, outputs a message and transmits the letter "B". Here is the following program:
import Adafruit_BBIO.UART as UART
import serial
#Enabling the serial ports
UART.setup("UART1")
#Serial setup values
ser = serial.Serial()
ser.port = "/dev/ttyO1"
ser.baudrate = 9600
READ_LEN = 1
ser.close()
rx = ""
while True:
print "Waiting for A... "
ser.open()
rx = ser.read()
ser.close()
if (rx == 'A'):
print "Got it!"
ser.open()
ser.write("B")
ser.close()
break
The program doesn't throw any errors, however, when testing it out with the device, the program gets stuck on the "Waiting for A" line. I have thoroughly checked that all connections are correct and that the other device is sending data. Additionally, the program runs perfectly on an older Beaglebone (debian image 2015-11-12).
Any help into this matter would be greatly appreciated.

config-pin "Whatever Pin You Are Using" uart
example:
config-pin P9.14 uart
Seth

Related

Python Serial Writing but seemingly not reading. Raspberry Pi 0 to Arduino

I'm having trouble with a python script running on an RPI0 reading serial input from an Arduino. I know the Arduino's code is correct as everything works as intended interacting with the Arduino over the built in serial monitor in the Arduino software(send code a10(code to drive a relay HIGH), Arduino sends back 11(basically asking for how long), send code b5, Arduino will hold pin HIGH for 5 seconds(b5)).
However when I attempt to read any serial input in python using the pyserial module, nothing happens. I know it does successfully send the code to the arduino as it will hold the pin HIGH for the specified seconds when I rewrite the python script with ser.write("a10b5").
The serial connection is NOT USB. I'm using jumper wires with a voltage shifter in between them using the Arduino's and Pi's GPIO TX and RX pins.
using python -V in the terminal it tells me I'm running version 3.8
I've tried multiple baud rates(300, 1200, 9600, 57600) with no change in behavior
I've also tried changing if x == 11: to if x == "11": in case for some reason it was receiving strings and not ints, also to no avail.
Here is the code:
import time
import serial
ser = serial.Serial(
port='/dev/ttyAMA0',
baudrate = 9600,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=None
)
print("sending data over serial now")
ser.write("a10") #a10 is relay HIGH code
while True:
x = ser.read()
if x == 11: ##arduino code 11(asking for how long)
print("recieved code 11")
print("arduino recieved relay HIGH code and is waiting for time to hold relay for")
print("sending time now")
ser.write('a5') # 5 seconds
time.sleep(1)
if x == 13: #arduino code 13(water success)
print("recieved code 13")
print("arduino reports watering complete")
x = 0 ##this is to clear the variable every loop. Not sure if it's needed
And here is a simple serial reader I've pulled from online. Opening it up in a second terminal and running it at the same time with my own script it will actually read the codes from the arduino business as usual.
#!/usr/bin/env python
import time
import serial
ser = serial.Serial(
port='/dev/ttyAMA0',
baudrate = 57600,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=1
)
while True:
x=ser.readline()
print x
What gives?
Answering my own question. In the arduino code I used
Serial.println(whatevergoeshere)
instead of
Serial.print(whatevergoeshere)
So the arduino was sending out '\n' at the end of every serial line that was not being printed by either the arduino serial console and the python script. Updating my IF statements in python to
if x == "11\n":
Solves the issue and everything works as intended.

Python pySerial on Raspberry Pi Zero W: detecting a disconnected serial device

In my project, there's a Raspberry Pi Zero W, linked with Arduino Pro Micro over the serial TX/RX lines (through 5 - 3.3V logic level converter). At power-on, the Arduino starts sending "are you there" command over the serial, until Pi has finished booting and launched a python program that listens on serial port, and it replies with "yes". Then Arduino proceeds with sending regular updates with sensor data.
For some reason not yet understood, the Arduino can disconnect and reboot, while the Pi is still running. And, for some reason, the connection on the Python end is severed in a way that does not raise exception if connection.in_waiting is read.
import serial
import time
ser = serial.Serial('/dev/serial0')
ser.baudrate = 9600
cmd = b''
while True:
time.sleep(1)
print(ser.is_open)
while ser.in_waiting:
ch = ser.read()
if ch == b'\n':
print('New command:', cmd)
cmd = b''
ser.write(b'OK\n')
continue
else:
cmd = cmd + ch
I have tested with this simple code, but in my tests, if I disconnect the Arduino and connect it back, the ser.is_open never is False, and the old connection works just fine also with reconnected Arduino. So, unfortunately I can not exactly replicate the loss of connection scenario when the data stop coming after disconnection. However, in order to investigate further, I'd like to add some monitoring code that would log serial disconnection incidents in file. But is there a way? If connection.is_open is always true, even without Arduino connected, then how one can detect if there is no connection?
The port remains open if there's a disconnection so your example code will loop continuously.
import serial
def connect(port):
return serial.Serial(port, baudrate=9600, timeout=1)
ser = connect('/dev/serial0')
buf = bytearray()
while True:
i = buf.find(b'\n')
if i >= 0:
buf = buf[i + 1:]
ser.write('OK\n')
num_bytes = max(1, min(1024, ser.in_waiting))
data = ser.read(num_bytes)
if data:
buf.extend(data)
else:
# no data to read aka disconnection has occurred
ser = connect('/dev/serial0')
if ser.isOpen():
continue
else:
# could not reconnect
break

Raspberry Pi RS485/Uart Modbus

I'm attempting to get an RS485 adapter connected at the UART to communicate via modbus on a Raspberry Pi. My end goal is to have all this working with a Node application, but so far my dev has been with Python.
My hardware connection looks like:
[Modbus-Device] <===> [RS485 chip <==> Raspberry PI GPIO] pins. The RS485 has three wires (Transmit, Receive, Direction) they are connected as follows
RaspiPi <=> Adapter
GPIO 14 (8) - Tx <=> Data+
GPIO 15 (10)- Rx <=>- Data-
GPIO 18 (12) - Direction
The RS485 isn't a typical 9-pin adapter. I have three wires running off a chip. A twisted pair that serves as differential set and a ground wire.
I have been able to send serial communications between this adpater and a USB-RS485 adapter by manually flipping GPIO18 for send/recieve. (Code below)[1]. This code is purely for proving the adapter works
I'm stuck at getting modbus to work on GPIO adapter. I've tried using minimalmodbus, which works well with the USB-RS485 adapter, but fails with the GPIO adapter. I suspect this is because the direction pin isn't being set.
The ideal resolution would be to find an RS485 driver for GPIO on the pi, but short of that I see three options
1 - Make my own driver (Something I am completely unfamiliar with)
2 - Somehow get a modbus library to flip the GPIO pin in Kernel space
3 - Manually send modbus messages over serial and adjust the GPIO pin in user space. This seems the easiest but also the worst in terms of speed and reliability. My code attempt is below [2]
Any advice on this topic would be very appreciated. If someone has done something similar before and could weigh in on my options that would be helpful. I've never worked on software at this level so I wouldn't find it surprising if there were some obvious answer I'm completely overlooking.
[1] This code communicates with another RS485 adapter on the raspberry pi connected with USB. This was written to prove the GPIO adapter is working and that I can control direction with Pin 12 on the Raspberry pi
import time
import serial
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(12, GPIO.OUT);
ser = serial.Serial(
port= '/dev/ttyS0',
baudrate= 57600,
parity= serial.PARITY_NONE,
stopbits= serial.STOPBITS_ONE,
bytesize= serial.EIGHTBITS,
timeout=1
)
def write_add():
counter = 0;
message = 0
while (True):
print "writing",
GPIO.output(12,1) #set high/transmit
ser.write('%d \n'%(message))
time.sleep(0.005) #baud for 57600
#time.sleep(0.5) #baud for 9600
GPIO.output(12, 0) #pin set to low/receive
loop_count = 0
res =""
while (res == ""):
res =ser.readline();
if(res != ""):
print ""
print "Read Cycles: "+str(loop_count)+" Total: "+str(counter)
print res
message = int(res) + 1
counter = counter + 1
elif(loop_count > 10):
res = "start over"
else:
print ".",
loop_count = loop_count + 1
write_add()
[2] This code is attempting to communicate with another modbus device. My message is being sent, but the response is garabge. My assumption is that the GPIO direction pin is being flipped either too soon and cutting off the message or too late and missing some of the response.
import serial
import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(12, GPIO.OUT)
ser = serial.Serial(
port='/dev/ttyS0',
baudrate = 57600,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=1
)
GPIO.output(12,1) #set high/transmit
ByteStringToSend = "\x00\x03\x01\xb8\x00\x01\x04\x02"
ser.write(ByteStringToSend)
time.sleep(0.005) #baud for 57600
GPIO.output(12, 0) #pin set to low/receive
ReceivedData = ""
while (ReceivedData == ""):
RecievedData = ser.readline();
print RecievedData
[3] Working USB-RS-485 code. USB adapter on Pi connected to Modbus device This code reads register 440 every second.
#1/usr/bin/env python
import minimalmodbus
import time
print minimalmodbus._getDiagnosticString()
minimalmodbus.BAUDRATE=57600
minimalmodbus.PARITY='N'
minimalmodbus.BYTESIZE=8
minimalmodbus.STOPBITS=1
minimalmodbus.TIMEOUT=0.1
instrument = minimalmodbus.Instrument('/dev/ttyUSB0', 0) #port and slave
#instrument.debug = True
while True:
batterVolt = instrument.read_register(440, 2) #register number, number decimals
print batterVolt
time.sleep(1)
Edit: Clarified scheme.
Edit2: Further clarified scheme and added/edited code
The code in example-2 actually works correctly. I just needed to format the response.
print RecievedData.encode('hex')
This will give the hex string in a modbus response format. As Andrej Debenjak alluded to time.sleep(x) will be dependent on baud rate and message size.
Side note: I found this page helpful in deciphering the modbus transmission.
http://www.modbustools.com/modbus.html
Edit: The ByteString I'm sending should not work on a proper modbus setup. The first byte x00 is the broadcast byte and should not solicit a response. It seems the hardware I'm working with has something funky going on. In a typical modbus setup you would need to address which device you're trying to communicate with. Thanks Marker for pointing this out.

Raspberry Pi Zero reboot after some AT commands to A6 gsm modem through serial

I have a problem with Raspberry Pi Zero 1.3 and A6 GSM modem. When I send speciffically commands which should communicate with the sim card on the gsm module (like AT+CGATT=1), the raspberry reboots with no entries in the logs pointing to the reboot. I am running latest Raspbian Lite.
Modem is connected to the Serial port on raspberry (Tx+Rx) and also 5V and Gnd. Raspberry is powered by 1,5A power supply through USB (pwr).
This errors also when Tx from GSM module is disconnected (so no received answer on raspberry).
I have tried changing the modem modules, but the error still occurs. I have also changed raspberry boards and the error seems to be absent on some boards.
Have any of you encountered something similar?
Here is my testing code in python:
import time
import serial
import sys
import os
print "Starting program"
os.system('echo raspberry | stty -F /dev/ttyAMA0 9600')
ser = serial.Serial('/dev/ttyAMA0', baudrate=9600,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=5
)
time.sleep(1)
try:
while True:
input = raw_input('Give me command master: ')
ser.write(input + '\r\n')
data = ser.read(10000)
print data
except KeyboardInterrupt:
print "Exiting Program"
except:
print "Error Occurs, Exiting Program"
finally:
ser.close()
pass
Thank you in advance :)

Raspberry PI USB to RS232 adapter Receiving Only Ctrl Chars

I'm using a USB to RS232 cable for get communication with a pure rs232 device.
With pyserial lib a got this code running in loopback tx -> rx cable pins.
Setting the port:
def __init__ (self, baudrate,timeout,parity,stopbits,bytesize):
try:
#self.s = serial.Serial(port="'/dev/ttyUSB0'",baudrate=baudrate,timeout=timeout,parity=parity,stopbits=stopbits,bytesize=bytesize)
#self.s = serial.Serial("/dev/ttyUSB0",9600)
self.s=serial.Serial(
"/dev/ttyUSB0",
baudrate=9600,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
writeTimeout = 0,
timeout = 10,
rtscts=False,
dsrdtr=False,
xonxoff=False)
except:
print ("Can't open Serial Port")
traceback.print_exc(file=sys.stdout)
Writing and reading from it:
def write(self,data):
if self.s.isOpen():
try:
self.s.write(data)
self.s.flush()
except:
traceback.print_exc(file=sys.stdout)
print "Error on writing"
else:
print "Port is closed"
def read(self):
receivedData=[]
if self.s.isOpen():
try:
while self.s.inWaiting()> 0:
receivedData.append(self.s.read(1))
return receivedData
except:
traceback.print_exc(file=sys.stdout)
print "Error on Reading"
else:
print "Port is closed"
traceback.print_exc(file=sys.stdout)
I sent 'Carlos'.
And received ['\x03', '\x01', '\x12', '\x0c', '\x0f', '\x13']
It is hex representation of ^C^a^r^l^o^s
I need to know why it is converting chars to control chars?
This is what you would expect if the sending end is using only 5 bits.
First check the settings on the sending device.
If possible, verify the bits are being send with an oscilloscope or logic analyser.
Perhaps the dongle is broken.
Maybe some part of the system has a poor power supply and the final 3 bits are not being detected properly.
After a lot of attempts without any idea about how fix this problem, I bought new cable USB to RS232, it is based on Prolific PL2303 Chipset and it is working properly right now.

Categories