Nano Sensor

By:
Posted: 10th December 2018
Category: Arduino
Comments: 0

After demonstrating the idea how to use the watchdog in a "thread" like mode, I can finally start to build a snode (Sensor Node) that can be deployed to gather data. The general idea is to keep the amount of components in the snode to as few as possible. This will ensure that there will be less things to break in the long run (and easy to replace if something does)! You probably have your own tested and proven method / style of doing it however I found my favourite set of components to accomplish this task:





I am not so sure if I will use the 3D printed mount at the end, but so far I like it. You can easily understand why I enjoy this small footprint (tiny and looks cool) and the screwshield is super useful because it will make sure that the pins will not fall out easily. I am sure that someone out there could design a PCB with all of the components but I do not have the skills to do so. The next thing that I would like this snode to do is to send temperature data to the "mothership". I will NOT USE the Raspberry Pi as the typical solution for the "storage server" and use an arduino uno (ideally Arduino Mega - massive flash memory for sketches and 4x more SRAM) with an ethernet shield (which has an SD Card slot for storing the data). I basically want something that will stay within the local network (I don't want it to be dependent on the internet - it is usually very tempting I know). The "mothership" implementation will be blogged about in the near future I guess... This will allow you to see the full picture of what I am trying to achieve here (hint: sensor network build only using Arduinos).

So now that I have all of the hardware sorted, it is time to get on to the software bit. Since this ethernet shield is not officially supported by the Arduino IDE you will need this library in order to talk to it. Also, this code uses the "thread" model so you will need to download and install this library as well for it to compile correctly. Here is what I have put together so far:

#include <UIPEthernet.h>
#include <Thread.h>
#include <ThreadController.h>

// Watchdog library !
#include <avr/wdt.h>

// ThreadController that will controll all threads
ThreadController controll = ThreadController();

//My Thread (as a pointer)
Thread* sendDataThread = new Thread();
//His Thread (not pointer)
Thread WotchDogThread = Thread();

#include <dht.h>
#define aPin A5 // Defines pin number to which the sensor is connected
dht DHT; // Creats a DHT object

EthernetUDP udp;

byte sensor_ip[] = {
192, 168, 7, 160 }; // sensor IP

byte sensor_server_ip[] = {
192, 168, 7, 150 }; // sensor server IP

// callback for sendDataThread
void sendSensorData()
{

int success;
int len = 0;

success = udp.beginPacket(sensor_server_ip, 8888);
Serial.print("beginPacket: ");
Serial.println(success ? "success" : "failed");

if (success )
{
// Read the Temp Data from the sensor
int readData = DHT.read11(aPin); // Reads the data from the sensor
float t = DHT.temperature; // Gets the values of the temperature
//float h = DHT.humidity; // Gets the values of the humidity

char float_str[6];

// use dtostrf() to convert from float to string:
// '1' refers to minimum width
// '3' refers to number of decimals
dtostrf( t, 1, 2, float_str);

success = udp.write(float_str);
Serial.println(float_str);

Serial.print("bytes written: ");
Serial.println(success);

success = udp.endPacket();

Serial.print("endPacket: ");
Serial.println(success ? "success" : "failed");
}

}

// callback for WotchDogThread
void resetWatchDog()
{
wdt_reset(); // reset the WDT timer
Serial.print("Watchdog RESET... ");
Serial.println(millis());
}

void setup() {

// immediately disable watchdog timer - just in case
wdt_disable();

Serial.begin(9600);
uint8_t mac[6] = {0x00,0x02,0x03,0xA3,0x14,0x05};
Ethernet.begin(mac, sensor_ip);

// Configure sendDataThread
sendDataThread->onRun(sendSensorData);
sendDataThread->setInterval(3000);

// Configure myThread
WotchDogThread.onRun(resetWatchDog);
WotchDogThread.setInterval(5000);

// Adds both threads to the controller
controll.add(sendDataThread);
controll.add(&WotchDogThread); // & to pass the pointer to it

wdt_enable(WDTO_8S);
Serial.println("Setup process complete..");
}

void loop()
{
// run ThreadController
// this will check every thread inside ThreadController,
// if it should run. If yes, he will run it;
controll.run();
}

Few things to note about the above code:

  • I am using UDP to send packets. You can convert it to use TCP however I do not see the point. TCP is much more taxing on the controller and does not really provide any benefits on a local network. And even if you loose a packet here and there it will not have a massive impact on the general outlook (your millage may vary if you are collecting CRITICAL data for one reason or another),

  • sensor_ip and sensor_server_ip need to be adjusted to meet your particular network configuration. Also do not forget about the DHT11 settings - they also need to reflect your setup. Or just replace it all together with a different sensor.... up to you as usual,

  • float_str variable is currently set to hold 6 characters.... If your working with one sensor only = nothing to do. However if you want to have 7 snodes -> you will need a way to accommodate it by adding an identifier (integer?) to the beginning of the string (this will need to be decoded by the arduino that receives the data cough cough sensor_server_ip cough cough). So for instance a string: 121.00 would mean: Temp 21.00 from snode with an ID = 1 (back garden). And a string: 235.00 would mean: Temp 35.00 from snode with an ID = 2 (car garage). I am confident you could potentially use JSON to make it a bit more flexible to potential changes in the length of the data being sent... I just might do that myself later on - will see,

  • when you compile the above code it will use around 63% of storage and 70% of dynamic memory. You can improve these numbers slightly by removing anything that has to do with the serial output (Serial.println, Serial.begin etc).


After burning the code onto the Nano the serial monitor should give you something similar to this:


The watchdog is being reset every five seconds (so the nano does not reboot) and the temperature data is being sent over to the "mothership" every three seconds. And in a nutshell this is it. The snode is finished. However at the moment it is being powered via an USB cable and there is no casing for protection. It is not suitable to be deployed out in the wild. I will however provide a solution to those last two issues soon (hopefully within one blog post).

Hope this helps !

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