• chevron_right

      Very DeepSleep and energy saving on ESP8266 – Part 6: Power DOWN/UP

      pubsub.slavino.sk / arduinodiy · Friday, 15 January, 2021 - 21:31 edit

    The easiest way to save power on an ESP8266 is in fact to switch it OFF when not needed and Switch it ON when needed. A typical example of that is a notifier that mail has been delivered or a door has been opened. Opening a mailbox or opening/closing a door activates a Switch that … Continue reading "Very DeepSleep and energy saving on ESP8266 – Part 6: Power DOWN/UP"

    Značky: #Elektro, #Arduino

    • chevron_right

      The IRF520 FET switching module

      pubsub.slavino.sk / arduinodiy · Sunday, 22 November, 2020 - 22:50 edit

    Various webstores sell a FET module that is aimed at switching high current loads with an Arduino or even a Raspberry pi. The module seems quite handy, especially if you do not like soldering. It has everything you need, including handy screw connectors for that heavy load you plan to switch. A quick glance on … Continue reading "The IRF520 FET switching module"

    Značky: #Arduino, #Elektro

    • chevron_right

      Dynamic icons & colours in Asynchronous webserver

      pubsub.slavino.sk / arduinodiy · Saturday, 24 October, 2020 - 17:11 edit

    What I will describe might be cut and dry for many people but beginners may struggle with it, hence this short instruction. Asynchronous webservers have some distinct advantages, he main one being the possibility to automatically update necessary elements of the served website without having to refresh the entire website. A typical example is a … Continue reading "Dynamic icons & colours in Asynchronous webserver"

    Značky: #Elektro, #Arduino

    • chevron_right

      Soil moisture sensors

      pubsub.slavino.sk / arduinodiy · Monday, 24 August, 2020 - 16:30 edit

    Soil moisture sensors are popular among hobbyists who e.g. want to monitor or automatically irrigate their plants. There are a number of cheap sensors available in the various ‘Chinese webshops’ but those come with a caveat. I will discuss a few and come with ‘solutions’ to some of the biggest problems. The above sensor is … Continue reading "Soil moisture sensors"

    Značky: #Elektro, #Arduino

    • chevron_right

      I2C address conflicts

      pubsub.slavino.sk / arduinodiy · Saturday, 25 April, 2020 - 10:55 edit · 3 minutes

    I 2 C is a handy protocol to control plenty of chips/sensors/actuators with only 2 pins. With 128 adresses available you would think you are not going to run into an address conflict, meaning you want to use 2 modules that have the same I2C address, but you’d be surprised. Many I 2 C modules can in fact be set for another address, usually through some address jumpers, but that is not always possible. Even when the chip itself has a possibility to select more than one I2C address, the module does not always implement that (Various PCF8591 modules for instance)
    The Adafruit I2C address list shows the I2C addresses of many modules.

    The Arduino does have one hardware I 2 C port, except for the Arduino Due, that has 2.

    So what can we do to use 2 or more I 2 C modules that share 0ne address?
    The only solution is to create multiple I2C busses.
    This can be done in 2 ways:

    Software
    The Wire Library that comes with the Arduino IDE only allows you to use the pins on the Arduino that are meant for I 2 C:

    Board I2C / TWI pins
    Uno, Ethernet A4 (SDA), A5 (SCL)
    Mega2560 20 (SDA), 21 (SCL)
    Leonardo 2 (SDA), 3 (SCL)
    Due 20 (SDA), 21 (SCL), SDA1 , SCL1

    The Wire library doesn’t cater for multiple I 2 C busses, you can only call one instance of it.

    So you will need a library that does allow multiple I 2 C objects. The 3 following libraries do that.

    SoftI2CMaster is a lean I2C implementation.

    SoftWire allows any pins of the Arduino to be used. It needs another library called AsyncDelay .

    Software_I2C on GitHub might be akin to this one from Seeedstudio , but I did not make a full comparison.
    Some more multiple bus Software I2C libraries can be found here .

    Using those software libraries is a quick and easy way to set up multiple I 2 C busses, but there is one major drawback. That is the fact that many existing libraries for I 2 C peripherals make direct calls to the “Wire” library. These would need some modification to make them work with another I2C library.

    Hardware .
    Instead of a software solution, it is also possible to use an I 2 C port expander. The TCA9548A is such an expander. It connects to the existing I 2 C port and then can be made to send commands to 1 of 8 different I 2 C ports.

    The TCA9548A has its own I 2 C address of 0x70, which can be changed using three pins. This allows you to have up to eight of these modules in your design, adding a total of 64 extra I 2 C buses that of course each can address some 128 device

    The TCA9548A operates on a range of 3 to 5.5 volts, making it suitable for say ‘old’ Arduino 5 Volt logic as well as the new 3V3 logic.

    Its use is quite simple: One only needs to write the required bus nr (0-7) to the Chips address (0x70 by default).
    It is easiest do to this in a routine:

    void TCA9548A(uint8_t bus)
    {
      Wire.beginTransmission(0x70);  // default TCA9548A address
      Wire.write(1 << bus);          // select bus
      Wire.endTransmission();
    }

    a program thus could look as follows:

    void setup()
    {
    TCA9548A(0);
    setup your device connected to bus 0
    TCA9548A(1);
    setup your device connected to bus 1
    }
    void loop()
    {
    TCA9548A(0);
    write to (or read from) device connected to bus 0
    TCA9548A(1);
    write to (or read from) device connected to bus 1
    }
    void TCA9548A(uint8_t bus)
    {
     Wire.beginTransmission(0x70);
     Wire.write(1 << bus);
     Wire.endTransmission();
    }
    

    As said, the default address of the TCA9548A is 0x70, but can be change over the range 0x70-0x77. Make sure that you have no other chip on the chosen address as commands to that chip could be seen as commands to the I 2 C expander.
    Chips in that range are:

    • HT16K33 LED Matrix Driver (0x70 – 0x77)
    • PCT2075 Temperature Sensor (0x28-0x2E, 0x48-0x4F, 0x70-0x77)

    • chevron_right

      Modifying the Cam32 Webserver HTML file

      pubsub.slavino.sk / arduinodiy · Monday, 9 March, 2020 - 13:45 edit · 1 minute

    20190803_150613.jpg?w=1024 The standard webserver for the CAM32 module comes with a hoist of options.
    If you want to modify that webserver e.g. add a button for the flash or whatever, you need to alter the webserver’s  HTML page.
    That however is not as straightforward as it may seem.
    Where is that HTML page??

    Well, if you look in the ArduinoIDE after loading the example file, there is one file, called ‘camera_index’  and when you open it up,you will see an array called “index_html_gz”. That is the index file…but it is encoded.
    So before one can work on it, it needs to be decoded back to html code.
    That is not impossible, as there is a site that can do that for us. It is Cyberchef .

    If you follow the above link, Cyberchef will open with the proper decode ‘Recipe’ set. You only need to paste in your code (from the array).
    In the output window you will see the decoded html file that can be saved.
    For efficacy I already did that for you and you can find the decoded html file here .

    After you made the desired changes, you need to encode the html page again and that can be done by cyberchef as well. When you click this link , it should give you the proper settings. Only need to use your HTML as input. Then copy the output without the first comma, and use that to replace the content of the “index_html_gz”  array in your camera_index file.

    Now I was going to add a flashbutton, but apparently that has been done already . You will also find a pretty decent one right here .
    You may also find a randomnerds article about various ESP32cam settings useful.

    The Pinout of the ESP32Cam is as follows:
    esp32camPins

    These pins are internally connected to the Micro SD card reader:

    • GPIO 14: CLK
    • GPIO 15: CMD
    • GPIO 2: Data 0
    • GPIO 4: Data 1 (also connected to the on-board LED)
    • GPIO 12: Data 2
    • GPIO 13: Data 3
    • chevron_right

      Very Deep Sleep and energy saving on ESP8266 – Part 5: ESP-NOW

      pubsub.slavino.sk / arduinodiy · Thursday, 6 February, 2020 - 17:13 edit · 5 minutes

    In the previous 4 articles on deepsleep and energy saving, I mainly focussed on establishing a WiFi connection to send data.

    Part 1 General – DeepSleep
    Part 2 Http requests – DeepSleep
    Part 3 MQTT publish – DeepSleep
    Part 4 MQTT subscribe – DeepSleep

    There are other ways to send data though that cost less time and therefore less energy than establishing a WiFi connection. One of those ways is to use ESP-NOW . ESP-NOW is a kind of connectionless Wi-Fi communication protocol that is defined by Espressif. In ESP-NOW, application data is encapsulated in a vendor-specific action frame and then transmitted from one Wi-Fi device to another without connection.
    The big gain in using ESP-NOW is that the ESP8266 (or ESP32 for that matter) does not need to make connection with a router, but it sends data immediately to another designated ESP, which makes the process much faster. That is also one of the drawbacks: you need an extra ESP8266 (or ESP32). That extra ESP can receive data from 20 other ESP’s.
    Another drawback is that the receiving ESP is ‘isolated’. Sure you can add an LCD to read the data, but it would be handier if the received data would be available on a network, for Home Assistant or openHAB being able to do something with it, or to store it in a database.
    ESP-NOW works fairly straightforward on the ESP32 and a very good “How To” can be found on randomnerdtutorials .

    It is perfectly well possible though to also use it on an ESP8266 and that is what I will be doing here. I am certainly no pioneer in this. Anthony Elder in fact already published code using ESP-NOW to transfer BME280 data and go to sleep in between, and also “ The guy with the Swiss accent’ did , as did some others , but usually based on Anthony’s code.
    Anthony’s sketches though do not have the receiving ESP connect to a network as well, but it can be done, albeit in a bit unorthodox way. Wim3D on instructables however follows an interesting concept as well as he has the sending ESP8266 connect to MQTT if the ESP-NOW transfer goes faulty. Sample code can be found here too (pdf),

    So what I will do here is:
    1 use one ESP8266 to read a sensor like the BME280 and send the data via ESP-NOW, keeping the ESP in deepsleep in between.
    2 use another ESP8266 to receive the incoming data and eventually send that via an http request or MQTT to the network

    1 The Sender
    There is plenty of information on the Web so there is no real need to reinvent the wheel. I used a sketch from Anthony Elder, that I adapted for my needs. It can be found here . Although this sketch does not have all the energy savings that can be made as shown in my parts 1-4, it is a good begin to test the ESP-NOW datatransfer.

    We can see that the transfer only takes a tadd less than 300ms and part of that is not even the active connection. By removing the print statements it is possible to shave off another 40-50msec. So can we win some more energy savings here. Let’s see. It turns out that that the biggest time saver we can implement is to add WiFi.persistent( false ); right at the beginning of the Setup(). Once we do that we go from 300msec to 87msec.

    That addition is now already in the sendfile I linked to earlier. When you decide to take out the Serial.print statements, do not remove the Serial.println(bme280.begin(), HEX); statement as that one initializs the BME280. You could ofcourse replace that by a simple bme280.begin(); call

    2 The receiver-basic
    As there is much info already available on the web, there is no need to re-invent the wheel. I adapted a sketch from Anthony Elder to serve my needs and it can be found here . It simply receives the ESPNOW messages and printes them to the serial monitor. Obviously that is still not what we want as we want it to function as either an HTTP or MQTT gateway, but for now it will do to test if we can make the ESPNOW data transfer.

    2 The receiver-MQTT
    Of course just printing data to the serial monitor is not going to be of much use, so I was looking for a way to make an ESP-NOW to MQTT Gateway. As it happens, ‘Swiss guy’ Andreas Spiess had already done work on that and provided a sketch that I only had to adapt slightly .
    As the present ESP-NOW sdk does not support simultaneous use of ESP-NOW and a wifi connection, the WiFi connection to the broker is now started a new when an ESP-NOW message is received. As apparently the ESP-NOW protocol cannot start after a WiFi connection has been made, the sketch is restarted every time an MQTT message is published.

    That of course is far from ideal and makes the gateway a bit slow, but it should not be a problem with ESP-NOW messages coming in that have a sensible sleeping period in between. Whether this reset is still necessary with the new sdk I need to check (when I have time)

    3 The receiver HTTP
    If you prefer an HTTP connection to upload the data to an SQL server (or Thinkspeak), that of course is possible as well. This sketch sends MQTT as well as HTTP .

    4 Miscellaneous
    There are a couple of functions important/needed to set up the ESP-NOW sender.
    Of course we begin with calling the necessary library espnow.h .
    Then we set up a data structure that we will send.
    We initialize the protocol with esp_now_init() .
    We define the role with esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);
    We define the peer (slave) that we will be sending to with esp_now_add_peer (remoteMac, ESP_NOW_ROLE_SLAVE, WIFI_CHANNEL, NULL, 0);
    and then we register the callback with esp_now_register_send_cb ([](uint8_t* mac, uint8_t sendStatus) . The callback function returns whether the delivery was successful or not.
    We finally send the data with esp_now_send (NULL, bs, sizeof(sensorData)); NULL means send to all peers (thats to say the ones we added)

    The code for the ESP8266 starts with a bit of an awkward instruction:

    extern "C" {
    #include <espnow.h>
    }

    that is basically to instruct the compiler to expect C code rather than C++ code
    Sendercode .
    ReceiveESPNOW and send through MQTT/HTTP code .

    • chevron_right

      stk500_getsync() attempt 1 of 10: not in sync: resp=0x7c

      pubsub.slavino.sk / arduinodiy · Friday, 31 January, 2020 - 19:47 edit

    There may be many reasons why you may get an stk500_getsync() error when uploading code to an arduino, but the 0x7c error is a bit rare.
    There might be various reasons for it, but when I recently got it on a “new” arduino nano, fresh from China, I could see that the Blink program that it came with worked, so I knew  that the processor was working.
    Ofcourse I tried another cable, eventhough a faulty cable usually gives another return code. Yes, it came with a CH340 chip, but that never caused a problem before.
    So i tried:
    Tools-Processor-Atmega328 (Old Bootloader)
    That worked immediately

    • chevron_right

      Very deep sleep – part 4, subscribing to MQTT messages

      pubsub.slavino.sk / arduinodiy · Sunday, 26 January, 2020 - 11:13 edit · 3 minutes

    In a previous article , I presented a deepsleep program for the ESP8266 that would publish mqtt messages when it woke up from deepsleep.

    In that article I wrote that receiving MQTT messages in a deepsleep-wake cycle is possible, but that it came with some issues of its own.  In the present article lets what we need to do to receive MQTT messsages while on a deepsleep wake cycle.

    First however ask yourselves if it is really a good idea to incorporate receiving MQTT messages in a deepsleep project: It will cost time and whatever you plan to regulate via MQTT will be practically null and void when the ESP goes into deepsleep.
    The only reason I can come up with is  using MQTT to instruct the ESP to not go to deepsleep yet, but do a firmware update first.

    Anyway, here we go. There are two hurdles to overcome:

    1. When did broker send the MQTT message?
      If your program sleeps for 3 hrs and the broker sent a message 2 hrs earlier, we need to make sure it is still there when the ESP8266 wakes up. Therefore we need to retain or persist the messages coming from the broker. Remember that when you retain a message, the broker will keep offering it on every wake up.
    2. How long do we need to wait for the messages to come in and how many messages are expected?
      Normally it is the ‘ client.loop ‘ instruction in void loop(){} that will gather the incoming messages, but with deepsleep we never get to the void loop() . But if we put the client.loop instruction in the setup, then it will run only once, which will likely not be enough to receive and process any incoming MQTT messages. So we need to build our own ‘loop’ in the setup.
      That loop should last long enough to process incoming messages, but still as short as possible to save battery-life.The most efficient way is to set a flag holding up the deepsleep and clear that flag when a message is received. But that means if no message received, the ESP does not go to sleep, so that’s not really an option (it can work with retained messages). That means we have to do it differently. Will get to that later.

    We will make a simple MQTT command to light the LED on a Wemos board. In the verydeepsleepMQTT.ino from the previous article, go to void reconnect, find:

    client.publish("home/sleep/stat/connection", "OK");

    and add right under that, the following line:

    client.subscribe("home/sleep/cmd/led");

    Then, at the end of the program, add the following routine

    void callback(char* topic, byte* payload, unsigned int length) {
    
    Serial.print("Message arrived in topic: ");
    Serial.println(topic);
    
    Serial.print("Message:");
    for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
    }
    digitalWrite(ledPin,LOW);
    }

    In the program find the line:

    //client.setCallback(callback);

    and uncomment that

    In the declaration section of the program, add the instruction:

    ledPin=3

    find the section ‘//Go do stuff’ and add:

    pinMode(ledPin, OUTPUT); // initialize digital ledPin as an output.

    then go to the setup() and find the line:

    sendMQTTmessage();

    and add right under that:

    if (!client.connected()) {
    reconnect();
    }
    for(int i=0;i<10; i++)
    {
    client.loop(); //Ensure we've sent & received everything
    delay(100);
    }

    This adds 1 sec to our wake time. You could try with less, depending on speed of yr connection and the amount of messages you expect.

    Now add an LED with 560 ohm-1k seriesresistor between 3.3V and the ‘ledPin’ and send the MQTT message “home/sleep/cmd/led” with payload “ON”. The next time the ESP8266 wakes up, the LED will light up for a short time and the serial monitor -if connected- will show the message that was received.

    To be fair……. this program will react to any payload, whether it is ON or OFF or anything else, as  I do not check for that, but you can easily do that yourself. My goal was just to show how to receive MQTT messages.
    Also, in the loop I created, I use short (100ms) delays. I do that because it is easy to follow. In real life though it is better to avoid delays.

    Full code download here . Beware. The sensor and ledPin are slightly different in that program.

    Part 1 General – DeepSleep
    Part 2 Http requests – DeepSleep
    Part 3 MQTT publish – DeepSleep
    Part 4 MQTT subscribe – DeepSleep
    Part 5 ESP-NOW -DeepSleep