Sending multiple variable array over RF Link NRF24L01

OK, thanks will read up on that over the next couple of days.

The challeneg after that will be in that I need to use this RF link with my Mega which will also be driving a 3.5" LCD display, this utilises pins 22-53 of the mega which is where the CSN, SCK, MOSI & MISO lines connect.

Can these be re-allocated to other pins in your library?

http://www.ebay.com.au/itm/331836198294?_trksid=p2057872.m2749.l2649&ssPageName=STRK%3AMEBIDX%3AIT

You must use the SPI pins for the nRF24 module and those pins cannot then be used for anything other than SPI.

Assuming your LCD does not use SPI it should be possible to move its connections elsewhere with a suitable modification to the LCD part of the program.

Of course, if the LCD does use SPI then sharing the SPI pins should be fine. SPI is designed for multiple devices.

I guess another possibility is to implement SPI in software - there may be a suitable library floating around. But I suspect it would be very much a second rate solution.

...R

OK, when I get to that stage I will parrallel it up and see how it goes.

Hi,

I have tried to implement the technique you used IE (Ackdata) but not getting the acknowledge data show up at the Tx unit.

Tx unit sends 4 variable of data to Rx unit, this works.
Rx unit increments counter and should send it back as an acknowledgement.

On the Rx I get “Acknowledge but no data -1”

Tx Unit

/* 
 *  Water Tank Level Meter
 *  
 *  
 * Outdoor Unit (Tx)
 *   Arduino Uno 
 * 
*/

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <dht.h>

dht DHT;

#define DHT11_PIN 7       // Define pin 7 for Temp sensor
#define CE_PIN   9
#define CSN_PIN 10

const int relay = 5; 
int inputPin = A0;        // Define pin ultrasonic signal reception Forward
int outputPin = A1;       // Define pin ultrasonic signal transmitter Forward
const byte slaveAddress[5] = {'R','x','A','A','A'};
int dataToSend[4];
int Fdistance = 0;
int temperature = 0;
int humidity = 0;

int ackData[2] = {-1, -1}; // 
bool newData = false;

RF24 radio(CE_PIN, CSN_PIN); // Create a Radio


void setup() {

    Serial.begin(9600);
    Serial.println("External Sensor Module V1.4");
    Serial.println("Type,\tstatus,\tHumidity (%),\tTemperature (C)");
    Serial.println();
    pinMode(relay, OUTPUT);      
    pinMode (inputPin, INPUT);             // Define ultrasound input pin 
    pinMode (outputPin, OUTPUT);           // Define ultrasonic output pin  

    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.setRetries(3,5); // delay, count
    radio.openWritingPipe(slaveAddress);
}

//====================


void loop() {
       
        delay(1000);
        digitalWrite(relay, HIGH);  
        delay(3000);
        digitalWrite(relay, LOW); 
        digitalWrite (outputPin, LOW);     // Let ultrasonic transmitter low voltage 2 μ s 
    
        Read_Ultrasonic_Sensor();
        Read_Temp();    
   
        dataToSend[0] = DHT.temperature;
        dataToSend[1] = DHT.humidity;
        //dataToSend[2] = Fdistance;
        dataToSend[3] = 69;
        Serial.print(Fdistance);
        send();

}

//====================


void Read_Ultrasonic_Sensor()
{
          digitalWrite (outputPin, LOW);     // Let ultrasonic transmitter low voltage 2 μ s 
          delayMicroseconds (2); 
          digitalWrite (outputPin, HIGH);    // Let ultrasonic transmitter high voltage 10 μ s, where at least 10 μ s 
          delayMicroseconds (10); 
          digitalWrite (outputPin, LOW);      // Maintain low voltage ultrasonic transmitter 
          float Fdistance = pulseIn (inputPin, HIGH);    // Read worse time difference 
          Fdistance = Fdistance/5.8/10;         // Time to turn to the distance (unit: cm) 
          Serial.print ("Level:");        // Output distance (unit: cm) 
          Serial.println (Fdistance);           // Display the distance 
          dataToSend[2] = Fdistance;
}

