The Pico/W In C: A Better Connect
Written by Harry Fairhead   
Monday, 23 January 2023
Article Index
The Pico/W In C: A Better Connect
The cyw43_arch Functions
A Better Connect

The cyw43_arch Functions

There is a small list of well-documented functions in the cyw43_arch library. They are all concerned with configuring the WiFi and not with transferring data.

The first group of functions are concerned with initialization:

 

  • int cyw43_arch_init (void)
    initializes the hardware to the default country

  • int cyw43_arch_init_with_country (uint32_t country)
    initializes the hardware to the specific country

  • uint32_t cyw43_arch_get_country_code (void)
    returns the country code of the current setup of the WiFi

  • void cyw43_arch_deinit (void)
    deinitalizes the hardware and the software

The country code sets the range of frequencies that can be used. If you don’t specify a code then the WiFi hardware is configured to use only the channels allowed in every country. The country codes are listed in the cyw43_driver documentation.

There are two functions which select the WiFi as a client, sta, or an access point, ap:

  • void cyw43_arch_enable_sta_mode(void)

  • void cyw43_arch_enable_ap_mode(const char *ssid,
    const char *password, uint32_t auth)

There are three functions that, after the hardware has been initialized, make a connection to an access point.

  • int cyw43_arch_wifi_connect_blocking(const char *ssid,
    const char *pw, uint32_t auth)

  • int cyw43_arch_wifi_connect_timeout_ms(const char *ssid,
    const char *pw, uint32_t auth, uint32_t timeout)

  • int cyw43_arch_wifi_connect_async(const char *ssid, const
    char *pw, uint32_t auth)

The auth parameter sets the type of authorization supported. You can use any of:

  • CYW43_AUTH_OPEN

  • CYW43_AUTH_WPA_TKIP_PSK

  • CYW43_AUTH_WPA2_AES_PSK

  • CYW43_AUTH_WPA2_MIXED_PSK

In most cases WPA2_MIXED is the best choice.

When working in polling mode you have to call void cyw43_arch_poll (void) every 1 ms or so.

Finally there are two functions which provide access to the GPIO lines that the WiFi hardware supports:

  • void cyw43_arch_gpio_put (uint wl_gpio, bool value)

  • bool cyw43_arch_gpio_get (uint wl_gpio)

These functions provide enough to make a connection to an access point.

 picow

Connecting To WiFi

Connecting the Pico to a WiFi Access Point (AP) is the “Hello World” of WiFi programming and it is generally the best place to start. If you cannot make a connection to an AP then you cannot move on to more interesting things.

Although it isn’t necessary, it does make things easier if you setup a serial connection between the Pico and the development machine, see Serial Data in Chapter 6. The reason is that the software sends connection status messages via the serial link and this allows you to track progress and see if there are any problems. You can stop the status information being sent to the serial port by setting the build to Release.

The first thing to do is initialize the hardware and the libraries:

    if (cyw43_arch_init_with_country(CYW43_COUNTRY_UK))
    {
printf("failed to initialize\n"); return 1; }

This also sets the country code so that the hardware know what channels and power it can use. Alternatively you can use cyw43_arch_init which uses the country set by PICO_CYW43_ARCH_DEFAULT_COUNTRY_CODE in cyw43_arch.h.

Once the system is initialized you can attempt a connection:

cyw43_arch_enable_sta_mode();
if (cyw43_arch_wifi_connect_blocking(ssid, pass,
        CYW43_AUTH_WPA2_MIXED_PSK))
    {
        printf("failed to connect\n");
        return 1;
    }

First we have to set the WiFi into client mode and then we attempt the connection. You have to supply the SSID and password to connect and connection can take a few seconds. While the connection is being made you will see messages via the serial connection:

cyw43 loaded ok, mac 28:cd:c1:00:56:34 
API: 12.2 Data: RaspberryPi.PicoW Compiler: 1.29.4 ClmImport: 1.47.1 Customization: v5 22/06/24 Creation: 2022-06-24 06:55:08 connect status: joining connect status: no ip connect status: link up

The time between the no ip message and link up can be quite long depending on how long the DCHP server takes to allocate an IP address. When you see link up the connection has been made and the client has an IP address ready to communicate.

This is all so standard we might as well put it together into a function and add a main program to use it:

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
int setup(uint32_t country, const char *ssid,
const char *pass,
uint32_t auth)
{
if (cyw43_arch_init_with_country(country))
{
return 1;
}
cyw43_arch_enable_sta_mode();
if (cyw43_arch_wifi_connect_blocking(ssid, pass, auth))
{
return 2;
}
}
char ssid[] = "myhost";
char pass[] = "mypassword";
uint32_t country = CYW43_COUNTRY_mycountry;
uint32_t auth = CYW43_AUTH_WPA2_MIXED_PSK;
int main()
{
stdio_init_all();
setup(country, ssid, pass, auth);
while (true)
{
sleep_ms(1);
}
}

The setup function makes the connection to the WiFi AP that you have specified the SSID and password for. The while loop just keeps the main program active while all this goes on.

To run this program you need a CmakeLists.txt and it has some additional instructions:

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()
add_executable(picow
picow.c
)
target_include_directories(
picow PRIVATE ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(picow pico_stdlib pico_cyw43_arch_lwip_threadsafe_background)
pico_add_extra_outputs(picow)

Here the program is stored in picow.c. Notice that you need the set(PICO_BOARD pico_w) instruction to compile the program. The use of the pico_cyw43_arch_lwip_threadsafe_background library means that we don’t have to poll. If you select the pico_cyw43_arch_lwip_poll instead everything works the same, but you have to include a call to cyw43_arch_poll() in the final while loop.

We also need to copy pico_sdk_import.cmake into the root of the project. You can get it from any existing project, but you can get an up-to-date copy from pico/pico-sdk/external. In addition we need a copy of a WiFi header file, lwipopts_examples_common.h, from the pico-examples/pico_w folder, which needs renaming to lwipopts.h. The lwipopts.h file sets the defaults for the operation of the LwIP library. You can make your own, but the example file is a good starting point.

Once you have assembled all this, you can compile and run the program. You should see it go through the various stages of connecting to the WiFi AP. If you don’t then check the SSID, password and authentication method. Make sure that you can connect via a phone or other device using the same credentials.



Last Updated ( Monday, 23 January 2023 )