I am trying to get an LED to respond to a python program (using python 3.8), and it is not receiving anything. When I connect to the port, the led blinks to indicate it is connected, but then does nothing. Here is my code:
import serial
ser=serial.Serial('/dev/cu.usbmodem1411', 2000000, timeout=1)
ser.write(b'H')
time.sleep(200)
while True:
#read echo back from arduino verify receipt of message
#will show printing of x from arduino program
data = ser.readline()[:-2]
if data:
print (data.decode())
The while loop doesn't print out anything, and I also tried using the Arduino interface and it send signals fine, so my wiring is correct, but there is something missing with the python code. Has anyone run into this before?
The problem seems to be due to the wrong band speed you are using for the serial port. ser=serial.Serial('/dev/cu.usbmodem1411', 2000000, timeout=1) The value 2000000 here can never be true. There is no such value. The default is 9600, but I'll share a photo showing you the band speed on the Arduino side, the band speeds here and there should be equal.
Related
I'm writing something like an SMS gate on Ubuntu. The device is a Huawei E173 Modem.
I use pyserial to write/read to and from the device. Here is my code:
import serial
import time
port = '/dev/ttyUSB0'
ser = serial.Serial(port,
stopbits=serial.STOPBITS_ONE,
parity=serial.PARITY_NONE,
bytesize=serial.EIGHTBITS
)
ser.write(b'AT\r\n')
time.sleep(0.1)
print(ser.read(ser.in_waiting))
This code works. But sometimes when I reconnect the device, I find that it cannot read anything. (ser.in_waiting=0 and nothing changes even if I set n larger).
But I can still use minicom to work with that port.
My Question: Why doesn't pyserial work but minicom can? Is there any difference between them?
What I guess it's happening is that the delay you are using together with the timeout you set when you open the port is conspiring with the time it takes for the modem to process the command.
To avoid that try reading data repeatedly for a certain time with a loop:
...
ser.write(b'AT\r\n')
timeout=time.time()+3.0
while ser.inWaiting() or time.time()-timeout<0.0:
if ser.inWaiting()>0:
data+=ser.read(ser.inWaiting())
timeout=time.time()+3.0 print(data)
With minicom or any other terminal you are always listening on the port so you always get the answer no matter how long the modem takes to process the command. In your code you send the command, wait 100 ms and then listen on the port for a time period defined by the timeout setting. Since you are not defining a timeout you have the default wait forever but that behavior is overridden by the use of the bytes in the buffer as an argument. If you happen to check the buffer before data arrives in it (because the command took longer than the 100 ms you gave it) the timeout becomes zero.
Considering the previous paragraph, and assuming you know the number of bytes it might be better to define a finite timeout and read with a ser.read(n) with n the expected bytes.
In my case, (on the BeagleBone Black), the above answer helped me get some bytes but not all. I realized, due to some reasons, minicom was reading the port and (maybe) flushing it. So, PySerial got nothing to read.
I simply closed minicom terminal and everything is good now :)
I'm using software which has Python scripting capabilities. I want to use it to move a Clearpath servo and run internal software commands intermittently.
Using an Arduino, I can control the servo, but it starts going wrong once I start using serial communication. After reading through other post, I'm thinking the problems are arising because serial communication is 8bit and I'm wanting to send large int.
For example, a section of the Arduino code shows:
void loop(){
if(Serial.available()){
inByte = Serial.readStringUntil('\n');
ser = inByte.toInt();
X.move(ser);
while(!X.commandDone()||!X.readHLFB())
{ }
Serial.print (inByte);
delay(1000);
}
}
Before I started using serial communication, I'd utilize integers in X.move(ser) and get flawless results. Now that I'm using the serial port, I can tell there's something wrong with this code. Even though it seems to work using the Serial Monitor, the more I try it (especially using larger numbers) the more I realize its probably not doing what it did before I used serial.
Then add Python into the mix and it gets even worse.
To give you an idea of what I'm trying to do, here was an example of Python code:
ser = serial.Serial('COM3', 9600, timeout=1)
ser.close()
ser.open()
while True:
var = "1000"
ser.write(var.encode())
time.sleep(1)'
Using this code, the servo moves but it's not right at all.
How can I send large integers (for example, 50502) from Python to Arduino through serial without it getting mangled during serial communication?
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.
I'm sending an integer from python using pySerial.
import serial
ser = serial.Serial('/dev/cu.usbmodem1421', 9600);
ser.write(b'5');
When i compile,the receiver LED on arduino blinks.However I want to cross check if the integer is received by arduino. I cannot use Serial.println() because the port is busy. I cannot run serial monitor first on arduino and then run the python script because the port is busy. How can i achieve this?
You could listen for the Arduino's reply with some additional code.
import serial
ser = serial.Serial('/dev/cu.usbmodem1421', 9600); # timeout after a second
while ser.isOpen():
try:
ser.write(b'5');
while not ser.inWaiting(): # wait till something's received
pass
print(str(ser.read(), encoding='ascii')) #decode and print
except KeyboardInterrupt: # close the port with ctrl+c
ser.close()
Use Serial.print() to print what the Arduino receives to the serial port, where your Python code is also listening.
You can upload an arduino program that listens for that specific integer and only blinks the light if it gets that int.
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.