Need help in Communication protocol..

i am creating a wireless network. my setup includes two arduino uno boards. one acting as a server the other as a client. a temperature/humidity DHT11 sensor is attached to my clients end. I have configured my client to sense the data from the sensor and send the data to my server. Now after that i minimized the circuit for the client and attached it to 2AA batteries. implementing sleep mode in it using jeelib and watchdog.. Now i want to create a communication protocol so as to control my client from my server, for example if i want to change the sleep times for my client i can do so through my server. without actually meddling with the clients code.

Can anyone help me how i can implement this protocol to control my client through my server. example sketches will be appreciated so i can understand whats going on

thank you

I would just set that stuff in the answer the server sends to the client in response to a new measurement value being transferred. You have to wait for that connection anyways as in the meantime the client is sleeping to save power. If you post the sketches you currently run on the server and the client we may help you add that new functionality.

the following are the sketches for the server and the client i currently have. i am trying to send an array to the client and on that array help client digitalwrite on the power pin of the DHT to switch it off if i want the sensor to stop drawing power from the board. and put the arduino to sleep for 60 seconds. i was wondering about interrupts i can introduce so as the arduino goes regularly to sleep after checking every 60 seconds if the power pin on the DHT Sensor is turned on to recieve data or not if not then the client goes back to sleep…

Server attached to the PC:

//server node
#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
float data[3];
void setup(){
  Serial.begin(9600);
  Mirf.csnPin = 8;
  Mirf.cePin = 9;
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();
  Mirf.setRADDR((byte *)"Servr");
  Mirf.setTADDR((byte *)"Clynt");
  Mirf.payload = 12;
  Mirf.config();
  Serial.println("Listening..."); 
}
void loop()
  {
  if(Mirf.dataReady()){
    do{
    Serial.println("Got packet \n");
    Mirf.getData((byte *) &data[0]);
    Serial.print ("Voltage(mV): ");
    Serial.print(data[0]);
    Serial.print ("temperature(*C): ");
    Serial.print(data[1]);
    Serial.print ("\t Humidity(%): ");
    Serial.print (data[2]);
    Serial.println("Reading.. \n");
    }
    while(Mirf.isSending());
    {
    float p=0; //changable value for pin
    float s=1; //changable value for sleepmode
    data[0]=p;
    data[1]=s;
    Mirf.send((byte *) &data[0]);
    if (p>0) {
      Serial.println("Sensor enabled");
  } else {
      Serial.println("Sensor disabled");
  }
      if (s>0) {
        Serial.println ("Sleep mode enabled");
      } else {
      Serial.println ("Sleep mode disabled");  
      }
    }
  }
  }

Client node running on batteries having the dht sensor attached to it:

//client node

#include <JeeLib.h>
#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
#include "DHT.h"
#define DHTPIN 4
#define DHTTYPE DHT11 
DHT dht(DHTPIN, DHTTYPE);
int powerpin = 5;
int datapin = 4;
int gndpin = 2;
float data[3];
ISR(WDT_vect) { Sleepy::watchdogEvent(); }
void setup(){
 Serial.begin(9600); 
 digitalWrite(powerpin, HIGH);
 digitalWrite(gndpin, LOW);
 pinMode(gndpin, OUTPUT);
 pinMode(powerpin, OUTPUT);
 pinMode(datapin, INPUT);
  Serial.println("DHT11 Gathering information!");
  dht.begin();
  Mirf.csnPin = 8; //configurable Mirf pins
  Mirf.cePin = 9;
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();
  Mirf.setRADDR((byte *)"Clynt");
  Mirf.setTADDR((byte *)"Servr");
  Mirf.config();
  Mirf.payload = 12;
  Serial.println("Beginning ... "); 
}
void loop()   
{
  analogReference(INTERNAL);
  delay(2); // Wait for Vref to settle
  float v=analogRead(A2); //using a Voltage divider R1= 1Mohm and R2=100kOhm
  v=v*1100/1023 ;//1.1*1000/1023 ;Calculate Vcc (in mV)
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  Serial.print("Current Voltage: ");
  Serial.print(v);
  Serial.print(" mV\t");
  data[0]=v;
  data[1]=t;
  data[2]=h;
  Mirf.send((byte *) &data[0]);
  if (isnan(t) || isnan(h)) {
    Serial.println("Failed to read from DHT");
    Sleepy::loseSomeTime(10000);
  } else {
    Serial.print("Humidity: "); 
    Serial.print(h);
    Serial.print(" %\t");
    Serial.print("Temperature: "); 
    Serial.print(t);
    Serial.println(" *C");
  }
  while(Mirf.isSending()){
  Serial.println("Finished sending");
  Sleepy::loseSomeTime(30000);
  }
  
if(Mirf.dataReady()){
      Serial.println("Recieved command \n");
      Mirf.getData ((byte *) &data[0]);
      if (data[0]>0) {
        digitalWrite(powerpin, HIGH);
      }
        else{
          digitalWrite(powerpin, LOW);
          Sleepy::loseSomeTime(60000);
        }
}

}
  analogReference(INTERNAL);
  delay(2); // Wait for Vref to settle
  float v=analogRead(A2); //using a Voltage divider R1= 1Mohm and R2=100kOhm
  v=v*1100/1023 ;//1.1*1000/1023 ;Calculate Vcc (in mV)

