Go Down

Topic: [solved]Sending sensor readings using RadioHead (Read 294 times) previous topic - next topic

simpa

Oct 25, 2015, 05:25 pm Last Edit: Oct 26, 2015, 11:05 am by simpa
Hi, I'm trying to make 2 Arduinos communicate over RF 434MHz using the RadioHead library. One of the Arduinos will take some sensor readings, right now it's only temperature and soil moisture content but I plan to add more sensors later. The temperature reading is stored as a float and the soil moisture as an int. What I want to do is pass this variables to the send-function and transmit them both at the same time. So I want all the readings to be sent in the same transmission and I will then have to split them up on the receiving side.

My sketch now looks like this (far from being finished but I want to solve this problem first):

Code: [Select]
#include <RHDatagram.h>
#include <RH_ASK.h>
#include <SPI.h>
#include <OneWire.h>
#include <DallasTemperature.h>

//RH communication
#define CLIENT_ADDRESS 2
#define SERVER_ADDRESS 1
// Singleton instance of the radio driver
RH_ASK driver;
// Class to manage message delivery and receipt, using the driver declared above
RHDatagram manager(driver, CLIENT_ADDRESS);

//OneWire sensors
// Data wire is plugged into port 16 on the Arduino
#define ONE_WIRE_BUS 10
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

void setup()
{
  Serial.begin(9600);
  
  //RF communication
  if (!manager.init())
    Serial.println("init failed");

  // OneWire sensors
  sensors.begin();

}

  // RH communication, Dont put this on the stack:
  uint8_t buf[RH_ASK_MAX_MESSAGE_LEN];

void loop()
{
  float tempValue;
  int soilValue;
  tempValue = temperature();
  delay(1000);
  soilValue = soil();
  delay(1000);
  SendValues();
  Serial.println ("");
   delay(2000);
}

//RH communication
void SendValues()
{

  uint8_t data[] = "Hello World";
  
  Serial.println("Sending to ask_datagram_server");
  int i = 0;
  int repeat = 5; //Times to repeat same message
    
  // Send a message to manager_server
  while (i<repeat)
  {
    if (manager.sendto(data, sizeof(data), SERVER_ADDRESS))
    {
      Serial.println("Message sent");  
    }
    else
    {
      Serial.println("sendto failed");
    }
    
    delay(100);
    i = i+1;
  }
}

//Get temperatures from Dallas sensor
float temperature()
{
  float temp;
  // issue a global temperature request to all devices on the bus
  Serial.print("Requesting temperatures from all...");
  sensors.requestTemperatures(); // Send the command to get temperatures
  Serial.println("DONE");
  // Print temperatures
  Serial.print("Temperature for the device 1 (index 0) is: ");
  Serial.println(sensors.getTempCByIndex(0));  
  temp = sensors.getTempCByIndex(0);
  return temp;
}

//Soil hygrometer
int soil()
{
 int humidity = 0;

 // read soil moisture from sensor
 int sensorValue = analogRead(A1);
 int sensorValueCons = sensorValue;
 
 sensorValueCons = constrain (sensorValue, 300,1023);
 //Sensor value 300 equals 100% humidity and sensor value 1023 equals 0% humidity

 humidity = map (sensorValueCons, 300, 1023, 100, 0);
 Serial.print ("Soil hygrometer: ");
 Serial.print (humidity);
 Serial.println ("%");
 //Print sensor value
 Serial.println ("Soil hygrometer sensor value: ");
 Serial.println (sensorValue);
 return humidity;
}


As you can see right now the send-function only sends "Hello world!" and the function does not accept any variables to be passed on to it. The values I want to send are stored in soilValue and tempValue present in the main loop. I assume I will need to convert the variable type and then combine them in some way, then pass it on to the send-function. I'm however not sure how to do this and could use some help here ;) Perhaps I got it completely wrong and there is a much smarter way to do all of this :P

Johnny010


Make a "packet" array for ints:

Code: [Select]
char int_packet[3]; //2 for int bytes and one for end of string thingy '/0'.

Convert the int in to 2 bytes:

Code: [Select]


int_packet[0]= the_int_to_be_sent;
int_packet[1]= the_int_to_be_sent >> 8; //Shift 8 bits along and store the least sig. 8 in a char.
int_packet[2]= '/0';


Then just send the contents of "int_packet".

The RX code then takes each byte at a time:
Reverse the bit shifting process to make the original int:

Code: [Select]
byte lowbyte=recieved_byte[0];
byte highbyte=recieved_byte[1];

int recieved_int=lowbyte+(highbyte << 8);

jremington

#2
Oct 25, 2015, 09:48 pm Last Edit: Oct 25, 2015, 09:50 pm by jremington
Reply #1 in this post shows you how to send and receive a few sensor readings with RadioHead.

simpa

The method described in that post worked perfect. Very nice method to send the whole data structure, made everything so much easier. Thank you.

I did some modification to get it to work with RHDatagram as manager. Will also use it with RHReliableDatagram later.

Posting my code again if someone else is looking for a solution like this.

Transmitter
Code: [Select]
#include <RHDatagram.h>
#include <RH_ASK.h>
#include <SPI.h>
#include <OneWire.h>
#include <DallasTemperature.h>

