Boards

The Raspberry Pi Pico W

The Pico with a wireless chip on it. Under MicroPython and CircuitPython the chip is modeled from its pins and joins Mokxi's simulated network.

The overview, with examples running, is on the board page and The Raspberry Pi Pico W model (every register).

For an Arduino sketch the WiFi is simulated behind a mailbox instead, and the LED works either way.

What it is

The same RP2040 on the same board outline with the same forty pins as the Raspberry Pi Pico, running on the same model. The core, the SIO GPIO, the TIMER, UART0 and PWM are all the Pico's, at the same addresses, and a program built for a Pico here is the same ELF a Pico W runs.

What the real board adds is a CYW43439: 2.4 GHz WiFi (802.11n) and Bluetooth, on a chip beside the RP2040 with its own antenna etched into the end of the board.

The CYW43439 and an Arduino sketch

This section and the next are about Arduino sketches. MicroPython and CircuitPython reach the real chip's interface, which is modeled for them: see MicroPython and CircuitPython below.

For a sketch, almost none of that chip is modeled. No SPI protocol to it, no firmware blob, no driver, no registers, and no Bluetooth: no LE, no GATT, no pairing, not even a stub. A sketch that calls into Bluetooth will not compile here, because the runtime does not declare it.

The one exception is its GPIO 0, which is the board's LED, because that is a pin a sketch really drives; see below. On real hardware the chip has to be powered and its firmware loaded before that pin does anything, which the Arduino core arranges at start-up; here it works from the first instruction, and that is a simplification rather than a model of the sequence.

That is deliberate. A stub that returned "not connected" would be a lie with a plausible shape, and one that returned "connected" would be worse.

What the board does have is a simulated network, described below, and what it is for beyond that is everything the Pico is for (the core, the timers, the PWM, the UART, the pins) on the board people actually bought. If a real radio is the point of your project, this board in Mokxi is not the tool for it, and neither is any other: there is no radio in this product.

WiFi, simulated

There is no radio. There never will be: an 802.11 MAC is not something this model could reproduce honestly.

What there is instead is a simulated network. A block that is Mokxi's own rather than the chip's (a mailbox at 0x4FFF_E000, where a real RP2040 has nothing mapped at all) carries WiFi.h, HTTPClient.h and WebServer.h, so the Arduino code a tutorial gives you runs here: the board joins an access point whose name and password are properties of the board, WiFi.status() walks the same states in the same one to three seconds, DHCP leases it 192.168.4.2, and a sketch can fetch a page or serve one.

What is behind it is software, and nothing is hidden about that. There is no 802.11, no channel, no scan, no WPA2, no TCP, no TLS and no real internet: four made-up names under .mokxi resolve and no others, and nothing a sketch does can reach the network your browser is on. WiFiClientSecure compiles and then fails, saying TLS is not simulated. The Web and Cloud panels along the bottom of the editor open with that sentence and do not scroll it away.

The one exception is Real internet, a switch in the Cloud panel for anyone signed in (more of it with Pro) that is off every time a page loads. With it on, a request for a name outside .mokxi, https:// included, goes out through Mokxi's gateway and the answer comes back to the sketch. See Real internet.

A mailbox is the honest shape here too. A real Pico W's wireless part is a CYW43439 on the far side of a three-pin SPI-ish link, driven by a closed binary blob, not a set of documented registers on the RP2040 any more than an ESP32's radio is a set of documented registers on its own die. So this is a command interface, which is what the real seam is. For a sketch, the CYW43439 itself is not modeled, and Bluetooth is not simulated at all.

The block is mapped on a Pico W and not on a plain Pico, so WiFi.h compiles for one board and refuses for the other, and the two boards' example programs are not interchangeable.

Four examples ship for this board: WiFi: join the network, WiFi: fetch the weather, API lab: fetch JSON and WiFi: a lamp on a web page.

Sketches written for arduino-pico

The Pico W's Arduino core is arduino-pico, and its WiFi examples build here as they are written: HelloServer with WebServer and LEAmDNS.h, BasicHttpsClient with a WiFiMulti and HTTPClient, and the WiFiServer ones with server.accept(). Its own calls are here too: WiFi.connected(), WiFi.noLowPowerMode(), WiFi.end(), http.setInsecure() and rp2040.getFreeHeap(). A few compile and do nothing, because what they reach is not simulated, and the serial monitor says so once: WiFi.ping() answers -1, WiFi.beginAP() leaves the board a station, MDNS.begin("picow") names nothing that resolves, and an https:// address still fails after setInsecure().

Two things to change in a copied sketch: the network name and password, which must match the board's own (Mokxi-Lab and breadboard unless you change them on the board), and any address outside .mokxi, which nothing answers. A sketch on a plain Raspberry Pi Pico does not build with WiFi.h at all, because that board has no wireless chip; change the board to a Pico W.

