Simple IoT image logging using

Since beginning of 2019 I’m participating in a project called “Low cost / low power sleep / WiFi Camera” so I purchased a couple of low cost boards, between them the LilyGO ESP 32 Camera.

ESP32 Lilygo 800×600 pix SVGA Camera. If you need a case, made one here is an interesting IOT API site

Not only an API but a very interesting infrastructure that is also possible to link BIGIOT with WeChat allowing to “chat” with your device and use it for Smart home or just to check what was the last image uploaded.
In my fork of this ESP32 Camera, since the original looks a bit unmaintained without even an issue board, I added some better display information: BIGIOT_UpdateImage.ino

This example shows how to set up an automatic camera that takes pictures every 20 seconds and sends them like an API Post push to BigIot.
So far so good, it works at first glance. The issue is that BigIOT is all in Chinese and there is no english. So if you consider that a problem then you can stop here. I didn’t because I think the Chinese know hell about this and they are leading the IoT world for a good reason.

So I translated it as I could just to register and get this pieces of information:

#define BIGIOT_API_KEY "KEYHASH" ( 智能设备 Devices -> APIKEY)

BigIOT Registration -> 注册


After registering you just have to open the activation Email and you are good to go. Just log in the Admin Panel and try to feel at home. Most important parts are:

智能设备列表 List of your Devices -> Add a “Camera device”

数据接口列表 List of your Inputs -> This is the Interface, so just make an “Upload interface”

And that are the two IDs you need, device ID and interface ID. After that and compiling this, the small camera is going to start pushing pictures to BigIOT and you can just click on the stats on the interface area and start checking the pictures when you are away.

Very good to control for example a 3D printer that you leave at home finishing something. This is the result:

Interface statistics
BigIOT Interface statistics
Here there is a great example on how to Listen to Commands to interact with WeChat

Espressif multi-SPI workshop

Serial parallel interface was developed by Motorola in the eighties and is the standard or short communication in embedded devices.

Left side: ESP32 master. SPI single slave example. Right side: Arducam camera slave
( on SS low camera communicates with master )

The data transmission is explained in detail in the Wikipedia SPI article. But basically is along this lines and we will add some code examples below:

  1. The bus master sets up the clock using a frequency supported by the Slave device.
  2. Master selects the slave device with a logic level 0 on the select line.
  3. During each SPI clock cycle a full duplex data transmission occurs. Master sends a bit on the Master Output Slave In line (MOSI) and the slave reads it. The slave sends a bit on the MISO line and master reads it.
Image source: Wikipedia SPI article

That’s basically the essence of it. There is much more happening under the hood and it’s explained with more in detail on the referenced article. The interesting part of the SPI interface is that we can have many Slaves communicating with the master, since when the SS line is HIGH the slave ignores the master, so we can basically have a different SS (Or Chip select line) per device. So you can use the same Clock, Mosi and Miso to communicate with many SPI devices as long as the data communication happens with one device at the time.

The problem appears when you need to communicate with two different SPI devices at the same time

For example, in the WiFi Camera project, we made an experimental model with a st7735 small 128×128 pixels color TFT display that is also SPI. So if you want to make a progress bar in the moment where we are reading the Camera memory, you cannot use the same SPI interface, because you will share the data line and get a corrupted image.

Maybe there is a way to do it that I’m not aware of. When yes, then please add a code example ;) So my intuitive solution to the problem was to use a second SPI interface, completely independent from the Camera SPI. So that was a nice idea, but implementing it was not so nice, and the issue is that most of the libraries instantiate SPI like this:


Or simply:

SPI.begin(); // To use default GPIOs

At this point we could make a stop and mention that the ESP32 has some custom SPI gpios that are by default used when you do an SPI.begin() without any values. And that is very well explained in the Espressif documentation for SPI master driver:

IOMUX pins for SPI controllers are as below:

GPIO Number

