ESP32 Camera module

Various Chinese webstores sell an ESP32 based Camera module. A known one is from LilyGo, but there are  very cheap, simpler module available too. The cheapest I found is the module as seen in the picture at 4.44 Euro, shipping included.

Using the built in camera program

Although it might not be the case for similar modules from various suppliers, mine actually already came with a camera application present in the ESP32.
To use that built-in program, one needs to connect to the ESP32-CAM acces-point in your WiFi list:


and then point your browser to ‘’ for  streaming video, or ‘’ for stills.
The documentation on this webserver is very scarce, only a bit of information is given here. But that does not really give much extra info. The Firmware in the camera could easily be something like this.

Uploading your own camera program

So far so good if you only want a simple IP cam and you do not mind it has its own AP. It is fairly easy though to upload a camera program, that for instance does not need connection to a separate AccessPoint, but what can be found within ones own regular network.

Such a program can be found among the ESP32 examples in the IDE:

We need to make a few changes in the program:
For my specific  module, I needed to select (lines 9-14 in the program)
and comment out the other defines.
For you that might be another model.
Now right under that, we define a string with the name we like the module to have in the DHCP list
Then find the “WiFi.begin()” command and add  2 lines in front, like so:

You will find it here.  Mind you though that this program needs ESP32 core 1.02 (or higher) to compile !!!! If you decide to role back to ESP32 1.01 core
Now we are (almost) ready for upload. As this ESP32-CAM module has no USB port for uploading, we need a 3V3 FTDI adapter to upload programs. Make sure it is a 3v3 FTDI adaptor (NOT a 5 Volt)

The connections are as follows

FTDI <-> ESP32
Ground <-> Ground
Rx <-> UOT
Tx<-> UOR

Additionally on the ESP32 module Pin IO0 needs to be connected with GND to put the module in Programming mode.
For my specific  module, I needed to select (lines 9-14 in the program)
and comment out the other defines.
Then in the IDE, under Tools, I needed to select
Board: “ESP32 Wrover module”
Partition Scheme: Huge APP (3MB No OTA)
Once the program is uploaded, Remove the  connection between IO0 and GND and press the reset button.
Now you need to find out the IP number. You can find this by opening the serial monitor, where the IP number is printed.
IF in the serial monitor you may see a ‘Brownout detector’  warning and repeated failed attempts to start the software, do not despair, it just means that your USB port does not provide enough power.
If that happens, connect the module to a proper powersource and check in the DHCP client list of your router, what the IP number is. The module should identify itself with the name we previously defined in the program. If you didn’t do that, it will identify itself as ‘expressif’.

Then open a browser and direct it to the IP number of the module.
In the screen that subsequently opens, scroll down and click “Start Stream”.
This should start the  camera stream.


There is also a button that says “Still”. That one should just make a still picture, but in the example program that we used, it will not store that picture. But that should not be too hard to add. I may do that in the future.Should you want to dabble into that, the following pins are connected to the SDCard:

  • GPIO 2: Data 0
  • GPIO 4: Data 1 (also connected to the on-board whiteLED)
  • GPIO 12: Data 2
  • GPIO 13: Data 3 (also connected to a small red led)
  • GPIO 14: CLK
  • GPIO 15: CMD

Mind you that the program will only allow one client to view the stream

Face Detection
The webserver has buttons for face detection. Sadly there is a bug. Face detection is working in the 1.01 core but not in the 1.02&1.03 core. So if you have core 1.02, you have to roll back AND use the ESP32CameraWebServer example program coming with THAT core. If you cant find that, it is (still) on the randomnerd github from Rui & Sara Santos

The site of Rui & Sara Santos is definitely good source on the ESP32Camera module is


Easy expansion of a DHT11 ESP8266-01 module

Various webstores sell (very cheap) a module with an DHT11, that takes a plug-in ESp8266-01, thus creating an easy way to ‘IoT’ the temperature and humidity in your house, or any place you want.

The module only uses 1 pin out of 4, but is a quick way to setup an ESP8266-01 application as it has a 3v3 regulator. As such it is also an easy base to use for projects that require a couple of more I/O pins.

Ofcourse one could solder wires directly to the head of the ESP8266-01, but a better solution is to create a little PCB in between  the module and the ESP8266.

For that, we need a couple of long headers and some scrap veroboard or strip board. This creates enough space to mount a small PCB as a ‘floor’ between the module and the ESP8266-01.

