Chtěl jsem si vyzkoušet ethernetový modul WIZ850io a naprogramovat na Picu vestavěný http (https) server, což se elegantně podařilo na platformě Mongoose. Webový návrhář Mongoose slouží výborně k navržení designu vestavěného webu a programátor se nemusí příliš zabývat záludnostmi TC/IP stacku a programováním http. Navíc je toto řešení multiplatformní, dá se pomocí něj programovat jak pro Pico s ethernetovými kartami WS5500 a Wifi, tak i na úplně jiné vývojové desky s úplně jinými ethernety. Je to mnohem elegantnější, než řešení pomocí FreeRTOS a knihovny od Wiznetu, čímž jsem se zabýval v loňském roce.
Knihovna Mongoose a jejich webový návrhář podporuje mnoho vývojových desek jak s ethernetem, tak i s wifi kartou. Zde je přehled:
| Architektura | Deska | Připojení k síti |
|---|---|---|
STM32 |
Nucleo-F207ZG |
vestavěný ethernet |
STM32 |
Nucleo-F429ZI |
vestavěný ethernet |
STM32 |
Nucleo-F439ZI |
vestavěný ethernet |
STM32 |
Nucleo-F746ZG |
vestavěný ethernet |
STM32 |
Nucleo-F756ZG |
vestavěný ethernet |
STM32 |
Nucleo-F767ZI |
vestavěný ethernet |
STM32 |
Nucleo-H563ZI |
vestavěný ethernet |
STM32 |
Nucleo-H723ZG |
vestavěný ethernet |
STM32 |
Nucleo-H743ZI |
vestavěný ethernet |
STM32 |
Nucleo-H753ZI |
vestavěný ethernet |
STM32 |
Nucleo-H755ZI-Q |
vestavěný ethernet |
STM32 |
Nucleo-H7S3L8 |
vestavěný ethernet |
STM32 |
STM32H735G-DK |
vestavěný ethernet |
STM32 |
STM32H745I-DISCO |
vestavěný ethernet |
STM32 |
STM32H747I-DISCO |
vestavěný ethernet |
STM32 |
STM32H573I-DK |
vestavěný ethernet |
NXP |
Teensy4.1 |
vestavěný ethernet |
NXP |
RT1170-EVKB |
vestavěný ethernet |
NXP |
RT1020-EVK |
vestavěný ethernet |
NXP |
RT1024-EVK |
vestavěný ethernet |
NXP |
RT1040-EVK |
vestavěný ethernet |
NXP |
RT1050-EVKB |
vestavěný ethernet |
NXP |
RT1060-EVKB |
vestavěný ethernet |
NXP |
RT1064-EVK |
vestavěný ethernet |
NXP |
FRDM-MCXN947 |
vestavěný ethernet |
NXP |
FRDM-RW612 |
vestavěný ethernet |
Texas Instruments |
EK-TM4C1294XL |
vestavěný ethernet |
Texas Instruments |
TMS570 |
vestavěný ethernet |
Espressif |
ESP32, ESP32xx |
vestavěná wifi karta |
Infineon |
XMC4400 2Go |
vestavěný ethernet |
Infineon |
XMC4700 2Go |
vestavěný ethernet |
Infineon |
KIT_XMC72_EVK |
vestavěný ethernet |
Raspberry PI |
RP2040, RP2350 |
Wiznet W5500, W5100 ethernet |
Raspberry PI |
Pico-W, Pico2-W |
CYW43439 wifi karta |
Nordic |
nRF9160 Thingy:91 |
vestavěný mobil |
Renesas |
RA6M4 |
vestavěný ethernet |
Zephyr |
libovolná |
vestavěný ethernet |
Zephyr |
libovolná |
W5500 ethernet |
Arduino |
libovolná |
W5500 ethernet |
Arduino |
libovolná |
libovolná wifi (třeba ESP32) |
Windows |
— |
— |
Linux, MacOS |
— |
— |
Takže pokud se naučím programovat pomocí Mongoose na Picu, tak budu moci své znalosti používat i jinde.
Programování pomocí webového kouzelníka šetří mnoho práce a vygenerovaný kód je velmi pěkný. Knihovna umožňuje se soustředit na podstané (návrh webu a propojení) a spousta věcí, kterým nerozumíme a nevíme jak naprogramovat bude fungovat. Jediné, co jsem zatím nenašel je podpora protokolu IPv6.
Ethernetový modul WIZ850io
Ethernetový modul WIZ850io používá chip firmy Wiznet W5500, který se připojuje k Raspberry Pi Pico pomocí SPI sběrnice. Podle tabulky uvedené výše bude modul vyhovovat knihovně Mongoose.
-
Modul má v sobě "zadrátované" protokoly TCP, UDP, ICMP, IPv4, ARP, IGMP, PPPoE.
-
Umožňuje až používat až 8 socketů.
-
Umožňuje se uspat
-
Umožňuje Wake on LAN pomocí UDP
-
SPI sběrnice v režimu high speed
-
PHY umí ethernet 10BaseT a 100BaseTX
-
Automatické vyjednávání na ethernetu.
-
Neumí IP fragmentaci
-
Napájecí napětí 3.3V (vstupy tolerují 5V).
-
standarní LED k indikaci provozu a linky
-
Modul neumí IPv6 a související protokoly.


