Cannot send/receive using Xbee's in API mode (python) - python

I have two Xbee Pro 900's, each attached to a Raspberry Pi. Both are updated to version 1061 and are set to API Enable with escapes. They also have the same Modem VID of 7FFF. Both Pi's have PySerial and the python-xbee library installed.
Xbee 1(Receiver) has a serial number of 0013A200409A1BB8
Xbee 2(Sender) has a serial number of 0013A200709A1BE9
I've included my code below, which is just sample code I've found online. My issue is that I'm not receiving anything on the appropriate Xbee. I have absolutely no idea what is wrong, I've triple checked the destination address, and both of the Xbee's configuration settings.
Xbee 2 Code(Sender):
#! /usr/bin/python
import time
from xbee import XBee
import serial
PORT = '/dev/ttyUSB0'
BAUD_RATE = 9600
# Open serial port
ser = serial.Serial(PORT, BAUD_RATE)
# Create API object
xbee = XBee(ser,escaped=True)
import pprint
pprint.pprint(xbee.api_commands)
DEST_ADDR_LONG = "\x00\x13\xA2\x00\x40\x9A\x1B\xB8"
# Continuously read and print packets
while True:
try:
print "send data"
xbee.tx_long_addr(frame='0x1', dest_addr=DEST_ADDR_LONG, data='AB')
time.sleep(1)
except KeyboardInterrupt:
break
ser.close()
Xbee 1 Code(Receiver):
#! /usr/bin/python
from xbee import XBee
import serial
PORT = '/dev/ttyUSB0'
BAUD_RATE = 9600
# Open serial port
ser = serial.Serial(PORT, BAUD_RATE)
# Create API object
xbee = XBee(ser,escaped=True)
# Continuously read and print packets
while True:
try:
print "waiting"
response = xbee.wait_read_frame()
print response
except KeyboardInterrupt:
break
ser.close()
When both programs are running, the Tx light on the sending Xbee blinks, but I receive nothing on the receiving Xbee. Is there something I'm missing? Thanks for your time!

Are you using XBee or XBeePro? I had the same problem and this post helped me a lot.
Try to modify the Receiver Code the following way:
import config
import serial
import time
from xbee import ZigBee
def toHex(s):
lst = []
for ch in s:
hv = hex(ord(ch)).replace('0x', '')
if len(hv) == 1:
hv = '0'+hv
hv = '0x' + hv
lst.append(hv)
def decodeReceivedFrame(data):
source_addr_long = toHex(data['source_addr_long'])
source_addr = toHex(data['source_addr'])
id = data['id']
samples = data['samples']
options = toHex(data['options'])
return [source_addr_long, source_addr, id, samples]
PORT = '/dev/ttyUSB0'
BAUD_RATE = 9600
# Open serial port
ser = serial.Serial(PORT, BAUD_RATE)
zb = ZigBee(ser, escaped = True)
while True:
try:
data = zb.wait_read_frame()
decodedData = decodeReceivedFrame(data)
print decodedData
except KeyboardInterrupt:
break
In my case the code above outputs the following:
[['0x00', '0x13', '0xa2', '0x00', '0x40', '0x9b', '0xaf', '0x4e'], ['0x68', '0x3f'], 'rx_io_data_long_addr', [{'adc-0': 524}]]
Here I shared configuration settings for Controller Node (compatible with X-CTU)

Are you sure the XBee modules are in escaped API mode (ATAP=2)? And 9600 baud?
Can you enable a mode in python-xbee to dump all characters in and out?
Have you confirmed the serial wiring is correct? (I see you're using USB, so that's not an issue.)
If you don't have hardware flow control hooked up, make sure the XBee modules have ATD6=0 and ATD7=0 set (disable RTS and CTS) and that python-xbee isn't expecting handshaking.
If you do have hardware flow control configured on the XBee, make sure you've told python-xbee to use it.
Can you use minicom or another serial terminal on the RaspPi to confirm that serial is working? Use minicom on the receiving end to see if you're getting anything at all?
Can you try sending and receiving with the radios connected to a PC instead of the Pi? Sending from the PC to the Pi, or vice-versa?

