• 08/19/19 - Official ESP-IDF Mesh example into PlatformIO

    David M.08/19/2019 at 23:20 2 comments

    I tried uploading the ESP-MESH Internal Communication Example through PlatformIO but I couldn't compile it due to several undefined variable errors. 

    Fig. 28 - I switched the framework from Arduino to espidf in platform.ini but I received errors when compiling.

    After a few tries I realized that a few variables weren't assigned because they are supposed to be defined in the project configuration menu when using the official ESP-IDF toolkit. I followed the getting started guide and tried uploading it the old-fashioned way.

    Fig. 29 - Project configuration menu

    However, I would like to continue using PlatformIO due to its "Peek Definition" feature, so I instead define all of these variables at the top of the file:

    Fig. 30 - Manual defining of the config variables without configuration menu.

  • 08/15/19 - Next steps, WiFi low-layer research, ESP-MESH example

    David M.08/15/2019 at 23:31 0 comments

    Before deciding my next step, I decided to look ahead a few steps ahead and began thinking of how I want my mesh to function in detail. At first I thought that the best approach for this kind of mesh would be to send out packets which any of the nodes could catch and send forward, increasing the performance of the mesh when compared to routing tables, but then I learned of the multicast WiFi problems and its general inefficiencies with battery operated devices and broadcast storms. I took a step away from ESP-NOW to look at how WiFi works in general. In my research, I established that there are two main ways to transmit packets though WiFi: TCP and UDP. TCP ensures that the packet has been received by waiting for a response and re-sending the packet if it has not been received. UDP doesn't do this check at all so there is no certainty that the packet has been received, but is faster than TCP. There are no encrypted kind of packets out there, so the encryption must happen outside of the transport layer. To protect my mesh from jamming and denial-of-service attacks, I think, the channel hopping will do most of the work there, but there are other techniques, like 4-way handshakes. However, to protect the mesh from getting infected from a single tampered node is a completely different matter. With this question, comes another question: how do I know when one of the nodes becomes tampered with? Following the footsteps of SSL, i don't need to make it impossible to do, i just need to make it very hard to do. An example of what is hard to do would be to take down a camera while other cameras are looking at it. Following this analogy, I could do something similar.

    All of this research made me realize just how much thought can be put into making a mesh. I got curious of how other mesh solutions solve these problems. I have decided to revisit the idea to try something other than ESP-NOW for my mesh solution. Despite the absence of online tutorials, I'm willing to give ESP-MESH programming a try once more. I found example code which I will try flashing onto ESP32 with PlatformIO.

  • 08/14/19 - M5Cam works, Two-way Communication Demo completed

    David M.08/12/2019 at 23:06 1 comment

    I have acquired my third mesh node, the M5Cam board, and through some testing it appears to be working.

    Fig. 27 - The M5Cam browser interface

    Also, I finished up the demo of two-way communication by displaying the transmission log on SSD1331 OLEDs. Video in the tweet below:

  • 08/06/19 - More hardware research and WiFi transmission techniques

    David M.08/06/2019 at 23:15 0 comments

    Today, while searching for hardware, I learned about various ESP boards available, their advantages and disadvantages. I learned that the modules which come with a PCB antenna and an IPEX connector contain a zero-ohm resistor which is soldered to the PCB antenna by default. To make use of the IPEX connector, the resistor must first be undersold from the PCB antenna and re-soldered onto the IPEX connector line. I also learned just how much can go wrong when buying an antenna to make use of the IPEX connector. These properties include the resonant frequency, the its bandwidth and the gain on different sides of the antenna. There's a lot of time that can be sunk into optimizing just the antenna part. 

    (Electronic Component)ESP32-S, View Electronic Component, Original Product Details from Shenzhen ...
    Fig. 25 - The ESP32-S version of the board comes with an optional IPEX connector, while keeping the FCC certification.

    Then I learned about the ESP32-PICO-D4, which is an ESP32 module tucked into a small QFN package. I found an article suggesting that it is a great alternative for wearable tech, but not so great when it comes down to heat dissipation. The package contains the 240MHz crystal inside which is debated as a bad move. If I were to use this chip for intense WiFi transmisisons, then the frequency may fluctuate as far as 1kHz due to quick rise and fall in temperatures of the WiFi chip. This in turn may affect precise code execution and decrease chip's lifespan.

    Inside the ESP32-PICO-D4, should you use it in your design?

    Fig. 26 - The inside of the ESP32-PICO-D4. The crystal is included in the package right next to the CPU which can reach temperatures as high as 70°C. Crystals are not something you would want to heat up.

    Then I learned about the techniques used in WiFi transmission itself. For example, during the hop between the first and second node, I could start negotiating a connection with the node which I am approaching before I loose connection with my current node. This way I could ensure a stable switch from node to node. 

    Another technique I discovered is channel hopping. The WiFi protocol comes with 14 channels which is useful to avoid cross-talk. I could just negotiate between each node of my mesh which channel each node will use but if I am using my mesh around other WiFi traffic, some specific nodes using the same channels will be less responsive than other nodes in the mesh. While I could make the nodes check for channel congestion and switch to a channel which is not in use, it will take precious processing time to check each channel like that. Instead, I could make the nodes in the mesh hop between a set of channels in a known sequence to spread out the interference. So if one of the channels is heavily congested, it won't make a drastic impact on any of the nodes in the mesh in particular.

  • 08/05/19 - Choosing a board for the 3rd mesh node

    David M.08/05/2019 at 23:31 0 comments

    Having accomplished two-way communication, I think it is finally time to add a third node into the equation, creating an actual mesh. I prefer having a diversity of boards instead of buying a bunch of the same ones due to the advantages of developing. I researched various ESP32 boards I could get which contain capabilities I do not have access to yet. One of those capabilities is camera input. For that, I have three options: ESP32-CAM, ESP-EYE, and M5stack ESP32 Camera. They are mostly similar, but have a few key differences. All three use the OV2640 camera sensor.

    ESP32-CAM has an SD card slot, PSRAM, 14 GPIO's and uses an ESP32-S (PCB antenna, IPEX block output, FCC Certified).

    ESP-EYE has a 3D-PIFA antenna, 8MB PSRAM, digital mic, SPI pads,  and USB-UART bridge.

    M5Cam has a 3D-PIFA antenna, USB-C, GROVE port, battery interface and USB-UART bridge (Pads for 6-axis gyro, analog mic, barometer).

    So far, I think I prefer the M5Cam, but I will fully decide on this next time.

  • Findings Summary #1

    David M.08/02/2019 at 23:23 0 comments

    To sum up our findings so far, we were able to transmit 250 byte packets in one way at 330Hz, which lends us [330times-per-second x 250Bytes x 8bits-per-Byte / 1Mb] = 0.66Mbps (Mega-bits per second) of transfer speed, which is quite low compared to ESP-MDF (ESP-MESH) max speed of 10Mbps (Sect. 5.2). This is pretty bad if I were to try to transmit a 60fps video stream using this method.

    The two-way communication of one byte of data one way and back took around 5 milliseconds on average. 

  • 08/02/19 - First two-way communication Success!

    David M.08/02/2019 at 21:22 0 comments

    In my pursuit to find the two-way communication solution, I have made three posts on the most applicable forums I could find. 

    https://arduino.stackexchange.com/questions/67621/esp-now-master-and-slave-at-the-same-time

    https://esp32.com/viewtopic.php?f=19&t=11752

    https://esp32.com/viewtopic.php?f=13&t=11765

    I have also read through the ESP-NOW API reference to check if I have missed something from my view.

    https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/network/esp_now.html

    A little bit more digging around, I found a few pages indicating that two-way communication is indeed possible:

    https://www.esp8266.com/viewtopic.php?t=10647

    https://hackaday.io/project/164132-hello-world-for-esp-now/log/160570-esp-now-introduction

    https://github.com/espressif/esp-idf/issues/1461

    Update! For some reason, I turn on the same exact modules I programmed yesterday which didn't work no matter how I tried, now work first try. The problem must be in how I structure my code, and the timings of function execution. I hope I will find the issue which caused it.

    Anyway, now that it works, let's take a look at how it functions:

    Fig. 24 - Two-way communication between Node A and Node B. Captured with Five Wire.

    After the nodes discover each other using the ScanForSlave function, Node A sends out the first packet in my case, containing a 0x00 (Green pin). After some time, Node B receives it (Light-blue pin), and right after, Node A gets a confirmation message that it has indeed been received (Pink pin). Also, right after receiving the 0x00, Node B increments it to 0x01 and sends it back (Brown pin). After some time, Node A receives the 0x01, after which it also increments it by one and sends it back.

    This is how my two-way communication works for now. What I wonder about is whether it would be possible to transmit and receive packets at the same time by taking the advantage of using different channels, but I'm not exactly sure if that is possible at all on such a device.

  • 08/01/19 - Two-way Communication, first attempt failed

    David M.08/01/2019 at 19:49 0 comments

    To begin developing two-way communication, I will began with the example sketches. I have tried combining both Master and Slave example sketches into one but failed. To help me resolve this issue, I have reached out for help on Arduino and Espressif forums. While I wait for answers, I decided to explore more closely the advantages and disadvantages of using a pre-built mesh library, like Painless Mesh or ESP-MDF. Here's a snippet of code which I tried to use, but failed:

    void setup()
    {
      Serial.begin(115200);
      WiFi.mode(WIFI_MODE_APSTA);
      // configure device AP mode
      configDeviceAP();
      // This is the mac address of the Slave in AP Mode
      Serial.print("AP MAC: ");
      Serial.println(WiFi.softAPmacAddress());
      Serial.print("STA MAC: ");
      Serial.println(WiFi.macAddress());
      // Init ESPNow with a fallback logic
      InitESPNow();
      // Once ESPNow is successfully Init, we will register for recv CB to
      // get recv packer info.
      esp_now_register_recv_cb(OnDataRecv);
      esp_now_register_send_cb(OnDataSent);
    }
    
    unsigned long nextManage;
    
    void loop() 
    {
      // In the loop we scan for slave
      ScanForSlave();
      // If Slave is found, it would be populate in `slave` variable
      // We will check if `slave` is defined and then we proceed further
      if (slave.channel == CHANNEL2)
      { // check if slave channel is defined
        // `slave` is defined
        // Add slave as peer if it has not been added already
        bool isPaired = manageSlave();
        nextManage = millis() + 10000;
        while (isPaired)
        {
          if (packetRecieved)
          {
            packetRecieved = false;
            // Send data to device
            sendData();
          }
    
          unsigned long t = millis();
          if (t > nextManage)
          {
            nextManage = t + 10000;
            // pair success or already paired
            isPaired = manageSlave();
          }
        }
        Serial.println("Slave pair failed!");
      }
    }
    Fig. 23 - My first, failed attempt at a two-way ESP-NOW communication sketch. 

  • 07/31/19 - Hackaday project log created

    David M.08/01/2019 at 18:30 0 comments

    Today I started transferring all of my written project logs into a project log on Hackaday. From now on the project logs are written the day they are made.

  • 07/30/19 - Proper ESP32 boot without USB connection

    David M.08/01/2019 at 18:26 0 comments

    A while back I have encountered a problem with my ESP32 programming fixture. It was resetting the ESP32 if powered with a power supply, however it was fine when powered through a USB plug. To this day, I still haven't figured out what the problem is but here are the steps I took to fully fix the problem:

    • Make sure the power supply voltage at the 5V pin on the fixture is between 5.10V and 5.15V. Measure the voltage with a voltmeter, but test that the voltmeter is properly functioning first.
    • Check the voltage at 3V3 pin is indeed 3.30 volts.
    • Tie pin 12 to ground on boot, explanation below. 
    • Check the continuity of the wires used. Use the shortest wire path possible if it still doesn't work.

    I'm not sure why pulling pin 12 low helps, but according to this reference guide, it definitely shouldn't be pulled high on boot:

    https://randomnerdtutorials.com/esp32-pinout-reference-gpios/

    When I saw that bit of information I decided to try it out. I pulled pin 12 low and it appeared to help.

    I checked pin 12 with a logic analyzer but it did not appear that pin 12 was being pulled high on boot by the fixture.

    Further testing showed that if the power input wasn't sufficient, then the ESP32 could still be booted if pin 12 is pulled high first, then low, which allows it to function for a few seconds before it starts requiring more power for WiFi transmission.