Table of Contents
There are a lot of videos and articles about using the new Raspberry Pi Pico W with MicroPython, but very little has been produced about using this new board with the Arduino IDE.
Today we will look at precisely that. While there has been no update to the Arduino RP2040 boards manager to include the Pico W yet, there is another boards manager that we can use instead.
Introduction
Amid all the confusion of life in 2020, there was one bright light – the release of the Raspberry Pi Pico. This was the first microcontroller produced by Raspberry Pi, which until then was known as a manufacturer of single-board computers focused on the educational and maker market.
The Pico was not only unique in its position in the Raspberry Pi product lineup, but it was also unique in that it used a new microcontroller chip that Raspberry Pi also manufactured. The RP2040 microcontroller is a powerful device that has onboard voltage regulation and two internal PIO (Programmable Input Output) processors to allow the creation of custom I/O interfaces.
At only 4 dollars, the Pico joined boards like the Seeeduino XIAO as a low-cost, high-performance microcontroller. And like the XIAO, it was missing one feature many makers craved – wireless connectivity.
That all changed in June 2022 when the folks at Raspberry Pi tweeted out a picture of a cow!
Raspberry Pi Pico W
It was a bit of an odd tweet from Raspberry Pi, a (hopefully) Photoshopped image of a cow bearing Raspberry Pi logo markings. The picture was titled “Pi Cow”.
Of course, we now know the meaning of the strange image, as “Pi Cow” is just a rearrangement of the words “Pico W”. Certainly a unique way of announcing a new microcontroller board!
Pico W Features & Specifications
The “W” in Pico W does, of course, refer to WiFi, as, unlike its predecessor, the Pico W does indeed have WiFi connectivity.
At a glance, the Pico W looks a lot like the Pico, with the obvious exception of the huge metal square that contains the WiFi magic. It has the same 40-pin castellated connector design that the original Pico has and the same 3-pin Debug connector, which has been moved to a different position to accommodate the WiFi module and onboard antenna.
The new device has exactly the same specifications as the older one, the only programming difference (aside from the WiFi) is that the onboard LED is now addressed differently, as the GPIO pin previously used to control it is required for the WiFi module.
Speaking of WiFi, the new Raspberry Pi Pico W uses the Infineon CYW43439 WiFi and Bluetooth module for its wireless network capability. This is a single-band 2.4 GHz 802.11n transceiver with a data rate of up to 96 Mbps. It has an integrated low noise amplifier (LNA) for improved performance.
As for that onboard LED, it’s now connected to the WL_GPIO0 pin on the Infineon CYW43439. You can address it using the “LED” constant in MicroPython, instead of directly addressing GPIO pin 25 as you did in the older Pico. In the Arduino IDE boards manager that I’ll be showing you soon, the onboard LED uses the constant LED_BUILTIN(as it does with many Arduino boards).
As with its predecessor, the Pico W is distributed in a simple plastic carrier package, and groups can be purchased in strips. You can also buy versions with the pins already soldered in.
What about Bluetooth?
In addition to the cryptic cow picture, the folks at Raspberry Pi have left us with another mystery – where is the Bluetooth? After all, the Infineon CYW43439 does indeed support Bluetooth 5.2. So why doesn’t the Pico W offer Bluetooth in addition to WiFi?
Currently, there is much debate about this in the maker community. Many people feel that it is just a matter of time before Raspberry Pi releases an official SDK for using Bluetooth with the Pico W.
But others point out that if you look at the specification sheet for the Infineon CYW43439, you’ll note that the WiFi and Bluetooth use different interfaces, although they share many of the same radio components. Bluetooth can use either a PCM or UART input, however, if you check out the schematic diagram for the Pico W, those pins appear to be unconnected.
Many are puzzled about how Bluetooth will work on the Pico W without those pins. Perhaps the schematic isn’t complete, or maybe we can use the same interface for both modes. If that’s the case, it’s possibly just a firmware update.
Eben Upton himself addressed the issue in his blog post announcing the Raspberry Pi Pico W:
“Eagle-eyed readers of datasheets will notice that CYW43439 supports both Bluetooth Classic and Bluetooth Low-Energy: we have not enabled Bluetooth on Pico W at launch, but may do so in the future.”
Until this all gets resolved, I wouldn’t plan on developing Bluetooth applications with the Raspberry Pi Pico W very soon!
Pico W vs. ESP32
Time to address the obvious question – which is better, the Raspberry Pi Pico W or the Espressif ESP32?
At a glance, it would seem that the lack of Bluetooth on the Pico W makes the ESP32 an instant winner, and when the rest of the specifications are compared, the ESP32 certainly wins in almost every category.
One aspect in which the Pico W may have an advantage is that at 6 US dollars a piece, the boards are cheaper than most ESP32 boards. And there is also the PIO feature in the Pico W which is exclusive to the RP2040 chip.
So if your application doesn’t require Bluetooth or touch switches, or if you want to drive a VGA display or an odd device using the PIO processors, then the Pico W is a great choice.
Preparing the Arduino IDE
Most tutorials to date will show you how to use the Pico W with MicroPython, which is a great and easy method of programming this device. And in the future, I’ll also show you some Pico W applications coded in MicroPython.
But today, we will use the Arduino IDE to program the Pico W with C++. To do this, we will have to add a Boards Manager to handle the new microcontroller.
I assume you have already installed the Arduino IDE on your Linux, Mac, or Windows workstation. Note that if you are a Windows user, you should install the IDE from the ZIP or EXE file on the Arduino website, not from the app in the Microsoft Store. It has been reported that the Microsoft Store version of the Arduino IDE has difficulty with the Pico, so it will likely have problems with the newer Pico W.
Raspberry Pi Pico Arduino core
The Raspberry Pi Pico Arduino core is a boards manager maintained on GitHub by user Earle F Philhower. This core covers not only the original Pico and the Pico W but also includes pretty well every RP2040-based board that you can find and is frequently updated.
In order to add this to your Arduino IDE, you will need to edit your Preferences to add a JSON string in the same fashion that we have done for other boards like the ESP32 and Seeeduino XIAO.
You can accomplish this as follows:
- Open the Arduino IDE.
- Click on the File menu item at the top and select Preferences. The Preferences dialog box will open.
- Within the Preferences dialog box, look for a text box labeled “Additional Boards Manager URLs”.
- This is where you will be inserting a JSON string. If the box is empty, you can paste it directly, otherwise, click on the icon on the right of the box to open a text window that allows you to add several JSON strings, one per line.
The string you want to add is as follows:
https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
Once you have added the string to your Additional Boards Manager URLs, you can click OK to save it in your Preferences.
Arduino IDE Boards Manager
The JSON file entry doesn’t actually install the new Pico RP2040 boards. Instead, it points to a location where your Boards Manager can get updates, mpw including one with the RP2040 board entries. You’ll need to add the new boards using the Boards Manager utility in the Arduino IDE.
Open the Boards Manager utility by selecting the Tools menu. Scroll down until you see an entry for the type of board (i.e., Arduino Uno) you are currently set up for. Highlight that, and another menu will appear, allowing you to change your existing board or launch the Boards Manager. You will want to launch the Boards Manager so that you can install the new Pico W board.
When the Boards Manager window has launched, filter your search by typing in “Pico”. You’ll get three results back, the second one, “Raspberry Pi Pico/RP2040” is the one you want.
Select it and click the Install button to install the new Boards Manager entry.
It will take a minute to copy all the files, once it’s done, you are ready to start using the Pico W on your Arduino IDE.
Testing the Installation – Blink
Now that you have the new boards manager files installed, you’ll want to test it. As the standard method of testing ANY new board is the Blink sketch, we’ll defer to tradition and use it.
In this case, it’s a good choice, as it uses the “LED_BUILTIN” constant for the onboard LED. Remember, with the new Pico W, this is how you need to address the LED, as it is no longer associated with GPIO port 25 but instead uses the WL_GPIO0 pin on the Infineon 43439 chip.
Load the Blink sketch, found in the Examples collection, into the Arduino IDE. We’ll be using it as it is, as it already uses “LED_BUILTIN” it should work with pour new Pico W.
Before we use it, however, we need to select the board and port we require.
Selecting a Board and Port
Now we need to select a board and port. This may not be as easy as it sounds!
Selecting the board is pretty simple. Open the Tools menu and go down to the listing for your currently selected board. Click on it, and you’ll open up a submenu, the same one we saw when we accessed the Boards Manager.
This time, you will want to select “Raspberry Pi Pico/RP2040”.
A menu with numerous RP2040 boards will be displayed. Scroll down until you see the “Raspberry Pi Pico W” and select it.
If you haven’t already, you can plug your Pico W into a USB connector on the computer. Depending upon your operating system and the current state of the Pico W, you may get a message regarding a new drive.
Back in the IDE, in the same Tools menu, select the port (COM port on Windows) that you have connected your board to. When you do this, one of three things will occur:
- You’ll see a Raspberry Pi Pico, in which case you should select it.
- You’ll see a generic USB port that wasn’t there before, in which case you might try selecting it.
- You won’t see a port.
In the third case (and possibly the second one), you can try and resolve this by pulling the USB cable from the Pico W out of the computer, holding down the Pico W’s BOOTSEL switch (the only switch on the board), and, keeping the switch held down, plug the USB cable back in. After you plug in the cable, you can release the BOOTSEL button.
Again, some operating systems may notify you about a new drive being mounted when you do this.
Now check the Port selection to see if you now have a Raspberry Pi Pico W available. Assuming that you do, you can now upload the Blink sketch.
If you get a blinking LED, then you’re in business!
Testing the Installation – ScanNetworks
Of course, blinking an LED is not a lot of fun, especially when we are evaluating a new board that is WiFi capable. Let’s now use this new feature!
A simple way to test the WiFi is to load one of the WiFi example sketches. A good test is the ScanNetworks sketch, which scans the area for WiFi networks and displays them, along with their signal strengths.
Go into the File menu, open Examples, and scroll down to the “Examples for Raspberry Pi Pico W” section. From there, navigate to the WiFi section.
Open the ScanNetworks sketch. This is a great sketch to test with, as it requires no WiFi credentials.
As the sketch requires no modifications, load it to your Raspberry Pi Pico. Then open your Serial Monitor and set the baud rate to 115,200 bps.
You should see a list of local WiFi networks, their SSID (if they allow it to be displayed), their encryption method, and their signal strengths. The list repeats after a short delay, so if nothing appears on your screen immediately, wait a few seconds before pressing the panic button!
WiFi Library with Pico W
Now that we have confirmed that we can work with the Pico W using the Arduino IDE, we are ready to write some of our own code to exploit the new WiFi feature.
To do that, we need to know how to connect the Pico W to a WiFi network and how to use web data and build web interfaces.
Connecting to WiFi network
The first task we will examine is a common one, connecting to a WiFi network as a client. This will require us to pass our login credentials to join an encrypted network. After connecting successfully, we will be assigned an IP address.
The WiFi Library, already included in the Arduino IDE, is the key to making all of this work. This library has all the basic functions you’ll need to connect to and communicate over a WiFi network.
WiFi Demo Sketch
This sketch will illustrate the basic operation of the WiFi library. It just connects the Pico to your local 2.4 GHz WiFi network and reads the IP address assigned to it by your network’s DHCP server.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
/* Pi Pico W WiFi Station Demo picow-wifi-station.ino Use WiFi library to connect Pico W to WiFi in Station mode DroneBot Workshop 2022 https://dronebotworkshop.com */ // Include the WiFi Library #include <WiFi.h> // Replace with your network credentials const char* ssid = "YOUR_SSID"; const char* password = "YOUR_PASSWORD"; void setup() { // Start the Serial Monitor Serial.begin(115200); // Operate in WiFi Station mode WiFi.mode(WIFI_STA); // Start WiFi with supplied parameters WiFi.begin(ssid, password); // Print periods on monitor while establishing connection while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); delay(500); } // Connection established Serial.println(""); Serial.print("Pico W is connected to WiFi network "); Serial.println(WiFi.SSID()); // Print IP Address Serial.print("Assigned IP Address: "); Serial.println(WiFi.localIP()); } void loop() { delay(2000); // Print IP Address Serial.print("Assigned IP Address: "); Serial.println(WiFi.localIP()); } |
We start, of course, by including the WiFi library.
Next, we define some character constants for the SSID and password for the network we wish to attach to. Of course, you’ll need to edit the code to match your network parameters.
In the Setup, we start the serial monitor, as we will use it to display our connection progress and our resulting IP address.
The next line specifies that we want to run in Station mode. This line is optional, if you omit it, the library will just default to station mode.
We then use a WiFi.begin to initiate the network connection. Note that we pass the SSID and password in this command.
We then wait for the network to connect by monitoring the status of the WL_CONNECTED constant. If it is FALSE, then we are not connected. While waiting, we print periods to the serial monitor as a progress indicator.
We then connect and print out the resulting IP address to the serial monitor.
In the Loop, we just repeat the IP address printout every two seconds. This is useful as you can’t have the serial monitor open while you upload to the Pico W, so by the time you get it open you may well miss the results from the Setup routine.
Load the sketch to your Pico W and observe the serial monitor. You should get an IP address indicating that you are connected to your network.
To verify this, you can ping the IP address from another terminal on your network. You should get a response from the Pico W.
Using Web Data – WiFiClient
One reason you might want to connect a microcontroller to the Internet is to use data from a remote server. One of the examples included with the Pico boards manager does just that.
The WiFiClient sketch is an adaptation of the same sketch for the ESP8266 (most of the sample code has been adapted from sketches from other microcontrollers). It connects to the djxmmx.net server and triggers it every five minutes with a “hello” message to get a response.
The response is an amusing “quote of the day”, which will be printed on the serial monitor.
You can find the sketch in the same WiFi section from which we got the ScanNetworks sketch. After opening it, you’ll need to edit the “ssid” and “password” constants to reflect the correct values for your WiFi network.
The sketch essentially connects to the server and confirms the connection. It sends a string that says “hello from ESP8266” (maybe they should edit that for Pico W!) to the server and listens for a response. That response will be the quote, which we’ll extract from the data and print on the Serial monitor.
After that, we delay everything for five minutes to avoid flooding the server.
Load the sketch and let it run for a while. You’ll see several amusing quotes from some famous people, if you run it long enough, you’ll also see some repeat quotes. I guess that there can only be so many “quotes of the day”!
Pico W LED Control
Now that we have a handle on connecting the Pico W to a WiFi network, we can use this ability to do something useful.
LED Control Web Page
The useful task we will perform is to control the onboard LED with a web-based interface. This is essentially the same thing that Raspberry Pi provides an example for doing in microPython, in our case, we will be using C++ and the Arduino IDE.
The web page will be very simple, displaying just a single toggle button and indicating the current state of the onboard LED.
Of course, you can modify this example to control just about anything.
LED Control Code
Here is the code we will be using for our web-based LED control.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
/* Pico W Web Interface Demo picow-web-control-demo.ino Web Interface & WiFi Connection Control the onboard LED with Pico W Adapted from ESP32 example by Rui Santos - https://randomnerdtutorials.com DroneBot Workshop 2022 https://dronebotworkshop.com */ // Load Wi-Fi library #include <WiFi.h> // Replace with your network credentials const char* ssid = "YOUR_SSID"; const char* password = "YOUR_PASSWORD"; // Set web server port number to 80 WiFiServer server(80); // Variable to store the HTTP request String header; // Variable to store onboard LED state String picoLEDState = "off"; // Current time unsigned long currentTime = millis(); // Previous time unsigned long previousTime = 0; // Define timeout time in milliseconds (example: 2000ms = 2s) const long timeoutTime = 2000; void setup() { // Start Serial Monitor Serial.begin(115200); // Initialize the LED as an output pinMode(LED_BUILTIN, OUTPUT); // Set LED off digitalWrite(LED_BUILTIN, LOW); // Connect to Wi-Fi network with SSID and password WiFi.begin(ssid, password); // Display progress on Serial monitor while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } // Print local IP address and start web server Serial.println(""); Serial.print("WiFi connected at IP Address "); Serial.println(WiFi.localIP()); // Start Server server.begin(); } void loop() { WiFiClient client = server.available(); // Listen for incoming clients if (client) { // If a new client connects, currentTime = millis(); previousTime = currentTime; Serial.println("New Client."); // print a message out in the serial port String currentLine = ""; // make a String to hold incoming data from the client while (client.connected() && currentTime - previousTime <= timeoutTime) { // loop while the client's connected currentTime = millis(); if (client.available()) { // if there's bytes to read from the client, char c = client.read(); // read a byte, then Serial.write(c); // print it out the serial monitor header += c; if (c == '\n') { // if the byte is a newline character // if the current line is blank, you got two newline characters in a row. // that's the end of the client HTTP request, so send a response: if (currentLine.length() == 0) { // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK) // and a content-type so the client knows what's coming, then a blank line: client.println("HTTP/1.1 200 OK"); client.println("Content-type:text/html"); client.println("Connection: close"); client.println(); // Switch the LED on and off if (header.indexOf("GET /led/on") >= 0) { Serial.println("LED on"); picoLEDState = "on"; digitalWrite(LED_BUILTIN, HIGH); } else if (header.indexOf("GET /led/off") >= 0) { Serial.println("LED off"); picoLEDState = "off"; digitalWrite(LED_BUILTIN, LOW); } // Display the HTML web page client.println("<!DOCTYPE html><html>"); client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"); client.println("<link rel=\"icon\" href=\"data:,\">"); // CSS to style the on/off buttons client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}"); client.println(".button { background-color: #4CAF50; border: none; color: white; padding: 16px 40px;"); client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}"); client.println(".button2 {background-color: #F23A3A;}</style></head>"); // Web Page Heading client.println("<body><h1>Pico W LED Control</h1>"); // Display current state, and ON/OFF buttons for Onboard LED client.println("<p>Onboard LED is " + picoLEDState + "</p>"); // Set buttons if (picoLEDState == "off") { //picoLEDState is off, display the ON button client.println("<p><a href=\"/led/on\"><button class=\"button\">ON</button></a></p>"); } else { //picoLEDState is on, display the OFF button client.println("<p><a href=\"/led/off\"><button class=\"button button2\">OFF</button></a></p>"); } client.println("</body></html>"); // The HTTP response ends with another blank line client.println(); // Break out of the while loop break; } else { // if you got a newline, then clear currentLine currentLine = ""; } } else if (c != '\r') { // if you got anything else but a carriage return character, currentLine += c; // add it to the end of the currentLine } } } // Clear the header variable header = ""; // Close the connection client.stop(); Serial.println("Client disconnected."); Serial.println(""); } } |
Once again, we start by loading the WiFi library and defining the SSID and password information.
Next, we create a WiFiServer object named “server”. We put it on port 80, which is the HTTP port.
We define variables to hold the HTTP request from the browser and to hold the state of the onboard LED, We use a string variable for the LED state so that we can print its value on our web page.
We also define variables to hold Time so we can have a timeout on our web page. This is essential; otherwise, we would never disconnect and eventually use up connections.
In Setup, we start the serial monitor. We then initialize the onboard LED pin as an output and set it LOW to keep the LED off.
We then proceed to connect to the WiFi network, exactly as we did in our earlier demo sketch.
Finally, after we connect, we start the WiFiServer object we created.
In the Loop, we listen for incoming client connections. When we get a connection (i.e.when a web browser accesses the page), we start the timeout and see if there is any information from the client. Remember, our client can send information to control the LED.
If we get information from the client (an HTTP request), we break it down to see what value is in the URL string. Depending on the value, we set our LED on or off and style the onscreen pushbutton accordingly.
You can modify the style sheet settings in the HTML if you wish to change the button shape or colors.
Load the code and give it a try. You should observe the LED responding to the onscreen push button, which will change color and label every time it is toggled.
Of course, you can expand upon this concept to add more buttons and control additional GPIO ports.
Pico W Servo Control
Our final Pico W experiment will be building another web-based interface. This time, instead of a LED, we will be controlling the position of a servo motor.
Servo Hookup
Let’s get started by hookup up a servo motor to our Raspberry Pi Pico W.
The hookup is very simple, I used GPIO pin 2 on the Pico W so that I could also run the “Sweep” demo to test the servo before I worked on my code. You could actually use any GPIO pin.
Note that I’m using a 6-volt battery pack to power the servo motor. Most hobby-grade servos require 5 to 6 volts and actually favor the higher voltage, so a power pack consisting of 4 AA cells is a great choice. Otherwise, any external power pack with the correct voltage specifications will work.
Adapting old code
This was a pretty simple example to put together, as I just grabbed some code from a previous article that I did on using servo motors with the ESP32. The servo control code is exactly what I need.
I needed to perform a few minor modifications to get it to work, but they were pretty simple.
- I change the servo library from ESP32Servo.h to Servo.h.
- I removed the lines allocating timers for the servo.
- I removed the line for setting the servo PWM frequency.
Another change I made was to the color of the header text, that was just a personal preference and had nothing to do with conversion from ESP32 code!
Otherwise, the sketch is unchanged.
This illustrates the ability to reuse old ESP32 or ESP8266 code with the Raspberry Pi Pico W. In this case, the main change was the library, as the ESP32 won’t work with the Arduino Servo Library. In many cases, you can run ESP32 code unaltered.
Servo Control Code
Here is the code for the servo motor controller. You might want to compare it to the code in the ESP32 article to see how they match. The article also describes the operation of the sketch, which uses JavaScript to exchange the data for the slider position with the web server.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
/* Pico W Web Servo Control Demo picow-web-servo-control.ino Web interface for servo motor position Adapted from ESP32 code - https://dronebotworkshop.com/esp32-servo DroneBot Workshop 2022 https://dronebotworkshop.com */ // Include WiFi and Servo libraries #include <WiFi.h> #include <Servo.h> // Create a servo object Servo myservo; // Servo GPIO pin static const int servoPin = 2; // Network credentials const char* ssid = "YOUR SSID"; const char* password = "YOUR PASSWORD"; // Web server on port 80 (http) WiFiServer server(80); // Variable to store the HTTP request String header; // Decode HTTP GET value String valueString = String(5); int pos1 = 0; int pos2 = 0; // Current time unsigned long currentTime = millis(); // Previous time unsigned long previousTime = 0; // Define timeout time in milliseconds (example: 2000ms = 2s) const long timeoutTime = 2000; void setup() { // Attach to servo and define minimum and maximum positions // Modify as required myservo.attach(servoPin, 600, 2400); // Start serial Serial.begin(115200); // Connect to Wi-Fi network with SSID and password WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } // Print local IP address and start web server Serial.println(""); Serial.println("Pico W is connected!"); Serial.print("Assigned IP address: "); Serial.println(WiFi.localIP()); server.begin(); } void loop(){ // Listen for incoming clients WiFiClient client = server.available(); // Client Connected if (client) { // Set timer references currentTime = millis(); previousTime = currentTime; // Print to serial port Serial.println("New Client."); // String to hold data from client String currentLine = ""; // Do while client is connected while (client.connected() && currentTime - previousTime <= timeoutTime) { currentTime = millis(); if (client.available()) { // if there's bytes to read from the client, char c = client.read(); // read a byte, then Serial.write(c); // print it out the serial monitor header += c; if (c == '\n') { // if the byte is a newline character // if the current line is blank, you got two newline characters in a row. // that's the end of the client HTTP request, so send a response: if (currentLine.length() == 0) { // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK) and a content-type client.println("HTTP/1.1 200 OK"); client.println("Content-type:text/html"); client.println("Connection: close"); client.println(); // Display the HTML web page // HTML Header client.println("<!DOCTYPE html><html>"); client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"); client.println("<link rel=\"icon\" href=\"data:,\">"); // CSS - Modify as desired client.println("<style>body { text-align: center; font-family: \"Trebuchet MS\", Arial; margin-left:auto; margin-right:auto; }"); client.println(".slider { -webkit-appearance: none; width: 300px; height: 25px; border-radius: 10px; background: #ffffff; outline: none; opacity: 0.7;-webkit-transition: .2s; transition: opacity .2s;}"); client.println(".slider::-webkit-slider-thumb {-webkit-appearance: none; appearance: none; width: 35px; height: 35px; border-radius: 50%; background: #ff3410; cursor: pointer; }</style>"); // Get JQuery client.println("<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>"); // Page title client.println("</head><body style=\"background-color:#70cfff;\"><h1 style=\"color:#f7e00a;\">Servo Control</h1>"); // Position display client.println("<h2 style=\"color:#ffffff;\">Position: <span id=\"servoPos\"></span>°</h2>"); // Slider control client.println("<input type=\"range\" min=\"0\" max=\"180\" class=\"slider\" id=\"servoSlider\" onchange=\"servo(this.value)\" value=\""+valueString+"\"/>"); // Javascript client.println("<script>var slider = document.getElementById(\"servoSlider\");"); client.println("var servoP = document.getElementById(\"servoPos\"); servoP.innerHTML = slider.value;"); client.println("slider.oninput = function() { slider.value = this.value; servoP.innerHTML = this.value; }"); client.println("$.ajaxSetup({timeout:1000}); function servo(pos) { "); client.println("$.get(\"/?value=\" + pos + \"&\"); {Connection: close};}</script>"); // End page client.println("</body></html>"); // GET data if(header.indexOf("GET /?value=")>=0) { pos1 = header.indexOf('='); pos2 = header.indexOf('&'); // String with motor position valueString = header.substring(pos1+1, pos2); // Move servo into position myservo.write(valueString.toInt()); // Print value to serial monitor Serial.print("Val ="); Serial.println(valueString); } // The HTTP response ends with another blank line client.println(); // Break out of the while loop break; } else { // New lline is received, clear currentLine currentLine = ""; } } else if (c != '\r') { // if you got anything else but a carriage return character, currentLine += c; // add it to the end of the currentLine } } } // Clear the header variable header = ""; // Close the connection client.stop(); Serial.println("Client disconnected."); Serial.println(""); } } |
Load the sketch to your Pico W and then read the serial monitor to get its IP address (if you’ve performed the previous sketches, it will likely just grab the same IP address). Then open your web browser to that page.
You should see a slider control and a display of the servo position, from 0 to 180. Moving the slider will change the position of the servo motor.
Conclusion
Using the Pico W with the Arduino IDE expands the possibilities for this new, inexpensive microcontroller, especially as you can repurpose code written for the Arduino, the ESP32, and ESP8266.
While it certainly won’t replace the ESP32, especially where Bluetooth is concerned, it is still a viable choice, given its low price tag and the support of an already huge RP2040 community.
And you have to love a board named after a cow!
Parts List
Here are some components that you might need to complete the experiments in this article. Please note that some of these links may be affiliate links, and the DroneBot Workshop may receive a commission on your purchases. This does not increase the cost to you and is a method of supporting this ad-free website.
COMING SOON!
Resources
Code from this article – Pico W code in a ZIP file for your convenience!
RP2040 Boards Manager – GitHub page for the boards manager.
Arduino IDE – Download the Arduino IDE.
Really loved to learn the little board’s abilities. Thank you and stay well.
it was a great idea to avoid the micropython crowd and show your readers how to use the Arduino IDE to access Wi-Fi on the pico. Thanks a lot
Hi,
Thank’s for your work to get the Raspberry Pi Pico W up and running.
/ Bo Mathisen
It’s working.
Good work.
Thx here from Denmark.
The post was very encouraging and I had no difficulty in getting some very similar code up and running on my Raspberry Pi pico. When I tried something a bit more ambitious (based on code working on an Arduino MKR 1010) I hit problems. A generated web page included rather more JavaScript than your Servo example and it was clear that a lot of the code was not being rendered to the browser. I cut the JS to a minimum to test and in the end arrived at a workaround – I wrote each line to the Serial object in… Read more »
As always excellent presentation and understandable content.
Keep up the good work. Will be transfering some arduino nano projects to Pico W
Thanks
Paul H
Thank you very much for making your presentation available.
As always, very well explained and detailed.
All sketches worked.
hug from Portugal
Luís G.
Hello!
Can you tell how can i configure it as an Access Point?
Dear DroneBotWorkshop
I have learned a lot from your YouTube tutorials on Arduino IDE programming. I am doing some project, I am using nRF24L01 module. It works very well on Arduino Nano, but I can’t run it on Raspberry Pi Pico in Arduino IDE (using C++).
I will be very grateful if you help me in this matter.
Thank you in advance.
I’m glad you showed us how to use the Arduino environment for this. So many other tutorials are just the same Micropython example over and over!. Thanks.
Thank you for an awesome bunch of tutorials. Using your instructions I was able to implement a small weather station/ patio light control at my house connected to our WiFi network. w3schools.com has been invaluable in helping me understand the html and CSS needed to make it look good. I have one question that I have not been able to find an answer for. In several instances, but specifically the tags, you put a backslash after the href= attribute . I have to put the line of code in quotes so it doesn’t turn into html when this is posted… Read more »
After going through all the comments on Random Nerd, Sara Santos had posted the answer to my question. – add a backslash (\) before every double quote (the HTML text has double quotes. To send those double quotes to the client, without interfering with the double quotes of the client.println(“”), you need to add an escape character called backslash ( \) before the double quotes) Changed the client.println() over to a Serial.Println and watched the Monitor Output. This works exactly as Sara stated. If you omit the \, then the compiler starts to act up, it sees the first quotes… Read more »
Hey Bill, love your videos and all the exceptional content you provide your viewers on YouTube and here on your website, you are a true inspiration! Thank you for that, I appreciate you! But, for the life of me I can’t seem to find anything to click on to subscribe to your newsletter! Would you be so kind as to just add my email to the DB please? It could be from all the dust of new construction going on in here, but I just can’t find the link, probably a user headspace issue. Thanks again for all you do,… Read more »
Thank you so much for the most concise examples and explanations!
i love your explanations with excellent presentations. Seeing your posts, i can be enable to realize some difficulties . Thank you so much. By the way, what software do you use in your presentations? (if you can)
Hi ! This is completely fun until I want to use a DS18B20 and send temp by wifi. In fact the library does not have support for OneWire.(For that I should use an Mbed library, but not support wifi :(… ) Any ideas how to get both things together ? I mean earlephilhower library plus DS18B20.
(Obviously in Arduino IDE)
Just solved by replacing the OneWire Arduino Library by this:https://github.com/PaulStoffregen/OneWire In this library there are a couple of modifications in files: OneWire_direct_gpio.h and in: OneWire_direct_regtype.h Also you can comment the line #455 of OneWire_direct_gpio.h to avoid the warning “OneWire. Fallback mode. Using……..” By the way, Bill, you’re the best explaining in Youtube. Cheers. Alberto.
I am a subscriber to your YouTube channel. Now I have a Raspberry Pi Pico RP2040 W. It’s from Amazon. But I can’t install it by the methods described by you. PORT is not showing. May you help me get out of this?
Dear Paul, also I’ve some trouble, do not know if this also your case, but I’ll try to exaplain mine. Into the Device Manager I’ve a exclamation mark over the RP2 Boot. To solve: 1. unplug the board from PC USB port 2. press the BOOTSEL button and the plug the board inside the USB PC port 3. release the BOOTSEL button 4. open the Computer icon and double click the new RPI-RP2 storage unit 5. you should have two files, double-click on the INDEX.HTM one 6. you will be redirect on a web page, scroll down into the web… Read more »
I have succeeded in Blink to LED on/off with pico-w. Thanks a lot. I am also a subscriber of your YouTube channel. If I want to control the LED from anywhere. How could I do it? If possible please enlighten me.
I have succeeded in Blink to LED on/off with pico w. Thanks a lot. Now I want to control the LED from anywhere. How to do it? If possible enlighten me.
Hey Bill, love this PICO W video.
I have tried all sketches and they do work, as always!
But there are the 2 sketches LEDCONTROL and SERVOCONTROL which produce an error:
In the loop you use:
WiFiClient client = server.available();
and that doesn’t work, if replaced by
WiFiClient client = server.accept();
Then both sketches are OK