So this is the script I am using to send each 2 seconds for four time the Time in microsecond to the microcontroller stm32f4 but unfoturnately it only sends some numbers(from 1-->4) which are not the same as when I do a print,it is like random numbers .
import time
import serial from datetime
import datetime from time
import gmtime, strftime
ser = serial.Serial(
port='/dev/ttyACM0',
baudrate=115200,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS
)
ser.writeTimeout = 0
ser.isOpen()
TM1 = int(round(time.time()*1000000))
ser.write(str(TM1).encode())
#ser.write( str(TM1)+" \r\n")
time.sleep(2)
TM2 = int(round(time.time()*1000000))
ser.write(str(TM2)+" \r\n")
time.sleep(2)
TM3 = int(round(time.time()*1000000))
ser.write(str(TM3)+" \r\n")
time.sleep(2)
TM4 = int(round(time.time()*1000000))
ser.write(str(TM4)+" \r\n")
I cannot see anything obviously wrong at first sight. I have a almost identical snippet of code running here that works. My guess would be that the settings of the serial port do not match. Double check that the baudrate, parity and stopbit settings match.
Second guess would be a mess-up with encodings. Have you set your default encoding in python to utf-8? If so you could try
ser.write(str(TM1).encode('ascii'))
Posting the output you get would help as well.
Edit: to avoid the microcontroller skipping some characters. You could use a small function like this. (I used that to send commands to a sensor that had the same issues. When I sent a command like this `ser.write("start logging") it would receive something like "sart lgging".
def write_safe(cmd):
for x in cmd:
ser.write(x)
sleep(0.05)
ser.write('\r\n')
Related
I've written some code to communicate between two Raspberry Pi's, using identical HC-12 433Mhz transceivers. I was able to successfully echo between the two Pi's using a direct serial connection and echo/cat, however am unable to replicate this using HC-12s, which theoretically work by a similar principal. I'm using the port ttyAMA0 on both for this example, but ttyS0 is also available and have tried every combination of these ports.
The following code is common to both the sending and receiving, just writing once for sake of brevity:
import serial
import time
ser = serial.Serial(
port = "/dev/ttyAMA0",
baudrate = 9600,
parity = serial.PARITY_NONE,
stopbits = serial.STOPBITS_ONE,
bytesize = serial.EIGHTBITS
)
print("Serial status: " + str(ser.isOpen()))
This is the sending program:
while True:
print("Sending...")
ser.write("hello\n".encode())
time.sleep(1)
And the receiving program:
while True:
print("Receiving...")
data = ser.readlines()
print(data.decode())
The sending program simply loops as expected, but the receiver prints "Receiving...", and then nothing.
When I keyboard interrupt the receiving program at that point, it says it is currently up to data = ser.readlines().
Any help would be much appreciated - I've spent the better part of the last week trawling and exhausting forums and READMEs to no avail, and this is literally my last option. Am close to insanity on this one!
The pyserial readlines() function relies on the timeout parameter to know when end-of-file is reached - this is warned about in the doco. So with no timeout, the end never occurs, so it keeps buffering all lines read forever.
So you can just add a timeout to the serial port open, and your existing code will begin to work.
ser = serial.Serial(
port = "/dev/ttyAMA0",
baudrate = 9600,
parity = serial.PARITY_NONE,
stopbits = serial.STOPBITS_ONE,
bytesize = serial.EIGHTBITS,
timeout = 2 # seconds # <-- HERE
)
A better approach might be to use readline() (note singular, no 's'), for each line in turn:
print( "Receiving..." )
while True:
try:
data = ser.readline()
print( data.decode() )
# TODO - something with data
except:
print( "Error reading from port" )
break
As that will allow the code to act on the input line-by-line.
Use Serial.read_until method. The default termination character is \n.
For example,
data = ser.read_until()
print(data)
esp8266 and cp2102 don't work! Why?
import serial
sp="/dev/ttyUSB0"
port = serial.Serial(sp)
while True:
port.write("AT+RST")
rcv = port.read(10)
print rcv
I pressed "AT+RST"[Enter] and don't have "READY" after it.
Make sure you include CRLF (\r\n) characters at the end of your command. I lost a day messing with this before I figured that out. I got the local echo back of the command but since I never sent a \r\n I would not get any more data. Here is what works for me as a basic terminal in Python using pyserial:
import serial
import time
ser = serial.Serial('/dev/tty.usbserial-A8004xaO', 115200, timeout=2.5)
while True:
cmd = raw_input("> ");
ser.write(cmd + "\r\n")
ret = ser.read(len(cmd)) # eat echo
time.sleep( 0.2 )
while ( ser.inWaiting() ):
ret = ser.readline().rstrip()
print ret
You aren't setting a baud rate when opening the serial port. The default is probably not appropriate for the ESP8266.
I'm trying to send 9 bytes through a serial port (tested with RS232, RS485) with Python 2.7 pySerial package.
If I write out the bytes to the serial port, some of the bytes randomly get lost (do not arrive on the receiving end).
If I use a 1 millisec wait between every write of a single byte, all bytes arrive to the receiving end.
I tested the functionality between 2 serial terminals on the same OS.
Here is the code fragment which causes packet (byte) losses:
import serial
import struct
ser = serial.Serial()
ser.baudrate = 9600
ser.parity = "N"
ser.rtscts = False
ser.xonxoff = False
ser.write(struct.pack('B', 0x61))
ser.write(struct.pack('B', 0x62))
ser.write(struct.pack('B', 0x63))
...
ser.close()
The fragment which is working:
import serial
import struct
from time import sleep
ser = serial.Serial()
ser.baudrate = 9600
ser.parity = "N"
ser.rtscts = False
ser.xonxoff = False
ser.write(struct.pack('B', 0x61))
sleep(0.001)
ser.write(struct.pack('B', 0x62))
sleep(0.001)
ser.write(struct.pack('B', 0x63))
sleep(0.001)
...
ser.close()
What can be the root cause for the random packet losses?
System details:
OSX 10.9.4
Python 2.7
Minicom or screen was used for terminal emulation
Test environment:
ATC USB/RS485 converters
ATC Serial/RS485 converters with USB-Serial adapter
Typically USB serial converters have to be configured to not flush the buffers on close. As you're seeing if you provide a sleep to wait for the data to complete it works. But if you just dump a bunch of characters then close the device it's buffer may still have data which gets trashed on the close. I'd simply recommend either configuring your device to not flush the buffers (if possible) or wait the character time before performing your close.
I have a rectifier outputting voltage and amperage information every 3 seconds. I installed python 2.7 and pySerial without a hitch. I am trying to get the following code to read data being sent at baud 2400, 7 data bits, even parity, and one stop bit. Other RS232 programs get it without a hitch. When I start the program from cmd I get a blinking underscore. What am I doing wrong?
import time
import serial
ser = serial.Serial(
port='COM3',
baudrate=2400,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.SEVENBITS
)
while True:
message = ser.readline()
print(message)
time.sleep(3)
I'm dealing with a gm29 by Sony Ericsson.
The datasheet says that plugging the power is not sufficient to switch on the modem. It says:
activate the RS232 control line DTR, high for > 0.2s.
I'm writing some tests in python, but:
#!/usr/bin/env python
import serial
from time import sleep
socket = serial.Serial('/dev/ttyS0',
baudrate=9600,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
timeout=1,
xonxoff=0,
rtscts=0
)
socket.setDTR(True)
sleep(3)
socket.setDTR(False)
try:
while True:
socket.write('AT'+chr(13));
sleep(1)
print "Reading"
print socket.readlines()
except:
socket.close()
does not works... I there a way to get DTR high in other ways? Let's say minicom or some other stuff? Or, easily, am I missing something?
Thanks in advance.
Ok, that was driving me mad. The clue is that the power supplier was "broken", or better, it works good testing with a tester, but plugging on the modem some wires moves and does not carry voltage...
Thanks anyway for the answer, marked as correct 'couse it was :D
There are several things that occur to me here.
1) the spec says that DTR is active low, so you may need to swap the true and false values to setDTR(), depending on who is confused here.
2) You are setting DTR to false after you wake the modem. This tells the modem to go offline, and ignore all input till it goes true again. Try the following:
import serial
from time import sleep
conn = serial.Serial('/dev/ttyS0',
baudrate=9600,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
timeout=1,
xonxoff=0,
rtscts=0
)
# Wake Modem
conn.setDTR(True)
sleep(3)
conn.setDTR(False)
sleep(5)
# Start talking
conn.setDTR(True)
try:
while True:
conn.write('AT'+chr(13));
print conn.readline() # readlines() will probably never return.
finally:
conn.close()
3) socket is probably a bad name for your serial connection.