| WIZ850io pin | Pico fyzický pin |
|---|---|
GND |
pin 38 |
3.3V |
pin 36 |
MOSI |
pin 25 (GP19) |
SCLK |
pin 24 (GP18) |
SCNn |
pin 22 (GP17) |
MISO |
pin 21 (GP16) |



Programování
Na GPIO2, GPIO3 a GPIO4 jsem si zapojil 3 LED, které chci dálkově ovládat pomocí webu.
Nejprve si navrhneme v internetovém prohlížeči web pomocí kouzelníka Mongoose Wizard.
Nastavení projektu
Na našem stroji si vytvoříme adresář (já jsem si udělal ~/mw5500).
Klikneme na tlačítko New a vytvoříme nový C/C++ projekt:

a stikneme tlačítko next.
Destination directory nastavíme na lokální adresář ~/mw5500, Target architecture nastavíme na
RP2040 (M0+ @ 133MHz x2, 264K RAM, 2048 Flash) + W5500 a Build environment/IDE na Pico-SDK.
Pokud se nás bude internetový prohlížeč ptát, zda může zapisovat do adresáře ~/mw5500, tak mu to povolíme.

a stiskneme next.
Vyberem si Single LED toggle šablonu a stikneme next

Tím je nastavení projektu prakticky dokončeno. (Můžeme ho kdykoliv změnit). Stikneme finish.

Návrh webového rozhraní
Nyní máme před sebou návrhář webu. Zde můžeme náš web libovolně upravovat.

Já změním popisky a přidám další dvě LED, jde to téměř intuitivně, ale velmi špatně se to zachycuje do článku. Doporučuji shlédnou úvodní video "LED toggle dashboard" na stránce Mongoose a pochopíte celý proces.
Zkopíruji si LED1 a změním jak popisku, tak i jméno prvku. Prvky se budou jmenovat leds.led1, leds.led2 a leds.led3
V REST API přidám endpoint leds typu data a přidám atributy led1, led2 a led3 typu bool s počáteční hodnotou false.

Nyní v Page content nastavím u prvků toggle jména API proměnných leds.led1, leds.led2 a leds.led3.

Toto mi ve výsledku vytvoří C strukturu, kde budou uloženy stavy jednotlivých LED:
struct leds {
bool led1,
bool led2,
bool led3
}
static struct leds s_leds = {false, false, false};
Nyní již jenom dokončím návrh webu. Změním název na Řídící panel, naimportuji do návrháře SVG soubor s logem a změním Toolbar text na Pico konzole.

