Arduino365 part 6: IoT Framework

26th April 2020

My goal in the past few weeks was to create a flexible IoT framework for the arduino nano (should work for uno as well). The typical scenario would be that the nano is placed in a remote or hard to access location in a custom enclosure + I want to be able to change some of the key settings from the comfort of my office. To do this I have used a combination of ideas. The node settings (IP address, subnet, gateway, IoT server IP address, PIN code etc) are all stored in the EEPROM and accessed during the startup of the board. This means that the IP address can be modified from a web interface (IoT Server) and changes will be applied when you restart the nano (which can also be initiated remotely). The second important part of the puzzle is the web server running on the nano. Without that none of the functionality mentioned above would be possible. I have been running very extensive tests on the uptime abilities of the nano (and uno) and I have found that running it for 50+ days is not a big deal. To achieve that I have obviously used a watchdog (software and wire plugged in to the reset PIN = works miracles), setting the burnout to a higher threshold, provided nice and steady power via an UPS and a thread library that allows me to run certain commands at preset intervals. The biggest challenge was to squeeze everything on such a small flash footprint and somehow have lots of flexibility with what the node can do.

I have designed this framework in a way that it has four threads:
1) watchdog: runs every 6.5 seconds and resets the watchdog timer
2) health: runs every X minutes and sends node health data to the IoT server (can be controlled)
3) sensor: runs every Y seconds and sends the sensor data to the IoT server (can be controlled)
4) custom: does whatever is needed for the specific deployment (can be controlled)

Thread 1-3 remain the same for all of the scenarios that a node will end up in. There is a limited amount of control the admin has over them. The two main options that are available provide you with the ability to disable a thread and to change the frequency of it sending the data to the IoT Server. The last thread however can have custom code inserted to do something different. I am currently experimenting with a temperature+relay addon (physical "block" that snaps into the main enclosure body). The custom code will be reading the temperature from the sensor (I am supporting DHT11/22 and DS18B20) and will trigger the relay at a specific threshold set in one of the EEPROM variables. It is possible to adjust that figure remotely by using one of the commands that I have implemented and it could be that I will be expanding that list as great ideas come in...

*** NODE MODE ***
112: Set Node Mode (IoT, P2P)

113: Set IPv4 Address
114: Set IPv4 Subnet
115: Set IPv4 Default Gateway
116: Disable / Enable PIN Check
117: Set PIN (4 digits)
118: Set IPv4 IoT Server Address
119: Disable / Enable Sensor Thread
120: Set Sensor Data Send Frequency
121: Disable / Enable Health Data
122: Set Health Data Send Frequency
124: Set RELAY1 ON/OFF at Startup
125: Set RELAY2 ON/OFF at Startup
126: RELAY1 Reverse Behaviour
127: RELAY2 Reverse Behaviour
128: Disable / Enable Thread
129: Set Thread Execution Frequency
130: Set Variable X
131: Set Variable Y
132: Set Variable Z
133: Report Relay Changes to IoT
*** P2P COMMANDS ***
140: Set Node 1 IPv4 Address
141: Set Node 1 PIN (4 digits)
142: Set Node 1 ON Command
143: Set Node 1 OFF Command
144: Set Node 2 IPv4 Address
145: Set Node 2 PIN (4 digits)
146: Set Node 2 ON Command
147: Set Node 2 OFF Command
600: Get Temperature From Sensor
700: ON / OFF Relay 1
800: ON / OFF Relay 2
998: Apply Changes
999: Restart Node
111: Get system data
123: Set Max Node Temperature
134: Set Request Spacer

* : new commands added on 28/06/2020
* : new commands added on 15/05/2020

Since I have demonstrated that my framework can work without an IoT server here, I decided to add few commands that will allow the administrator to adjust things as required. The general structure of the commands so far is that they allow you to control two other nodes. So you can set the IP of the node you want to control, the PIN code that it requires for you to authenticate and the command that sets something ON or OFF. I have been thinking and trying few different use case scenarios and so far this seems to be best way forward (until I find something better). So in a way in P2P mode the node acts a bit like a command center (Master/Slave relationship obviously).

To run a command you need to adhere to a certain format and rules. For example if you would like to change the IP address of the node to than this is how the command should look like. I am also going to assume that the current node IP address is and the PIN code is 5512. I am running this from a linux terminal and using the curl tool.


As you can clearly see there are 3 blocks of data that the node is expecting to see. First 3 characters are the command you want to issue (113 in our case). The following 4 character are reserved for the PIN code. And if the PIN check is not enabled you still need to provide it with something (good idea is just to use four zeros). Everything after that is considered as the data payload. The node will be expecting the IP address in hex format as it is easier to parse. Once the command is successful the node will return code 0. The second command (code 999) restarts the node so that the IP change will take effect. The interesting thing at the moment is that the node once restarted will send a "Hello" packet to the IoT server with the new IP address so that you will be able to see it on the dashboard that your changes took effect. I could also implement some sort of safety mechanism that will revert back to the old settings if things go south... So far it is what it is. Will be putting together a live node and I will be playing around with the temperature trigger and relay to activate something (I have a spare USB fan...).

Hey, like this? Why not share it with a buddy?