Opening serial ports, Pyserial - python

I'd like to connect with Lake Shore Temperature Controler M331 via RS232, and I've got a little problem with that. When i give a "command" it still waits for another one instead of sending it to my device. Here is my code:
import serial
import time
port = serial.Serial(15)
print "Opening serial port: " + port.name
out = []
command = raw_input('Command: ')
if command == 'exit':
port.close()
exit()
else:
port.write(command)
time.sleep(1)
out.append(port.read(8))
if len(out) == 0:
print ':('
else:
print out
port.close()
What is wrong with my code?

found it sorry for interrupting ;) there should be:
port.write(command +'\r')

Related

Unable to read from serial in c#, but works in python

I am unable to read from serial port in C#, all of the settings are matching (baud, sbit etc...), the code actually sends the SCPI code to my gadget, but it is not responding (the gadget).
I have a very similar code in Python 3.7 and that is working correctly, with the same gadget and with every other.
So this is the C# code:
SerialPort com = new SerialPort("COM22",9600,Parity.Even,7,StopBits.Two);
com.Open();
Thread.Sleep(100);
com.DiscardOutBuffer();
com.DiscardInBuffer();
Console.Write("SCPI: ");
string cmd = Console.ReadLine();
com.Write(cmd + "\n");
Thread.Sleep(2000);
string answ = com.ReadExisting();
Console.WriteLine("The answer "+answ);
com.Close();
Here in C# I have also tried ReadChar(), ReadByte() and ReadLine()...
And also I have tried to change HandShake.
And here goes the Python code:
import time
import serial
while 1:
try:
comPort = input("Insert COM port num to use: ")
ser = serial.Serial(
port='COM' + comPort,
baudrate=9600,
parity=serial.PARITY_EVEN,
stopbits=serial.STOPBITS_TWO,
bytesize=serial.SEVENBITS
) # serial port settings
ser.isOpen()
break
except Exception:
print("Bad COM port. Try again.")
print('Enter your commands below.\nInsert "exit" to leave the application.')
while 1:
cmd = input("Insert your command: ") # insert the commands
if cmd == 'exit':
ser.close()
exit()
else:
ser.write(str.encode(cmd + '\n')) # send the character to the device
out = " "
time.sleep(2) # wait one second before reading output (give device time to answer)
while ser.inWaiting() > 0:
out += ser.read(1).decode("ascii")
print(">>" + out) # output the answer
As you can see they are very similar, with the same waiting time...

Python Serial on Windows: USB monitor loop while reading serial information does not work

I have a website and an usb rfid reader. The python script monitors the usb connection to the rfid reader. If the reader is not connected at the beginning of the script, the content of the website swipes to the right and shows instructions to connect the usb cable of the rfid reader. If then connected, it swipes back to the left and shows the user to identify himself with a rfid card. The reader shall only begin to read the rfid data when a certain content is in the viewport. But I don't get to this step because the serial communication seems to be blocked.
import serial
import mysql.connector
import time
import datetime
from serial.tools import list_ports
from selenium import webdriver
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.common.keys import Keys
capabilities = webdriver.DesiredCapabilities().FIREFOX
capabilities["marionette"] = True
binary = FirefoxBinary('C:/Program Files/Mozilla Firefox/firefox.exe')
driver = webdriver.Firefox(firefox_binary=binary, capabilities=capabilities, executable_path="C:/Python37x64/geckodriver.exe")
# ------------------ USB monitorloop -------------------------------------
stop = 0
swipe = 0
driver.get('https://website.php')
while True:
try:
myports = [tuple(p) for p in list(serial.tools.list_ports.comports())]
arduino_port = [port for port in myports if 'COM3' in port ][0]
def check_presence(correct_port, interval=0.1):
global swipe
global stop
while True:
myports = [tuple(p) for p in list(serial.tools.list_ports.comports())]
if arduino_port not in myports:
stop = 1
swipe = swipe + 1
if swipe == 1:
print ("Arduino has been disconnected!")
driver.execute_script("$('.in_viewport,#usb_connect, #header_usb_connect').animate({ left: '+='+'100vw'});");
time.sleep(1.0)
else:
continue
else:
if swipe >= 1 and stop == 1:
swipe = 0
print ("Arduino connected!")
driver.execute_script("$('.in_viewport,#usb_connect, #header_usb_connect').animate({ left: '-='+'100vw'});");
time.sleep(1.0)
else:
continue
import threading
port_controller = threading.Thread(target=check_presence, args=(arduino_port, 0.5,))
port_controller.setDaemon(True)
port_controller.start()
break
except:
stop = 1
if swipe == 0:
print("Connect USB cable")
driver.execute_script("$('.in_viewport,#usb_connect, #header_usb_connect').animate({ left: '+='+'100vw'});");
time.sleep(1.0)
swipe = 1
continue
else:
time.sleep(1.0)
# --------- connecting to COM 3 and database -----------------------
device_port = 'COM3'
baud = 9600
while True:
try:
print ("Trying...",device_port)
connect_arduino = serial.Serial(device_port, baud)
print ("Successfully connected to",device_port)
print ("Try to connect to database")
db = mysql.connector.connect(host="",port="",user="",passwd="",db="")
print ("Successfully connected to database")
break
except mysql.connector.Error as err:
print("Something went wrong: {}".format(err))
print ("failed to connect to database")
time.sleep(1)
continue
# ------- reading the card identification number and current time -------------
while True:
try:
print ("Reading USB device")
rfid_data = connect_arduino.readline()
now = datetime.datetime.now()
print (rfid_data.decode('utf-8'),"read on", now.strftime("%d-%m-%Y"), "at", now.strftime("%H:%M:%S"))
time.sleep(2)
break
except:
time.sleep(2)
continue
I expected to be able to serial.readline() the rfid_data, but I think that the monitor loop is blocking the serial ports and the communication to the ports.
Sorry to throw in the basics here, but have you checked you can read the serial port with something else, say a terminal emulator?
I have had endless problems with serial ports, especially the USB versions. Either something else grabs the port when I don't want it to or something is misbehaving with mapping USB into a COM number. Sometimes you need something else to double check them.
I think your biggest issue is the break statement in your reading loop. It is working as intended and breaking the normal flow of the loop so you only call the serial port read function once.
One way to improve your loop is checking if the RX buffer is empty:
while True:
if connect_arduino.inWaiting() != 0:
print ("Reading USB device")
rfid_data = connect_arduino.readline()
now = datetime.datetime.now()
print (rfid_data.decode('utf-8'),"read on", now.strftime("%d-%m-%Y"), "at", now.strftime("%H:%M:%S"))
If you call readline() only when you're sure there will be data in the buffer and you know the RFID reader sends \r\n as a terminating character you are sure you will always read the tag.
EDIT: It seems what you want is to sniff on the port. You cannot keep the same port open from two different applications directly. If you are on Windows you can try this solution.

