ESP32lights

luca 08/01/2018 12

Today’s project, ESP32lights, is a smart device based on the esp32 chip.

esp32lights-004 esp32lights-005

Thanks to ESP32lights you can turn a load on and off (I used it for my christmas lights)

  • manually
  • based on daily schedules
  • based on the light intensity

ESP32lights connects to your wifi network, can be configured and operated via a web browser and it’s optimized for mobile devices (responsive web interface based on jQuery Mobile).

Components

The heart of ESP32lights is the Lolin32 Lite devboard by Wemos. One of its digital pins is connected to a relay module, which controls the load. Two digital pins are assigned to the first i2c controller of the esp32 chip and are connected to a BH1750 light intensity sensor. All the elements are powered by an HLK-PM01 module by Hi-Link, which directly converts the mains’ 220V AC to 5V DC without the need of any external components:

esp32l-001

All the components are placed in a waterproof enclosure, to be able to use the device outdoor:

esp32lights-006 esp32lights-007

Programming

The firmware for the esp32 devboard is available in my Github repository.

In a following paragraph I’ll explain how it works. If you just want to build the device, you can program the firmware as it follows:

1) clone my repository in a local folder of your PC (you also have to install the development env esp-idf):

2) configure the correct settings for your wifi network and your timezone via menuconfig:

esp32lights-003

3) compile and flash the firmware:

make flash

4) store the image of the SPIFFS partition into the flash memory (replace the COM port of your devboard and the path where you saved the img file):

python $IDF_PATH/components/esptool_py/esptool/esptool.py --chip esp32 --port COM15
 --baud 115200 write_flash --flash_size detect 0x180000 /home/esp32lights.img

If everything is ok, when you connect to the serial console of the devboard (make monitor) you should see the following output:

esp32lights-025

Use

ESP32light publishes an HTTP interface you can use to set the schedules or the light intensity threshold or to manually turn the load on and off.

You can open the web interface connecting – through a PC or a smartphone -to the address http://<esp_ip> (the IP address of the board is displayed in the serial output as shown in the previous paragraph).

The interface has 3 tabs, one for each working mode:

esp32lights-001

The page footer displays the actual working mode and the relay status:

esp32lights-002

In this short video, you can see how the device works:

Software

I developed the firmware for ESP32lights leveraging what I explained in my previous tutorials about the esp32 chip. If you follow my blog, you probably understood that I really like the divide et impera method, that is divide a complex project into small, simpler tasks.

All the configuration settings of ESP32lights (actual working mode, start and stop time…) are stored in the NVS partition of the flash memory, as I explained in this tutorial.  In this way, it’s possible to keep them even if the chip is restarted:

nvs_handle my_handle;
int working_mode;
[...]
esp_err_t err = nvs_flash_init();
err = nvs_open("storage", NVS_READWRITE, &my_handle);
err = nvs_get_i32(my_handle, "mode", &working_mode);

The different elements of the web interface (html page, css style sheets…) are stored in an SPIFFS partition. In a previous tutorial you learned how to prepare the image and, in your program, get its content:

esp32l-002

In other tutorials I’ve also already explained you how to connect to a wifi network and how to use digital pins.

The setup phase is completed after having configured the BH1750 light intensity sensor. This sensor offers an i2c interface and therefore can be connected to one of the two i2c controllers of the esp32 chip as shown in this tutorial. In my program I included a driver developed by pcbreflux.

The main program runs two different tasks:

xTaskCreate(&http_server, "http_server", 20000, NULL, 5, NULL);
xTaskCreate(&monitoring_task, "monitoring_task", 2048, NULL, 5, NULL);

esp32l-003

The first one publishes the web interface, while the second one verifies – every second – if conditions exist (time or light intensity) to turn the load on or off:

