0
shares
- Author
- Recent Posts
Researcher at
CIEMAT – PSA PhD. in Computer Science / Solar Thermal Energy Researcher
(see all)
- Flutter on Raspberry Pi with flutter-pi – 26 November, 2019
- ESP8266 NodeMCU pinout for Arduino IDE – 19 November, 2019
- Cross-compile and deploy Qt 5.12 for Raspberry Pi – 17 November, 2019
Let’s see how we can remotely control an RGB LED connected to our ESP8266 NodeMCU board. In this tutorial, we will set up an asynchronous web server and an API REST to control an RGB LED. For easily controlling it, we will develop a multi-platform app using Felgo. This app, same source code, can be compiled for Desktop (Linux, Windows and macOS) and mobile devices (iOS and Android). Have a look at the video below to see the app in action.
Background
We already covered some of the basics in previous tutorials. Check the following links to learn more about these topics.
- Work with a breadboard, a NodeMCU board and LEDs – Basic ESP8266 NodeMCU tutorial: Breadboard, Pinout and Dimmable LED with Pulse-Width Modulation (PWM)
- ESP8266 NodeMCU programming using Arduino IDE –ESP8266 NodeMCU programming: First Steps
- Set up an asynchronous web server for ESP8266 systems –Getting started with ESP8266 NodeMCU remote control from custom apps on Desktop, iOS and Android
- Develop multi-platform apps with Felgo Qt, QML and Felgo tutorial. NASA Astronomy Picture of the Day app for Desktop, iOS and Android
Hardware
We need an ESP8266 NodeMCU board, a breadboard, an RGB LED and some wires. If you have doubts about the different kinds of boards, have a look at An Introductory Guide to ESP8266, ESP-XX modules and NodeMCU. You can buy the parts separately or as a set (excluding the NodeMCU board). There are plenty of options. Hardware used in the particular example can be bought in the following links. The kit below is quite complete, it includes many sensors and even a development board compatible with Arduino UNO R3. I recommend that you buy it if you plan to work on additional projects, otherwise buying the parts separately is more cost effective.
- NodeMCU V2
- Elegoo EL-KIT-001 UNO R3 Project Complete Starter Kit with Tutorial for Arduino
These are affiliate links. This means if you click on the link and purchase the promoted item, we will receive a small affiliate commission at no extra cost to you, the price of the product is the same. We would really appreciate your support to our work and website if this is fine for you.
Outline
- Circuit diagram
- ESP8266 NodeMCU sketch
- Custom app for Desktop, iOS and Android
Circuit diagram
An RGB LED has indeed three LEDs, one per color, and four pins. The largest one is the common cathode (-) or anode (+) lead, depending on the RGB LED. If we have a common cathode (-) RGB, we have to connect this lead to the ground (GND pin). On the other hand, if our RGB has a common anode (+) lead, we have to connect it to the power (PWD pin).
The lead that is alone in one of the sides of the common lead corresponds to the red LED. The other two leads at the other side correspond to the green and blue LEDs, being the green lead the closer to the common LED lead.
By oomlout – RGB LED – RGBL-01-05, CC BY-SA 2.0, Link
In my particular case, I have a common cathode (-) RGB LED, therefore the common lead must be connected to the ground pin. The red, green and blue leads are connected, through three 220-Ω resistances, to the 12 (D6), 13 (D7) and 15 (D8) pins, respectively. The diagram is shown below. If you want to know more details about LEDs and the NodeMCU pin map, read Basic ESP8266 NodeMCU tutorial: Breadboard, Pinout and Dimmable LED with Pulse-Width Modulation (PWM).
RGB LED sketch
ESP8266 NodeMCU sketch
Our sketch is shown below. We need to install the ArduinoJSON, ESPAsyncTCP and ESPAsyncWebServer libraries on Arduino IDE. Check, Getting started with ESP8266 NodeMCU remote control from custom apps on Desktop, iOS and Android for further details about how to install libraries and the asynchronous web server.
#include <ESP8266WiFi.h> #include <ESPAsyncTCP.h> #include <ESPAsyncWebServer.h> #include <ArduinoJson.h> const char ssid[] = "WiFi_ID"; const char pass[] = "WiFi_Password"; const int port = 2390; const String REQUEST_LED_R = "/led_r"; const String REQUEST_LED_G = "/led_g"; const String REQUEST_LED_B = "/led_b"; const char PARAM_VALUE[] = "value"; const char STATE[] = "state"; const int R_PIN = 12; const int G_PIN = 13; const int B_PIN = 15; const int MIN_ANALOG = 1023; const int MAX_ANALOG = 0; const int MIN_COLOR = 0; const int MAX_COLOR = 255; AsyncWebServer server(port); void setup() { Serial.begin(115200); pinMode(R_PIN, OUTPUT); pinMode(G_PIN, OUTPUT); pinMode(B_PIN, OUTPUT); analogWrite(R_PIN,MIN_ANALOG); analogWrite(G_PIN,MIN_ANALOG); analogWrite(B_PIN,MIN_ANALOG); WiFi.mode(WIFI_STA); WiFi.begin(ssid, pass); Serial.print("Connecting "); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(300); } Serial.println(""); Serial.print("WiFi connected to: "); Serial.println(WiFi.SSID()); Serial.print("IP address: "); Serial.println(WiFi.localIP()); // Red LED server.on(REQUEST_LED_R.c_str(), HTTP_GET, [] (AsyncWebServerRequest *request) { // Set LED value setLEDvalue(request,R_PIN); // Send Json response to client sendJsonResponse(request); }); // Green LED server.on(REQUEST_LED_G.c_str(), HTTP_GET, [] (AsyncWebServerRequest *request) { // Set LED value setLEDvalue(request,G_PIN); // Send Json response to client sendJsonResponse(request); }); // Blue LED server.on(REQUEST_LED_B.c_str(), HTTP_GET, [] (AsyncWebServerRequest *request) { // Set LED value setLEDvalue(request,B_PIN); // Send Json response to client sendJsonResponse(request); }); server.onNotFound(notFound); server.begin(); } void setLEDvalue(AsyncWebServerRequest *request, const int pin) { if (request->hasParam(PARAM_VALUE)) { int value = request->getParam(PARAM_VALUE)->value().toInt(); int analogValue = map(value,MIN_COLOR,MAX_COLOR,MIN_ANALOG,MAX_ANALOG); analogWrite(pin,analogValue); } } void notFound(AsyncWebServerRequest *request) { request->send(404, "text/plain", "Not found"); } void sendJsonResponse(AsyncWebServerRequest *request) { // Create and fill json object for client response DynamicJsonBuffer jsonBuffer; JsonObject &json = jsonBuffer.createObject(); json[STATE] = "Done!"; AsyncResponseStream *response = request->beginResponseStream("application/json"); json.printTo(*response); request->send(response); } void loop(){}
The different part of the code with respect to the previous example (Getting started with ESP8266 NodeMCU remote control from custom apps on Desktop, iOS and Android ) is that we have declared three server.on statements for each one of the colors: red (REQUEST_LED_R), green (REQUEST_LED_G) and blue (REQUEST_LED_B). On each of them, we do the same: set the LED value accordingly to the value requested (setLEDvalue function) and send a response to the client (sendJsonResponse function).
Assuming that the ESP8266 NodeMCU IP address is 192.168.1.43, we are expecting requests of the following types. Once our sketch is loaded and our NodeMCU is powered up, we can check them in our browser.
http://192.168.1.43:2390/led_r?value=255 http://192.168.1.43:2390/led_g?value=0 http://192.168.1.43:2390/led_b?value=72
The setLEDvalue function checks that the request has the PARAM_VALUE (“value”) parameter, reads the value as a string and converts it to an integer value. We expect in the request values in [0,255] = [MIN_COLOR, MAX_COLOR].
Since we are applying Pulse-Width Modulation (PWM) to set the brightness of each LED, we have to set the range in [0,1023] = [MIN_ANALOG, MAX_ANALOG]. Have a look at Basic ESP8266 NodeMCU tutorial: Breadboard, Pinout and Dimmable LED with Pulse-Width Modulation (PWM) for more information about PWM.
We use the map function to map a value from the [0, 255] range to the [0, 1023] range. After that, we set the converted value (analogValue) to the appropriate pin.
void setLEDvalue(AsyncWebServerRequest *request, const int pin) { // If state is a parameter then read it and call setLEDvalue if (request->hasParam(PARAM_VALUE)) { int value = request->getParam(PARAM_VALUE)->value().toInt(); int analogValue = map(value,MIN_COLOR,MAX_COLOR,MIN_ANALOG,MAX_ANALOG); analogWrite(pin,analogValue); } }
The sendJsonResponse function sends a simple JSON object for acknowledgment purposes. We can inspect this response in our browser after sending a request.
{"state" = "Done!"}
Custom app for Desktop, iOS and Android
This app is open source and it’s available in our GitHub account. It is similar to one previously develop in Getting started with ESP8266 NodeMCU remote control from custom apps on Desktop, iOS and Android.
Felgo custom app
In this case, the body of our app has three sliders (red, green and blue colors). The QML code for the red slider is shown below, the same applies for the others. In this component code, we set some visual configuration together with the interval [from, to] = [0, 255] and the step size (1). We also call the processValueChanged JavaScript function when the slider value changes.
AppSlider{ id: sRed anchors.horizontalCenter: parent.horizontalCenter width: parent.width - 2*dp(50) tintedTrackColor: "red" from: 0 to: 255 stepSize: 1 onValueChanged: processValueChanged(confDialog.ip, key_r_led, value) }
The processValueChanged function receives as parameters: the IP address, a LED identifier (key_r_led, key_g_led or key_b_led) and the LED value. This function checks if the IP address is valid an uses a generic function to send a HTTP request to the asynchronous web server in our ESP8266 NodeMCU. This process and the code are explained in Getting started with ESP8266 NodeMCU remote control from custom apps on Desktop, iOS and Android.
This is the end of this tutorial! I hope you liked the content. Remember to stay tuned to Mechatronics Blog for cool and fun tutorials.
4.5
2
votes Article Rating