So if I understand well and you see the GPIO writings on most ESP32 boards SPI.begin() without parameters starts the interface using the VSPI gpios also 18,19 and 23. But what happens if you want to use another GPIOS ?
No problem, just start SPI.begin() with the GPIOs you want to use. That as long that you don’t need to use a second SPI device. Because when you are instantiating SPI at a global level, you are instantiating a class that will use that GPIOs for all your program. So the solution is to use two different classes and there is a very good example about this in the SPI Multiple buses example on Espressif repository.

The problem is many libraries have not considered the possibility of multiple SPIs

At this point I had a solution but I was still far away of implementing it. Arducam library is pretty old and I could say, not maintained for the future generations of ESP32 chips. Even the SPI instantiation has to be done outside the Lib although the SPI.transfer and so on are fixed inside it. Too bad. TFT st7735 is a very nice lib and well maintained so it lets you define your own SPI gpios in the configuration. So after some minutes of doubt I decided to recode the SPI functions of the Arducam and make them mine. So that is what I did, to recode the SPI functions, leaving arducam library as a minimal I2C communication lib and taking SPI to my own command. Not a big deal, just check what functions are in charge of SPI.transfers and so on, copy them to your own and replace this by your own implementation.

We start our own class in a global level:

SPIClass * hspi = NULL;

void setup() {
   hspi = new SPIClass(HSPI);

  //        sck, miso, mosi, ss
   hspi->begin(16, 0, 4, CS);
   hspi->setFrequency(4000000);  // 4 Mhz

And that is it. After this we will use this hspi for our camera communication, leaving the other SPI for the display. It worked out, after some minutes of tweaking and burning my fingers changing wires from one GPIO to another.

PlatformIO: An alternative to Arduino IDE and a complete ecosystem for IoT

PlatformIO Logo

As an introduction I would like to make clear that I’m not a C++ advanced coder or IoT professional, I do this just because it’s a challenge, and because it’s a lot of fun compared to my 9 hrs/5 days a week web developer doing PHP and Admin panels for clients in Germany. Two months ago I started tinkering with SPI Cameras and the Espressif systems boards and that’s how this open source project was born. So far I was using Arduino since I do not need a super IDE, sometimes I also edit the code with vi or gedit instead of open a monster IDE that will eat your CPU alive. But gladly this is not the case. I was since long looking for a competitive alternative to Arduino when this github issue on the FS2 Camera Project called my interest:

tablatronix commented 8 days ago

I had to manually install this button library as it is not in platformio , is it in arduinos?

And that’s how after a few clicks I discovered that according to their home page it’s an open source IoT ecosystem. But what interested me more than this is the subtitle:  “Cross-platform IDE and unified debugger. Remote unit testing and firmware updates

So instead of answering tablatronix issue, I started installing this new IDE, that happened in a breeze.
1. First thing is to install the VS CODE Version. I choosed the Visual Studio code option since it has more features. Microsoft’s Visual Studio Code is the base and PlatformIO is built on the top of this.

2. Go to “Extensions” and install PlatformIO IDE “Development environment for IoT, Arduino, Espressif (ESP8266/ESP32)”

platformio IDE extensions is marked in RED just before PlatformIO logo

3. In my case since I used Arduino IDE before, go to PlatformIO alien face logo and select “Import project from Arduino”. Then select the folder where your Arduino project is and PlatformIO will create a Workspace for you with all the necessary structure.

4. Adjust serial monitor baud rate.  If you are using Espressif chips edit platformio.ini and add the following line at the end:

monitor_baud = 115200

This will make your serial work in the right baud rate for ESP8266 /ESP32 (Serial is the plug icon in the bottom just before the Terminal > icon)

5. FS Data. If you are using SPIFFS that in Arduino is the /data folder inside your sketch you will notice that in PlatformIO this folder needs to be at the root level. So you can simply move it one directory above. To upload SPIFFS data use the following command in the terminal:

pio run --target uploadfs
IMPORTANT: As difference with Arduino if you try to save a file in /1.JPG here you will get it saved on:
/spiffs/1.JPG so create this folder on /data or you will get; VFSFileImpl(): fopen(/spiffs/1.jpg) failed

6. Libraries in PlatformIO live inside a folder on your project called .piolibdeps Thanks god, they are not distributed on 3 different parts, like it happens with Arduino (Some in Arduino/libraries, some in Programs/Arduino/libraries and so on) but are there available for you in just one place :)
To install a new library is very easy, just go to and type the name of the library to search. If found copy the resultant line in the Terminal just like point 5 and the IDE will look this up for you and download it using github to the  .piolibdeps folder.