You probably won't measure correct results as the ADC input impedance shouldn't be greater than about 10k?.

the following are the sketches for the server and the client i currently have. i am trying to send an array to the client and on that array help client digitalwrite on the power pin of the DHT to switch it off if i want the sensor to stop drawing power from the board. and put the arduino to sleep for 60 seconds. i was wondering about interrupts i can introduce so as the arduino goes regularly to sleep after checking every 60 seconds if the power pin on the DHT Sensor is turned on to recieve data or not if not then the client goes back to sleep..

Does that system work as expected?

Your do/while loop inside the if (Mirf.dataReady()) block doesn't make sense in my opinion. What do you expect that part to do? Did you look at the Mirf server example?

Hi thank you for the advice for 10k . what should be the R2 Value in that case 4.7k ? … secondly i modified the client code in this fashion. i think you are right about the problem from server → client communication. basically this is how i want the setup to work:

  1. Client node gathers the value for Voltage used by the board, humidity and temperature value from the sensor.
  2. client sends these three values in float format to the server side.
  3. server receives the values and prints it on its serial monitor
  4. server responds with a single value of its own. ( payload is 12 so 3 values can be sent. i just want to use one value. that sends a 0 or 1 value to the client, rest two values i want to be empty or filled with something i wont use. )
  5. client receives the reply from the server.
    i. if the reply is 1 . i want client to go into sleep mode. unless the data is demanded again from server side.(acting as interrupt)
    ii. if the reply is 0. i want to continue receiving data from the client to the server.

i am facing the issue with the 5th and last implimentation to send data from the server to the client and use that data to act accordingly. and implimentation of interrupt. so if you can help me with the code for that part on both server and client side id appreciate it. this is the changes i have made in the sending code of server and recieving code of the client so far , iam not sure about it. its not working as it is suppose to when i change the value of p to 1 o 0.

server send code:

#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
float data[3];
float rec[3];
void setup(){
  Serial.begin(9600);
  Mirf.csnPin = 8;
  Mirf.cePin = 9;
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();
  Mirf.setRADDR((byte *)"Servr");
  Mirf.setTADDR((byte *)"Clynt");
  Mirf.payload = 12;
  Mirf.config();
  Serial.println("Listening..."); 
}
void loop()
  {
  if(!Mirf.isSending() && Mirf.dataReady()){
    Serial.println("Got packet \n");
    Mirf.getData((byte *) &data[0]);
    Serial.print ("Voltage(mV): ");
    Serial.print(data[0]);
    Serial.print ("temperature(*C): ");
    Serial.print(data[1]);
    Serial.print ("\t Humidity(%): ");
    Serial.print (data[2]);
    Serial.println("Reading.. \n");
    delay (1000);
}      
    while(Mirf.isSending());
    {
    float p=0; //changable value for pin
    rec[0]=p;
    if (p>0) {
      Serial.println("Sleep mode ENABLED");
  } else {
      Serial.println("Sleep mode DISABLED");
  }
   Mirf.send((byte *) &rec);
    }
    
  }

Client receive code and actions taken:

#include <JeeLib.h>
#include <SPI.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
#include "DHT.h"
#define DHTPIN 4
#define DHTTYPE DHT11 
DHT dht(DHTPIN, DHTTYPE);
int powerpin = 5;
int datapin = 4;
int gndpin = 2;
float data[3];
float rec[3];
unsigned long startTime = 0;
unsigned int timeoutValue = 5000;
ISR(WDT_vect) //watchdog interupt
  {
  wdt_disable();  // disable watchdog
  }

void myWatchdogEnable(const byte interval) 
  {  
  MCUSR = 0;                          // reset various flags
  WDTCSR |= 0b00011000;               // see docs, set WDCE, WDE
  WDTCSR =  0b01000000 | interval;    // set WDIE, and appropriate delay

  wdt_reset();
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);  
  sleep_mode();            // now goes to Sleep and waits for the interrupt
  } 

void setup()
{
 Serial.begin(9600); 
 digitalWrite(powerpin, HIGH);
 digitalWrite(gndpin, LOW);
 pinMode(gndpin, OUTPUT);
 pinMode(powerpin, OUTPUT);
 pinMode(datapin, INPUT);
  Serial.println("DHT11 Gathering information!");
  dht.begin();
  Mirf.csnPin = 8; //configurable Mirf pins
  Mirf.cePin = 9;
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();
  Mirf.setRADDR((byte *)"Clynt");
  Mirf.setTADDR((byte *)"Servr");
  Mirf.config();
  Mirf.payload = 12;
  Serial.println("Beginning ... "); 
}  // end of setup

void loop()
{
   analogReference(INTERNAL);
  delay(2); // Wait for Vref to settle
  float v=analogRead(A2); //using a Voltage divider R1= 10kohm and R2=4.7kOhm
  v=v*1100/1023 ;//1.1*1000/1023 ;Calculate Vcc (in mV)
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  Serial.print("Current Voltage: ");
  Serial.print(v);
  Serial.print(" mV\t");
  data[0]=v;
  data[1]=t;
  data[2]=h;
  if (isnan(t) || isnan(h)) {
   Serial.println("Failed to read from DHT");
    Sleepy::loseSomeTime(10000);
  } else {
   Serial.print("Humidity: "); 
    Serial.print(h);
    Serial.print(" %\t");
    Serial.print("Temperature: "); 
    Serial.print(t);
    Serial.println(" *C");
  }
  Mirf.send((byte *) &data[0]);
  while(Mirf.isSending()){
  }
  Serial.println("Finished sending");
  delay (10);
while(!Mirf.dataReady()){
       if (millis() - timeoutValue > startTime){
 Serial.println("TIMEOUT");
 Serial.print("Timed out at ");
 Serial.print(millis());
 Serial.println();
 break;
      }
}
  Serial.print ("Command recieved");
 Mirf.getData ((byte *) &rec);
    if (rec>0) {
        Serial.println("Sleep Mode ENABLED");
        int i;
      for (i = 0; i <30; i++)
      {  
      myWatchdogEnable (0b100001);  // loop to sleep for 4mins
       }
    }
    else
    {
    Serial.println("Sleep Mode DISABLED");
   wdt_disable();  // disable watchdog
        }
}

Learn to format your code! Your IDE supports you by offering an entry in the Tools menu to do an auto-formatting.

I’ve done the formatting for your server code and inserted remarks where things go strange:

#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
float data[3];
float rec[3];
void setup(){
	Serial.begin(9600);
	Mirf.csnPin = 8;
	Mirf.cePin = 9;
	Mirf.spi = &MirfHardwareSpi;
	Mirf.init();
	Mirf.setRADDR((byte *)"Servr");
	Mirf.setTADDR((byte *)"Clynt");
	Mirf.payload = 12;
	Mirf.config();
	Serial.println("Listening..."); 
}
void loop() {
	if(!Mirf.isSending() && Mirf.dataReady()){
		Serial.println("Got packet \n");
		Mirf.getData((byte *) &data[0]);
		Serial.print ("Voltage(mV): ");
		Serial.print(data[0]);
		Serial.print ("temperature(*C): ");
		Serial.print(data[1]);
		Serial.print ("\t Humidity(%): ");
		Serial.print (data[2]);
		Serial.println("Reading.. \n");
		delay (1000);
	}      
	while(Mirf.isSending()); // this call is waiting for everthing to be sent
{ // this block is not necessary and has no function at all
	float p=0; //changable value for pin
	rec[0]=p;
	if (p>0) {
		Serial.println("Sleep mode ENABLED");
	} else {
		Serial.println("Sleep mode DISABLED");
	}
	Mirf.send((byte *) &rec); // this is sent in every loop, so your air link is completely blocked by this
} // end of unnecessary block
	
}