Related

Sending data between ESP32 and computer through USB with micropython

I have an ESP32 connected to to my computer through the usb port and have tried sending and receiving serial data. It works, but I can't make it so the ESP32 recognizes what is being sent using this code
from machine import Pin, PWM, UART #type: ignore
import time
uart = UART(115200)
while True:
if uart.any():
msg = uart.read()
uart.write(msg)
if msg == 'hello':
uart.write("hello received")
The ESP32 should send "hello received", but it returns "hello" instead. Furthermore, this code only works when sending serial data from the arduino serial monitor. When I try running a separate python script to send "hello" and print what the ESP32 returns,
import serial, time
ser = serial.Serial('COM5', 115200)
ser.write(b"hello")
time.sleep(1)
i = ser.readline()
print(i)
Nothing gets printed to the console. Is there a problem with my code? Thanks
Edit:
Alright I fixed my code up to include the \n and it still didn’t work. I found out using this script that I’m not sending any serial data
ESP32:
from machine import Pin, PWM, UART #type: ignore
import time
uart = UART(1,115200)
while True:
print("starting")
msg = uart.readline()
print(msg)
time.sleep(0.01)
Computer:
import serial, time
ser = serial.Serial('COM5', 115200)
while True:
ser.write(b'hello\r\n')
print(ser.readline())
time.sleep(1)
The esp returns b'starting\r\n' b'None\r\n

using PySerial don't work until port is opened with minicom

I developed a plugin for Domoticz on a RPi3B+. This plugin is in Python.
I want to send commands to a Arduino board using a USB serial port.
The plugin opens the serial port, sends a command and closes the serial port. It works well except after a reboot.
After a reboot, the port is open, and the command seems to be sent to the Arduino, but it doesn't understand it, just as if the baud rate were wrong. Arduino's Rx LED is blinking.
If I open the serial in parallel using minicom and exit minicom without resetting the parameters, then the plugin starts working properly.
Here's my code:
serialCmd = "gpio sh" + str( shutterId ) + "_" + order +" on for " + str( PULSE_DURATION_MS ) + "\r"
Domoticz.Debug( "Serial command : " + serialCmd )
# open serial port
try:
Domoticz.Debug( "Opening serial port : " + Parameters["SerialPort"] )
serialPort = serial.Serial( port = Parameters["SerialPort"],
baudrate = 115200,
bytesize = serial.EIGHTBITS,
parity = serial.PARITY_NONE,
stopbits = serial.STOPBITS_ONE,
timeout = 1,
xonxoff = False,
rtscts = False,
dsrdtr = False )
except:
serialPort = None
if serialPort:
serialPort.write( serialCmd.encode( 'utf-8' ) )
serialPort.close()
serialPort = None
The serial port is /dev/ttyUSB0.
If I try to use exclusive = True in serial.Serial(...), it fails to open the port, as if the port were already open.
Another strange thing: when the Arduino board reboots, it sends some information to the serial port.
I can't read it with the plugin in Python with PySerial, but I can read it with minicom.
If I close minicom with resetting the parameters, each time I open minicom this information is read by minicom (without resetting the Arduino board) as if the input buffer has never been read, and the Python plugin still doesn't work.
How do I solve the problem?
This issue was because of Arduino nano schematic where DTR signal is connected to the reset signal which makes the Arduino to reset each time the serial port is open. This post made me search the right thing on the internet. That's why opening minicom and closing without resetting the port makes it work...
When the serial is not used anymore by a process the DTR line is reset so next time a process open the serial port the DTR is driven which makes the Arduino reboot.
A way to fix it is to modify the board or two disable the DTR handling. This can be done by dsiable the HUPCL bit of the terminal lib.
Some people manage to fix it with pySerial but it does not work for me so I had to do as below...found here and here.
import serial
import termios
port = '/dev/ttysUSB0'
f = open(port)
attrs = termios.tcgetattr(f)
attrs[2] = attrs[2] & ~termios.HUPCL
termios.tcsetattr(f, termios.TCSAFLUSH, attrs)
f.close()
se = serial.Serial()
se.baudrate = 115200
se.port = port
se.open()

