Magnus Bane
Magnus Bane

Reputation: 1

Can't connect Raspberry Pi Pico W to MQTT broker, not getting CONNACK

I am trying to connect a Raspberry Pi Pico W to a virtual machine which runs a MQTT broker and Node-RED server. MQTT broker is password protected. I added MQTT broker IP in the MQTT node on Node-RED and connection runs fine on Node-RED. I am trying to write a MicroPython script using Thonny on the Raspberry Pi Pico to publish a message to the server. I am not able to connect my device to the MQTT broker. It is not getting the CONNACK signal from the broker:

from mqtt_as import MQTTClient, config
import uasyncio as asyncio
import socket

# Local configuration
config['ssid'] = 'user'
config['wifi_pw'] = 'password'
config['server'] = '192.168.122.1'  # Change to suit e.g. 'iot.eclipse.org'

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('Nodered', 0)  # renew subscriptions

async def main(client):
    print("Hello")
    await client.connect()
    print("Hello")
    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('Nodered', 'hello there', qos = 0)
        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

mqtt_as Python code. Error:

MPY: soft reboot
Hello
Checking WiFi integrity.
Got reliable connection
Connecting to broker.
Traceback (most recent call last):
  File "<stdin>", line 38, in <module>
  File "uasyncio/core.py", line 1, in run
  File "uasyncio/core.py", line 1, in run_until_complete
  File "uasyncio/core.py", line 1, in run_until_complete
  File "<stdin>", line 22, in main
  File "/lib/mqtt_as.py", line 645, in connect
  File "/lib/mqtt_as.py", line 314, in _connect
  File "/lib/mqtt_as.py", line 213, in _as_read
OSError: (-1, 'Timeout on socket read')

Upvotes: 0

Views: 764

Answers (1)

hardillb
hardillb

Reputation: 59751

This is probably a routing a problem.

You have said that the broker is running in a VM and 192.168.122.x is the default IP address range assigned to VMs by Linux/LibVirt.

Given this the most likely cause is that the Pico W doesn't know how to read the VM. It will be getting an IP address from your local LAN, assuming this is a home network then this will be from the DHCP server on your router.

As part of the DHCP setup it will also be given a default route which again will be the router.

The problem is that the router doesn't know how to reach the VM because it only knows about the subnet it's assigned to the LAN, and all other traffic it will send out over the internet via your ISP.

You have 2 choices

  1. Setup a route on the router that sends all traffic to 192.168.122.x to the machine hosting the VM. You may also have to mess with the firewall/routes on the host machine to have it allow traffic
  2. Configure the VM to use a "bridged" network adaptor rather than "NAT" interface, this should mean that the VM will get a IP address from the router via DHCP and appear to be directly connected to the LAN.

Option 2 is probably best for this.

Upvotes: 0

Related Questions