avatarFerry Djaja

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

3932

Abstract

to Wi-Fi Access Points.</p><div id="dce3"><pre><span class="hljs-built_in">cyw43_arch_enable_sta_mode</span>();</pre></div><p id="9bf4">Attempt to establish a connection to the Wi-Fi access point using the provided parameters for the Wi-Fi SSID, password, and authorization type.</p><div id="7c8a"><pre><span class="hljs-keyword">if</span> (<span class="hljs-built_in">cyw43_arch_wifi_connect_timeout_ms</span>(WIFI_SSID, WIFI_PASSWORD, CYW43_AUTH_WPA2_AES_PSK, <span class="hljs-number">30000</span>)) { <span class="hljs-built_in">printf</span>(“failed to connect\n”); <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>; }</pre></div><p id="0178">Additionally, validate whether the provided IP address is a valid ASCII representation of an internet address and convert it to a binary address.</p><div id="641b"><pre><span class="hljs-type">ip_addr_t</span> addr; <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">ip4addr_aton</span>(“XX.XX”, &addr)) { <span class="hljs-built_in">printf</span>(“ip error\n”); <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>; }</pre></div><p id="f102">Create a new MQTT client instance.</p><div id="d161"><pre>mqtt->mqtt_client_inst = <span class="hljs-built_in">mqtt_client_new</span>();</pre></div><p id="4328">Set callback to handle incoming publish requests from server.</p><div id="451a"><pre><span class="hljs-built_in">mqtt_set_inpub_callback</span>(mqtt->mqtt_client_inst, mqtt_incoming_publish_cb, mqtt_incoming_data_cb, mqtt);</pre></div><p id="e1e2">The <code>mqtt_incoming_publish_cb</code> function is called whenever an incoming publish message is received by the MQTT client, while the <code>mqtt_incoming_data_cb</code> function is called when data related to the publish message is received.</p><div id="d648"><pre><span class="hljs-function"><span class="hljs-type">static</span> <span class="hljs-type">void</span> <span class="hljs-title">mqtt_incoming_publish_cb</span><span class="hljs-params">(<span class="hljs-type">void</span> arg, <span class="hljs-type">const</span> <span class="hljs-type">char</span> topic, <span class="hljs-type">u32_t</span> tot_len)</span> </span>{ MQTT_CLIENT_DATA_T mqtt_client = (MQTT_CLIENT_DATA_T)arg; <span class="hljs-built_in">strcpy</span>((<span class="hljs-type">char</span>)mqtt_client->topic, (<span class="hljs-type">char</span>)topic);

