Pages: [1] 2   Go Down
Author Topic: sending DS18B20 data over NRF24L01 using RF24 library from Uno to Mega2560  (Read 5638 times)
0 Members and 1 Guest are viewing this topic.
UK
Offline Offline
Newbie
*
Karma: 1
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi all

I've searched the web for any sketches than can help with the above but all I've found is the RF24Network by maniacbug which doesn't seem to have any recent development.

I currently have a Mega2560 reading 7 wired DS18B20 temp sensors & it works fine.
I want to add an additional 6 to 8 DS18B20's but it will be difficult to cable them into the existing arrangement hence the interest in reading the additional sensors over a wireless connection.
I want to use a Uno for this task but don't know how to go about it.  I've run the 'Getting Started' sketch by Maniacbug between my Mega2560 & Uno & this works fine but I'm at a loss as to how to proceed with reading data from DS18B20 temp sensors.

Can anyone help with this project please? (my programming skills are very basic)
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 653
Posts: 50923
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

There seem to be two parts to what you want to do. First, you want to read sensors on the remote Arduino. This is no different from reading them on the existing Arduino.

Second, you want to send some data from the remote Arduino to the existing Arduino. You say that you know how to do this, and that it is working.

So, what IS the problem?
Logged

UK
Offline Offline
Newbie
*
Karma: 1
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi PaulS

Perhaps I didn't explain myself clearly.

I can read the sensor data on the Uno but don't know how to send it to the Mega over a wireless connection - the Mega is where all calculations & subsequent actions base on that data are performed.

The 'Getting Started' sketch by Maniacbug is a simple Tx & Rx sketch sending a small packet that tests the 2-way link between my Mega & Uno.

I understand the packet size is very limited (32 byte?) but my major problem is that I don't know how to 'wrap up' my digital sensor data (12bit) from 6 DS18B20 sensors on the Uno into a packet for transmission across the wireless link to the Mega.

I hope I've made this clearer?
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 653
Posts: 50923
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Each sensor returns 2 bytes of data. 6 * 2 = 12. 12 < 32.

You can create a union containing 6 ints and 12 bytes. Create an instance of the union, and set the 6 ints. Then, send the 12 bytes. Receive 12 bytes, storing them in the byte portion of the same union, and use the 6 ints from that union.
Logged

Dee Why NSW
Offline Offline
Edison Member
*
Karma: 48
Posts: 2312
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

my major problem is that I don't know how to 'wrap up' my digital sensor data (12bit) from 6 DS18B20 sensors on the Uno into a packet for transmission across the wireless link to the Mega.


I want to do the same as you. I have not had a chance to use my NRF24s but I have been sending data to the internet via cosm. I didn't realise you had to "wrap up" data packets, but it sounds similar to the procedure for cosm. Here is a snippet of my cosm code.

Code:
LiquidCrystal lcd(8,9,56,5,6,7);

// Define the strings for our datastream IDs
char sensorId0[] = "InThermo";
char sensorId1[] = "OutThermo";
char sensorId2[] = "DrainThermo";
char calcId1[] = "diff";

const int bufferSize = 140;
char bufferValue[bufferSize]; // enough space to store the string we're going to send
CosmDatastream datastreams[] = {
  CosmDatastream(sensorId0, strlen(sensorId0), DATASTREAM_FLOAT),
  CosmDatastream(sensorId1, strlen(sensorId1), DATASTREAM_FLOAT),
  CosmDatastream(sensorId2, strlen(sensorId2), DATASTREAM_FLOAT),
  CosmDatastream(calcId1, strlen(calcId1), DATASTREAM_FLOAT),
};
// Finally, wrap the datastreams into a feed
CosmFeed feed(83153, datastreams, 4 );

