Skip to content

Commit c80026d

Browse files
Add UDP transmitter example (#306)
Co-authored-by: Andrew McDonnell <[email protected]>
1 parent 5bb4f7f commit c80026d

File tree

5 files changed

+125
-0
lines changed

5 files changed

+125
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ App|Description
122122
[picow_tcp_client](pico_w/tcp_client)| A simple TCP client. You can run [python_test_tcp_server.py](pico_w/python_test_tcp/python_test_tcp_server.py) for it to connect to.
123123
[picow_tcp_server](pico_w/tcp_server)| A simple TCP server. You can use [python_test_tcp_client.py](pico_w/python_test_tcp/python_test_tcp_client.py) to connect to it.
124124
[picow_wifi_scan](pico_w/wifi_scan)| Scans for WiFi networks and prints the results.
125+
[picow_udp_beacon](pico_w/udp_beacon)| A simple UDP transmitter.
125126

126127
#### FreeRTOS examples
127128

pico_w/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ if (PICO_CYW43_SUPPORTED) # set by PICO_BOARD=pico_w
3232
add_subdirectory(tcp_client)
3333
add_subdirectory(tcp_server)
3434
add_subdirectory(freertos)
35+
add_subdirectory(udp_beacon)
3536
endif()
3637
endif()
3738
endif()

pico_w/udp_beacon/CMakeLists.txt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
add_executable(picow_udp_beacon_background
2+
picow_udp_beacon.c
3+
)
4+
target_compile_definitions(picow_udp_beacon_background PRIVATE
5+
WIFI_SSID=\"${WIFI_SSID}\"
6+
WIFI_PASSWORD=\"${WIFI_PASSWORD}\"
7+
)
8+
target_include_directories(picow_udp_beacon_background PRIVATE
9+
${CMAKE_CURRENT_LIST_DIR}
10+
${CMAKE_CURRENT_LIST_DIR}/.. # for our common lwipopts
11+
)
12+
target_link_libraries(picow_udp_beacon_background
13+
pico_cyw43_arch_lwip_threadsafe_background
14+
pico_stdlib
15+
)
16+
17+
pico_add_extra_outputs(picow_udp_beacon_background)
18+
19+
add_executable(picow_udp_beacon_poll
20+
picow_udp_beacon.c
21+
)
22+
target_compile_definitions(picow_udp_beacon_poll PRIVATE
23+
WIFI_SSID=\"${WIFI_SSID}\"
24+
WIFI_PASSWORD=\"${WIFI_PASSWORD}\"
25+
)
26+
target_include_directories(picow_udp_beacon_poll PRIVATE
27+
${CMAKE_CURRENT_LIST_DIR}
28+
${CMAKE_CURRENT_LIST_DIR}/.. # for our common lwipopts
29+
)
30+
target_link_libraries(picow_udp_beacon_poll
31+
pico_cyw43_arch_lwip_poll
32+
pico_stdlib
33+
)
34+
pico_add_extra_outputs(picow_udp_beacon_poll)

pico_w/udp_beacon/lwipopts.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef _LWIPOPTS_H
2+
#define _LWIPOPTS_H
3+
4+
// Generally you would define your own explicit list of lwIP options
5+
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html)
6+
//
7+
// This example uses a common include to avoid repetition
8+
#include "lwipopts_examples_common.h"
9+
10+
#endif

pico_w/udp_beacon/picow_udp_beacon.c

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/**
2+
* Copyright (c) 2022 Andrew McDonnell
3+
*
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
*/
6+
7+
#include <string.h>
8+
#include <stdlib.h>
9+
10+
#include "pico/stdlib.h"
11+
#include "pico/cyw43_arch.h"
12+
13+
#include "lwip/pbuf.h"
14+
#include "lwip/udp.h"
15+
16+
#define UDP_PORT 4444
17+
#define BEACON_MSG_LEN_MAX 127
18+
#define BEACON_TARGET "255.255.255.255"
19+
#define BEACON_INTERVAL_MS 1000
20+
21+
void run_udp_beacon() {
22+
struct udp_pcb* pcb = udp_new();
23+
24+
ip_addr_t addr;
25+
ipaddr_aton(BEACON_TARGET, &addr);
26+
27+
int counter = 0;
28+
while (true) {
29+
struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, BEACON_MSG_LEN_MAX+1, PBUF_RAM);
30+
char *req = (char *)p->payload;
31+
memset(req, 0, BEACON_MSG_LEN_MAX+1);
32+
snprintf(req, BEACON_MSG_LEN_MAX, "%d\n", counter);
33+
err_t er = udp_sendto(pcb, p, &addr, UDP_PORT);
34+
pbuf_free(p);
35+
if (er != ERR_OK) {
36+
printf("Failed to send UDP packet! error=%d", er);
37+
} else {
38+
printf("Sent packet %d\n", counter);
39+
counter++;
40+
}
41+
42+
// Note in practice for this simple UDP transmitter,
43+
// the end result for both background and poll is the same
44+
45+
#if PICO_CYW43_ARCH_POLL
46+
// if you are using pico_cyw43_arch_poll, then you must poll periodically from your
47+
// main loop (not from a timer) to check for WiFi driver or lwIP work that needs to be done.
48+
cyw43_arch_poll();
49+
sleep_ms(BEACON_INTERVAL_MS);
50+
#else
51+
// if you are not using pico_cyw43_arch_poll, then WiFI driver and lwIP work
52+
// is done via interrupt in the background. This sleep is just an example of some (blocking)
53+
// work you might be doing.
54+
sleep_ms(BEACON_INTERVAL_MS);
55+
#endif
56+
}
57+
}
58+
59+
int main() {
60+
stdio_init_all();
61+
62+
if (cyw43_arch_init()) {
63+
printf("failed to initialise\n");
64+
return 1;
65+
}
66+
67+
cyw43_arch_enable_sta_mode();
68+
69+
printf("Connecting to WiFi...\n");
70+
if (cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASSWORD, CYW43_AUTH_WPA2_AES_PSK, 30000)) {
71+
printf("failed to connect.\n");
72+
return 1;
73+
} else {
74+
printf("Connected.\n");
75+
}
76+
run_udp_beacon();
77+
cyw43_arch_deinit();
78+
return 0;
79+
}

0 commit comments

Comments
 (0)