IoT – From the Sensor to the Cloud and back
IoT – Internet of … “T”echnologies?
In this blog I am going to present an example of a simple IoT (Internet of Things) project and share my experience. My goal is to get data from an embedded system to the cloud (sensor data/states) and back (control commands). The block diagram below provides an overview of the system I want to build (or how it eventually looked like!). Using Docker for all host-side services wouldn’t be necessary, however it’s an interesting technology to explore. In the end, Docker proved to be immensely beneficial, as it streamlined the overall workload.
In order to determine whether a gate is open or closed, a sensor is needed. Additionally, there may also be an actuator for opening and closing said gate, so I can control it remotely for example by using an app or via web interface. This is a very basic example when talking about IoT, where a simple piece of information is transmitted through a stack of technologies to eventually reach interested parties and/or vice versa. In the end my tech stack will use the following: A microcontroller using I2C to connect to a corresponding sensor and read out its data, a Wi-Fi module connected via an SPI interface, an InfluxDB that can be reached using HTTP to store and present previously collected data, and an app/webpage to control the actuator communicating using MQTT.
My embedded system is based on an Arduino UNO Wifi to which I’ve added a breakout board with a BME680 sensor (for temperature, pressure and humidity). As an actuator, I have an ST Stepper Motor Shield X-NUCLEO-IHM03A1 that drives a NEMA-17 stepper motor, which eventually is supposed to open and close the window of a greenhouse based on two temperature levels.
Using the most popular open source libraries, it was a simple task to connect to the sensor (Adafruit_BME680) and to drive the stepper motor (Ponoor_PowerSTEP01Library). Since I don’t have a starlink gateway available to get connected from the dessert, I have been satisfied having quickly established a connection to my local network. Nevertheless, for this use case it would be indeed interesting to have a mobile network integration or a LoRa link. But to keep it small and simple (or not too big and too complicated), I switch to computer-side services at this point.
Database and Dashboard – and First Docker Running Container
My teammates recommended to use InfluxDB for storing timeline data and Grafana for setting up a dashboard. However, since InfluxDB also provides dashboard creation capabilities, I decided to drop Grafana for now. Using Docker, setting up InfluxDB wasn’t a hack, as you simply download and run an already available docker image with InfluxDB installed. It eventually was a mix of using Docker Desktop and command line. Having the docker container running, I could log into InfluxDB which was now accessible through localhost:8086. At that point I have to create and configure a bucket, which provided the required credentials for the node (i.e. organisation’s name, bucket’s name and a super long token).
Now it’s time to set up an http inquiry to the set up InfluxDB to local host. How did I do it? I asked ChatGPT of course. After encountering a few minor issues, I was able to receive data sent by my node.
On InfluxDB, the sent data started popping up and I could adjust the dashboard, so that it eventually displayed the temperature, pressure, and humidity data in a viewable form.
Remote Controlled Node
As previously described, I want to control a stepper motor to open and close a gate, i.e. in my real case the window of a greenhouse. The node controls the window in respect to the temperature itself, which of course makes sense. Thus, there neither would be the need of having any remote control capability. But as a major focus of this project is on gaining knowledge of certain technologies, I require the ability to remotely open, close the window or activate auto-mode. As my expertise in creating web pages is limited, I turned again to ChatGPT for assistance.
The capability of ChatGPT is really exiting. But I also had to come back to reality at a certain point. It started off very well, however, I added too many and too generic requirements that ChatGPT was unable to comprehend. This resulted in more and more errors, ending up in completely starting over the entire web page project (to be said at this point: simply never hesitate to setup and use git which really helps to return to running states). By asking more concrete and simpler questions, ChatGPT supported me a lot to establish a web page eventually also running in a docker container accessible on localhost:8080 (shown below).
Pressing the buttons will now publish an MQTT message with the corresponding command (i.e. ‘open’, ‘close’ and ‘auto’, known by the node). In return my node publishes its status on a different MQTT topic on which my webpage has subscribed (‘Status’ and ‘Mode’).
Docker – the Solution
In the end of the day, I have three services running in Docker containers: an MQTT broker (I used Mosquitto), InfluxDB to store and display timelines of my environmental data, and my web page, which can control the opening or closing of the window. Now, handling three (or many more) containers starts to become a hassle. To mitigate that issue, I started to set up a YAML file (for which I kindly asked ChatGPT for support again). Inside the YAML file I could add the configurations for all Docker components, so it became quite simple to manage all the containers in one stroke. For the MQTT broker and InfluxDB, there were pre-built images available on Docker Hub, ready to use. Only my web page required a custom-built image, which was based on the default settings of my web project.
Looking back 10 years it for sure become (one may say) very simple to make a setup that transfer data from an embedded system to the cloud and back. It may even sound like that I have accomplished this IoT project in just one day. However, there were many new topics to learn, and not everything worked right out of the box. Ultimately, it took me about 10 uninterrupted working days to get an automatic greenhouse window, all troubleshooting included.
Eventually, I managed to control my node using a web interface and MQTT as a communication interface. The node reads environmental data and sends it to InfluxDB, where it is displayed on a dashboard. Upon sending e.g. the “Auto” command, the node starts to control its connected motor based on the temperature, opening it when too hot and closing it when too cold.
In terms of feedback for ChatGPT, I would say it helped me quite a bit in understanding the different topics. In other words, it seems to be a very useful tool to get started with new topics. However, it’s important not to overlook the moment where one needs to re-engage their own critical thinking.
This was really worth digging into. It provides another layer of abstraction to the operating system on which the services are running on, i.e. you don’t have to care about its installation details that are related to your specific OS (i.e. Linux, MacOS, Windows etc.). For many purposes there’s an image available already, like the ones I used for the MQTT broker and the InfluxDB. So it becomes a one-liner to download that image and run it.
And also, very supporting was “docker compose”. By creating a YAML file (you may ask ChatGPT of how to do that), you can add all container details into it, i.e. what image to use, what port to open, where to store persistent data, etc.. And then, it becomes a one-liner so start and stop all container inside that composition (or a one-clicker when using Docker Desktop). Compositions provide the advantage of controlling all containers in a single place. Docker Desktop will then visually group them accordingly so they are easier to manage and oversee.
IoT – Hardware
- Node: Arduino UNO Wifi Rev. 2
- Sensor: BME688 breakout board by PIMORONI
- Actuator: NEMA17 stepper motor and a
- ST X-Nucleo IHM03A1 (stepper motor driver shield to drive the NEMA17)
- Visual Studio Code with PlatformIO
- Ponoor PowerSTEP01 Library by Ponoor Experiments Inc
- Adafruit BME680 Library by Adafruit
- MQTT by Joel Gaehwiler
- WiFiNINA by Arduino
- Visual Studio (ASP.NET Core Web App)