Teď už jenom stačí vygenerovat céčkový kód, který se nahraje do lokálního adresáře ~/mw5500. Stisknu tlačítko Generate C/C++ code.
V adresáři ~/mw5500 máme vygenerované soubory:
jirka@pt3610:~/mw5500$
jirka@pt3610:~/mw5500$ ls -l
celkem 15
-rw------- 1 jirka jirka 631 čec 19 17:30 CMakeLists.txt
-rw------- 1 jirka jirka 439 čec 19 17:30 hal.c
-rw------- 1 jirka jirka 1111 čec 19 17:30 hal.h
-rw------- 1 jirka jirka 969 čec 19 17:30 main.c
-rw------- 1 jirka jirka 766 čec 19 17:30 Makefile
drwx------ 2 jirka jirka 3452 čec 19 17:30 mongoose
-rw------- 1 jirka jirka 3775 čec 19 17:30 pico_sdk_import.cmake
-rw------- 1 jirka jirka 1951 čec 19 17:30 README.md
Přeložíme vygenerovaný kód:
jirka@pt3610:~$ cd ~/mw5500
jirka@pt3610:~/mw5500$ make
| Nemusíme mít ani nainstalované Pico-SDK, make si Pico-SDK v rámci sestavovaní nainstaluje samo. |
V adresáři ~/mw5500/build nalezneme výsledný produkt firmware.uf2, který standardním postupem nahrajeme na Pico.
jirka@pt3610:~/mw5500$ cd build/
jirka@pt3610:~/mw5500/build$ cp firmware.uf2 /media/jirka/RPI-RP2/
V minicomu (minicom -b 115200 -D /dev/ttyACM0) si můžeme prohlédnout, co prorgam dělá. Hlavně musíme zjistit, jakou IP adresu má náš webový řídící panel.
98d56 1 mongoose.c:4389:onstatechange Link down
98d57 1 mongoose.c:5159:mg_tcpip_poll Network is down
9913e 1 mongoose.c:5159:mg_tcpip_poll Network is down
99526 1 mongoose.c:4386:onstatechange Link up
9952e 3 mongoose.c:4499:tx_dhcp_discov DHCP discover sent. Our MAC: 02:60:4b:99:43:2a
3ef 1 mongoose.c:5159:mg_tcpip_poll Network is down
7d7 1 mongoose.c:4386:onstatechange Link up
7df 3 mongoose.c:4499:tx_dhcp_discov DHCP discover sent. Our MAC: 02:60:4b:99:43:2a
8c4 3 mongoose.c:5118:mg_tcpip_rx Unknown eth type 26
bc5 3 mongoose.c:4499:tx_dhcp_discov DHCP discover sent. Our MAC: 02:60:4b:99:43:2a
bd8 3 mongoose.c:4478:tx_dhcp_reques DHCP req sent
be3 2 mongoose.c:4621:rx_dhcp_client Lease: 3600 sec (3603)
be6 1 mongoose.c:4383:onstatechange Got IP
bf0 2 mongoose.c:4379:onstatechange READY, IP: 192.168.120.221
bf3 2 mongoose.c:4380:onstatechange GW: 192.168.120.1
bf9 2 mongoose.c:4381:onstatechange MAC: 02:60:4b:99:43:2a
1084 3 mongoose.c:5118:mg_tcpip_rx Unknown eth type 26
1844 3 mongoose.c:5118:mg_tcpip_rx Unknown eth type 26
2044 3 mongoose.c:5118:mg_tcpip_rx Unknown eth type 26
2804 3 mongoose.c:5118:mg_tcpip_rx Unknown eth type 26
2fc4 3 mongoose.c:5118:mg_tcpip_rx Unknown eth type 26
3784 3 mongoose.c:5118:mg_tcpip_rx Unknown eth type 26
3f84 3 mongoose.c:5118:mg_tcpip_rx Unknown eth type 26
442c 3 mongoose.c:5118:mg_tcpip_rx Unknown eth type 88cc
4744 3 mongoose.c:5118:mg_tcpip_rx Unknown eth type 26
4f04 3 mongoose.c:5118:mg_tcpip_rx Unknown eth type 26
Náš web má IP adresu 192.168.120.221, podíváme se na něj prohlížečem.

