This is the second part of the series for my Arduino wireless project I’ve been working on for a couple weeks now. You can start reading from the first post: https://aasullivan.com/?p=1146.
We have the idea, now we have to build it. I have three Arduinos set up at this point in this manner:
- (1) Set up as wireless receiver/hub; this will read data, print to Serial and log to ethernet eventually
- (2) Transmitters which simply read data every ~5 seconds to blindly send to receiver (node 0)
This layout will allow me to test from a couple devices to make sure the layout of the node IDs will work properly and be read properly as well. I ran into my first set of issues at this point: I can only read one Arduino at a time off Serial from the IDE, so went and imaged an older Dell D630 to handle the receiving end of things to troubleshoot the payload issues I ran into.
So, massive issues begin once first code goes into place and I learn how difficult it is to troubleshoot wireless data transfers when I cannot tell if it’s a receiver or transmitter issue. After many frustrating hours, I finally get a build working that transmit static values from one node to one hub. Mind you, this doesn’t include the actual ethernet logging as this was a whole new issue (will explain in later post).
Code is below, should have enough comments to understand the general idea behind it. For now, this will take data from a DHT11 temp/humidity sensor along with voltage readings and push this to the main hub/receiver node, which will read and push this to the Serial read bus.
Hope this is helpful, in the next post I’ll go over the updates to the SPI set up when using both the RF24 modules and an ethernet shield at the same time. Cheers!
Code for original build, receiver:
#include <RF24Network.h> #include <RF24.h> #include <SPI.h> // Number of Temperature sensors #define NumNodes 3 // nRF24L01(+) radio attached RF24 radio(9,10); // Network uses that radio RF24Network network(radio); // Channel of our node const uint16_t channel = 90; // Address of our node const uint16_t this_node = 0; // Structure of our payload struct payload_t { unsigned long counter; float tempC; float tempF; float Vcc; // 4 bytes }; // Since nodes start at 1, I added 1 to arrays to make it easier unsigned long NodeCounter[NumNodes+1]; float NodeTempC[NumNodes+1]; float NodeTempF[NumNodes+1]; float NodeVcc[NumNodes+1]; //Prototypes for utility functions void getRadioData(); // get Radio data void setup(){ //Start Serial Serial.begin(57600); Serial.println("Temperature Data"); SPI.begin(); // Radio setup radio.begin(); // network.begin(/*channel*/, /*node address*/); network.begin(channel, this_node); } void loop() { // Pump the network regularly network.update(); // Is there anything ready for us? while ( network.available() ){ // If so, grab it and print it out getRadioData(); } delay(100); } ////////////////////////////////////////////////////////////////////////////////// // getRadioData() // get Network data ////////////////////////////////////////////////////////////////////////////////// void getRadioData(){ RF24NetworkHeader header; payload_t payload; bool done = false; while (!done){ done = network.read(header,&payload,sizeof(payload)); NodeCounter[header.from_node] = payload.counter; NodeTempC[header.from_node] = payload.tempC; NodeTempF[header.from_node] = payload.tempF; NodeVcc[header.from_node] = payload.Vcc; Serial.print("Received packet #"); Serial.print(NodeCounter[header.from_node]); Serial.print(" from node#: "); Serial.print(header.from_node); Serial.print(" TempC: "); Serial.print(NodeTempC[header.from_node], 1); Serial.print(" TempF: "); Serial.print(NodeTempF[header.from_node], 1); Serial.print(" Vcc: "); Serial.println(NodeVcc[header.from_node], 1); } }
Code for transmitter:
//Updated Send Node to send from DHT data pulled from PIN2 #include <RF24Network.h> #include <RF24.h> #include <SPI.h> #include "DHT.h" //Define DH information #define DHTPIN 2 #define DHTTYPE DHT11 // DHT 11 //Set DHT options DHT dht(DHTPIN, DHTTYPE); float humid; float temp; int sleepDelay = 5000; // in milliseconds // nRF24L01(+) radio attached (CE, CSN) RF24 radio(9,10); // Network uses that radio RF24Network network(radio); // Channel of our node const uint16_t channel = 90; // Address of our node const uint16_t this_node = 1; // Address of the other node const uint16_t other_node = 0; // How many packets have we sent already unsigned long packets_sent; // Structure of our payload, limited to 32 bytes struct payload_t // 32 bytes max { unsigned long counter; // 4 bytes float humid; // 4 bytes float temp; // 4 bytes float Vcc; // 4 bytes }; // Analog pins #define VccPin 0 // Digital pins #define ActivePin 7 float Vcc; //Supplied Voltage // Prototypes void getVoltage(); // getVoltage void getStats(); // get DHT stats void sendPayload(); // check if time to send payload void setup(void) { //Serial.begin(57600); analogReference(INTERNAL); // Set analog reference to 1.1V analogRead(VccPin); //discard first analogRead pinMode(ActivePin, OUTPUT); // Set for output SPI.begin(); radio.begin(); network.begin(channel, this_node); // Power down the radio. Note that the radio will get powered back up on the next write() call. radio.powerDown(); } void loop(void){ // Pump the network regularly network.update(); getVoltage(); getStats(); sendPayload(); delay(sleepDelay); //Narcoleptic.delay(sleepDelay); // During this time power consumption is minimized } void getStats() { //Pull data from DHT11 //Set variables to inputs humid = dht.readHumidity(); temp = dht.readTemperature(true); //If variables are empty //print failed to read //if (isnan(temp) || isnan(humid)) { // Serial.println("Failed to read DHT"); //} //Serial.print("Humidity: "); //Serial.print(humid); //Serial.print(", Temp: "); //Serial.println(temp); } ////////////////////////////////////////////////////////////////////////////////// // Read analog input for VccPin averaged over NUM_SAMPLES // Uses a running average // Vcc is scaled with a voltage divider * 75K/(75K + 240K) so reverse // Should be 4.2, try 3.9 ////////////////////////////////////////////////////////////////////////////////// void getVoltage(){ const byte NUM_SAMPLES = 20; float SumTotal=0; for (byte j=0;j<NUM_SAMPLES;j++){ SumTotal+= analogRead(VccPin); delay(10); } Vcc = ((SumTotal/NUM_SAMPLES)*1.1/1023.0)*3.9; } ////////////////////////////////////////////////////////////////////////////////// // sendPayload(); // send payload ////////////////////////////////////////////////////////////////////////////////// void sendPayload(){ digitalWrite(ActivePin, HIGH); // Turn on LED payload_t payload = { packets_sent++, humid, temp, Vcc }; RF24NetworkHeader header(/*to node*/ other_node); bool ok = network.write(header,&payload,sizeof(payload)); // Power down the radio. Note that the radio will get powered back up on the next write() call. radio.powerDown(); digitalWrite(ActivePin, LOW); // Turn off LED }