//RH communication
#define CLIENT_ADDRESS 2
#define SERVER_ADDRESS 1
// Singleton instance of the radio driver
RH_ASK driver;
// Class to manage message delivery and receipt, using the driver declared above
RHDatagram manager(driver, CLIENT_ADDRESS);

//OneWire sensors
// Data wire is plugged into port 16 on the Arduino
#define ONE_WIRE_BUS 10
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

struct dataStruct{
  float tempValue;
  int soilValue;
  int soilRaw;
  unsigned long counter;
   
}SensorReadings;

 // RF communication, Dont put this on the stack:
  byte buf[sizeof(SensorReadings)] = {0};

void setup()
{
  Serial.begin(9600);
 
  //RF communication
  if (!manager.init())
    Serial.println("init failed");

  // OneWire sensors
  sensors.begin();

  SensorReadings.tempValue = 0;
  SensorReadings.soilValue = 0;
  SensorReadings.soilRaw = 0;
  SensorReadings.counter = 0;
}

void loop()
{
  Serial.println("------------------------------------");
  float tempValue;
  int soilValue;
 
  temperature(); //Read temp sensor
  delay(1000);
 
  soilValue = soil(); //Read hygrometer
  delay(1000);
 
  SendValues(); //Send sensor values
  delay(2000);
  Serial.println("------------------------------------");
}

//Get temperatures from Dallas sensor
void temperature()
{
  // issue a global temperature request to all devices on the bus
  Serial.print("Requesting temperatures from all...");
  sensors.requestTemperatures(); // Send the command to get temperatures
  Serial.println("DONE");
  // Print temperatures
  Serial.print("Temperature for the device 1 (index 0) is: ");
  Serial.println(sensors.getTempCByIndex(0));
  Serial.println(""); 
  SensorReadings.tempValue = sensors.getTempCByIndex(0);
}

//Soil hygrometer
int soil()
{
 // read soil moisture from sensor
 int sensorValue = analogRead(A1);
 int sensorValueCons = sensorValue;
 
 sensorValueCons = constrain (sensorValue, 300,1023);
 //Sensor value 300 equals 100% humidity and sensor value 1023 equals 0% humidity

 SensorReadings.soilValue = map (sensorValueCons, 300, 1023, 100, 0);
 Serial.print ("Soil hygrometer: ");
 Serial.print (SensorReadings.soilValue);
 Serial.println ("%");
 //Print sensor value
 Serial.print ("Soil hygrometer sensor value: ");
 Serial.println (sensorValue);
 Serial.println("");
 SensorReadings.soilRaw = sensorValue;
}

//RF communication
void SendValues()

  //Load message into data-array
  //byte data[sizeof(sensorValues)];

  byte zize=sizeof(SensorReadings);
  memcpy (buf, &SensorReadings, zize);

 
  Serial.println("Sending to ask_datagram_server");
  int i = 0;
  int repeat = 10; //Times to repeat same message
   
  // Send a message to manager_server
  while (i<repeat)
  {
    if (manager.sendto(buf, zize, SERVER_ADDRESS))
    {
      Serial.println("Message sent");   
    }
    else
    {
      Serial.println("sendto failed");
    }
    delay(100);
    i = i+1;
  }
  SensorReadings.counter = SensorReadings.counter + 1;
}


Reciever
Code: [Select]
#include <RHDatagram.h>
#include <RH_ASK.h>
#include <SPI.h>

//#define CLIENT_ADDRESS 1
#define SERVER_ADDRESS 1

// Singleton instance of the radio driver
RH_ASK driver;
// Class to manage message delivery and receipt, using the driver declared above
RHDatagram manager(driver, SERVER_ADDRESS);

struct dataStruct{
  float tempValue;  //Store temperature sensor value (degC)
  int soilValue;    //Store soil moisture level (%)
  int soilRaw;      //Store hygrometer sensor reading
  unsigned long counter;
   
}SensorReadings;

void setup()
{
  Serial.begin(9600);
  if (!manager.init())
    Serial.println("init failed");

  SensorReadings.tempValue = 0;
  SensorReadings.soilValue = 0;
  SensorReadings.soilRaw = 0;
  SensorReadings.counter = 0;
}

void loop()
{
ReciveFromSensors();
}

void ReciveFromSensors()
{
  // Dont put this on the stack:
  uint8_t buf[sizeof(SensorReadings)];
  uint8_t from;
  uint8_t len = sizeof(buf);
 
  if (manager.available())
  {   
    // Wait for a message addressed to us from the client
    if (manager.recvfrom(buf, &len, &from))
    {
      int i;
      memcpy(&SensorReadings, buf, sizeof(SensorReadings));
      Serial.println("--------------------------------------------");
      Serial.print("Got message from unit: ");
      Serial.println(from, DEC);
      Serial.print("Transmission number: ");
      Serial.println(SensorReadings.counter);
      Serial.println("");
       
      Serial.print("Temperature: ");
      Serial.println(SensorReadings.tempValue);
       
      Serial.print("Soil moisture content: ");
      Serial.println(SensorReadings.soilValue);
       
      Serial.print("Hygrometer sensor reading");
      Serial.println(SensorReadings.soilRaw);
      Serial.println("--------------------------------------------");
    }
  }
}

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy