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:

Tabulka 1. Podporované desky
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.

Modul WIZ850io

wiz850io

Zapojení pinů

wiz850io pinmap

Tabulka 2. Zapojení pinů (zbylé piny jsou nezapojeny)
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)

Zapojení

IMG 20250718 230418

IMG 20250718 230405

IMG 20250718 230334

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:

Nový projekt

wizard 20250719 160018

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.

Nastavení adresáře, desky a IDE

wizard 20250719 160727

a stiskneme next.

Vyberem si Single LED toggle šablonu a stikneme next

Výběr šablony

wizard 20250719 161818

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

Dokončení nastavení

wizard 20250719 162432

Návrh webového rozhraní

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

Návrhář webu

wizard 20250719 162809

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.

Nastavení REST API proměnných

wizard 20250719 170021

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

Nastvení řídících elementů k REST API

wizard 20250719 170214

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.

Dokončení návrhu webu

wizard 20250719 171406

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.

Výstup v minicomu
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.

První web

web 20250719 185958

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

komunikace 20250719 184934

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ů.

main.c před úpravami
// 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;
}
main.c po úpravě
// 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

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.

Uložení projektu

wizard save 20250719 203853

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 SettingsSource Code GeneratorTarget 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.

Zdroje a odkazy