In the last episode, we configured the ESP32 to set up its own local Wi-Fi network. With a PC, smartphone or tablet, we are able to log into this network called ‘ESP32_MyJourneyIoT’ and request a configuration page from the ESP32 web server using a web browser (at address 192.168.4.1). Now the SSID and password of the actual home network which connects to the internet via the router is entered into the text boxes on the page. After this page is returned, the ESP32 immediately tries to connect to the home router network while still being accessible via its own local network. If the login is successful, the RGB LED we hooked up to the ESP32 board using a breadboard, lights up green. The ESP32 is now ready to deliver another web page via the router network where another LED can be controlled.

PWM signals from the ESP32

The green LED indicating operational readiness is useful but a permanently lit LED only really tells you that the corresponding controller port pin is ‘high’. It could be that controller operation has frozen for some reason with this port pin stuck in a high state. In this condition, despite the LED state the controller will not be able to service any client requests. A flashing LED would be a more reliable indicator. Something like that can be easily implemented by slightly modifying the Arduino sketch used in the last installment. The main loop periodically checks to see if an HTTP request from a client has come in, followed by a short delay of 50 ms (and so on). By incrementing a count variable, we could easily make the LED go on and off, say approximately once per second. Even better, instead of switching between on and off we could gradually fade the LED brightness. To implement this you can use PWM functions of the ESP32 which the developers at Espressif have made available in a hardware-orientated library (see this tutorial). With
 
ledcSetup(0, 5000, 8);
ledcAttachPin(PinNumber, 0);
 
In the setup function the PWM channel 0 is set with a resolution of 8 bits and assigned an output pin. In the loop function you can then use
 
ledcWrite(0, DutyCycle)
 
to supply a duty cycle value ranging from 0 to 255 on channel 0. The equivalent Arduino PWM functions analogWrite(…) are not yet supported by the version of the ESP32 library I used.


Object Orientated Programming

The task now is to use the green LED to indicate signs of controller life using reusable routines stored as  files in our own library. I found a good tutorial describing how to do this on the internet, the original is in German. I then created two files RGBLED.h and RGBLED.cpp and put them in the library folder of the Arduino IDE. By default, the compiler searches for the code when the library is referenced in the main program using:
 
#include <RGBLED.h>

The library (which you can download below) is written in the form of a class library. It specifies variables and functions and is therefore a blueprint for what an RGB LED must be able to do within a program. For example, we can use the function
 
setRGB(byte colorRed, byte colorGreen, byte colorBlue)
 
to assign 8-bit values for the colors red, green, and blue so that the LED can take on any desired color. The class variables
 
byte redPin;
byte greenPin;
byte bluePin;
 
are byte values used to define the pins to which the red, the green and the blue leads of the LED are connected.
However, to address a particular RGB LED in the application code, we still need to construct an object from the blueprint (the class code) which is responsible for our RGB LED. In the main program, we can do that with
 
RGBLED BreadboardRGBLED(PIN_LED_RED, PIN_LED_GREEN, PIN_LED_BLUE);

RBGLED is the name of our class, BreadboardRGBLED is the name of the object which we can now use to address the specific RGB LED in the main program code. The constructing function (the constructor) is passed as a parameter together with the three ESP32 pin numbers to which the RGB LED is connected. Due to hard-coding used to assign the PWM channels 0, 1 and 2 in the library (screenshot), it is not possible to create more objects with this class to address additional RGB LEDs in the project. To build in that sort of functionality we would require tables to manage the hardware resources.



From now on we can define the color of our breadboard RGB LED in the main program by using
 
BreadboardRGBLED.setRGB(colorRed, colorGreen, colorBlue);
 
The fact that the LED is switched using PWM, with ledc… functions, all happens behind the scenes. Developers of the main program only need to know the above include line, the constructor, and the so-called ‘public’ function to set the LED color.

I also implemented the dimRGB() function in the library to be able to dim the color value set with setRGB() in about 16 steps (one step with each call, then the brightness returns to the set color value again). I have also moved the SwitchRGBLED(…) function into the library (we used this earlier). Using
 
BreadboardRGBLED.SwitchRGBLED(LED_GREEN);
 
you can make the LED light up green, with
 
BreadboardRGBLED.SwitchRGBLED(LED_ON);
 
the color that has just been defined using the setRGB function is applied again.
 

The ESP32 web server indicates signs of life

Using the library it is now easy to configure the ESP32 so that it continuously sends out a signal indicating it is waiting for requests. Now when the router SSID and password are set correctly, instead of the RGB LED showing a steady green light, it cycles continuously fading between full bright green and off.
It was only necessary to change the main program from the last installment slightly. Just before the 'delay 50 ms' in the main loop I inserted the line
 
BreadboardRGBLED.dimRGB();
 
The dimming only occurs when the router is actually logged in. The new status variable RouterNetworkDeviceState, is used for indicate this and is set to NETWORKSTATE_LOGGED when successful login is achieved.

I couldn’t resist expanding on the application we used in the last episode. It starts with this circuit: and I connect the blue LED in the RGB-LED via a 1k series resistor to pin 25 of the ESP32. Now in the configuration page, which can be reached using ‘192.168.4.1’, the color of the ‘OK signal’ indicated by the LED can be changed (see screenshot). After all you may prefer a blue OK indicator instead of green, or maybe the LED should not be so bright? Instead of text boxes, three sliders are used on the form to define the LED color values.



In the main program all setting values ​​are managed as usual using several arrays. The new array
 
int    ConfigType[8];

Determines whether the configuration value is of the type String (input is a text field) or Byte (the value of a slider position). The function
 
String EncodeFormHTMLFromValues(String TitleOfForm, int CountOfConfigValues)

generates the corresponding code of the HTML page.

When the network address 192.168.4.1 is accessed, a page containing six configuration values ​​(the first being the setting value for the actor LED) is sent. If you request the ‘normal’ web page via the router network, then the form sent consists of just a single text field to switch the LED. Since we use the same functions for compiling the HTML code and to evaluate the answers for both web pages, the program is quite compact.

Why not try it out - download the Arduino sketch below (it's worthwhile comparing it with the sketch from the previous installment). The library is of course included in the download. The RGBLED folder containing files with .h and .cpp extension, must - as already mentioned - be installed in the Arduino IDE library folder.

In the next installment, we will build on the knowledge gained in previous episodes to develop a device for sending measurement values to the cloud.