pio lib install "WifiManager"

Sometimes you will need a library in a special branch and there is also an easy way to do this. Just use :

pio lib install <repository#tag> 

// Install development version of WifiManager library
pio lib install

7. If you use Arduino before it’s possible that you used some of it’s constants. So if your sketch compiles, but it does not runs like expected try to add this include line at the beginning

#include <Arduino.h>
Including Arduino.h at the beginning of the sketch

As a footer note I must make clear that it takes some time to get accustomed to the new IDE. But it comes with a great benefit as it shows you much better C++ warnings, it’s prettier to use, and has the advantage that you can Ctrl+Click and navigate between different classes. Something that it was not possible to do with my old IDE. And the most beautiful update is that all libraries are in a single place per Project, like it should be, leaving you a clear idea of how much code and dependencies you are adding into your sketch.

In FS2 project porting it to the ESP8266 Wemos board this happened like a breeze. And it was just the fact of upgrading my code to use OneButton library. adding the include Arduino.h and that is. After uploading SPIFFS data and the new code, the camera was ready to be used. Now it’s not always that easy. trying to compile the same code to an Heltec ESP32 board, I got SPI communication issues with the camera and I’m still fighting with it.

UPDATE: I found what is going on here, and it’s that there are some problems with my sketch that uses I2C and wire library to comunicate with the Camera on the Heltec ESP32 environment. Error message is:
i2cCheckLineState(): Bus Invalid State, TwoWire() Can’t init. I solved it updating the platformio.ini configuration file to use:
board = lolin_d32
So using this board it compiles and works correctly. No idea why it does not using heltec_wifi_lora_32 I will have to research more.

Additional links of interest:

Source filter: src_filter
This option allows to specify which source files should be included/excluded from build process. It could be useful to keep the same core for ESP8266 and ESP32 but including different files to support both. So far I’ve been using 2 different branches something that is hard to maintain for obvious reasons.

Library dependencies: lib_deps declaration in platformio.ini
Like composer for PHP, this IDE offers a way to declarate your libs in the ini file. To check how a professional software for 3D-printing does take a look in Marlin configuration file. This is a very important point to keep in mind since after the lib_deps list is correctly added and tested, people testing your code just need to hit “build” to download them, saving a huge amount of time. This are FS2 library dependencies.

FS2 Camera project

If you are interested to build your own WiFi Camera for around 40€ of components and maybe 5€ of 3D-printed case, then check this project on github:

I’m giving out in december ten free 3D-printed cases, if you are interested on getting one and putting together a WIFi Camera please choose between Black PLA, black PETG or RED transparent and comment in this post. You can send me the address later per private message or in twitter. Thanks for your interest!

Chunk uploading files via WiFi with Espressif boards

Derived from this FS2 Camera project I would like to make an sequential uploader that matches this use-case.
Any file major than 50 Kilobytes will be uploaded in chunks of 50 Kb, using the following workflow:

Picture.jpg (150 Kb) -> Read fifo from Arducam
                                              -> Send first 50 Kb to upload API along with an md5 hash of this first 50 Kb (Called API from now on)

API uploads this first 50 Kb chunk and returns a true if md5(File)==hash received if not returns false

-> ESP board receives this signal and repeats the upload if it’s false up to N times (3 or 4 times at least)

When sending the last part to API, we will add some parameter like EOF = 1 or something in this direction so the API understand this will be the last part to receive. And in successful upload of this last part the server side API will put this chunks together and return the full URL to the image.

This can be the basis to upload big images with consistency.

