MiniMQTT on RPi Pico

CircuitPython on hardware including Adafruit's boards, and CircuitPython libraries using Blinka on host computers.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
ilikecake
 
Posts: 15
Joined: Thu Dec 19, 2019 12:30 am

MiniMQTT on RPi Pico

Post by ilikecake »

Hi All,

I am having trouble using MiniMQTT with a new Raspberry Pi Pico. To start, I followed this guide here. I installed CircuitPython (8.0.0, beta 4) and was able to set up the Pi to connect to my local wifi network and ping google.com as shown in the guide.

I then switched over to this guide to set up the MQTT client and connect. This is where I run into trouble. The code I am running is:

Code: Select all

# SPDX-FileCopyrightText: 2022 Liz Clark for Adafruit Industries
#
# SPDX-License-Identifier: MIT

import time
import ssl
import os
import ipaddress
import wifi
import socketpool
import adafruit_minimqtt.adafruit_minimqtt as MQTT

print()
print("Connecting to WiFi")

#  connect to your SSID
wifi.radio.connect(os.getenv('WIFI_SSID'), os.getenv('WIFI_PASSWORD'))

print("Connected to WiFi")

pool = socketpool.SocketPool(wifi.radio)

#  prints MAC address to REPL
print("My MAC addr:", [hex(i) for i in wifi.radio.mac_address])

#  prints IP address to REPL
print("My IP address is", wifi.radio.ipv4_address)

mqtt_topic = "home/CO2_val"

# Define callback methods which are called when events occur
# pylint: disable=unused-argument, redefined-outer-name
def connected(client, userdata, flags, rc):
    # This function will be called when the client is connected
    # successfully to the broker.
    print("Connected")
    # Subscribe to all changes on the onoff_feed.
    #client.subscribe(onoff_feed)


def disconnected(client, userdata, rc):
    # This method is called when the client is disconnected
    print("Disconnected")


def message(client, topic, message):
    # This method is called when a topic the client is subscribed to
    # has a new message.
    print("New message on topic {0}: {1}".format(topic, message))


# Create a socket pool
pool = socketpool.SocketPool(wifi.radio)

# Set up a MiniMQTT Client
mqtt_client = MQTT.MQTT(
    broker=os.getenv('homeassistant_IP'),
    port=int(os.getenv('homeassistant_port')),
    username=os.getenv('homeassistant_uname'),
    password=os.getenv('homeassistant_passwd'),
    socket_pool=pool,
    ssl_context=ssl.create_default_context(),
)
    

# Setup the callback methods above
mqtt_client.on_connect = connected
mqtt_client.on_disconnect = disconnected
mqtt_client.on_message = message

# Connect the client to the MQTT broker.
MQTT_Connected = False
print("Connecting to MQTT broker")
mqtt_client.connect()
#try:
#    mqtt_client.connect()
#    MQTT_Connected = True
#except:
#    print("Failed to connect")
#    MQTT_Connected = False

TestVal = 0

while True:
    # Poll the message queue
    if MQTT_Connected:
        mqtt_client.loop()

        # Send a new message
        print("Sending value: %d..." % TestVal)
        mqtt_client.publish('home/CO2_val', TestVal)
        print("Sent!")
        TestVal += 1
    else:
        print("Nothing to do...")
    time.sleep(5)

This code fails when trying to connect to the MQTT broker:

Code: Select all

]0;🐍code.py | 8.0.0-beta.4\
Connecting to WiFi
Connected to WiFi
My MAC addr: ['0x28', '0xcd', '0xc1', '0x6', '0x49', '0x5d']
My IP address is 192.168.2.36
Connecting to MQTT broker
Traceback (most recent call last):
  File "code.py", line 74, in <module>
  File "/lib/adafruit_minimqtt/adafruit_minimqtt.py", line 544, in connect
  File "/lib/adafruit_minimqtt/adafruit_minimqtt.py", line 930, in _wait_for_msg
  File "/lib/adafruit_minimqtt/adafruit_minimqtt.py", line 982, in _sock_exact_recv
MemoryError: memory allocation failed, allocating 4294955020 bytes
]0;🐍982@/lib/adafruit_minimqtt/adafruit_ MemoryError | 8.0.0-beta.4\
Code done running.

Press any key to enter the REPL. Use CTRL-D to reload.
That memory allocation error is so large that I assume there is a problem somewhere in the code (as opposed to the uC not having enough memory to run MicroMQTT). Poking a bit deeper into the MiniMQTT library, I find the _sock_exact_recv function is being fed a buffer size, and is trying to allocate a chunk of memory for it. This is where the actual failure occurs

Image

However, this does not appear to be where the problem lies, Instead, I assume that this function should not be sent an unreasonably large buffer size. Looking at the calling function, we see the variable 'sz' is sent to that function. Adding a few debug lines to the code shows the problem:

Image

At this point, I am sorta stuck. It looks like the code is trying to read a length from the server, receiving back a zero response, and then using that to feed a negative buffer size to the receive function. Did I mess up my code?

User avatar
tannewt
 
Posts: 3298
Joined: Thu Oct 06, 2016 8:48 pm

Re: MiniMQTT on RPi Pico

Post by tannewt »

Looks like you've done some good debugging! I'd suggest posting an issue on the library's github repo. That'll make it easier for library developers to find. The repo is here: https://github.com/adafruit/Adafruit_Ci ... QTT/issues

Locked
Please be positive and constructive with your questions and comments.

Return to “Adafruit CircuitPython”