Veroboard and stripboard both have their pros  and cons: Veroboard needs you to connect the individual copper islets, but you don’t have to cut between the pins of the header, whereas stripboard doesn’t require you to connect individual islets, but you need to carefully cut the tracks between the 0.1″ spaced header columns.

Eventually you should be able to come up with something like this:

In this picture I expanded the module with a DS18B20, which explains the resistor at the top (is already replaced by an 0805 SMD resistor).

The DHT11 connects to GPIO2 and I have used GPIO0 for the DS18B20. If we look at the circuit of the module, we see that it has no pull up resistors on GPIO0 and GPIO2.

The reason for that is that the module is presumably for the ESP8266-01S that already has pull ups on GPIO0 and GPIO2, bt as I was using the regular ESP8266-01, there were no pull-ups.
The DHT11 module may boot without pullups and the DHT11 may render readings, but there will probably be an increased amount of false (‘nan’)  readings.
That can be solved by adding the appropriate 10k pull-ups to the board.
Here e.g. I have added an SMD resistor between the signal pin of the DHT11 and Vcc, which is a pull up on GPIO2 just as well.

Anyway, the extra PCB in between makes a further 3 pins available: GPIO0, GPIO1 and GPIO3. The latter 2 are ofcourse the Tx and Rx pin.
In order to use those as regular I/O pins, one needs to add the following two statements in the program:

pinMode(1, FUNCTION_3);
pinMode(3, FUNCTION_3);

A final remark on this module: realise that the DHT11 is placed close to the microprocessor, that generates heat and radiowaves. Those do affect the temperature reading. This can be up to 8-9 degrees difference. Bending out the DHT11 sensor -as shown in one of the pictures- gives much more reasonable readings.

The  method described here can also be used for some other ESP8266-01 modules that are available, such as the relay module , the DS18B20 module and the Neopixel controller (same link)

Solved: Starting programs at boot didn’t work on raspberry

Today I made a new fresh install of Raspbian-Stretch on my old RaspberryPi 1B. That board mainly has some python programs on it that MQTT info onto my network to OpenHab. The previous install had become a bit broken I think, it would crash every two days and rather than sorting that out, I decided a fresh install would be the quickest.

After installing a fresh Stretch image, I put all the programs and required libraries back on, a quick test and that all worked.
OK, now it is time to have the programs start automatically at boot.
That is also simple, I usually add the programs I want to start at boot in my /etc/rc.local file.

Always worked for me.
However, this time it didn’t and for the life of me I couldn’t figure it out. Why is a setup that used to work suddenly not working anymore, starting the programs at boot, while the programs itself work when started manually.
Trying trying trying. Writing the output from each command to a log file didn’t help me, logfiles stayed empty.
Then I decided to write the output of the entire rc.local file to a logfile with:

exec > /tmp/rc-local.out 2>&1;set -x

put that in the rc.local file right before the line that says “# Print the IP address”:

I rebooted and checked the file: /tmp/rc-local.out.

Now it became clear…. the paho (mqtt) module that these python programs were using was not found.
Odd.. I am sure I installed it……and when I manually start the programs they work 100%

I was thinking….. in my previous setup, I had installed the paho.mqtt library manually. It resided in a folder in my /home/pi directory. This time I had installed it with pip. Now it wouldn’t be that…… no, it couldn’t, could it?
The commands in the rc.local file, as far as I know are given by root and my /home/pi directory was owned by ‘pi’…….but that hadn’t changed between two installs and root has privilege anywhere right?

After some more searching I learned that the library “paho” had been installed by pip in the folder “/home/pi/.local/lib/python2.7/site-packages” but “sudo python” searches this library in the folder “/usr/local/lib/python2.7/dist-packages”.

I was not using sudo… but that is in fact what the rc.local does, so I was guessing that that was where my problem lied.

So, I needed to link the one directory to the other somehow.

This is what did that:

cd /usr/lib/python2.7/dist-packages
sudo ln -s /home/pi/.local/lib/python2.7/site-packages/paho

Then it all worked again.

Interesting info on how to start your programs at boot can be found here.

Using limitswitches with diodes

DC motors are often used in electronic projects and a special case is when a DC motor needs to be brought to a certain begin or end position without going further. Typically limit switches are then used. Such a switch is pressed by the motor when that motor reaches its end position. Similarly such a switch can be used when a motor reaches its begin position again.

Obviously, when a limit switch is pressed an action needs to be taken to stop the motor. The solution for that is in fact simple and old news, but surprisingly many hobbyists don’t know about that solution or struggle with it, and that’s why I will explain it here (with apologies to all people who do know it)

Motor in middle position

In the picture above there is a typical circuit for a motor with limit switches. Let’s presume the left switch is opened when the motor comes to its desired left position and the right one opens when the motor comes to its desired right position. Let’s also presume that the motor in that picture is in between left and right position.

It is easy to see that the electrical circuit is closed and that it doesn matter what polarity is used.

We then apply a positive voltage to the top wire and a negative voltage to the bottom wire. The motor starts turning left, until it reaches, presses and opens SW1.

Motor in leftmost position

At that moment, the electric circuit is open: Switch S1 is open and the left diode blocks a positive voltage. The motor stops.

To make the motor go back to its original position, we need to reverse polarity, so now the left most diode sees a negative voltage on its cathode and wil conduct curent: the motor turns reverse. After it travelled a fraction, SW1 will close again (as in the firts picture)…but that only becomes relevant later. We let the motor travel reverse till it comes to its desired right position, where it opens SW2.

Motor in desired right position

As soon as SW2 is open, the circuit gets broken again, no current will flow and the motor stops. As SW1 has closed again after the motor started travelling, the circuit will now conduct for a positive voltage on the top connector. Though SW2 is open, the right-side diode will conduct.

Arduino Atmega 2560 with ethernet W5500 module

If you want to connect the Arduino Atmega2560 with ethernet, there are various options. The easiest might be to get a shield. The regular Arduino shield should fit on the Arduino Mega as well. there are 3 versions of the shield: with an ENC28J60, with a W5100 and with a W5500.
The shields are fairly expensive, it is cheaper to get an ethernet module. These are also available as ENC28J60, W5100 and W5500.

With prices all in the same range (currently around 2.60 Euro), it is best to get a W5500, the most modern chip of the range, that definitely needs less memory than the ENC28J60.

To connect it to an Arduino Mega2560, one only needs 7 connections as shown in the image below.

The SPI connections can be best taken from the ICSP connector  and the chipselect from Pin 10.
Connections on the W5500 module are equally simple as they are usually printed on the module:
SCS is the chipselect that goes to pin 10
SCLK is the clock signal that goes to SCK on the 6 pin header.

When using the W5500, the ‘old’ Ethernet library is not usable anymore. You need to use the Adafruit Ethernet2 library or the WIZ_Ethernet_Library that supports the W5100, W5200 and W5500

Is the Si1145 reliable or is it a piece of crap

Currently working on a project that includes the Si1145 lightsensor.
The Si1145 measures visible light and infrared light and then calculates the UVI from that, without measuring actual UVA or UVB levels.
According to Adafruit it is very reliable.
When i used it however, it seemed the visible and infrared readings always hung around 625 or were 0, while the UVI was always 0.
Now ofcourse I could have a faulty sensor, but some browsing on the internet showed that this was a common occurrence.
When I put the (adafruit) library next to the datasheet, at first glance I couldn’t help but get the impression the library had some shortcomingins that might well explain the erratic behavior.

After some searching I found a latched library that worked better……but even then, in total darkness the ambient light and IR light hung around 600, but at least in daylight I would get different values and even a UVI reading.

The latter though proved totally inaccurate, easily going up to 7 in overcast weather.

I will do some further digging in the code but for now I would not recommend this sensor

Adding ADC channels to an ESP8266

One of the drawbacks of the ESP8266 is that it only has one ADC port.
In case you need more ADC ports, you could add an I2C ADC converter like the PCF8591 or the ADS1115, but there is a cheaper way that is easier to program as well.
You could use an analog multiplexer like the HCT4051, that can switch 8 ADC channels individually to the ADC input of your ESP8266.
Does this method have drawbacks? yes, you need 3 I/O pins to control the HCT4051 and the ESP8266 does not have an abundance of pins to begin with.
The circuit looks like this:

I have chosen GPIO12-14 to control the multiplex chip. If all control lines are LOW, the A0 line is patched through to the ADC of the ESP8266. If all control lines are HIGH, then the A7 line is patched through to the ADC channel of the ESP8266, the table below, shows the state of the I/O pins need to be in to read every individual analog channel

      S0      S1      S2
      GPIO14  GPIO13  GPIO12
A0     0       0       0
A1 0 0 1
A2 0 1 0
A3 0 1 1
A4 1 0 0
A5 1 0 1
A6 1 1 0
A7 1 1 1