There are many applications to using ESP-WROOM-02 and its wifi communication function via Arduino program. Today, we’re going to get even more creative and make another Christmas decoration that glows according to weather information we obtain from a weather API!
Estimated time to complete: 90 minutes
Parts needed:
First, I’d like to try out a sample program to enable wifi communication on the Arduino program of ESP-WROOM-02. Choose File → Sketch Example → ESP 8266 WiFi → WiFi Web Server. This sample program is used for basic processing for wifi communication with Arduino.
Figure 1. Load sketch sample
This sample program makes ESP-WROOM-02 a server. When the program is started, it waits until there is a request from another terminal and as soon as a request arrives with a specified argument, it processes the argument. In our case, we’ll light up the LED using this program.
I’d like to test using the circuit from last time. Change where “2” pin is specified in the sample program to “13” pin.
Figure 2. LED control circuit
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 |
/* * This sketch demonstrates how to set up a simple HTTP-like server. * The server will set a GPIO pin depending on the request * http://server_ip/gpio/0 will set the GPIO2 low, * http://server_ip/gpio/1 will set the GPIO2 high * server_ip is the IP address of the ESP8266 module, will be * printed to Serial when the module is connected. */ #include <ESP8266WiFi.h> #include <Servo.h> const char *ssid = "Provide SSID of wireless router here"; const char *password = "Provide the wireless router password here"; // Create an instance of the server // specify the port to listen on as an argument WiFiServer server(80); void setup() { Serial.begin(115200); delay(10); // prepare GPIO2 pinMode(2, OUTPUT); digitalWrite(2, 0); // Connect to WiFi network Serial.println(); Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); // Start the server server.begin(); Serial.println("Server started"); // Print the IP address Serial.println(WiFi.localIP()); } void loop() { // Check if a client has connected WiFiClient client = server.available(); if (!client) { return; } // Wait until the client sends some data Serial.println("new client"); while(!client.available()){ delay(1); } // Read the first line of the request String req = client.readStringUntil('\r'); Serial.println(req); client.flush(); // Match the request int val; if (req.indexOf("/gpio/0") != -1) val = 0; else if (req.indexOf("/gpio/1") != -1) val = 1; else { Serial.println("invalid request"); client.stop(); return; } // Set GPIO2 according to the request digitalWrite(2, val); client.flush(); // Prepare the response String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now "; s += (val)?"high":"low"; s += "</html>\n"; // Send the response to the client client.print(s); delay(1); Serial.println("Client disonnected"); // The client will actually be disconnected // when the function returns and 'client' object is detroyed } |
When you start the program, try connecting to the router. If it’s connected it’ll display IP address, etc. on the serial monitor. So try accessing that IP address from the browser. When connected to /gpio/1, the LED lights up, and when connected to /gpio/0, the LED lights off.
Figure 3. Wifi access successful
Figure 4. Connection from smartphone
Next, for a practical example, let’s try to control the servo motor via wifi. The servo motor control should be the same as the LED control, basically. I will add a little bit of modification to the LED program and also add a bit of HTML when accessing from the browser.
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 |
#include <ESP8266WiFi.h> #include <Servo.h> const char *ssid = "Provide SSID of wireless router here"; const char *password = "Provide the wireless router password here"; Servo myservo; WiFiServer server(80); void setup() { Serial.begin(115200); delay(10); Serial.println(); Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); server.begin(); Serial.println("Server started"); Serial.println(WiFi.localIP()); myservo.attach(2); } void loop() { WiFiClient client = server.available(); if (!client) { return; } Serial.println("new client"); while(!client.available()){ delay(1); } String req = client.readStringUntil('\r'); Serial.println(req); client.flush(); // Match the request int val; if (req.indexOf("/gpio/0") != -1){ val = 0; } else if (req.indexOf("/gpio/30") != -1){ val = 30; } else if (req.indexOf("/gpio/60") != -1){ val = 60; } else if (req.indexOf("/gpio/90") != -1){ val = 90; } else if (req.indexOf("/gpio/120") != -1){ val = 120; } else if (req.indexOf("/gpio/150") != -1){ val = 150; } else { Serial.print("REQ:"); Serial.println(req); Serial.println("invalid request"); client.stop(); return; } myservo.write(val); client.flush(); String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now "; s += (val)?"high":"low"; s += "<ul>"; s += "<li><a href='/gpio/0/'>0</a></li>\n"; s += "<li><a href='/gpio/30/'>30</a></li>\n"; s += "<li><a href='/gpio/60/'>60</a></li>\n"; s += "<li><a href='/gpio/90/'>90</a></li>\n"; s += "<li><a href='/gpio/120/'>120</a></li>\n"; s += "<li><a href='/gpio/150/'>150</a></li>\n"; s += "</ul>\n"; s += "</html>\n"; client.print(s); delay(1); Serial.println("Client disonnected"); } |
In this program, angles 0 to 150 are displayed in the browser and when you click on each value, the servo motor moves to a specified angle.
Figure 5. Servo motor control via wifi
Since Christmas is just around the corner, I decided to make a Christmas decoration. Luxurious lighting that adds a lot of LEDs is good, but something that feels like Christmas right on your desk is even better. So, I modeled a snowman using 123d design. It is a tool that can model while combining different shapes, so even beginners can easily create 3D models.
Snowman model
Figure 6. Modeling a snowman
Please feel free to change the shape or the size according to your preference. When modeling is done, I tried outputting with a 3D printer. The arm didn’t come off nicely…unfortunately.
Figure 7. 3D printed snowman
Now we’ll need a full-color LED. Let’s combine the full color LED and wifi communication into a desktop device that will change the color of the LED according to the weather data from a specific location.
As usual, let’s think about the configuration of the device before creating a program or a circuit. The overall structure is as follows.
Figure 8. Overall device configuration
You can also connect directly to the API from the Arduino program to process and retrieve the data, but since the capacity of the Arduino program is small, we can consider external expansion, Arduino installs an external server “SERVER PROGRAM” and makes a request. The external server program connects to the API, acquires data in JSON format, and returns only necessary data to Arduino.
The API we’ll be using this time is OpenWeatherMap. It’s a free API available to you if you register. With this API, weather information of a place can be acquired by inputting the position information and a city name.
Figure 9. http://openweathermap.org/
Programs of external servers connected to the API are created in PHP. Using the program below, we can obtain weather information by using country, city, appid-API key as an argument. We will install this program in the environment where PHP runs and confirm the operation.
External server program (PHP): Get data from weather API
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?php $country = htmlspecialchars($_GET["country"], ENT_QUOTES, 'UTF-8'); $city = htmlspecialchars($_GET["city"], ENT_QUOTES, 'UTF-8'); $appid = htmlspecialchars($_GET["appid"], ENT_QUOTES, 'UTF-8'); $jsonAry = json_decode(file_get_contents("http://api.openweathermap.org/data/2.5/weather?q=".$city.",".$country."&APPID=".$appid)); if(isset($jsonAry->weather)){ echo $jsonAry->weather[0]->main; } else{ echo "no result"; } |
It’s complete if the weather information of the designated city is displayed when accessing the program from the browser.
Figure 10. Confirm in the browser
Next, let’s look at how to use the full color LED on the output side. Although it is said to be a full-color LED, basically it’s RGB (i.e. red, green and blue) LEDs on one board.
As shown in Figure 11, since the LED of each color glows with + and – combination, solder it so that it can be connected to the breadboard.
Figure 11. Full color LED
Figure 12. Solder the full-color LED
If you emit 3 full-color LEDs, the color becomes white. Since the voltage and current amount required for each color LED are different, it’s necessary to add different resistance values to each circuit.
Colors are displayed based on the following weather information when data is acquired from the API.
Figure 13. Full Color LED Control Circuit Diagram
ESP-WROOM-02: Light changing according to the weather
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 |
#include <ESP8266WiFi.h> const char *ssid = "Provide SSID of wireless router here"; const char *password = "Provide the wireless router password here"; const char* host = "external server host name where the program is installed"; const char* appid = "Set API key"; // APPID registered with OnlineWeatherMap const char* city = "Seattle"; //select city const char* country = "us"; //select country int color[3] = {255,255,255}; int colorPin[3] = {11,12,13}; void setup() { Serial.begin(115200); delay(10); Serial.println(); Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } int value = 0; void loop() { delay(1000); ++value; Serial.print("connecting to "); Serial.println(host); WiFiClient client; const int httpPort = 80; if (!client.connect(host, httpPort)) { Serial.println("connection failed"); return; } String url = "/sample/esp-wroom-02/weather.php"; url += "?appid="; url += appid; url += "&country="; url += country; url += "&city="; url += city; Serial.print("Requesting URL: "); Serial.println(url); client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n"); delay(1000); while(client.available()){ String line = client.readStringUntil('\r'); line.trim(); if(line.equals("Clouds")){ color[0] = 255; color[1] = 0; color[2] = 0; } else if(line.equals("Clear")){ color[0] = 0; color[1] = 0; color[2] = 255; } else if(line.equals("Rain")){ color[0] = 0; color[1] = 255; color[2] = 0; } else if(line.equals("Snow")){ color[0] = 55; color[1] = 128; color[2] = 255; } Serial.println(line); } for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 5) { for(int cp = 0; cp < 3; cp++){ float ledValue = color[cp] / 255; ledValue = ledValue * fadeValue; Serial.print("cp:"); Serial.print(colorPin[cp]); Serial.print(" ledValue:"); Serial.println((int)ledValue); analogWrite(colorPin[cp], (int)ledValue); } delay(100); } for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 5) { for(int cp = 0; cp < 3; cp++){ float ledValue = color[cp] / 255; ledValue = ledValue * fadeValue; analogWrite(colorPin[cp], (int)ledValue); } delay(100); } Serial.println(); Serial.println("closing connection"); } |
In this program, data is acquired every time to confirm the operation. Please change the settings according to your preference. When you start the program, the device glows based on that data after weather data is acquired.
Figure 14. Snowman glows based on the weather data acquired
After some final touches to the to the snowman, we’re done.
Figure 15. Complete snowman decoration
This time, we created a cute Christmas decoration using the weather API. By incorporating other APIs, programs and linking to a smartphone, I think you can create an even more interesting device. Please share your thoughts and ideas in the comment section below!