Issues with combining micropython-async (Encoder) and mqtt_as #15281
-
I am starting to build a basic IoT device and experimenting with mqtt_as and micropython-async (Encoder / Pushbutton drivers) to provide the basic functionality. As a test I have combined the basic examples for each library so that when a button is pressed or the encoder value changes it will publish a MQTT message. Everything works as expected for the Pushbutton, however, when the encoder callback function is triggered nothing happens. This seems to be related to the Any input would be gratefully received :) The test code is shown below (minus the MQTT config) from mqtt_as import MQTTClient, config
import asyncio
from machine import Pin
from primitives import Encoder, Pushbutton
def local_input(data1, data2):
print ('****', data1, data2)
await client.publish('Result', '{}'.format(data1), qos = 0)
px = Pin(2, Pin.IN, Pin.PULL_UP) # Change to match hardware
py = Pin(3, Pin.IN, Pin.PULL_UP)
sw = Pushbutton(Pin(4), Pin.IN, Pin.PULL_UP)
enc = Encoder(px, py, div=4, callback=local_input) # div mtches mechanical detents
sw.press_func(local_input, (4,'Test'))
async def messages(client): # Respond to incoming messages
async for topic, msg, retained in client.queue:
print((topic, msg, retained))
async def up(client): # Respond to connectivity being (re)established
while True:
await client.up.wait() # Wait on an Event
client.up.clear()
await client.subscribe('foo_topic', 1) # renew subscriptions
async def main(client):
await client.connect()
for coroutine in (up, messages):
asyncio.create_task(coroutine(client))
n = 0
while True:
await asyncio.sleep(5)
print('publish', n)
# If WiFi is down the following will pause for the duration.
await client.publish('result', '{}'.format(n), qos = 1)
n += 1
config["queue_len"] = 1 # Use event interface with default queue size
MQTTClient.DEBUG = True # Optional: print diagnostic messages
client = MQTTClient(config)
try:
asyncio.run(main(client))
finally:
client.close() # Prevent LmacRxBlk:1 errors |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Hello, There are two possible approaches to fix this: Use a callback for publish: `def local_input(data1, data2, publish_callback): rest of your code def publish_message(topic, message, qos): enc = Encoder(px, py, div=4, callback=lambda d1, d2: local_input(d1, d2, publish_message)) `async def publish_message(topic, message, qos): def local_input(data1, data2): rest of your code |
Beta Was this translation helpful? Give feedback.
Hello,
There are two possible approaches to fix this:
Use a callback for publish:
Instead of using await, modify the local_input function to take a callback function as an argument. This callback can be called after the publishing is complete (if the library supports it). Here's an example:
`def local_input(data1, data2, publish_callback):
print ('****', data1, data2)
Call publish in a separate thread or use a callback if supported
publish_callback healthinsurancemarket ('Result', '{}'.format(data1), qos = 0)
rest of your code
def publish_message(topic, message, qos):
client.publish(topic, message, qos)
Handle any errors here
enc = Encoder(px, py, div=4, callback=lambda d1, d2: local_inpu…