python pyserial read data and respond

I am trying to open a serial port connection and keep it open as long as data if communicating. I also want to respond if certain data is received. Below is an example of the python script. I am able to open the serial port send data and the script responds, it will not respond with the elif data.
I am new to pyserial and have been working on python lately but not great by any means.
Thank you
import serial
import time
ser = serial.Serial('/dev/ttyUSB0', timeout=10) # open serial port
print(ser.name) # check which port was really used
response = ser.read()
if response == (b'\r'):
ser.write (b'ID=')
elif response == (b'\r\r\x1bPG1\r'):
ser.write (b'110 1.8<CR><ACK><CR><ESC>[p<CR>')
#time.sleep(5)
#print ()
#ser.close() # close port

How to read and write from a COM Port using PySerial?

I have Python 3.6.1 and PySerial Installed. I am trying the
I am able to get the list of comports connected. I now want to be able to send data to the COM port and receive responses back. How can I do that? I am not sure of the command to try next.
Code:
import serial.tools.list_ports as port_list
ports = list(port_list.comports())
for p in ports:
print (p)
Output:
COM7 - Prolific USB-to-Serial Comm Port (COM7)
COM1 - Communications Port (COM1)
I see from the PySerial Documentation that the way to open a COM Port is as below:
import serial
>>> ser = serial.Serial('/dev/ttyUSB0') # open serial port
>>> print(ser.name) # check which port was really used
>>> ser.write(b'hello') # write a string
>>> ser.close() # close port
I am running on Windows and I get an error for the following line:
ser = serial.Serial('/dev/ttyUSB0')
This is because '/dev/ttyUSB0' makes no sense in Windows. What can I do in Windows?
This could be what you want. I'll have a look at the docs on writing.
In windows use COM1 and COM2 etc without /dev/tty/ as that is for unix based systems. To read just use s.read() which waits for data, to write use s.write().
import serial
s = serial.Serial('COM7')
res = s.read()
print(res)
you may need to decode in to get integer values if thats whats being sent.
On Windows, you need to install pyserial by running
pip install pyserial
then your code would be
import serial
import time
serialPort = serial.Serial(
port="COM4", baudrate=9600, bytesize=8, timeout=2, stopbits=serial.STOPBITS_ONE
)
serialString = "" # Used to hold data coming over UART
while 1:
# Wait until there is data waiting in the serial buffer
if serialPort.in_waiting > 0:
# Read data out of the buffer until a carraige return / new line is found
serialString = serialPort.readline()
# Print the contents of the serial data
try:
print(serialString.decode("Ascii"))
except:
pass
to write data to the port use the following method
serialPort.write(b"Hi How are you \r\n")
note:b"" indicate that you are sending bytes

Error in working with pyserial module of python

import time
import serial
# configure the serial connections (the parameters differs on the device you are connecting to)
ser = serial.Serial(
port='/dev/ttyS0',
#port='/dev/ttyACM0',
baudrate=115200,
parity=serial.PARITY_ODD,
#stopbits=serial.STOPBITS_TWO,
#bytesize=serial.SEVENBITS
)
ser.isOpen() # returns true
time.sleep(1);
ser.write("some_command \n")
ser.close()
I have a embedded board. It has a serial port which is connected to my computer. I am running above script to access this serial port and run some board specific commands.
My problem
I open my serial port (using minicom in linux) separately and then run above script, It works. If I don't open serial port separately, Script doesn't work.
try
ser.write("some_command \n".encode())
alternatively try
ser.write(bytes(b"some_command \n"))

Categories

Resources