if(working_mode == MODE_LIGHT && lux_valid) {
  int actual_light_value = get_light_value();
  if(actual_light_value < lux) {
    if(relay_status == false) {
      gpio_set_level(CONFIG_RELAY_PIN, 1);
      relay_status = true;
    }

Here’s in details how the http server fetches a static resource, stored in the SPIFFS partition.

First it adds to the resource path the root prefix for the SPIFFS partition (/spiffs):

sprintf(full_path, "/spiffs%s", resource);

then it checks if the resource exists in the partition:

if (stat(full_path, &st) == 0) {

if so, it opens the file in read mode:

FILE* f = fopen(full_path, "r");

and sends the content of the file to the client, reading blocks of 500 bytes:

char buffer[500];
while(fgets(buffer, 500, f)) {
  netconn_write(conn, buffer, strlen(buffer), NETCONN_NOCOPY);
}

Finally, this is how the web interface works. The interface is made by an html page (index.html) which uses jQuery to perform AJAX requests to the server and update the different page elements. You don’t need to enter the page name in the browser because of the http server automatically performs a redirect to it if the default page is requested:

if(strstr(request_line, "GET / "))
  spiffs_serve("/index.html", conn);

endpoints are published by the server and accessed using AJAX calls::

  • setConfig, to send a new configuration
  • getConfig, to read the actual configuration
  • getLight, to get the actual light intensity

When the page is loaded, it calls the getConfig endpoint to display the actual configuration; moreover it schedules every 5 seconds a call to the getLight endpoint to keep the light value updated:

refreshConfig();
setInterval("refreshLightLevel()", 5000);

When you click on the SET button, the page calls setConfig to send to the server the new configuration:

esp32l-004

All the information are sent using the JSON format. The esp-idf framework includes the cJSON library which makes it easy to create or parse a json message:

cJSON *root = cJSON_Parse(body);
cJSON *mode_item = cJSON_GetObjectItemCaseSensitive(root, "mode");
[...]
cJSON *root = cJSON_CreateObject();
cJSON_AddNumberToObject(root, "lux", light_value);
char *rendered = cJSON_Print(root);

Making of

I started the build of the device cutting a perfboard to the size of the enclosure:

esp32lights-008 esp32lights-009

The perfboard is screwed to the enclosure using two spacers:

esp32lights-010 esp32lights-011

I made two holes in one side of the enclosure for the main switch and for a status led:

esp32lights-012 esp32lights-013

I soldered all the different components on the perfboard and made the electric connections using wires:

esp32lights-014 esp32lights-015

To simplify the installation, all the external components (led, relay module…) are connected using jumpers:

esp32lights-016 esp32lights-017

First test:

esp32lights-018

I attached the light sensor to the top of the enclosure, after having made a hole to allow it to “see” the external light:

esp32lights-019 esp32lights-020

Finally I made the external connections, installing the main switch:

esp32lights-021 esp32lights-022

and connecting the output of the relay module to a wire with an universal plug at its end:

esp32lights-023 esp32lights-024

12 Comments »

  1. Georgian 08/01/2018 at 20:51 - Reply

    Hello, I see that you use a lot that AC/DC convertor. Are you satisfied with it. I just started using one for an ESP8266 project and so far no smoke and everything seems to work fine. Did you have any issues with them?
    Thank you.

    • luca 08/01/2018 at 21:32 - Reply

      Hi, so far the AC/DC modules I used in my projects worked great! No issues at all!

      • Georgian 09/01/2018 at 21:08 - Reply

        Thank you, I hope that mine will do just fine too. Great work.

  2. tom 09/01/2018 at 08:19 - Reply

    hi, Luca, i am in China and we want develop a device using ESP32 as the WIFI module. we have a device needs to be controlled remotelly with mobile phone. do you know any company or ppl who is good at this ESP32 based development?

    Thanks.

    • luca 09/01/2018 at 09:28 - Reply

      Hi Tom, try asking on esp32.com, it’s the “official” forum and there are freelancers who regularly write on it

  3. tom 09/01/2018 at 16:03 - Reply

    thanks, i will go for it.

  4. Daren 12/01/2018 at 08:49 - Reply

    Economics of scale kicking in. A 1A USB charger is much cheaper than the Hi-Link module, and is about the same size.
    The build quality is questionable and you have to pot them yourself then of course, but I have had good luck with them in similar applications.

    If you really wanted to get cheap since your design can be entirely isolated: Switch your relay out for a logic level triac and you can then drive this directly from mains with just two capacitors, a switching diode, and a zener. This comes with the warning that one leg of the ESP32 will be at mains level then so no human contact allowed once in circuit, and triac failure will likely fry the ESP32.

    • luca 12/01/2018 at 09:43 - Reply

      Hi Daren, thanks for your suggestions! To be honest I had some Hi-Link modules laying around and I this was a good project to test them.

  5. Lachlan 14/01/2018 at 12:15 - Reply

    Hi Luca, great project, is there anywhere that describes how the data in the webapp is accessed by the esp32 ?
    js and web development is not my strongpoint by any stretch
    thanks ! keep up the good work

  6. Lachlan 14/01/2018 at 12:17 - Reply

    ah sorry, ignore my question i hadn’t got that far down the article :-)

  7. Ted 14/01/2018 at 18:06 - Reply

    Your Hi-Link is dead!

    • luca 15/01/2018 at 08:23 - Reply

      Thanks Ted, now fixed

Leave A Response »

Click here to cancel reply.

This website uses cookies to ensure you get the best experience on our website maggiori informazioni

Questo sito utilizza i cookie per fonire la migliore esperienza di navigazione possibile. Continuando a utilizzare questo sito senza modificare le impostazioni dei cookie o clicchi su "Accetta" permetti al loro utilizzo.

Chiudi