Teď nám to nebude ještě zcela fungovat, protože nemáme webové přepínače propojeny s příslušnými piny 3,4 a 5.
Jak to spravit se dozvíte dále.
Jak to celé funguje

Webový prohlížeč pošle HTTP požadavek na naše Pico GET /api/leds. Program v Picu se podívá do struktury struct leds tmp a snaží se přečíst pomocí funkce my_get_leds(&tmp); hodnoty jednotlivých pinů.
Potom odešle do prohlížeče JSON soubor:
{
"led1":false,
"led2":false,
"led3":false
}
Pokud chceme změnit stav některé LED, tak prohlížeč odešle HTTP požadavek:
POST {
"led1":true,
"led2":false,
"led3":false
}
což v Picu zavolá funkce:
struct leds tmp = {0};
parse_json(&tmp);
my_set_leds(&tmp);
Avšak funkce my_get_leds() a my_set_leds() nic nedělají (jsou prázdné), protože jsme je dosud nenaprogramovali.
Doprogramování ovládacích funkcí
Otevřeme soubor ~/mw5500/mongoose/mongoose_glue.c
// SPDX-FileCopyrightText: 2024 Cesanta Software Limited
// SPDX-License-Identifier: GPL-2.0-only or commercial
// Generated by Mongoose Wizard, https://mongoose.ws/wizard/
// Default mock implementation of the API callbacks
#include "mongoose_glue.h"
static struct leds s_leds = {false, false, false};
void glue_get_leds(struct leds *data) {
*data = s_leds; // Sync with your device
}
void glue_set_leds(struct leds *data) {
s_leds = *data; // Sync with your device
}
Tady vidíme funkce glue_get_leds a glue_set_leds, tyto funkce nedělají nic s piny.
Do souboru main.c musíme napsat implementaci funkcí my_get_leds() a my_set_leds() a nastavit ovladač mongoose_set_http_handlers() který propojí ovládací prvky s příslušnými piny a http serverem.
Dále je dobré udělat nějakou inicializaci pinů.
// SPDX-FileCopyrightText: 2024 Cesanta Software Limited
// SPDX-License-Identifier: GPL-2.0-only or commercial
// Generated by Mongoose Wizard, https://mongoose.ws/wizard/
// hal used to generate an address and adapt your particular hardware,
// as plain Picos don't have Ethernet nor Wi-Fi
#include "hal.h"
#include "mongoose_glue.h"
static void blink_timer(void *arg) {
(void) arg;
gpio_put(PICO_DEFAULT_LED_PIN, !gpio_get(PICO_DEFAULT_LED_PIN));
}
int main(void) {
stdio_init_all();
gpio_init(PICO_DEFAULT_LED_PIN); // Initialise GPIO
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT); // Set as output
gpio_put(PICO_DEFAULT_LED_PIN, 1);
ethernet_init(); // Initialise Ethernet pins
MG_INFO(("Hardware initialised, starting firmware..."));
// This blocks forever. Call it at the end of main()
mongoose_init();
mg_timer_add(&g_mgr, 1000, MG_TIMER_REPEAT, blink_timer, NULL);
for (;;) {
mongoose_poll();
}
return 0;
}
// SPDX-FileCopyrightText: 2024 Cesanta Software Limited
// SPDX-License-Identifier: GPL-2.0-only or commercial
// Generated by Mongoose Wizard, https://mongoose.ws/wizard/
// hal used to generate an address and adapt your particular hardware,
// as plain Picos don't have Ethernet nor Wi-Fi
#include "hal.h"
#include "mongoose_glue.h"
// piny s LED
#define MODRA_LED 3
#define CERVENA_LED 4
#define BILA_LED 5
static void blink_timer(void *arg) {
(void) arg;
gpio_put(PICO_DEFAULT_LED_PIN, !gpio_get(PICO_DEFAULT_LED_PIN));
}
// získání hodnot LED
void my_get_leds(struct leds *data) {
data->led1 = gpio_get(MODRA_LED);
data->led2 = gpio_get(CERVENA_LED);
data->led3 = gpio_get(BILA_LED);
}
//nastavení hodnot LED
void my_set_leds(struct leds *data) {
gpio_put(MODRA_LED, data->led1);
gpio_put(CERVENA_LED, data->led2);
gpio_put(BILA_LED, data->led3);
}
int main(void) {
stdio_init_all();
gpio_init(PICO_DEFAULT_LED_PIN); // Initialise GPIO
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT); // Set as output
gpio_put(PICO_DEFAULT_LED_PIN, 1);
gpio_set_function(23, GPIO_FUNC_SIO); // nastaveni PWM na malý šum
gpio_set_dir(23, true);
gpio_put(23,1);
// nastavení LED pinů a test funkce (po 500ms zhasneme)
gpio_set_function(MODRA_LED, GPIO_FUNC_SIO);
gpio_set_dir(MODRA_LED, true);
gpio_put(MODRA_LED,1);
gpio_set_function(CERVENA_LED, GPIO_FUNC_SIO);
gpio_set_dir(CERVENA_LED, true);
gpio_put(CERVENA_LED,1);
gpio_set_function(BILA_LED, GPIO_FUNC_SIO);
gpio_set_dir(BILA_LED, true);
gpio_put(BILA_LED,1);
sleep_ms(500);
gpio_put(MODRA_LED, 0);
gpio_put(CERVENA_LED, 0);
gpio_put(BILA_LED, 0);
ethernet_init(); // Initialise Ethernet pins
MG_INFO(("Hardware initialised, starting firmware..."));
// nastavení ovladače LED
mongoose_set_http_handlers("leds", my_get_leds, my_set_leds);
// This blocks forever. Call it at the end of main()
mongoose_init();
mg_timer_add(&g_mgr, 1000, MG_TIMER_REPEAT, blink_timer, NULL);
for (;;) {
mongoose_poll();
}
return 0;
}
Soubory main.c a mongoose/mongoose_glue.c uložíme a přeložíme celý projekt pomocí make.
Nahrajeme firmware na Pico a už to funguje.
Mohli bychom i upravit funkce glue_get_leds() a glue_set_leds() v souboru mongoose/mongoose_glue.c, ale pokud budeme dále upravovat projekt pomocí kouzelníka a uložíme ho, tak budou tento soubor přepsán. Proto je lepší dělat úpravy v main.c.
|
Hotový projekt je zde mw5500.tar.gz, je ale hodně velký: 399540660 bytů.
Uložení projektu
Celý projekt si můžeme uložit v kouzelníkovi stisknutím tlačítka Save, udělá se nám json soubor wizard.json
{
"version": "1.0.2",
"api": {
"leds": {
"type": "data",
"read_level": 0,
"write_level": 0,
"attributes": {
"led1": {"type": "bool", "value": false},
"led2": {"type": "bool", "value": false},
"led3": {"type": "bool", "value": false}
}
}
},
"ui": {
"production": false,
"brand": "Brand Name",
"logo": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!-- Created with Inkscape (http://www.inkscape.org/) -->\n\n<svg\n width=\"18.014mm\"\n height=\"6.0799999mm\"\n viewBox=\"0 0 18.014 6.0799999\"\n version=\"1.1\"\n id=\"svg5\"\n xml:space=\"preserve\"\n inkscape:version=\"1.2.2 (b0a8486541, 2022-12-01)\"\n sodipodi:docname=\"logo.svg\"\n xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:svg=\"http://www.w3.org/2000/svg\"><sodipodi:namedview\n id=\"namedview7\"\n pagecolor=\"#ffffff\"\n bordercolor=\"#666666\"\n borderopacity=\"1.0\"\n inkscape:showpageshadow=\"2\"\n inkscape:pageopacity=\"0.0\"\n inkscape:pagecheckerboard=\"0\"\n inkscape:deskcolor=\"#d1d1d1\"\n inkscape:document-units=\"mm\"\n showgrid=\"false\"\n inkscape:zoom=\"20.70196\"\n inkscape:cx=\"32.098411\"\n inkscape:cy=\"-1.1834628\"\n inkscape:window-width=\"2560\"\n inkscape:window-height=\"1368\"\n inkscape:window-x=\"0\"\n inkscape:window-y=\"0\"\n inkscape:window-maximized=\"1\"\n inkscape:current-layer=\"layer1\" /><defs\n id=\"defs2\" /><g\n inkscape:label=\"Vrstva 1\"\n inkscape:groupmode=\"layer\"\n id=\"layer1\"\n transform=\"translate(-38.629921,-152.15161)\"><path\n style=\"fill:#f7110b;stroke:none;stroke-width:0.0846667\"\n d=\"m 39.688255,152.68078 v 5.08 h 3.81 v -5.08 h -3.81 m 12.615333,3.21733 c 0.07908,1.52103 2.732955,1.89431 3.301238,0.50767 0.339598,-0.82858 -0.464199,-1.34767 -1.218579,-1.56105 -0.26416,-0.0747 -0.748634,-0.12626 -0.896885,-0.39663 -0.227076,-0.41415 0.916775,-0.43487 1.088902,-0.0916 l 0.942657,0.10224 c -0.04436,-1.49391 -2.808478,-1.6767 -3.098038,-0.254 -0.191516,0.9411 0.825246,1.19256 1.489287,1.4181 0.229362,0.0779 0.699535,0.11772 0.51039,0.44366 -0.349843,0.60302 -0.872933,-0.0455 -1.205334,-0.14151 -0.277368,-0.0801 -0.626872,-0.0269 -0.913638,-0.0269 m -11.006666,-2.53998 v 2.87867 c 0.459655,0 1.747011,0.0276 1.747011,0.0276 v 0.85033 c 0,0 -2.164774,-0.0713 -2.932345,0.004 v -3.76051 h 1.185334 m 2.539999,0 v 3.81 l 1.169676,-0.0123 c 0.02479,-1.26573 0.01566,-2.53174 0.01566,-3.79764 l -1.185336,-6e-5 m 1.947336,6e-5 1.130958,1.80855 -1.215625,1.91679 1.3298,0.0101 0.665783,-1.08756 c 0.236186,0.32305 0.520776,0.81194 0.744335,1.14373 0.422101,0.0101 0.844225,0.019 1.266353,0.0278 l -1.258411,-2.00552 1.041527,-1.84606 c -0.525466,-0.0274 -1.246937,0.004 -1.246937,0.004 0,0 -0.374663,0.73087 -0.546867,1.11318 l -0.676762,-1.10252 -1.234151,0.0171 m 5.672666,3.81 v -3.81 c -0.283633,0 -1.129704,-0.009 -1.129704,-0.009 -0.0041,1.26137 -1.93e-4,2.52461 0.0021,3.78621 0,0 0.843993,0.0326 1.127626,0.0326 z\"\n id=\"path490\"\n sodipodi:nodetypes=\"ccccccsssccsscscccccccccccccccccccccccccccccccc\" /><rect\n style=\"opacity:0.98;fill:none;fill-opacity:0.943343;stroke:#000000;stroke-width:0.0656969;stroke-linejoin:miter;stroke-miterlimit:11.5;stroke-dasharray:none\"\n id=\"rect595\"\n width=\"16.34374\"\n height=\"5.0793033\"\n x=\"39.688602\"\n y=\"152.68114\"\n rx=\"0.15227537\"\n ry=\"0.15227537\" /></g></svg>\n",
"toolbar": {
"label": "Pico konzole"
},
"theme": {
},
"pages": [
{"title": "Řídící panel", "icon": "desktop", "level": 0, "css": "padding: 0.75rem;\ngap: 0.5rem;\nmin-height: 2rem;\ndisplay: flex;\nflex-direction: column;\nflex-grow: 1;", "layout": [
{"classes": "container", "layout": [
{"classes": "panel", "css": "width: 14rem", "layout": [
{"classes": "title", "format": "Řízení LED"},
{"classes": "labeled", "layout": [
{"classes": "label", "format": "modrá LED"},
{"type": "toggle", "ref": "leds.led1", "autosave": true}
]},
{"classes": "labeled", "layout": [
{"classes": "label", "format": "červená LED"},
{"type": "toggle", "ref": "leds.led2", "autosave": true}
]},
{"classes": "labeled", "layout": [
{"classes": "label", "format": "bílá LED"},
{"type": "toggle", "ref": "leds.led3", "autosave": true}
]}
]}
]}
]}
]
},
"http": {"http": true, "https": true, "ui": true, "login": false, "ca": ""},
"mqtt": {"enable": false, "url": "mqtt://broker.hivemq.com:1883", "ca": "", "rx": "{device_id}/rx", "tx": "{device_id}/tx"},
"dns": {"type": "default", "url": "udp://8.8.8.8:53", "captive": false},
"sntp": {"enable": false, "type": 0, "url": "udp://time.google.com:123", "interval": 3600},
"modbus": {"enable": false, "port": 502},
"build": {"mode": "new", "board": "pico2-w", "ide": "Pico-SDK", "rtos": "baremetal"}
}
Tlačítkem Load si můžeme rozpracovaný uložený soubor nahrát zase do webového kouzelníka.

Možné úpravy
Pokud bychom potřebovali změnit zapojení SPI sběrnice na jiné piny, tak je potřeba upravit definici pinů v souboru mongoose/hal.h
// Copyright (c) 2023 Cesanta Software Limited
// All rights reserved
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "hardware/spi.h"
#include "pico/stdlib.h"
void hal_genmac(unsigned char *mac);
enum { SPI_CS = 17, SPI_CLK = 18, SPI_TX = 19, SPI_RX = 16 }; // Pins
// enum { SPI_CS = 5, SPI_CLK = 2, SPI_TX = 3, SPI_RX = 4 }; // Pins
static inline void ethernet_init(void) {
// Init SPI pins
spi_init(spi0, 500 * 1000);
gpio_set_function(SPI_RX, GPIO_FUNC_SPI); // MISO
gpio_set_function(SPI_TX, GPIO_FUNC_SPI); // MOSI
gpio_set_function(SPI_CLK, GPIO_FUNC_SPI); // CLK
gpio_init(SPI_CS); // CS
gpio_set_dir(SPI_CS, GPIO_OUT); // Set CS to output
gpio_put(SPI_CS, 1); // And drive CS high (inactive)
}
// Construct MAC address from the unique board ID
#include "pico/unique_id.h"
static inline void ethernet_genmac(unsigned char *mac) {
pico_unique_board_id_t board_id;
pico_get_unique_board_id(&board_id);
mac[0] = 2;
memcpy(&mac[1], &board_id.id[3], 5);
}
Pokud bychom potřebovali provozovat podobný projekt na Raspberry Pi Pico W (s wifi kartou), tak v kouzelníkovi změníme v Settings → Source Code Generator → Target architecture na `Pico W (RP2040 (M0+ @ 133MHz x2, 264k RAM, 2048 Flash) + CYW43439). Necháme si vygenerovat kód a přeložíme to pro Pico W. Je potřeba jenom upravit zdrojový kód a nastavit WiFi ESSID sítě a přihlašovací heslo.