WiFi, simulated is how to use it; Simulated WiFi is the contract, limit by limit.

The LED is not on GP25

This is the part that catches people, and it catches them on a desk too.

A Pico's green LED is on GP25. A Pico W's is not. On a Pico W, GP23, GP24 and GP25 all go to the CYW43439 instead (WL_ON, WL_D and WL_CS), and the LED hangs off the CYW43's own GPIO 0, reached over the same link the radio uses.

So digitalWrite(25, HIGH) lights nothing here, and it lights nothing on real hardware either.

digitalWrite(LED_BUILTIN, HIGH) does light it, on both. LED_BUILTIN on this board is not a GPIO number at all: the runtime sends it to the wireless part over the same mailbox the network uses, which is the path the Arduino core takes on the real board. The lamp on the board in the editor comes on with it.

One thing that link cannot carry is a duty cycle, so analogWrite(LED_BUILTIN, …) does nothing on a Pico W. A breathing LED wants a header pin, which is what the Fade example does.

Wire an LED and a 220 ohm resistor from a header pin to a ground pin and blink that instead. The board's own blink example does exactly that.

The pins

Exactly the Pico's forty, in the same order and with the same names: see the Raspberry Pi Pico. This is a 3.3 volt board and its pins are not 5 V tolerant.

GP29 is WL_CLK on a Pico W as well as the VSYS divider, and GP24 is not VBUS sense. Nothing drives it here, so it reads low. Neither is on the header on either board.

What is modeled, and what is not

The same as the Pico, every line of it, plus one block that is not the chip's at all: SIO GPIO, the 64-bit TIMER, UART0, UART1 (Serial2, on its pins), PWM, the ADC, the simulated network mailbox and the one CYW43 pin behind it are there; PIO, DMA, SPI, I2C, USB, the RTC, the clock tree, the second core and the boot ROM are not, and neither is the rest of the CYW43439. That is a sketch's board: under MicroPython and CircuitPython the board boots through its ROM with the Pico's full chip model, and the CYW43439 is on its pins (below). analogRead() reads GP26 to GP28 (A0 to A2) as on the Pico.

The full list is in the Raspberry Pi Pico W model, which says only what differs, and the Raspberry Pi Pico model, which says everything else.

Stock Arduino libraries

The same as on the Pico: Servo.h, Wire.h (on GP4 and GP5), SPI.h, EEPROM.h (in RAM), LiquidCrystal_I2C.h, Adafruit_SSD1306.h, Adafruit_NeoPixel.h and DHT.h compile as they stand.

The examples

Blink, Button, Serial, Fade and Chaser are the Pico's own, compiled again for this board. Blink drives LED_BUILTIN and GP15, so the board's own lamp and one on the breadboard blink together; Fade fades GP14 only, because there is no PWM on the link to the board's lamp. The Pico's game controller examples (the four Fight stick steps, Fight stick, Leverless controller, Mixbox-style controller and Stop the light) are here too.

Four more are this board's alone, because only this board has a network: WiFi: join the network, WiFi: fetch the weather, API lab: fetch JSON, and WiFi: a lamp on a web page, which switches both lamps from the Web tab.

A Pico W build uses a block a plain Pico leaves unmapped, so the two boards carry different program strings and the editor offers each its own list.

MicroPython and CircuitPython

Pick MicroPython (main.py) or CircuitPython (code.py) in the board's Firmware panel and Run boots the official Pico W firmware: MicroPython v1.29.0's Pico W build, or CircuitPython 10.3.1's. Either one drives the CYW43439 the way it does on a desk, over the chip's own pins (GP23, GP24, GP25 and GP29), and the chip is modeled to the depth their driver reaches it: the bus, the firmware upload (accepted and dropped) and the WiFi commands.

  • The LED is the chip's GPIO 0: Pin("LED") in MicroPython, board.LED in CircuitPython.
  • WiFi joins Mokxi's simulated access point, whose name and password are the board's WiFi properties (Mokxi-Lab and breadboard unless you change them). In MicroPython, network.WLAN(network.STA_IF) connects and socket, requests and urequests reach the .mokxi sites; a socket server on the board opens in the Web panel. In CircuitPython, wifi.radio.connect() connects and socketpool with adafruit_requests fetches the same sites.
  • Not simulated: Bluetooth, the access point mode's clients, power save, TLS, and any network but Mokxi's. In CircuitPython, wifi.radio.ap_info raises NotImplementedError, because its Pico W port does not implement it.

See the Pico for MicroPython and CircuitPython on the Pico for CircuitPython; the Raspberry Pi Pico W model has the detail.

Elsewhere