void Read_Temp()
{
      int chk = DHT.read11(DHT11_PIN);
      switch (chk)
      {
        case DHTLIB_OK:  
                Serial.print("Temp Sensor Read OK,\t"); 
                break;
        case DHTLIB_ERROR_CHECKSUM: 
                Serial.print("Checksum error,\t"); 
                break;
        case DHTLIB_ERROR_TIMEOUT: 
                Serial.print("Time out error,\t"); 
                break;
        case DHTLIB_ERROR_CONNECT:
              Serial.print("Connect error,\t");
        break;
        case DHTLIB_ERROR_ACK_L:
              Serial.print("Ack Low error,\t");
        break;
        case DHTLIB_ERROR_ACK_H:
            Serial.print("Ack High error,\t");
        break;
        default: 
            Serial.print("Unknown error,\t"); 
            break;
  }
      Serial.print(DHT.humidity, 1);
      Serial.print(",\t");
      Serial.println(DHT.temperature, 1);
}



void send() {

    bool rslt;
    rslt = radio.write( &dataToSend, sizeof(dataToSend) );
    Serial.print("Data Sent ");
    Serial.print(dataToSend[0]);
    Serial.print("  ");
    Serial.print(dataToSend[1]);
    Serial.print("  ");
    Serial.print(dataToSend[2]);
    Serial.print("  ");
    Serial.print(dataToSend[3]);

if (rslt) {
        if ( radio.isAckPayloadAvailable() ) {
            radio.read(&ackData, sizeof(ackData));
            newData = true;
        }
        else {
            Serial.println("  Acknowledge but no data ");
        }
        Serial.println(ackData[0]);
      }
    else {
        Serial.println("  Tx failed");
    }

Rx unit

//* 
 *  Water Tank Level Meter
 *  
 *  
 *  Indoor Unit (Rx)
 *   Arduino Mega 
 * 
*/

#include <TFT_HX8357.h> // 3.5" Display Library
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#define CE_PIN   9
#define CSN_PIN 53

const byte thisSlaveAddress[5] = {'R','x','A','A','A'};

RF24 radio(CE_PIN, CSN_PIN);

int dataReceived[4]; // this must match dataToSend in the TX
int ackData[2] = {109, -4000}; // the two values to be sent to the master
bool newData = false;

TFT_HX8357 tft = TFT_HX8357();

#define DHT11_PIN 5

const int water_button = 2;
int tank_height = 170;
int Fspeedd = 0;        //-Speed 
int Fdistance = 0;
int start = 240;
int step = 20;
int buttonState = 0;    // variable for reading the pushbutton status
int timer_minutes = 0;
int timer_seconds = 0;
int sample = 0;
int watering_flag = 0;

void setup() {

    tft.begin();
    Serial.begin(9600);
    Serial.println("SimpleRx Starting");
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.openReadingPipe(0, thisSlaveAddress);
    radio.startListening();
   
    pinMode(water_button, INPUT);  
}




void loop(void) {

 

sample_data:  getData();
       showData();

       
       tft.setRotation(1);
       //delay(2000);
       Title();              // Display title
       Draw_Tank(TFT_CYAN);  // Draw tank outline

        //
        // Print actual measurement on display
        //
        tft.setCursor(50, 150);
        tft.setTextColor(TFT_YELLOW); tft.setTextSize(4);
        tft.print(dataReceived[0]);
        tft.setTextColor(TFT_WHITE); tft.setTextSize(2);
        tft.setTextSize(2);
        tft.println();
        tft.print("         ");
        tft.print(dataReceived[1]);
        tft.println(" %");

        if (dataReceived[3] == 69) 
          { tft.println("Comms = good");
          }
          else
          {tft.println("Comms = bad");
            
          }
          dataReceived[3]=0;

        {


void watering_routine(){
      
      tft.fillScreen(TFT_BLACK);
      tft.setCursor(50, 30);
      tft.setTextColor(TFT_GREEN); tft.setTextSize(3);
      tft.println("WATERING IN PROGRESS");
      timer_seconds=59;  
      timer_minutes = 0;
      // Activate Relay
      
Loop: tft.setCursor(150, 100);    
      tft.setTextColor(TFT_GREEN); tft.setTextSize(5);
      tft.println(timer_minutes);
      tft.setCursor(160, 100);  
      tft.println(" : ");
      tft.setCursor(230, 100);  
      tft.println(timer_seconds);
      timer_seconds = timer_seconds-1;
      if (timer_seconds < 0) 
        {
        timer_minutes = timer_minutes-1;
        if (timer_minutes==-1)
        {
        return;
        }  
        timer_seconds = 59;
        }
end:    delay(1000);
        tft.fillRect(150, 100, 200, 50, TFT_BLACK);
        
        //
        // Check for button pressed again to stop watering
        //
        //delay(300);
        buttonState = LOW;
        buttonState = digitalRead(water_button);
        if (buttonState == HIGH) 
          {  
          // Reset Relay
          return;
          }
        
        goto Loop;  
   
    }  


void getData() {
    if ( radio.available() ) {
        radio.read( &dataReceived, sizeof(dataReceived) );
        newData = true;
        updateReplyData();  // new
        Fdistance = dataReceived[2];
    }
}

void showData() {
    if (newData == true) {
        Serial.print("Data received ");
        Serial.println();
        Serial.print("Temp = ");
        Serial.println(dataReceived[0]);
        Serial.print("Humidity = ");
        Serial.println(dataReceived[1]);
        Serial.print("Level = ");
        Serial.println(dataReceived[2]);
        Serial.print("Comms = ");
        Serial.println(dataReceived[3]);
        
        Serial.print(" ackPayload sent ");
        Serial.print(ackData[0]);
        newData = false;

        //
        // Print actual data on display
        //
       
        tft.setTextColor(TFT_WHITE); tft.setTextSize(2);
        tft.println();
        tft.print(" Comms: ");
        tft.println(dataReceived[3]);
        tft.print(" Temp: ");
        tft.println(dataReceived[0]);
        tft.print(" Humidity: ");
        tft.println(dataReceived[1]);
        tft.print(" Level: ");
        tft.println(dataReceived[2]);
    }
}



void updateReplyData() {
     watering_flag = watering_flag+1;
     ackData[0] = watering_flag;
     radio.writeAckPayload(0, &ackData, sizeof(ackData)); // load the payload for the next time
}

How about calling the enable functions before trying to use the features?

enableDynamicPayloads();
enableAckPayload();

Whandall:
How about calling the enable functions before trying to use the features?

enableDynamicPayloads();

enableAckPayload();

What are these commands?
I have double checked the example code (ackPayload example) on http://forum.arduino.cc/index.php?topic=421081 and dont see these commands beign used there either…?

The "commands" are function calls (methods of the RF24 object, often named "radio").

The library you should be using is documented here.

The datasheet of the NRF24L01+ is here and explains which configurations are needed for the different operation modes.

dudester: I have double checked the example code (ackPayload example) on http://forum.arduino.cc/index.php?topic=421081 and dont see these commands beign used there either...?

I reckon a treble check is required.

...R

Hi,

Thank you for your help, no command enableAckPayload(); but did find radio.enableAckPayload(); I tried placing this in the void setup() area and everything works perfectly now.

By the way, running my 3.5" colour TFT display piggybacked of the same pins as the RF link on the mega works perfectly.

dudester: no command enableAckPayload(); but did find radio.enableAckPayload();

Aren't they the same thing?

...R

Robin2: Aren't they the same thing?

...R

I am a beginner so was not aware of that, what does the preceeding "radio." command actually mean?

Functions of a class are most often called as object.function([parameters]); Like Serial.print("something");

In your case radio (an object of the class RF24) and enableAckPayload() (a function of the class without parameters) -> radio.enableAckPayload();

[quote author=dudester [/quote]

I am doing with same stuff. which ultrasonic sensor are u using in water tank?

vijaysurat: [quote author=dudester

I am doing with same stuff. which ultrasonic sensor are u using in water tank?

I used this one.... http://www.ebay.com.au/itm/Waterproof-Ultrasonic-Module-JSN-SR04T-Distance-Transducer-Sensor-for-Arduino-/152234039330?hash=item2371db1822:g:Yu8AAOSwi0RX0RFN