Posts: 5
Threads: 2
Joined: Jan 2018
Hello,
I use this code to send command to an Arduino using this code from here:https://tungweilin.wordpress.com/2015/01/04/python-serial-port-communication/
import serial
port = "COM4"
baud = 38400
ser = serial.Serial(port, baud, timeout=1)
# open the serial port
if ser.isOpen():
print(ser.name + ' is open...')
while True:
#cmd = raw_input("Enter command or 'exit':")
# for Python 2
cmd = input("Enter command or 'exit':")
# for Python 3
if cmd == 'exit':
ser.close()
exit()
else:
ser.write(cmd.encode('ascii')+'\r\n')
out = ser.read()
print('Receiving...'+out) But I get this error:
ser.write(cmd.encode('ascii')+'\r\n')
TypeError: can't concat bytes to str I tried many changes, among which is this:
while True:
#cmd = raw_input("Enter command or 'exit':")
# for Python 2
cmd = input("Enter command or 'exit':")
# for Python 3
if cmd == 'exit':
ser.close()
exit()
else:
ser.write(cmd.encode('UTF-8')+ b"\n")
out = ser.read()
print('Receiving...'+out) But I get this error:
print('Receiving...'+out)
TypeError: Can't convert 'bytes' object to str implicitly How can I send the command correctly?
Posts: 1,298
Threads: 38
Joined: Sep 2016
I haven't tried this, but what if you changed '\r' and '\n' to their decimal equivilents?
So this line:
ser.write(cmd.encode('ascii')+'\r\n') becomes:
ser.write(cmd.encode('ascii') + b'13' + b'10')
If it ain't broke, I just haven't gotten to it yet.
OS: Windows 10, openSuse 42.3, freeBSD 11, Raspian "Stretch"
Python 3.6.5, IDE: PyCharm 2018 Community Edition
Posts: 2,124
Threads: 11
Joined: May 2017
Jan-30-2018, 04:25 PM
(This post was last modified: Jan-30-2018, 04:25 PM by DeaD_EyE.)
You can not concatenate bytes with strings.
Just concatenate them, when they are still str:
cmd = input("Enter command or 'exit':") + '\r\n'
...
ser.write(cmd.encode()) PS: cmd.encode('ascii') + b'13' + b'10' is wrong.
You have following possibilities:
your_str.encode() + b'\x0d' + b'\x0a'
your_str.encode() + bytes([13, 10])
your_str.encode() + bytes([0x0d, 0x0a])
or with a str:
end = '\x0d\x0a'
cmd.encode() + end.encode()
I think the best way is, to do all formatting and concatenation with strings and when you need them to send them as bytes, do it at this place directly without any additional stuff like concatenation.
Posts: 1,298
Threads: 38
Joined: Sep 2016
I stand corrected and learned a new method. Thanks.
If it ain't broke, I just haven't gotten to it yet.
OS: Windows 10, openSuse 42.3, freeBSD 11, Raspian "Stretch"
Python 3.6.5, IDE: PyCharm 2018 Community Edition
Posts: 5
Threads: 2
Joined: Jan 2018
Thank you, I managed to make it send command, but not to make the
out = ser.read()
print('Receiving...'+out) work. What I am trying to do is this: I wrote a code to read from Arduino through Serial, and I want to send commands to the Arduino through serial (by typing the commands through the keyboard). The code I am using is this:
import serial,time
ser = serial.Serial(
port='COM4',
baudrate=38400,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
xonxoff=False
)
line = ser.readline();
while line:
line = ser.readline()
print(line)
ser.reset_input_buffer()
cmd = input("Enter command or 'exit':") + '\r\n'
if len(cmd)>0:
ser.write(cmd.encode())
else:
continue but what I see is that the code blocks, until I print something. I want to read continuously from Serial what Arduino sends and if I type a command from keyboard, to write it to the serial. I am trying changes and I read the pyserial documentation but I cannot figure out something...
Posts: 3
Threads: 0
Joined: Feb 2018
Maybe you need to add back in the timeout=1 arg in the serial.Serial() constructor? Otherwise the call to ser.readline() will block (i.e., not return) until data is received (specifically an EOF).
Posts: 2,124
Threads: 11
Joined: May 2017
As mentioned ser.readline() is a blocking call. You try to read a reply before you have sent a request.
Maybe you think about the concept.
- You switch your Arduino on
- You switch your PC on
- You start the program on the PC
- Program is waiting for input from serial which should magically come from the Arduino
The point is, the Arduino does not know when there is a new connection.
The program should on the Arduino work as follows:
- Arduino runs in a loop.
- A blocking call reads the received data (readline).
- When the request has been received, it executes the program.
- The Arduino answers the request with a reply.
On the other side your program should do following in a loop: - Connects to serial
- Inside a loop
- Reads the input from user
- if no command, break out of the loop to close the program
- Reads the received data from serial
- Prints it to console
Posts: 2
Threads: 1
Joined: Feb 2019
I am learning Python new and i want send to date and time but i have some problem.
When i write to input method something, i can send to my message.But the message been date and time on windows ,cannot send to arduino. Screen output become like that b' ' . I need to year,month,day,hour,minute and second data.
import serial
import time
import datetime
ser = serial.Serial('COM3', 9600, timeout=0)
ser.reset_input_buffer()
time.sleep(1.5)
now=datetime.datetime.now()
#str_now=now.strftime("%Y.%m.%d.%H.%M.%S")+'\r\n'
year = now.strftime("%Y")+'\r\n'
#print("year:", year)
#month = now.strftime("%m")+'\r\n'
#print("month:", month)
#day = now.strftime("%d")+'\r\n'
#print("day:", day)
#hour = now.strftime("%H")+'\r\n'
#print("hour:", hour)
#minute = now.strftime("%M")+'\r\n'
#print("minute:", minute)
#second = now.strftime("%S")+'\r\n'
#print("second:", second)
#var = input("Enter something: ")+'\r\n'
ser.write(year.encode())
while 1:
try:
print (ser.readline())
time.sleep(1.5)
except ser.SerialTimeoutException:
print('Data could not be read') Arduino code:
int incomingByte = 0;
void setup(){
// Open serial connection.
Serial.begin(9600);
}
void loop(){
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();
// say what you got:
Serial.print("I got: "); // ASCII printable characters
Serial.println(incomingByte,DEC);
}
} Output:
[Image: 1pcuo0.jpg]
How to change python code and send to date and time datas
Posts: 1
Threads: 0
Joined: Jun 2020
Thank you for this useful reply. However -
I am afraid that the result of your illustration is ambiguous. You have included so many brackets and quote marks that I have no idea how cmd ends up, so what pyserial encodes and sends. You cannot assume that the naive user (me) understands the detailed syntax or how it is interpreted by the compiler, especially as the questioner also failed to understand the syntax.
Is cmd = "Enter command or 'exit':"\r\n
or cmd = input("Enter command or 'exit':")\r\n
or cmd = Enter command or 'exit':\r\n
or cmd = what?
And if cmd1 = G0 X11.4158 Y0.5132
rtnl = \r\n
can I state
cmd2 = cmd1 + rtnl
to create
cmd2 = G0 X11.4158 Y0.5132\r\n
and is that the same as
cmd2 = 'G0 X11.4158 Y0.5132' + '\r\n'
?
(Jan-30-2018, 04:25 PM)DeaD_EyE Wrote: You can not concatenate bytes with strings.
Just concatenate them, when they are still str:
cmd = input("Enter command or 'exit':") + '\r\n'
...
ser.write(cmd.encode()) PS: cmd.encode('ascii') + b'13' + b'10' is wrong.
You have following possibilities:
your_str.encode() + b'\x0d' + b'\x0a'
your_str.encode() + bytes([13, 10])
your_str.encode() + bytes([0x0d, 0x0a])
or with a str:
end = '\x0d\x0a'
cmd.encode() + end.encode()
I think the best way is, to do all formatting and concatenation with strings and when you need them to send them as bytes, do it at this place directly without any additional stuff like concatenation.
|