As you can see here uploading any File that is larger than 40 / 50 Kb is already a big challenge.  And I still didn’t saw this implemented anywhere so it will be a great challenge to build something in this direction

ESP-32 a new standard of speed and connectivity

Developed by Espressif the ESP32 brings a new standard in low-cost WiFi boards. After porting one project to this new board I must say that it’s very similar to the ESP8266 and most code except some updated libraries, should work with minimal effort. 

ESP32 is a series of low-cost, low-power system on a chip microcontrollers with integrated Wi-Fi and dual-mode Bluetooth. The ESP32 series employs a TensilicaXtensa LX6 microprocessor in both dual-core and single-core variations and includes in-built antenna switches, RF balun, power amplifier, low-noise receive amplifier, filters, and power-management modules.” – Wikipedia description

What is still pending on my side is to compare power consumption and other details as WiFI range (With and without antenna) between ESP8266 and this new ESP32. But overall I’m really excited to build things on the top of this.

Combined with @tablatronix amazing WiFi Manager library it gives creators the possibility to have an independant IoT device with custom configuration, autoconnect and full info of the device.

It’s still pretty much on development so they are many things that are normally worst at the beginning (SPI Flash File System for example, a hell lot slower and at the moment only usable for small configuration files for me) But that’s normal, things are going to be fixed over the time, and hell it’s open source so let’s give these guys a hand and report new findings so they can fix it as soon as possible.

Yesterday I found the time to refactor my digital Camera project to use ESP32 (Makerfocus Heltec board). If you are interested in seeing the code updates please my commits in the board/esp32-oled branch.

So far still on my tests I won’t expand myself too long on this one. Giving some pointers and links for further research below.

Arduino Core

SPIFFS (ESP8266 code should be refactored to reflect library update)


Using the OLED built in the Makerfocus ESP32

The ESP32 directory when installed using Arduino in Ubuntu is:
/home/martin/.arduino15/packages/esp32 -> I find weird that Arduino  keeps libraries in 3 different Folders making it very confusing to see library source code.

Uploading your pictures directly into the cloud

Yesterday I found some time to make an example of image push to the Cloud using Seafile storage. The idea is that instead of making a regular file upload that needs some kind of Backend gallery to preview the pictures, we can have a different take, like pushing the picture directly to your Cloud-storage.

WiFi Camera (C++) > API Endpoint (PHP) > Seafile cloud (Python/C)

So the first thing I tried is to browse the Seafile Web API manual and repeat in command line the curl commands. And then I found in packagist this great library that is a wrapper for all commands to implement them easily on your script.

For sure this would be also possible to do it without the middleware PHP, directly in C++ on the Espressif  SoC,  but I would like to have proper error handling and also to save a copy of the image in the case that the Cloud->push fails for any reason. It can be also a very complicated task considering they are at least 3 API calls using the bearer Auth token.


Short for Seafile upload this a code-example to make a PHP File upload using Seafile API and a simple JSON configuration

Repository lives here:

Configuration is easy:

1– You need to obtain a Token

curl -d “”

{“token”: “14fd3c026886e3121b2ca630805ed425c272Xxxx”}

2- Edit the sea-config.json and add it along with your seafile server and repository ID settings

  "seafile_host": "",
  "token": "14fd3c026886e3121b2ca630805ed425c272Xxxx",
  "repository_id": "Is on the last part of Url when opening a library: #my-libs/lib/REPOSITORY_ID"

3- That’s it ! You are ready to open the test provided in the github repository and see if the image appears on the cloud

FS2 camera from Blender to production

In this entry, I wanted to document what is the process of making one of this cameras, starting from the 3D – model to the end product where you turn it on and connects to WiFi ready to take pictures.

After removing the support and sanding the round columns the first thing is to connect the front and back case together and see that they fit correctly. Usually, they do but PET is a tricky plastic to print and the end termination is a bit rougher than with PLA so it requires some post-production work. As an advantage, this plastic is stronger than PLA, and will stand a crash much better since it’s more elastic and resistant. I would say the best termination and strength balance would be to print this in ABS but I dislike the smokes and the fact that is also very difficult to print at home.

