RPICO32 – RP2040 / IEEE802.11 2.4GHz module

The RPICO32 is an Arduino/Micropython compatible embedded micro controller module based on the Raspberry Pico chip RP2040 paired with an ESP8285 WiFi subsystem. The RPICO32 combines the raw power of the RP2040 with the simple to use Espressif ESP8285 WiFi creating an extremely easy to use module that can be integrated into your products.

The RPICO32 module is based on the design of our existing Challenger RP2040 WiFi board meaning that existing software can be ported without any major effort and new board support packages for Arduino and CircuitPython simplfies the mapping of any hardware differences.

RP2040 micro controller

RP2040 is the debut microcontroller from Raspberry Pi. With a large on-chip SRAM memory, symmetric dual-core processor complex, deterministic bus fabric, and rich peripheral set augmented with our unique Programmable I/O (PIO) subsystem,  The RP2040 provides professional users with unrivalled power and flexibility. With detailed documentation, a polished MicroPython port, and a UF2 bootloader in ROM, it has the lowest possible barrier to entry for beginner and hobbyist users.

RP2040 is a stateless device, with support for cached execute-in-place from external QSPI memory. This design decision allows you to choose the appropriate density of non-volatile storage for your application, and to benefit from the low pricing of commodity Flash parts. The RP2040 is manufactured on a modern 40 nm process node, delivering high performance, low dynamic power consumption, and low leakage, with a variety of low-power modes to support extended-duration operation on battery power. Whatever your microcontroller application — from machine learning to motor control, from agriculture to audio — RP2040 has the performance, feature set, and support to make your product fly.

The RPICO32 module also contain a 12MHz crystal that drives the RP2040 to as well as a 8Mbyte 133MHz QSPI FLASH memory well suited for full speed operation of the RP2040.


The RPICO32 module is based on the ESP8285 WiFi chip. For those of you that is unfamiliar with this device, it is basically an ESP8266 device with an integrated 1MByte of flash memory. This allows us to have an AT command interpreter inside this chip that the main controller can talk to and connect to you local WiFi network. The communications channel between the two devices is one of the UARTs on the main controller and the standard UART on the ESP8285. As simple as it can be.

As mentioned the ESP8285 chip comes pre-flashed with Espressif’s AT command interpreter stored in the internal 1MByte of the ESP8285. This interpreter support most of the operating and sleep modes of the standard ESP8266 framework which makes it easy to work with. Talking to the device is as easy as opening the primary serial port (Serial1, UART0), resetting the ESP8285 and start listening for events and sending commands. Check out the examples for more details on how to do this.,

Form factor

Design Support

Eagle and KiCAD libraries and examples are being developed making it super easy for you to start building your own products. The example boards will show among other things how to position the module on the PCB for best RF performance as well as how to route USB tracks.


Sample units do not hold any certification but are the same units that are being submitted to the certification lab.

Production units hold both FCC and CE certifications for use in commercial devices both in Europe and US countries.

Weight 0.009 kg
Dimensions 5.07 × 2.28 × 0.72 cm

Using the Arduino environment

We’ve teamed up with Earle F. Philhower over at his Github page to provide Arduino support for all of our Raspberry Pi Pico based boards. All instructions on how to install the board support packaged as well as multiple examples on how to use the Raspberry Pi Pico processor.


The RPICO32 module is fully compatible with Adadfruits CircuitPython package found at Adafruits CircuitPython. Instruction are available on how to install the python interpreter of your choice is available on respective web site.

Short initialization example

To simplify the hardware aspect of the WiFi modem we have included a small helper class in the Arduino IDE that is always available to you as a developer. This new class replaces the previous examples on how to do a proper reset and sync.

The first thing you need to do in your sketch is to include the support library by entering:

#include <ChallengerWiFi.h>

After this basically all you need to do before starting the WiFi manager is the following:

if (Challenger2040WiFi.reset())
    Serial.println(F("WiFi Chip reset OK !"));
    Serial.println(F("Could not reset WiFi chip !"));

After these step the modem is initialized and is ready to accept your commands. The reset() function of the built in Challenger2040WiFi library will perform a HW reset of the WiFi modem and wait for it to return the “ready” prompt. After this a WiFi manager can be started and start communicating with the modem. Here at iLabs we use the WiFiEspAT library and initializing the stack is as easy as


At this point you can also do a check to make sure that the data link is setup properly.

if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);

You are now good to go, so doing something like this:

Serial.println("Waiting for connection to WiFi");
while (WiFi.status() != WL_CONNECTED) {
Serial.println("Connected to WiFi network.");

will work as expected.

Changing the baudrate

The default baudrate between the RP2040 micro controller and the ESP8285 WiFi modem is 115200 and while this is probably good for most IoT applications that normally don’t send very much data it can sometimes be useful to increase the baudrate. The Challenger2040WiFi contains a method for doing this and again it is super simple to use. Just do the following and the baud rate will be altered on both systems and the devices will be synced up.


After this you can proceed to communicate with the device as normal.

Sending and AT command

After the modem has been initialized and it has reported that it is ready you can now send a command to it. Here’s an example on how a simple command can be sent.


This command simply tells the modem not to repeat everything back that you send to it. If you want to enable this again you would simply send the following command:


Pass through example

This example Arduino program creates a USB2Serial pass through to the ESP8285. This can be used to flash the ESP with new upgraded software or you can write your own code and use this short snippet to flash the device.

  Challenger USB to serial port.

  This is an example on how to flash the onboard ESP8285.
  TinyUSB must be selected in the Arduino IDE for this sketch to work.

  The ESP8285 should to flashed with the following command:
  esptool.py --port <port> --baud <rate> write_flash -e -fm dout -fs 1MB <filename.bin>

  This program must be compiled with tinyUSB to work.

#include <Arduino.h>

#include <Adafruit_TinyUSB.h>

// Sets the level of debug info that is printed on the serial output
// 0 = No debug information at all
// 1 = Basic debug information
// 2 = Full debug information
#define DEBUG_LVL 0

#define ESP_PORT Serial2
#define PC_PORT Serial
#define DEBUG_PORT Serial1

#define PACKET_SIZE 64

int led = LED_BUILTIN; // the PWM pin the LED is attached to
int led_state = 0;
int wifi_rst = 19;
int wifi_mode = 13;
uint32_t baud_rate = 115200;
static int port = -1;
static int words = 0;
uint8_t ch;
char buffer[PACKET_SIZE];
size_t received;

void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* coding) {
  (void) itf;
#if DEBUG_LVL >= 1
  if (coding->bit_rate != baud_rate) {
    baud_rate = coding->bit_rate;
#if DEBUG_LVL >= 1
    DEBUG_PORT.printf("Setting new baudrate to %d ", baud_rate);

// This overrides the stack functionality to capture cdc line state
// changes.
void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) {
  (void) itf; // interface ID, not used

  if (rts) {
    digitalWrite(wifi_rst, LOW);
#if DEBUG_LVL >= 1
    DEBUG_PORT.printf("RST=low ");
  } else {
    digitalWrite(wifi_rst, HIGH);
#if DEBUG_LVL >= 1
    DEBUG_PORT.printf("RST=high ");

  if (dtr) {
    digitalWrite(wifi_mode, LOW);
#if DEBUG_LVL >= 1
  } else {
    digitalWrite(wifi_mode, HIGH);
#if DEBUG_LVL >= 1
#if DEBUG_LVL >= 1

// DTR = false is counted as disconnected
  if (!dtr) {
// touch1200 only with first CDC instance (Serial)
    if (itf == 0) {
      cdc_line_coding_t coding;

      if (coding.bit_rate == 1200) {

// the setup routine runs once when you press reset:
void setup()
  pinMode(led, OUTPUT);
  digitalWrite(led, 0);

#if DEBUG_LVL >= 1
  DEBUG_PORT.println("nnnnnnDebug monitor !");

// Set default baudrates


// Set initial state of control pins
// Normal start when the reset pin is released
  digitalWrite(wifi_rst, LOW);
  pinMode(wifi_rst, OUTPUT);
  digitalWrite(wifi_mode, HIGH);
  pinMode(wifi_mode, OUTPUT);
// delay(1);
// digitalWrite(wifi_rst, HIGH);

  while (!PC_PORT);
  digitalWrite(led, HIGH);

// The main loop were data is received from the host and then forwarded
// to the ESP8285 and vice versa.
void loop() {

  // Handle data from the USB port ment for the ESP8285
  if (PC_PORT.available()) {
    received = PC_PORT.readBytes(buffer, PACKET_SIZE);
    ESP_PORT.write(buffer, received);

#if DEBUG_LVL >= 2
    if (port != 1) {
      port = 1;
      words = 0;
      DEBUG_PORT.println("nFrom USB to ESP8285 ==================================");
    for (int i=0;i<received;i++) {
      DEBUG_PORT.printf("%02x ", buffer[i]);
      if (++words > 15) {
        words = 0;

  // Handle response data from the ESP8285
  if (ESP_PORT.available()) {
    received = ESP_PORT.readBytes(buffer, PACKET_SIZE);
    PC_PORT.write(buffer, received);

#if DEBUG_LVL >= 2
    if (port != 2) {
      port = 2;
      words = 0;
      DEBUG_PORT.println("nFrom ESP8285 to USB ==================================");
    for (int i=0;i<received;i++) {
      DEBUG_PORT.printf("%02x ", buffer[i]);
      if (++words > 15) {
        words = 0;

This section will be updated shortly

Pin assignments

Pin description

External control pins

Connection between MCU and ESP8285 WiFi controller.

The board uses the first UART (UART 0) of the MCU to connect to the ESP8285 as well as two GPIO pins that allows the RP2040 to reset and put the ESP8285 in flash mode. The pins used are as follows.

  • GPIO0 acts as UART0 TXD
  • GPIO1 acts as UART0 RXD
  • GPIO2 is connected to ESP8285 reset and is active low (PIN_ESP8285_RST in the arduino IDE).
  • GPIO3 Is connected to the mode pin of the ESP8285. If it is pulled low at the same time the reset signal is going high the chip will enter flash mode (PIN_ESP8285_MODE in the arduino IDE).

Main Processor

  • Raspberry Pi Pico Dual Core Cortex-M0 @ 133MHz
  • 8 MByte FLASH Memory.
  • 264 KByte SRAM Memory.
  • Up to 2 Hardware I2C channel.
  • Up to 2 Hardware SPI channel.
  • 1 Hardware UART for the user (UART1).
  • 1 Hardware UART connected to the network processor (UART0 @ 1Mbit/s)
  • 12 Bit ADC.
  • All pins are PWM capable.

Network Processor

  • ESP8285 with internal 1MByte FLASH Memory
  • WiFi (2.4GHz)
  • Espressif AT interpreter
  • Communicates with 921600 bits/s

Add relevant documents in list form

You can always get our products from your local reseller if you like. Here is a list of current resellers.

  • The Pi Hut Raspberry Pi Superstore
  • The largest maker shop in Switzerland


There are no reviews yet.

Only logged in customers who have purchased this product may leave a review.