The Pico/W In C: Simple Web Client
Written by Harry Fairhead   
Monday, 31 October 2022
Article Index
The Pico/W In C: Simple Web Client

Putting all this together gives the complete program:

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/apps/http_client.h"
char myBuff[1000];
void result(void *arg, httpc_result_t httpc_result,
u32_t rx_content_len, u32_t srv_res, err_t err)
printf("transfer complete\n");
printf("local result=%d\n", httpc_result);
printf("http result=%d\n", srv_res);
err_t headers(httpc_state_t *connection, void *arg,
struct pbuf *hdr, u16_t hdr_len, u32_t content_len)
printf("headers recieved\n");
printf("content length=%d\n", content_len);
printf("header length %d\n", hdr_len);
pbuf_copy_partial(hdr, myBuff, hdr->tot_len, 0);
printf("headers \n");
printf("%s", myBuff);
return ERR_OK;
err_t body(void *arg, struct altcp_pcb *conn,
struct pbuf *p, err_t err)
pbuf_copy_partial(p, myBuff, p->tot_len, 0);
printf("%s", myBuff);
return ERR_OK;

char ssid[] = "mySSID";
char pass[] = "myPassword";
uint32_t country = CYW43_COUNTRY_mycountry;
uint32_t auth = CYW43_AUTH_WPA2_MIXED_PSK;
int main()
setup(country, ssid, pass, auth,
uint16_t port = 80;
httpc_connection_t settings;
settings.result_fn = result;
settings.headers_done_fn = headers;
err_t err = httpc_get_file_dns(
printf("status %d \n", err); while (true){ sleep_ms(500); } }

The setup function given earlier in the chapter has been omitted from the listing but for completeness of this extract it is:

int setup(uint32_t country, const char *ssid, 
const char *pass, uint32_t auth,
const char *hostname, ip_addr_t *ip,
ip_addr_t *mask, ip_addr_t *gw)
if (cyw43_arch_init_with_country(country))
return 1;
if (hostname != NULL)
netif_set_hostname(netif_default, hostname);
if (cyw43_arch_wifi_connect_async(ssid, pass, auth))
return 2;
int flashrate = 1000;
int status = CYW43_LINK_UP + 1;
while (status >= 0 && status != CYW43_LINK_UP)
int new_status = cyw43_tcpip_link_status(
if (new_status != status)
status = new_status;
flashrate = flashrate / (status + 1);
printf("connect status: %d %d\n",
status, flashrate);
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
if (status < 0)
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
if (ip != NULL)
netif_set_ipaddr(netif_default, ip);
if (mask != NULL)
netif_set_netmask(netif_default, mask);
if (gw != NULL)
netif_set_gw(netif_default, gw);
printf("IP: %s\n",
printf("Mask: %s\n",
printf("Gateway: %s\n",
printf("Host Name: %s\n",
return status;

You also need to modify the CmakeLists.txt file to include the line:

target_link_libraries(picow pico_stdlib 

Notice the addition of pico_lwip_http. You also need a default lwipopts.h file.

If you run this program you will see the Pico connect to the WiFi and then you should see two copies of the web page – the first complete with headers and the second minus the headers.

If you want to use the simpler httpc_get_file function with a raw IP address you will need to setup an IP address struct:

ip_addr_t ip;
IP4_ADDR(&ip, 192, 168, 253, 45);   
httpc_connection_t settings;
settings.result_fn = result;
settings.headers_done_fn = headers;
err_t err = httpc_get_file(

As long as the web server works with a raw IP address this works in the same way as the previous program.

In chapter but not in this extract:

  • A Web Server
  • A Custom Web Site
  • A Dynamic Web Page – Server Side Includes
  • Listing
  • Where Next



  • The Pico W’s new WiFi hardware is connected via an SPI bus and this makes use of several GPIO lines that are used in the Pico for different things. In particular, GP25 is no longer used to control the internal LED. The internal LED is now controlled by a GPIO line on the WiFi chip.

  • The new WiFi software has two components – a low-level driver and the LwIP library which provides higher-level networking making use of the driver.

  • The WiFi system works in two modes, polling or background mode.

  • Connecting to a WiFi access point is easy, but providing feedback on the current state to the user is more difficult.

  • Creating a web client can be done using low-level TCP functions, but it is simpler to use the supplied HTTP client app.

  • Similarly a web server can be built using TCP functions, but the supplied HTTP server is easier to use.

  • To use the server you need to build and apply the htmlgen/makefsdata to convert the web site into a single C file which can be included in your project.

  • To create a dynamic web site you need to include SSI (Server Side Include) tags and a suitable SSI handling function.

  • The driver and the LwIP library provide a huge range of poorly documented possibilities.


Programming the Raspberry Pi Pico In C

By Harry Fairhead


Buy from Amazon.


  • Preface
  • Chapter 1 The Raspberry Pi Pico – Before We Begin
  • Chapter 2 Getting Started
  • Chapter 3 Getting Started With The GPIO
  • Chapter 4 Simple Output
  • Chapter 5 Some Electronics
  • Chapter 6 Simple Input
        Extract:   GPIO Input ***NEW!
  • Chapter 7 Advanced Input – Events and Interrupts
  • Chapter 8 Pulse Width Modulation
        Extract: Basic PWM
  • Chapter 9 Controlling Motors And Servos
  • Chapter 10 Getting Started With The SPI Bus
  • Chapter 11 A-To-D and The SPI Bus
  • Chapter 12 Using The I2C Bus
  • Chapter 13 Using The PIO
        Extract: A 1-Wire PIO Program  
  • Chapter 14 The DHT22 Sensor Implementing A Custom Protocol
  • Chapter 15 The 1‑Wire Bus And The DS1820
  • Chapter 16 The Serial Port
  • Chapter 17 Using the Pico W
       Extract: Simple Web Client
       Extract:A Better Connect
  • Chapter 18 The Pico/W In C: Direct To Hardware 




To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.


Amazon Updates Q Family And Previews App Studio

Amazon made multiple announcements at its AWS Summit in New York, including a preview of AWS App Studio, the addition of Q Developer to SageMaker Studio, and an Amazon Q Apps API.

Pg_lakehouse Makes PostgreSQL Quack

Pg_Lakehouse from ParadeDB is an extension that turns PostgreSQL into the analytical engine of DuckDB. Why is that useful? How do you use it?

More News

kotlin book



or email your comment to:

Last Updated ( Monday, 23 January 2023 )