When this step is ready then it’s the time to heat up the soldier and prepare the ON/off switch and the shutter button. Then there are 8 cables more that go from the Arducam (2 or 5 mega version) to the Wemos D1, that is the responsible of uploading the picture to the cloud. This is a prototype for myself so it looks a bit messy but shows how it is at this stage:

3 pair of cables from the left to the right: Battery, ON/off and shutter button

Then comes the reality shock moment that is to connect the Wemos ESP8266 through USB to the computer and upload the program that will do the magic of receiving the JPEG image from Arducam and upload it to a php API endpoint. Usually, at this point there is something that needs to be corrected, but either nothing works or all is fine and dandy. I open the mobile hotspot and turn on the camera. See if connects, try to take a picture, preview it on the PHP-gallery.  Try to test timelapse mode, see it works, and that’s pretty much it. A new camera is ready to be delivered.

FS2 WiFi camera

Connecting to SSL from Espressif 8266 SoC

There are 2 ways that I know about validating an SSL certificate:

1 –  Generate a root certificate in DER format (somehow tricky)

2 –  Copying the SHA1 hash from the browser certificate details (easier)

… and as we are mostly lazy developers we will go for the number 2

DER format into hexa

In this example, we will generate the code to validate https:://

In the address bar, to the left of the URL, click on the circled ‘i’ icon for more information.

Click on the ‘>’ icon.

Click on “More Information” button at the bottom of the window.

In the new window titled Page Info –, click on the “View Certificate” button. In the “Certificate Viewer” window, click on the “Details” tab.

In the “Certificate Hierarchy” top window pane click on “DigiCert High Assurance EV Root CA” so it is highlighted.

Click on the “Export…” button at the bottom of the page.

At the bottom of the page select “X.509 Certificate (DER)” format then click on Save.

Use your favorite program to convert the binary DER format to ASCII. Here is what I do in Ubuntu:

$ xxd -i DigiCertHighAssuranceEVRootCA.crt.der >cacert.h

Edit cacert.h to add PROGMEM and const keywords like in this ESP8266 example

Using a SHA1 hash

Well this one is the most easier and the one I use. Repeating the first steps of the first option, in the first window that you see the certificate information there is the SHA1 hash at the bottom.

So the trick is to simply copy it and for is:

Open it in any text editor and replace the “:” for ” ” spaces to paste it in the firgerprint variable declaration:

const char* fingerprint = “5F F1 60 31 09 04 3E F2 90 D2 B0 8A 50 38 04 E8 37 9F BC 76”;

Here you can see an example that is ready to compile and test

And since I’m really lazy to delete this Gutenberg demo of WordPress new editor I will leave the rest here. In resume, in this new editor pressing (+) you can add anything you want in the world. And it would be even cooler if they add a magical (-) button so you can remove the content with the same ease as adding it.

The rest comes from the new editor bells & whistles and it’s not of my writing

Imagine everything that WordPress can do is available to you quickly and in the same place on the interface. No need to figure out HTML tags, classes, or remember complicated shortcode syntax. That’s the spirit behind the inserter—the (+) button you’ll see around the editor—which allows you to browse all available content blocks and add them into your post. Plugins and themes are able to register their own, opening up all sort of possibilities for rich editing and publishing.

Go give it a try, you may discover things WordPress can already add into your posts that you didn’t know about. Here’s a short list of what you can currently find there:

  • Text & Headings
  • Images & Videos
  • Galleries
  • Embeds, like YouTube, Tweets, or other WordPress posts.
  • Layout blocks, like Buttons, Hero Images, Separators, etc.
  • And Lists like this one of course :)

Visual Editing

A huge benefit of blocks is that you can edit them in place and manipulate your content directly. Instead of having fields for editing things like the source of a quote, or the text of a button, you can directly change the content. Try editing the following quote:

The editor will endeavor to create a new page and post building experience that makes writing rich posts effortless, and has “blocks” to make it easy what today might take shortcodes, custom HTML, or “mystery meat” embed discovery.

