Pico W souží jako AP, na kterém běží DHCP server, DNS server a web server, který slouží jako ovládací panel. Dále je k Picu připojen monitor VGA a hodnoty řídícího panelu jsou na něm též zobrazovány.

Projekt ovládá vestavěnou LED, řídí intenzitu svitu další LED pomocí PWM, měří teplotu pomocí interního čidla a vybírá barvu na obrazovku. VGA monitor umí zobrazovat 256 barev a rozlišení 320x240 bodů (rozlišení a barevná hloubka je omezena malou pamětí RAM). Ovládání je možné z mobilního telefonu tak, že se připojíme na AP SSID picow_test s heslem password. PicoW není připojeno do Internetu, díky omezenému dosahu můžeme použít protokol http. Bezpečnost tedy není nijak řešena.

Projekt demonstruje jednak to, že PicoW není jenom nějaká hračka, ale velmi dobrý kus hardware, na kterém je možné programovat i poměrně složité úlohy, které musí běhat velmi rychle. Ukazuje pokročilé programátorské techniky jazyka C: událostmi řízené programování za pomocí vláken (Protothreads) a použití obou jader procesoru. Dále pak poměrně složitou síťařinu a programovaní v PIO assembleru. V neposlední řadě demonstruje, že rozdílné knihovny (VGA a síť) mohou velmi dobře spolupracovat.

Projekt je připravován na den otevřených dveří školy.

Schéma zapojení

Schéma zapojení VGA monitoru k Picu W

schema picow VGA

Základní kostra programu

// ========================================
// === core 1 main -- started in main below
// ========================================
void core1_main(){

  //  === add threads  ====================
  // for core 1
  pt_add_thread(protothread_graphics) ;
  //
  // === initalize the scheduler ==========
  pt_schedule_start ;
  // NEVER exits
  // ======================================
}


// ========================================
// === core 0 main
// ========================================
int main(){
    // set the clock -- if you want
    //set_sys_clock_khz(250000, true); // 171us

    //========================================
    // start the serial i/o
    stdio_init_all() ;

    // ======================================
    // Initialize the VGA system
    initVGA() ;

    // =====================================
    // turn on ADC (move to thread)
    // adc_init();
    // adc_set_temp_sensor_enabled(true);
    // adc_select_input(4);

    //========================================
    // network init
    // start the cyw43 in access point mode
    // start the DHCP server
    // start the DNS server
    // start the TCP server
    // =======================================
    TCP_SERVER_T *state = calloc(1, sizeof(TCP_SERVER_T));
    if (!state) {
        DEBUG_printf("failed to allocate state\n");
        return 1;
    }

    if (cyw43_arch_init()) {
        DEBUG_printf("failed to initialise\n");
        return 1;
    }

    // Get notified if the user presses a key
    state->context = cyw43_arch_async_context();
    //>>>> key_pressed_worker.user_data = state;
    //>>>>async_context_add_when_pending_worker(cyw43_arch_async_context(), &key_pressed_worker);
    stdio_set_chars_available_callback(key_pressed_func, state);

    // access point SSID and PASSWORD
    // WPA2 authorization
    const char *ap_name = "picow_test";
    const char *password = "password";

    cyw43_arch_enable_ap_mode(ap_name, password, CYW43_AUTH_WPA2_AES_PSK);

    // 'state' is a pointer to type TCP_SERVER_T
    ip4_addr_t mask;
    IP4_ADDR(ip_2_ip4(&state->gw), 192, 168, 4, 1);
    IP4_ADDR(ip_2_ip4(&mask), 255, 255, 255, 0);

    // Start the dhcp server
    // and set picoW IP address from 'state' structure
    // set 'mask' as defined above
    dhcp_server_t dhcp_server;
    dhcp_server_init(&dhcp_server, &state->gw, &mask);

    // Start the dns server
    // and set picoW IP address from 'state' structure
    dns_server_t dns_server;
    dns_server_init(&dns_server, &state->gw);

    if (!tcp_server_open(state, ap_name)) {
        DEBUG_printf("failed to open server\n");
        return 1;
    }


    // ======================================
    // init thread communication semaphores
    // init pt strucdtures

    //========================================
    // start core 1 threads --

    multicore_reset_core1();
    multicore_launch_core1(&core1_main);

    // === config threads ========================
    // for core 0
    // announce the threader version on system reset
    printf("\n\rStarting Protothreads RP2040 v1.1.2 two-core\n\r");
    // pt_add_thread(protothread_access);
    pt_add_thread(protothread_toggle_gpio2) ;
    pt_add_thread(protothread_serial) ;
    // pt_add_thread(protothread_graphics) ;
    //
    // === initalize the scheduler ===============
    pt_schedule_start ;
    // NEVER exits
    // ===========================================
    // NEVER gets here
    // tcp_server_close(state);
    dns_server_deinit(&dns_server);
    dhcp_server_deinit(&dhcp_server);
    cyw43_arch_deinit();
} // end main

Obrázky

Zapojení VGA konektoru

VGA zapojeni2

Fungující web s monitorem 1

fungujici web s VGA

Fungující web s monitorem 2

fungujici web s VGA2

Webová stránka 1 na telefonu

web page1

Webová stránka 2 na telefonu

web page2

Zdroje a odkazy