In that code the server does not respond to the clients request but continually sends out the same data.

i am trying to fix it by going with watchdog timer. so as my client checks to send data at regular interval. it checks if there is any response from server and if there is any response it continues to send the data or goes to sleep. atleast thats what i am trying to achieve i am not sure it is working though. so what do you think below are the codes.

//client

#include <SPI.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
#include "DHT.h"
#define DHTPIN 4
#define DHTTYPE DHT11 
DHT dht(DHTPIN, DHTTYPE);
int powerpin = 5;
int datapin = 4;
int gndpin = 2;
float data[3];
volatile unsigned int counter = 0;
void WatchdogEnable() 
{  
  MCUSR = 0; // Clear the reset flag, the WDRF bit (bit 3) of MCUSR.
  WDTCSR = bit (WDCE) | bit (WDE);
  WDTCSR =bit (WDIE) | bit (WDP3) | bit (WDP0); //watchdog enable, setting timer for 8seconds
  wdt_reset();
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);  
  sleep_enable();            // now goes to Sleep and waits for the interrupt
  sleep_cpu ();              // sleep within 3 clock cycles of above
}
void SleepDevices()
{
ADCSRA = ADCSRA & B01111111; // Disable the ADC by setting the ADEN bit (bit 7) to zero.
ACSR = B10000000; // Disable the analog comparator by setting the ACD bit (bit7) to one
DIDR0 = DIDR0 | B00111111; // Disable digital input buffers on all analog input pins by setting bit 0-5 to one/
sleep_cpu (); 
} 

void WakeUp()
{ 
ADCSRA = ADCSRA & B11111111; 
ACSR = B00000000;
DIDR0 = DIDR0 | B00000000;   
}

ISR(WDT_vect) //watchdog interupt
{
  counter++;
  wdt_disable();
}

void setup()
{ 
  Serial.begin(9600); 
  digitalWrite(powerpin, HIGH);
  digitalWrite(gndpin, LOW);
  pinMode(gndpin, OUTPUT);
  pinMode(powerpin, OUTPUT);
  pinMode(datapin, INPUT);
  dht.begin();
  Mirf.csnPin = 8; //configurable Mirf pins
  Mirf.cePin = 9;
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();
  Mirf.setRADDR((byte *)"Clynt");
  Mirf.setTADDR((byte *)"Servr");
  Mirf.config();
  Mirf.payload = 12;
}  // end of setup
void loop()
{ 
  SleepDevices();
 while (counter < 20) //sleeping for 160s= 8x20s
      { 
        WatchdogEnable ();
      }
  WakeUp();
  analogReference(INTERNAL);
  delay(2); // Wait for Vref to settle
  float v=analogRead(A2); 
  v=v*1100/1023 ;//1.1*1000/1023 ;Calculate Vcc (in mV)
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  Serial.print("Current Voltage: ");
  Serial.print(v);
  Serial.print(" mV\t");
  data[0]=v;
  data[1]=t;
  data[2]=h;
  if (isnan(t) || isnan(h)) {
    Serial.println("Failed to read from DHT");
  } 
  else {
    Serial.print("Humidity: "); 
    Serial.print(h);
    Serial.print(" %\t");
    Serial.print("Temperature: "); 
    Serial.print(t);
    Serial.println(" *C");
  }
  Mirf.send((byte *) &data[0]);
  while(Mirf.isSending()){

    delay (1000);
    if(!Mirf.dataReady()){
      while (counter < 20) //sleeping for 160s
      { 
        WatchdogEnable ();
      }
    }
    else {
      wdt_disable();
    }
  }
}

it seems that the watchdog is not working. It keeps printing the output every second on the servers serial monitor??

You didn't fix the server part but playing around with the watchdog on the client side? I don't think that this will bring you forward. And the code is still not properly formatted.

The ATmega may wake up because the server is constantly sending data, have you thought about this?

So basicly i remove the communication from the server side. the last while loop where is tries to send data back ?

No, you don't have to remove the whole communication because then it wouldn't be a server anymore. Remove the while() loop and move the of the sending code inside the if block. That way the server only sends a response if the client sent it's data.