Matt Mullenweg, 2017

The information corresponding to the source of the quote is a separate text field, similar to captions under images, so the structure of the quote is protected even if you select, modify, or remove the source. It’s always easy to add it back.

Blocks can be anything you need. For instance, you may want to add a subdued quote as part of the composition of your text, or you may prefer to display a giant stylized one. All of these options are available in the inserter.

You can change the amount of columns in your galleries by dragging a slider in the block inspector in the sidebar.

Media Rich

If you combine the new wide and full-wide alignments with galleries, you can create a very media rich layout, very quickly:

Accessibility is important — don’t forget image alt attribute

Sure, the full-wide image can be pretty big. But sometimes the image is worth it.

The above is a gallery with just two images. It’s an easier way to create visually appealing layouts, without having to deal with floats. You can also easily convert the gallery back to individual images again, by using the block switcher.

Any block can opt into these alignments. The embed block has them also, and is responsive out of the box:

You can build any block you like, static or dynamic, decorative or plain. Here’s a pullquote block:

Code is Poetry

The WordPress community

If you want to learn more about how to build additional blocks, or if you are interested in helping with the project, head over to the GitHub repository.

Thanks for testing Gutenberg!


Digital Camera FS2

Days after publishing this post about ArduCam and ESP8266 I got some good feedback and 2 friends asked me to get one Camera. At the same time my new 3D Printer “Prusa MK3” has arrived so I decided to make a case remake and release a new small Low-Resolution, instant WiFi upload Camera. What I’m trying to achieve here is a digital Polaroid. Press the shooter buttton and the JPEG will be uploaded to a digital gallery in the next 4 seconds. So it’s a pure WiFi camera, without memory card, and you need to be online to use it.
And that’s nowadays very easy right ? You just need to make a mobile hotspot in the phone if you are outside home. And if the camera does not detect a WiFi then creates an Access point called:

Then you have to connect to it through the phone and browse there will greet you a “WiFi manager” so you can select a WiFi and write the credentials to make a connection. After that you are all set, you just need to enable the hotspot and the camera will reset and connect to it automatically.

It can take a picture both with the shutter button or have a Video stream or Photo shoot via the Web UI. ( cam.local )


3D Renderings made with Blender

I decided to make a small release of 5 FS2 digital WiFi instant upload cameras at the price of 70 € each.

Materials and costs if anyone is interested to make one are the following:

  • 1S 3.7V Li-Polymer  (Got one in eBay)
    Battery size: 6 x 41 x 68mm  2000mAh /hr
    8.50 €
  • Charger: Adafruit Micro Lipo w/MicroUSB Jack  (eBay Not in the picture since this is just my personal prototype)
    8 €
  • Arducam Multi Camera Adapter Board 2MP (eBay)
    25 €
  • Wemos D1 mini
    6 € but can be purchased for less
  • Various connectors and cables (8 Pin SPI white)
    2.5 €

That gives a total of 50 € as total hardware costs, printing the case and testing that all works together I’m summing up and additional 20. And you can get 1 year of API use for free. Then you can move it to your own server or you will get part of my Amazon AWS invoice ;)

With the battery full loaded should be online for about 18 hours. It has an On/Off switch that is still not in the picture.

The photos now when it has all cables soldered are better than before although I liked some of the strange effects when the cables where loose. The idea is to make a camera that you shoot blindly without looking at the frame. That gives for me interesting results and I had a lot of fun with it. That combined that in about 4 seconds the picture is already online is really cool. If you are interested in getting one just contact me through this website. Shipping costs are not included.

Picture previews:


Photo shooter has 3 options:

  1. ONE CLICK Shuts only one picture
  2. LONG CLICK enters time-lapse mode (a picture every 5 min. but can be configured to your request, should be minimun time 5 seconds though)
  3. DOUBLE CLICK disables time-lapse mode

The picture is uploaded in my API but the code is called PHP-gallery and it’s in a public repository on github so it can be hosted in any location that supports PHP 5+ and image-magick (Thumbs generator)