0

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.

Tissi_2
  • 1
  • 5

2 Answers2

0

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.

Marcos G.
  • 3,371
  • 2
  • 8
  • 16
  • The problem is that I cannot connect to this port because the monitor loop is keeping the port in use. I would like to monitor any removal or reconnection of the usb cable AND simultaneously read the port when needed. – Tissi_2 Aug 02 '19 at 14:05
  • OK, I see what you mean, I'll modify my answer. – Marcos G. Aug 02 '19 at 16:12
0

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.

Buzby
  • 345
  • 1
  • 11
  • If I open up the serial monitor of the Arduino IDE, the data of the rfid card shows up when a card is read. The COM port is definitely COM3. And yes, I close the arduino IDE before using any python code. The port is blocked by the monitor loop. Maybe I need a complete new approach with other monitor loops. I probably should use windows events to let the com port open. – Tissi_2 Aug 02 '19 at 14:33