How can I get python to trigger a process based on an incoming string from serial listening?

Totally new to Python. Working with a Paspberry Pi and Rockblock 2 satellite SBD transceiver connected over FTDI cable. Have managed enough python code to listen to the rockblock to catch a SBDRING trigger. Once received I need it to recognise this so I can try to get it to take an action. My code here fails to trigger and just keeps listening. Is there some rule or reason I've not been able to find as to why the python equalto won't work on what is being listened to?
import time
import serial
port = "/dev/ttyUSB0"
ser = serial.Serial(port, baudrate=19200, timeout=5)
print "Starting monitor of '" + port + "'"
try:
ser.isOpen()
print(port + " is open")
except:
print("Error")
exit()
if(ser.isOpen()):
try:
while(1):
print(ser.readline())
if(ser.readline() == "SBDRING"):
print "Message detected!"
except Exception:
print("Error reading serial")
else:
print("Cannot open '" + port + "'")
Expected result: on display a new line ticks over every 5 seconds. When "SBDRING" appears it should be followed by "Message detected!" and carrying on.
Actual result: on display a new line ticks over every 5 seconds. When "SBDRING" appears it does not displays "Message detected!", just carries on.
I intend to replace the 'print "Message detected!"' part with a actual action once it functions.
Maybe the string you're expecting includes a terminating character like a CR or LF.
You should print what you get from the port and study its length.
Otherwise, you can loosen a bit your comparison, maybe something like:
if("SBDRING" in ser.readline()):
print "Message detected!"
EDIT: Looking at the manual, it seems the device terminates everything with "\r" so I guess you should manage with:
if(ser.readline() == "SBDRING\r"):
print "Message detected!"

Receiving "NO CARRIER" error while tring to make a call using GSM modem in Python

I want to make a call using my GSM modem. So I wrote the below program:
import time
import serial
recipient = "+98xxxxxxxxxx"
phone = serial.Serial("COM10", 115200, timeout=5)
try:
time.sleep(0.5)
phone.write(b'ATZ\r')
time.sleep(1)
phone.write(b'ATD"'+recipient.encode() +b'"\r')
while(1):
print(phone.readline())
time.sleep(0.5)
finally:
phone.close()
But when I run it I receive this output:
>>> ================================ RESTART ================================
>>>
b'ATZ\r\r\n'
b'OK\r\n'
b'ATDxxxxxxxxxx\r\r\n'
b'NO CARRIER\r\n'
What does this "NO CARRIER" error means?
Note that I can send SMS successfully.
This is the program that I use to send SMS:
import time
import serial
recipient = "+98xxxxxxxxxx"
message = "Test"
phone = serial.Serial("COM10", 115200, timeout=5)
try:
time.sleep(0.5)
phone.write(b'ATZ\r')
time.sleep(0.5)
phone.write(b'AT+CMGF=1\r')
time.sleep(0.5)
phone.write(b'AT+CMGS="' + recipient.encode() + b'"\r')
time.sleep(0.5)
phone.write(message.encode() + b"\r")
time.sleep(0.5)
phone.write(bytes([26]))
time.sleep(0.5)
finally:
phone.close()
I found the origin of the error :
The syntax is ATD+98xxxxxxxxxx; followed by terminating string. I was forgotten to put semicolon at the end after the number.
So I replace
phone.write(b'ATD"'+recipient.encode() +b'"\r')
with
phone.write(b'ATD"'+recipient.encode() +b';"\r')
And now it works fine.
Based on the brackets in this documents, I thought that using ";" is optional. But it seems that I was wrong.

esp8266 and cp2102 don't work with python serial

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.

Categories

Resources