Help Needed: RFID Reader Timeout When Adding Wi-Fi and MQTT Code on M5Stack with MicroPython
-
Hi everyone,
I'm working on a project using the M5 Dial with MicroPython and UIFlow 2.0, and I'm encountering an issue where adding Wi-Fi and MQTT code causes my RFID reader to timeout and throw exceptions. When I run the RFID code alone, it works perfectly, but when I include the Wi-Fi connection and MQTT functionalities, the RFID reader starts experiencing problems.
Problem Description:
-
RFID Reader Works Alone: The RFID reader functions correctly when running only the RFID-related code.
-
Issue When Adding Wi-Fi and MQTT: Including Wi-Fi connection code and MQTT client causes the RFID reader to throw timeout errors and sometimes leads to the device restarting.
-
Error Messages:
Exception during RFID operation: [Errno 116] ETIMEDOUT Traceback (most recent call last): File "<stdin>", line XX, in main_loop File "unit/rfid.py", line X, in is_new_card_present File "driver/mfrc522/__init__.py", line XXX, in picc_request_a ... (additional traceback lines) OSError: [Errno 116] ETIMEDOUT
What I'm Doing:
- RFID Reader: Reading RFID tags using the built-in RFID unit connected via the M5Stack PORT.B (I2C).
- Wi-Fi Connection: Connecting to a Wi-Fi network using the built-in Wi-Fi module.
- MQTT Client: Publishing and subscribing to topics using the
umqtt.simple
library. - Asynchronous Tasks: Using
uasyncio
to handle asynchronous operations, including reading RFID tags and maintaining MQTT connections.
Code Snippets:
Here are the relevant parts of my code:
-
RFID Reading Loop:
async def main_loop(): global rfid while True: try: if rfid: # Attempt to detect a card card_present = rfid.is_new_card_present() if card_present: # Read card UID card_uid = rfid.read_card_uid() # Process the card UID else: print("RFID object is None, attempting to reinitialize") try: rfid = RFID() print("RFID reinitialized") except Exception as e: print(f"Error reinitializing RFID: {e}") except Exception as e: print(f"Exception in main_loop: {e}") await asyncio.sleep(0.1)
-
Wi-Fi Connection Function:
async def connect_wifi(): global wlan wlan = network.WLAN(network.STA_IF) wlan.active(True) await asyncio.sleep(1) wlan.connect('Your_SSID', 'Your_Password') while not wlan.isconnected(): print('Waiting for Wi-Fi connection...') await asyncio.sleep(1) print('Wi-Fi Connected')
-
MQTT Connection Function:
async def connect_mqtt(): global mqtt_client mqtt_client = MQTTClient('client_id', MQTT_BROKER, port=MQTT_PORT, user=MQTT_USER, password=MQTT_PASSWORD) mqtt_client.connect() print('MQTT Connected')
-
Initialization Function:
async def setup(): global rfid M5.begin() # Initialize RFID try: rfid = RFID() print("RFID initialized") except Exception as e: print(f"Error initializing RFID: {e}") rfid = None # Connect to Wi-Fi await connect_wifi() # Connect to MQTT await connect_mqtt()
Observations:
- Possible Resource Conflict: I suspect there might be a resource conflict between the RFID reader and the Wi-Fi module when both are active.
- Task Scheduling Issues: The asynchronous tasks for Wi-Fi, MQTT, and RFID might be interfering with each other, causing timeouts in RFID operations.
- RFID Timeout Only When Wi-Fi and MQTT Are Active: If I remove the Wi-Fi and MQTT code, the RFID reader works without any issues.
What I've Tried:
-
Using Asyncio Locks: Implemented
asyncio.Lock()
around hardware access code to prevent resource conflicts.# Initialize a lock lock = asyncio.Lock() # In RFID operation async with lock: # RFID read code # In Wi-Fi and MQTT operations async with lock: # Wi-Fi and MQTT code
-
Adjusting Task Frequencies: Increased sleep durations in non-critical tasks to reduce CPU load and potential interference.
-
Ensuring Proper Initialization: Made sure all variables and hardware components are properly initialized and declared as global where necessary.
-
Simplifying the Code: Tested the code by removing the Wi-Fi signal strength monitoring task, but the issue still persists when MQTT is active.
Questions:
-
Resource Contention: Could the RFID reader and Wi-Fi module be conflicting due to shared hardware resources? If so, how can I effectively manage this conflict?
-
Task Synchronization: Is there a recommended way to synchronize tasks involving RFID, Wi-Fi, and MQTT to prevent interference?
-
Hardware Limitations: Are there known limitations with the M5Stack Core2 when using RFID and Wi-Fi/MQTT simultaneously?
-
Alternative Approaches: Suggest some other methods to handle such scnarios
Additional Information:
- Device: M5Stack Core2
- Programming Language: MicroPython
- RFID Reader Connection: Built-in RFID unit connected via I2C (PORT.B)
- Wi-Fi Module: Built-in Wi-Fi module
- MQTT Library: Using
umqtt.simple
- Asyncio Version: Using
uasyncio
for asynchronous operations
Any insights or suggestions would be greatly appreciated! I'm looking for guidance on how to resolve this issue so that I can use RFID, Wi-Fi, and MQTT together without conflicts.
Thank you!
-
-
Hello @edraak
I am confused about whether you are using an M5Core2 or an M5Dial. Could you please clarify?
Also it would help if you could share your complete program in the UIFlow2 Project Zone.
Thanks
Felix -
@felmue
Hi, Apologies for confusion I am using m5 dial
and below is the link of my codehttps://uiflow2.m5stack.com/?pkey=7b06b0d459f14c8ab16e70d5b073bf76
-
Hi @edraak
I am running your code with
test.mosquitto.org
as MQTT broker; but so far I was not able to break it, e.g. no ETIMEDOUT error so far.Thanks
Felix -
Hello @edraak
one thing I would change. After
card_uid = rfid.read_card_uid()
check for read being successful: e.g.if card_uid != None:
Thanks
Felix -
This error occurs inconsistently—sometimes very frequently, and other times, it only happens after 4,000 or 5,000 scans. In some cases, I encounter the issue after just 20 scans.