void setup() {

void loop() {

  int ret=0;
  //get the values from the DS8B20's
  sensors.requestTemperatures();

  float InTemp = (sensorValue(InThermo));
  float OutTemp = (sensorValue(OutThermo)); 
  float DrainTemp = (sensorValue(DrainThermo));

  float diff = OutTemp - InTemp;

  datastreams[0].setFloat(InTemp);
  datastreams[1].setFloat(OutTemp);
  datastreams[2].setFloat(DrainTemp);
  datastreams[3].setFloat(diff);

  k=k+1; 

  if (k>9 )
  {   

// ++++++++++++++++++++++++++++++++  feed section   
  ret = cosmclient.put(feed, cosmKey);    // SEND FEED TO COSM

Logged

UK
Offline Offline
Newbie
*
Karma: 1
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
You can create a union containing 6 ints and 12 bytes. Create an instance of the union, and set the 6 ints. Then, send the 12 bytes. Receive 12 bytes, storing them in the byte portion of the same union, and use the 6 ints from that union.

Sorry PaulS, this is as clear as mud - my programming skilss are VERY limited.  Could you explain using a sketch?

Thanks
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 653
Posts: 50923
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The union:

Code:
union stuff
{
   int temps[6];
   byte data[12];
};

An instance:
Code:
stuff myStuff;

Get the temperatures, and store them:
Code:
  myStuff.temps[0] = temp0;
  // do the others, too.
  myStuff.temps[5] = temp5;

The payload to send, then, is myStuff.data, with a size of 12 bytes.

On the other end, you'd use myStuff.data as the receive buffer, and read the values using myStuff.temps[n] to get the nth temperature.
Logged

UK
Offline Offline
Newbie
*
Karma: 1
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks PaulS

I'll give it that try & let you know
Logged

UK
Offline Offline
Newbie
*
Karma: 1
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi PaulS

Still having problems with wireless comms between Uno (Tx) & Mega2560 (Rx); can you help please?

Tx from Uno seems OK but Rx on Mega doesn't report same temps as Tx'd

I'm running 8 DS18B20 sensors but hope to run more

Tx part (Rx to follow)


Thanks

Code:
//ONLY RUNS UNDER ARDUINO 1.0

//Arduino Uno as transmitter


/* YourDuino Multiple DS18B20 Temperature Sensors on 1 wire
  Connections:
  DS18B20 Pinout (Left to Right, pins down, flat side toward you)
  - Left   = Ground
  - Center = Signal (Pin 2):  (with 3.3K to 4.7K resistor to +5 or 3.3 )
  - Right  = +5 or +3.3 V

   Questions: terry@yourduino.com
   V1.01  01/17/2013 ...based on examples from Rik Kretzinger
  
/*-----( Import needed libraries )-----*/
// Get 1-wire Library here: http://www.pjrc.com/teensy/td_libs_OneWire.html
#include <OneWire.h>

//Get DallasTemperature Library here:  http://milesburton.com/Main_Page?title=Dallas_Temperature_Control_Library
#include <DallasTemperature.h>

/*-----( Declare Constants and Pin Numbers )-----*/
#define ONE_WIRE_BUS_PIN 7

/*-----( Declare objects )-----*/
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS_PIN);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

/*-----( Declare Variables )-----*/
// Assign the addresses of your 1-Wire temp sensors.
// See the tutorial on how to obtain these addresses:
// http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html

DeviceAddress Probe00 = { 0x28, 0x18, 0x64, 0xAA, 0x04, 0x00, 0x00, 0xC6 };
DeviceAddress Probe01 = { 0x28, 0xE6, 0x4F, 0x08, 0x03, 0x00, 0x00, 0xFB };
DeviceAddress Probe02 = { 0x28, 0x7A, 0x60, 0x08, 0x03, 0x00, 0x00, 0xA0 };
DeviceAddress Probe03 = { 0x28, 0x9A, 0x47, 0xAA, 0x04, 0x00, 0x00, 0xF4 };
DeviceAddress Probe04 = { 0x28, 0x55, 0x52, 0xAA, 0x04, 0x00, 0x00, 0xE1 };
DeviceAddress Probe05 = { 0x28, 0xD8, 0x34, 0xAB, 0x04, 0x00, 0x00, 0x43 };
DeviceAddress Probe06 = { 0x28, 0x53, 0x44, 0xAA, 0x04, 0x00, 0x00, 0xB3 };
DeviceAddress Probe07 = { 0x28, 0x5B, 0x70, 0xAA, 0x04, 0x00, 0x00, 0x89 };
DeviceAddress Probe08 = { 0x28, 0x18, 0x76, 0xAB, 0x04, 0x00, 0x00, 0xB6 };
DeviceAddress Probe09 = { 0x28, 0xA3, 0x75, 0xAB, 0x04, 0x00, 0x00, 0x07 };
DeviceAddress Probe10 = { 0x28, 0xA3, 0xE6, 0xAA, 0x04, 0x00, 0x00, 0x71 };

//End of 1-wire initialisation

/*
 * Simplest possible example of using RF24Network
 *
 * TRANSMITTER NODE
 * Every 2 seconds, send a payload to the receiver node.
 */

  #include <RF24Network.h>
  #include <RF24.h>
  #include <SPI.h>

// nRF24L01(+) radio attached using Getting Started board
  RF24 radio(9,10);            //CE, CSN connections on NRF24L01 board for Uno

// Network uses that radio
  RF24Network network(radio);

// Address of our node
  const uint16_t this_node = 1;

// Address of the other node
  const uint16_t other_node = 0;

// How often to send 'hello world to the other unit
  const unsigned long interval = 1000; //ms

// When did we last send?
  unsigned long last_sent;

// How many have we sent already
  unsigned long packets_sent;

// Structure of our payload
  struct payload_t
{
   byte data;
 
};

//End of nRF24L01 initialisation


void setup()   /****** SETUP: RUNS ONCE ******/
{
  // start serial port to show results
  Serial.begin(9600);
  Serial.print("Initializing Temperature Control Library Version ");
  Serial.println(DALLASTEMPLIBVERSION);
  
  // Initialize the Temperature measurement library
  sensors.begin();
  
  // set the resolution to 10 bit (Can be 9 to 12 bits .. lower is faster)
  //9>>0.5C steps, 10>>0.25C steps, 11>>0.125C steps, 12>>0.06C steps
  sensors.setResolution(Probe00, 10);
  sensors.setResolution(Probe01, 10);
  sensors.setResolution(Probe02, 10);
  sensors.setResolution(Probe03, 10);
  sensors.setResolution(Probe04, 10);
  sensors.setResolution(Probe05, 10);
  sensors.setResolution(Probe06, 10);
  sensors.setResolution(Probe07, 10);
  sensors.setResolution(Probe08, 10);
  sensors.setResolution(Probe09, 10);
  sensors.setResolution(Probe10, 10);
  
  
   Serial.println("RF24Network/examples/helloworld_tx/");
 
  SPI.begin();
  radio.begin();
  network.begin(/*channel*/ 90, /*node address*/ this_node);

}//--(end setup )---

void loop()   /****** LOOP: RUNS CONSTANTLY ******/
{
  delay(2000);
  Serial.println();
  Serial.print("Number of Devices found on bus = ");  
  Serial.println(sensors.getDeviceCount());  
  Serial.print("Getting temperatures... ");  
  Serial.println();  
  
  // Command all devices on bus to read temperature  
  sensors.requestTemperatures();  
  
  Serial.print("Probe 00 temperature is:   ");
  printTemperature(Probe00);
  Serial.println();

  Serial.print("Probe 01 temperature is:   ");
  printTemperature(Probe01);
  Serial.println();
 
  Serial.print("Probe 02 temperature is:   ");
  printTemperature(Probe02);
  Serial.println();
  
  Serial.print("Probe 03 temperature is:   ");
  printTemperature(Probe03);
  Serial.println();
  
  Serial.print("Probe 04 temperature is:   ");
  printTemperature(Probe04);
  Serial.println();
  
  Serial.print("Probe 05 temperature is:   ");
  printTemperature(Probe05);
  Serial.println();
  
  Serial.print("Probe 06 temperature is:   ");
  printTemperature(Probe06);
  Serial.println();
  
  Serial.print("Probe 07 temperature is:   ");
  printTemperature(Probe07);
  Serial.println();
  
// Pump the network regularly
  network.update();

// If it's time to send a message, send it!
  unsigned long now = millis();
  if ( now - last_sent >= interval  )
  {
    last_sent = now;
 
//The union
  union stuff
{
   int temps[8];
   byte data[16];
};  
//An instance

int temp0 = (sensors.getTempCByIndex(00));     //used for testing
int temp1 = (sensors.getTempCByIndex(01));    //used for testing
int temp2 = (sensors.getTempCByIndex(02));     //used for testing
int temp3 = (sensors.getTempCByIndex(03));     //used for testing
int temp4 = (sensors.getTempCByIndex(04));     //used for testing
int temp5 = (sensors.getTempCByIndex(05));     //used for testing
int temp6 = (sensors.getTempCByIndex(06));     //used for testing
int temp7 = (sensors.getTempCByIndex(07));     //used for testing

stuff myStuff;
//Get the temperatures, and store them
 myStuff.temps[0] = temp0;
 myStuff.temps[1] = temp1;
 myStuff.temps[2] = temp2;
 myStuff.temps[3] = temp3;
 myStuff.temps[4] = temp4;
 myStuff.temps[5] = temp5;
 myStuff.temps[6] = temp6;
 myStuff.temps[7] = temp7;
 

  Serial.print("Sending...");
  Serial.print(myStuff.temps[0]);
  payload_t payload = { /*millis(), packets_sent++,*/myStuff.data[16]};
  RF24NetworkHeader header(/*to node*/ other_node);
  bool ok = network.write(header,&payload,sizeof(payload));
if (ok)
      Serial.println("ok.");
 else
      Serial.println("failed.");
}

// vim:ai:cin:sts=2 sw=2 ft=cpp

//The payload to send, then, is myStuff.data, with a size of 12 bytes.
//On the other end, you'd use myStuff.data as the receive buffer and read the values using myStuff.temps[n] to get the nth temperature.

  
}//--(end main loop )---

/*-----( Declare User-written Functions )-----*/
void printTemperature(DeviceAddress deviceAddress)
{

int tempC = sensors.getTempC(deviceAddress);

   if (tempC == -127.00)
   {
   Serial.print("Error getting temperature  ");
   }
   else
   {
   Serial.print("C: ");
   Serial.print(tempC);
   Serial.print(" F: ");
   Serial.print(DallasTemperature::toFahrenheit(tempC));
   }
}// End printTemperature
//*********( THE END )***********




Logged

UK
Offline Offline
Newbie
*
Karma: 1
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi PaulS

Here's the Rx part

Code:
//ONLY RUNS UNDER ARDUINO 1.0

//Arduino Meaga2560 as receiver

/*
 Copyright (C) 2012 James Coliz, Jr. <maniacbug@ymail.com>

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 version 2 as published by the Free Software Foundation.
 */

/**
 * Simplest possible example of using RF24Network,
 *
 * RECEIVER NODE
 * Listens for messages from the transmitter and prints them out.
 */

  #include <RF24Network.h>
  #include <RF24.h>
  #include <SPI.h>

// nRF24L01(+) radio attached using Getting Started board

  RF24 radio(9,53);            //CE, CSN connections on NRF24L01 board for Mega2560

// Network uses that radio
  RF24Network network(radio);

// Address of our node
  const uint16_t this_node = 0;

// Address of the other node
  const uint16_t other_node = 1;

// Structure of our payload
  struct payload_t
{
  int temps;
  byte data;
 
};

void setup(void)
{
  Serial.begin(9600);
  Serial.println("RF24_Network_Rx");
 
  SPI.begin();
  radio.begin();
  network.begin(/*channel*/ 90, /*node address*/ this_node);
}

void loop(void)
{
// Pump the network regularly
  network.update();
 
//The union
  union stuff
{
   int temps[8];
   byte data[16];
};   
//An instance
  stuff myStuff;
 
// Is there anything ready for us?
  while ( network.available() )
  {
// If so, grab it and print it out
    RF24NetworkHeader header;
    payload_t payload;
    network.read(header,&payload,sizeof(payload));
    Serial.println("Received packets ");
   
//Get the temperatures, and store them
  int temp0 = myStuff.temps[0];
  int temp1 = myStuff.temps[1];
  int temp2 = myStuff.temps[2];
  int temp3 = myStuff.temps[3];
  int temp4 = myStuff.temps[4];
  int temp5 = myStuff.temps[5];       
  int temp6 = myStuff.temps[6];
  int temp7 = myStuff.temps[7];
     
  Serial.println(temp0);
  Serial.println(temp1);
  Serial.println(temp2);
  Serial.println(temp3);
  Serial.println(temp4);
  Serial.println(temp5);
  Serial.println(temp6);
  Serial.println(temp7);
 
   
}
}
// vim:ai:cin:sts=2 sw=2 ft=cpp
//The payload to send, then, is myStuff.data, with a size of 12 bytes.
//On the other end, you'd use myStuff.data as the receive buffer and read the values using myStuff.temps[n] to get the nth temperature.
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 653
Posts: 50923
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

payload_t is defined to be a struct of one byte. You are then creating an instance of that struct, called payload, and assigning it the value in the 17th position of a 16 element array.

The structure payload_t needs to be 16 bytes long. The 16 bytes in the myStuff.data array need to be COPIED to the 16 byte array in the payload_t instance.
Logged

UK
Offline Offline
Newbie
*
Karma: 1
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi PaulS

sorry for being a bit 'thick' but I don't understand your reply smiley-sad
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 653
Posts: 50923
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Look at the definition of payload_t:
Code:
// Structure of our payload
  struct payload_t
{
   byte data;
 
};
The size of the payload is one byte. That is NOT the size that you want, is it?

Make data an array of the needed size.

Quote
You are then creating an instance of that struct, called payload
here:
Code:
  payload_t payload = {

Quote
and assigning it the value in the 17th position of a 16 element array.
Here:
Code:
myStuff.data[16]

The data member of the stuff union is an array that can hold 16 elements. The indexes into that array run from 0 to 15. [16] is the 17th element of the array, and is out of bounds.

The payload instance will contain an array, when you define payload_t correctly. The data you want to send is in an array, myStuff.data. To get data from one array to another, you have to copy it. You could use memcpy() or a for loop. The for loop is more intuitive, in my opinion, although memcpy() will be faster. Only marginally, though, since it uses a for loop, too.
Logged

UK
Offline Offline
Newbie
*
Karma: 1
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi PaulS

I can't get the last copy routine to work.
I've set structure payload_t to:-

Code:
// Structure of our payload
  struct payload_t
{
 
  byte data[16];
 
};

I've set payload_t payload to:-

Code:
payload_t payload = {myStuff.data[16]};


I've set the array myStuff.data[16]

As I understand it, the array myStuff.data holds 16 bytes (0-15) of temp data (2 bytes per temp reading) so how do I get 8 temp readings out from these 16 bytes?

I've tried to read data using:-
Code:
//Get the temperatures, and store them
byte temps[16];
int i = 0;
for (i; i < 16; i=i+1)
{
  temps[i] = myStuff.data[i]; 
  Serial.println(temps[i]);
}

But this doesn't print out the correct temps

I seem to be going nowhere with this smiley-sad
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 653
Posts: 50923
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I've set structure payload_t to:-
Good.

Quote
I've set payload_t payload to:-
Bad.

Go back and read what I have written, again. You are still referring to a SINGLE element that is not in the range of valid elements.

Quote
I've set the array myStuff.data[16]
What, specifically, does this mean? One doesn't "set an array". One values the elements in an array or populates an array.

Quote
As I understand it, the array myStuff.data holds 16 bytes (0-15) of temp data (2 bytes per temp reading)
Yes.

Quote
so how do I get 8 temp readings out from these 16 bytes?
Exactly the same as you put them in.

The code that reads from the radio is populating the byte part of the union instance. Then, you copy the int part to other place(s).

Quote
But this doesn't print out the correct temps
Of course not. You need the same union on the receiver, too. You copy the data received into the byte part of the union instance, and read the int part as the temperatures.
Logged

Pages: [1] 2   Go Up
Jump to: