Category: IoT

I bought a pack of 5 BME280s from ebay, unfortunately they sent BMP280s instead and wouldn’t offer a refund. A colleague at work had the same issue, it’s actually really hard to get the BME and not get fobbed off with the BMP. Another colleague mentioned to buy them from this seller on Aliexpress as they’re legit (he had a pack of them in his hand, the right ones!). Anyway, I haven’t ordered them yet so I’ll play with the BMP280 for now, same interface, just lacks the humidity sensor.

I ordered the BME280s but got sent the BMP280s, annoying!

Finding the I2C pins

Every board has the potential to use different SDA/SCL pins, fortunately for me, it was printed on the reverse of the board, but you might have to hunt around in the specification sheet of your board to find them.

Wemos Lolin32 board

Finding the I2C device

You can have many devices on the I2C bus, think of it like a public highway with many cars (devices) travelling on it at any time. Each device will have it’s own ID which you’ll need to know to communicate with it in your application. If the manufacturer doesn’t specify the device ID, fortunately there is an easy way to find it using the I2C scanner that Arduino provide, run this sketch and you should see something like the following

Arduino code for the I2C Scanner

Note that I had to override the I2C pins on the Wire.begin(), you might need to do that too.

Scanning...
I2C device found at address 0x76 !
done

Writing some code to read data from the sensor

Now I know the I2C pins, and the device address, I can start to write some code. I started off by looking at the example from Mongoose OS, but it seems theres an issue with the Arduino compat library, fortunately theres an answer on the forums.

Conclusion

Once again, Mongoose OS makes it REALLY easy to get started, the hardest part was figuring out the I2C connections but there’s plenty of resources online for helping with that.

My plan is to have a few of these setup, 2 inside my lizard enclosure (for hot and cool sides), a few around the house (humidity would be great, had a few issues with mould) and one for outside temperature readings. The next challenge I have is understanding how I can deploy the same application to multiple devices but with different config, so I can name the MQTT topics for each board. Time to get reading!

There’ll be quite a lot going on in this post, I’ve had a crash course in Mongoose OS the past few weeks so this serves as a brain dump!

The goal

To create a low powered, wifi enabled device that I can install under the access hatch in my rainwater tank, that will periodically take readings of the water level via an ultrasonic sensor and report that data to AWS IoT.

With no IoT experience, I was inspired by a colleague at work who has also done this, I thought it’d be a good way to get stuck in and learn something! I wrote a previous post about getting started with Mongoose OS

Wiring things up

First things first, the JSN SR04T sensor that I’m using here is the waterproof equivalent of the HC SR04, I didn’t realise this at first, but it’ll help you find resources easier knowing the interfaces are the same. One thing to note is that the HC SR04 will be able to take measurements at closer distances than the JSN SR04, this is because the HC SR04 has separate transmitter and receiver modules, whereas the JSN SR04 is a combined unit, and there is a delay in switching from the transmit to the receive signals, so it can’t read below about 20cm.

The sensor operates on 5v, which is great as the ESP32 has a 5v out, but we need to convert that down to 3.3v on the input (echo) as the ESP32 operates at 3.3v.

Kolbans’ ESP32 book has a wiring diagram for this, here’s a screenshot (also go check out the book and send him a few $, well worth it!)

HC SR04 wiring diagram from Kolbans book

I’m using a breadboard and jumper cables to make it easier, it’s not pretty but it does the job!

ESP32 setup with JSN SR04 using a breadboard. The helping hand is just there to hold the sensor

Interacting with the sensor

There are plenty of examples of how to use this sensor using Arduino, but I couldn’t find any for using Mongoose OS. I initially tried to use the Mongoose OS Arduino compatibility library, but unfortunately it wasn’t just a case of dropping in some Arduino code and it working as others have suggested, because there are certain Arduino functions that need to be wrapped in Mongoose OS (like pulseIn).

Thankfully the kind souls over on the Mongoose OS forums were able to help me with a pulseIn implementation so I could read the sensor data!

Interacting with the sensor is simple, signal the trigger pin for at least 10 microseconds, then read the duration of a signal from the echo pin. The duration is the time it took for the ultrasound signal to return.

Casting our minds back to Maths class all those years ago, with time (duration of the signal) and speed (constant of sound) we can calculate distance. Remember the pyramid? Heres an image from the BBC Maths website to jog your memory

I’ve chosen to send the data as JSON as it’ll be easier for me to do something with it later on.

The hardest part was understanding how the config works on Mongoose OS, I’ll have to do another post about that, but just remember that after flashing the device, it loses any previous configuration such as AWS config. So if you flash, you need to run this again.

mos build && mos flash
mos aws-iot-setup

Then head over to the AWS console and test this by subscribing to the topic, you should see something like this

Subscribing to a topic via the AWS IoT console

If your device appears to be working, but nothing is making it to the AWS console, check you haven’t blown away the AWS keys after a flash, run “mos ls”, then “mos aws-iot-setup” if theres no AWS pem/key files on the device.

Conclusion

As stated by the Mongoose OS team, it’s really easy to get started with an ESP32 device and AWS IoT. It took me about 2-3 hours getting the AWS IoT working, but admittedly most of that was lost understanding config injection in Mongoose OS, and drinking beer (it is a Saturday night after all).

This year, my goal is to learn as much as I can about IoT and AWS, they go well together and a $10 ESP32 board and a few dollars on the AWS account is a great way to get started.

The finished product!

I’ve spent a few weeknights playing around with Mongoose, most of my time was lost searching for documentation and guides, there’s not a lot out there so hopefully if you’re reading this, it’ll save you some time/pain.

Getting setup with Mongoose OS

You can use the Arduino IDE, but I’m going to jump straight in and use Mongoose instead, have a look at the Mongoose site for reasons why it’s a good choice.

Download and install the MOS tool (check their site for latest instructions). Once it’s installed, from the command line run the following to confirm it’s installed OK.

You can also open a terminal, I’ve got mine setup like this, works well for me so far.

My IDE setup for Mongoose OS development

Make sure you go into the settings for VS Code and change the save mode, I’ve been caught several times wondering why my code isn’t working, only to realise it doesn’t auto save by default and I’d just been deploying the old code over and over again!

"files.autoSave": "onFocusChange",

Deploying a hello world app

Now we’ve got our environment setup, lets deploy an app. I’ve created a skeleton hello world app so grab that using

mos console – attaches a console to the device so you can see any output

Check the github, but notice in the code I’ve setup a loop to keep printing hello world, this demonstrates importing some libraries and using a callback. Also notice that there is a newline on the end of the print, I found that if you don’t do this, the print buffers output, so the app will appear like it’s doing nothing for around 5 seconds then you’ll get one line printed with Hello World 50 odd times. The newline forces the buffer to flush to console.

Get familiar with that, then move onto the next section where we make it more interesting.

Making the app a bit more interesting, adding some LEDs

OK, so we can control the GPIO pins on the board (those with numbers) to either turn them on or off (HI or LOW). What I’ve done here is attach a resistor and LED to 3 of the GPIO pins and we’ll have the code cycle through those every second.

I’ve annotated the code with comments, but one important thing to note is that the GPIO pins can work on either input or output, so we have to set the mode to output (we’re outputting voltage to power the LEDs, not reading input data).

Also note that some of pins are reserved, here’s a quote from Kolbans book (well worth checking out if you haven’t already)

There are 34 distinct GPIOs available on the ESP32.
They are identified as:
• GPIO_NUM_0 – GPIO_NUM_19 Page 232
• GPIO_NUM_21 – GPIO_NUM_23
• GPIO_NUM_25 – GPIO_NUM_27
• GPIO_NUM_32 – GPIO_NUM_39
The ones that are omitted are 20, 24, 28, 29, 30 and 31.
Note that GPIO_NUM_34 – GPIO_NUM_39 are input mode only. You can not use these pins for signal output.
Also, pins 6, 7, 8, 9, 10 and 11 are used to interact with the SPI flash chip … you can not use those for other purposes.

Build and deploy the LED blinker code using

mos build && mos flash && mos console

Now we need to hook up the components, but at least with the above running you can use a multimeter to check the pins are being triggered, put the black probe on GND then the red on one of the specified pins, every 3 seconds you should see it powered on for 1 second, we’re almost there!

Prototyping the electronics

The easiest way of connecting this all up is with a breadboard. Take a positive lead from each of the 3 pins, then pass each one through a resistor, the LED, and then back to ground, you’re setting this up in parallel and only one route will be powered at a time.

LEDs connected via the GPIO pins

Remember to have the longer legs on the LED on the positive side, the resistors can be either way around, it doesn’t matter. You can also route all 3 to the same ground, I’ve used the negative rail on the breadboard to make this a bit cleaner.

Conclusion

That’s it, pretty simple, but it’s covered a lot of groundwork, at least in getting the environment setup, deploying an app, plugging in some electronics and testing it out. Next up I’m planning to use the JSN-SR04 sensor, which is a waterproof ultrasonic sensor. I’m already most of the way there using the LED example, should just be a case of reading from an echo pin!