<span class="hljs-keyword">if</span> (<span class="hljs-built_in">strcmp</span>((<span class="hljs-type">const</span> <span class="hljs-type">char</span>)mqtt->topic, <span class="hljs-string">"stop"</span>) == <span class="hljs-number">0</span>) { <span class="hljs-built_in">printf</span>(<span class="hljs-string">"STOP\n"</span>); } <span class="hljs-keyword">if</span> (<span class="hljs-built_in">strcmp</span>((<span class="hljs-type">const</span> <span class="hljs-type">char</span>)mqtt->topic, <span class="hljs-string">"start"</span>) == <span class="hljs-number">0</span>) { <span class="hljs-built_in">printf</span>(<span class="hljs-string">"START\n"</span>); }

}</pre></div><div id="6cfb"><pre><span class="hljs-function"><span class="hljs-type">static</span> <span class="hljs-type">void</span> <span class="hljs-title">mqtt_incoming_data_cb</span><span class="hljs-params">(<span class="hljs-type">void</span> arg, <span class="hljs-type">const</span> <span class="hljs-type">u8_t</span> data, <span class="hljs-type">u16_t</span> len, <span class="hljs-type">u8_t</span> flags)</span> </span>{ <span class="hljs-built_in">printf</span>(<span class="hljs-string">"mqtt_incoming_data_cb\n"</span>); MQTT_CLIENT_DATA_T mqtt_client = (MQTT_CLIENT_DATA_T)arg; <span class="hljs-built_in">LWIP_UNUSED_ARG</span>(data); <span class="hljs-built_in">strncpy</span>((<span class="hljs-type">char</span>*)mqtt_client->data, (<span class="h

Options

ljs-type">char</span>*)data, len); }</pre></div><p id="db6a">Subsequently, to establish a connection to the MQTT server.</p><div id="58cc"><pre><span class="hljs-type">err_t</span> err = <span class="hljs-built_in">mqtt_client_connect</span>(mqtt->mqtt_client_inst, &addr, MQTT_PORT, &mqtt_connection_cb, mqtt, &mqtt->mqtt_client_info); <span class="hljs-keyword">if</span> (err != ERR_OK) { <span class="hljs-built_in">printf</span>(“connect error\n”); <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>; }</pre></div><p id="d583">Furthermore, an attempt is made to publish the message to the <code>pub_topic</code> topic.</p><div id="ee3e"><pre><span class="hljs-function"><span class="hljs-type">err_t</span> <span class="hljs-title">do_publish</span><span class="hljs-params">(<span class="hljs-type">mqtt_client_t</span> *client, <span class="hljs-type">void</span> *arg)</span> </span>{ <span class="hljs-type">const</span> <span class="hljs-type">char</span> pub_payload= “Picow MQTT”; <span class="hljs-type">err_t</span> err; <span class="hljs-type">u8_t</span> qos = <span class="hljs-number">2</span>; <span class="hljs-comment">/ 0 1 or 2, see MQTT specification /</span> <span class="hljs-type">u8_t</span> retain = <span class="hljs-number">0</span>; <span class="hljs-comment">/ No don’t retain such crappy payload… */</span> <span class="hljs-built_in">cyw43_arch_lwip_begin</span>(); err = <span class="hljs-built_in">mqtt_publish</span>(client, “pub_topic”, pub_payload, <span class="hljs-built_in">strlen</span>(pub_payload), qos, retain, mqtt_pub_request_cb, arg); <span class="hljs-built_in">cyw43_arch_lwip_end</span>(); <span class="hljs-keyword">if</span>(err != ERR_OK) { <span class="hljs-built_in">printf</span>(“Publish err: %d\n”, err); } <span class="hljs-keyword">return</span> err; }</pre></div><p id="63ad">Follow these steps to subscribe to topics:</p><div id="2d0e"><pre><span class="hljs-built_in">mqtt_sub_unsub</span>(client, “start”, <span class="hljs-number">0</span>, mqtt_request_cb, arg, <span class="hljs-number">1</span>); <span class="hljs-built_in">mqtt_sub_unsub</span>(client, “stop”, <span class="hljs-number">0</span>, mqtt_request_cb, arg, <span class="hljs-number">1</span>);</pre></div><p id="ba82">Build the program using CMake.</p><div id="1a00"><pre><span class="hljs-function"><span class="hljs-title">cmake</span></span> .. make -j4</pre></div><p id="7a7c">Then, copy the UF2 file to the Pico and let’s test it with Home Assistant.</p><p id="235b">The full code is provided below.</p><div id="cf00" class="link-block"> <a href="https://github.com/ferrygun/pico_mqtt"> <div> <div> <h2>GitHub - ferrygun/pico_mqtt: pico_mqtt</h2> <div><h3>You can't perform that action at this time. You signed in with another tab or window. You signed out in another tab or…</h3></div> <div><p>github.com</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/0*lHcFtNxfAs_RmmrL)"></div> </div> </div> </a> </div> <figure id="8cc0"> <div> <div> <img class="ratio" src="http://placehold.it/16x9"> <iframe class="" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FvbPJRM3AomE%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DvbPJRM3AomE&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FvbPJRM3AomE%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" allowfullscreen="" frameborder="0" height="480" width="854"> </div> </div> </figure></iframe></div></div></figure></article></body>

Raspberry Pico Wireless MQTT

This guide provides a simple approach to establishing an MQTT connection with lwIP library based on the lwIP MQTT client.

LwIP stands for Lightweight IP, and it is an open-source TCP/IP stack designed to be used in embedded systems with limited resources such as memory, processing power, and storage. LwIP provides a range of networking protocols and features that enable communication over the internet or other networks.

LwIP is commonly used in many embedded systems, such as network routers, industrial automation, IoT devices, and other similar applications. It is lightweight, efficient, and can be easily customized for specific applications.

Let’s get started !

An instance of MQTT client is instantiated, which is associated with the data structure MQTT_CLIENT_DATA_T.

mqtt=(MQTT_CLIENT_DATA_T*)calloc(1, sizeof(MQTT_CLIENT_DATA_T));
typedef struct MQTT_CLIENT_DATA_T {
 mqtt_client_t *mqtt_client_inst;
 struct mqtt_connect_client_info_t mqtt_client_info;
 uint8_t data[MQTT_OUTPUT_RINGBUF_SIZE];
 uint8_t topic[100];
 uint32_t len;
} MQTT_CLIENT_DATA_T;
struct mqtt_connect_client_info_t mqtt_client_info =
{
 “picow”,
 “mqtt_user”, /* user */
 “mqtt_password”, /* pass */
 0, /* keep alive */
 NULL, /* will_topic */
 NULL, /* will_msg */
 0, /* will_qos */
 0 /* will_retain */
#if LWIP_ALTCP && LWIP_ALTCP_TLS
 , NULL
#endif
};

To establish a connection to the Wi-Fi network, we initialize the cyw43_driver code and set up the lwIP stack.

if (cyw43_arch_init())
 {
 printf(“failed to initialise\n”);
 return 1;
 }

Next, we activate the Wi-Fi STA (Station) mode, which allows the device to connect to Wi-Fi Access Points.

cyw43_arch_enable_sta_mode();

Attempt to establish a connection to the Wi-Fi access point using the provided parameters for the Wi-Fi SSID, password, and authorization type.

if (cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASSWORD, CYW43_AUTH_WPA2_AES_PSK, 30000))
 {
 printf(“failed to connect\n”);
 return 1;
 }

Additionally, validate whether the provided IP address is a valid ASCII representation of an internet address and convert it to a binary address.

ip_addr_t addr;
 if (!ip4addr_aton(“XX.XX”, &addr)) {
 printf(“ip error\n”);
 return 0;
 }

Create a new MQTT client instance.

mqtt->mqtt_client_inst = mqtt_client_new();

Set callback to handle incoming publish requests from server.

mqtt_set_inpub_callback(mqtt->mqtt_client_inst, mqtt_incoming_publish_cb, mqtt_incoming_data_cb, mqtt);

The mqtt_incoming_publish_cb function is called whenever an incoming publish message is received by the MQTT client, while the mqtt_incoming_data_cb function is called when data related to the publish message is received.

static void mqtt_incoming_publish_cb(void *arg, const char *topic, u32_t tot_len) {
  MQTT_CLIENT_DATA_T* mqtt_client = (MQTT_CLIENT_DATA_T*)arg;
  strcpy((char*)mqtt_client->topic, (char*)topic);

  if (strcmp((const char*)mqtt->topic, "stop") == 0) {
    printf("STOP\n");
  }
  if (strcmp((const char*)mqtt->topic, "start") == 0) {
    printf("START\n");
  }

}
static void mqtt_incoming_data_cb(void *arg, const u8_t *data, u16_t len, u8_t flags) {
    printf("mqtt_incoming_data_cb\n");
    MQTT_CLIENT_DATA_T* mqtt_client = (MQTT_CLIENT_DATA_T*)arg;
    LWIP_UNUSED_ARG(data);
    strncpy((char*)mqtt_client->data, (char*)data, len);
}

Subsequently, to establish a connection to the MQTT server.

err_t err = mqtt_client_connect(mqtt->mqtt_client_inst, &addr, MQTT_PORT, &mqtt_connection_cb, mqtt, &mqtt->mqtt_client_info);
 if (err != ERR_OK) {
 printf(“connect error\n”);
 return 0;
 }

Furthermore, an attempt is made to publish the message to the pub_topic topic.

err_t do_publish(mqtt_client_t *client, void *arg)
{
 const char *pub_payload= “Picow MQTT”;
 err_t err;
 u8_t qos = 2; /* 0 1 or 2, see MQTT specification */
 u8_t retain = 0; /* No don’t retain such crappy payload… */
 cyw43_arch_lwip_begin();
 err = mqtt_publish(client, “pub_topic”, pub_payload, strlen(pub_payload), qos, retain, mqtt_pub_request_cb, arg);
 cyw43_arch_lwip_end();
 if(err != ERR_OK) {
 printf(“Publish err: %d\n”, err);
 }
 return err;
}

Follow these steps to subscribe to topics:

mqtt_sub_unsub(client, “start”, 0, mqtt_request_cb, arg, 1); 
mqtt_sub_unsub(client, “stop”, 0, mqtt_request_cb, arg, 1);

Build the program using CMake.

cmake ..
make -j4

Then, copy the UF2 file to the Pico and let’s test it with Home Assistant.

The full code is provided below.

Mqtt
Pico
Raspberry Pico
Raspberry Pi
Home Assistant
Recommended from ReadMedium