Master The Pico WiFi: UDP For Speed
Written by Harry Fairhead & Mike James   
Monday, 27 November 2023
Article Index
Master The Pico WiFi: UDP For Speed
Sending data

To send data we need to use a PBUF of the correct type and size and store the data in its payload field:

char message[] = "Hello UDP World";
struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, 
                           strlen(message)+1, PBUF_RAM);
snprintf(p->payload, strlen(message)+1, "%s", message);

There are many ways of transferring the data into the payload field but using snprint has the advantage of being able to incorporate data from different sources.

Finally we can send the datagram:

err_t er = udp_send(pcb, p); 
pbuf_free(p);

Notice that we have to free the PBUF and you cannot reuse it to send another payload as it has been replaced by the UDP packet that has been sent.

The complete program is:

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/pbuf.h"
#include "lwip/udp.h"
#include "setupWifi.h"
int main()
{
    stdio_init_all();
    connect();
    struct udp_pcb *pcb = udp_new();
    udp_bind(pcb, IP_ADDR_ANY, 8080);
    ip_addr_t ip;
    IP4_ADDR(&ip, 192, 168, 11, 101);
    udp_connect(pcb, &ip, 8080);
    char message[] = "Hello UDP World";
    struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, 
                       strlen(message) + 1, PBUF_RAM);
snprintf(p->payload, strlen(message) + 1,
"%s", message);
err_t er = udp_send(pcb, p); pbuf_free(p); while (true) { sleep_ms(500); } }

The lwipopts.h and CmakeLists.txt file are the very simplest. The define:

#define LWIP_UDP 1

has to be included in lwipopts.h for the UDP library to be compiled but this is in the default lwipopts.h file from the Pico examples.

There is also a

udp_sendto(pcb,p,ip,port)

function which can be used to send a packet to the machine specified by ip and port without making any changes to the PCB.

There is one special use of UDP, DHCP (Dynamic Host Configuration Protocol), which requires sending a datagram to a machine even though the current network connection doesn’t yet have an IP address of its own. To do this you can use the two special functions:

udp_sendto_if(pcb,p,dst_ip,dst_port,netif)	

and

udp_sendto_if_src(pcb,p,dst_ip,dst_port,netif,	src_ip)	

These send a datagram to the destination ip and port number using the netif interface. The second function also includes the specified source ip address in the datagram even though the interface might not have an IP address yet.

Notice that you can have multiple PCBs active at any given time and can use any of them to send a UDP packet to a given IP address and port. The PCBs are managed in a linked list and you can use:

udp_remove(pcb)

to remove, and hence effectively deactivate and free, the pcb.

picomaster180

A Python UDP Client

It can be difficult to test UDP programs without a suitable client or server to connect to. Using Python it is very easy to create a UDP client which can be used to test UDP servers:

import asyncio
class ClientDatagramProtocol(asyncio.DatagramProtocol):
    def datagram_received(self, data, addr):
        message = data.decode("utf8")
        print("Received",message,"from", addr)
async def main():
    loop = asyncio.get_running_loop()
    transport, protocol = 
await loop.create_datagram_endpoint( lambda: ClientDatagramProtocol(), local_addr=('0.0.0.0', 8080)) await asyncio.sleep(100000) transport.close() asyncio.run(main())

If you want to know more this program is from Programmer’s Python: Async by Mike James, ISBN: 978-1871962595.

In chapter but not in this extract

  • UDPLite
  • Broadcast UDP
  • A UDP Client
  • A Custom Python UDP Server
  • Polling UDP

 Summary

  • UDP is a lightweight protocol that can be used to exchange data between two machines.

  • The sending machine specifies the address of the receiving machine and a port number.

  • The receiving machine specifies the address and port number it wants to receive data from.

  • UDP doesn’t offer error correction or confirmation of receipt. Essentially packets or datagrams are sent into the network for other machines to pick up and if they are lost on the way that’s something that has to be accommodated.

  • There is error detection in the form of a checksum. Any datagram that has an error is automatically discarded.

  • Implementing a UDP client or server follows the same lines as the use of TCP.

  • There is a UDPLite protocol which allows you to ignore any errors in the data detected by the checksum.

  • Datagrams can be broadcast to every machine on the local network but only using IPv4.

Master the Raspberry Pi Pico in C:
WiFiwith lwIP & mbedtls

By Harry Fairhead & Mike James

picomaster360

Buy from Amazon.

Contents

       Preface

  1. The Pico WiFi Stack
  2. Introduction To TCP
          Extract:
    Simplest HTTP Client
  3. More Advanced TCP
  4. SSL/TLS and HTTPS
          Extract:
    Simplest HTTPS Client
  5. Details of Cryptography
          Extract:
    Random Numbers
  6. Servers
          Extract: HTTP Server NEW!!
  7. UDP For Speed
          Extract: 
    Basic UDP
  8. SNTP For Time-Keeping
  9. SMTP For Email
  10. MQTT For The IoT

    Appendix 1 Getting Started In C

<ASIN:B0C247QJLK>

 

espbook

 

Comments




or email your comment to: comments@i-programmer.info

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.



Last Updated ( Monday, 27 November 2023 )