NRFLITE library

Hi,
i am trying to port my code to nrflite and having a hard time.

need to send 3 variables and receive them on the other side

current code for transmitting:

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

int Inputpin[3]; // Used to store value before being sent through the NRF24L01
RF24 radio(2, 3); // NRF24L01 used pins 2 and 3 on the ATTINY84
const uint64_t pipe = 0xE8E8F0F0E1LL; // Needs to be the same for communicating between 2 NRF24L01

void setup()
{
  pinMode(7, INPUT); // Define the arcade switch NANO pin as an Input using Internal Pullups
  pinMode(8, INPUT);
  pinMode(9, INPUT);

  //***************************************************
  radio.begin(); // Start the NRF24L01
  radio.setPALevel(RF24_PA_HIGH);
  radio.setDataRate(RF24_1MBPS);
  radio.setCRCLength(RF24_CRC_16);
  radio.openWritingPipe(pipe); // Get NRF24L01 ready to transmit
}

void loop()
{
  Inputpin[0] = digitalRead(7);
  Inputpin[1] = digitalRead(8);
  Inputpin[2] = digitalRead(9);
  //Serial.println(Inputpin[2]);
  radio.write( Inputpin, sizeof(Inputpin) );
    
}

i need to modify it to this format example to match the above code that works very well as is:

#include <SPI.h>
#include <NRFLite.h>

NRFLite _radio;
uint8_t _data;

void setup()
{
    Serial.begin(115200);
    _radio.init(1, 9, 10); // Set this radio's Id = 1, along with its CE and CSN pins
}

void loop()
{
    while (_radio.hasData())
    {
        _radio.readData(&_data);
        Serial.println(_data);
    }
    
}

cant seem to make sense of it.

  pinMode(7, INPUT); // Define the arcade switch NANO pin as an Input using Internal Pullups
  pinMode(8, INPUT);
  pinMode(9, INPUT);

Either the comment is lying or you should use INPUT_PULLUP.

  radio.write( Inputpin, sizeof(Inputpin) );

This sends 6 bytes.

        _radio.readData(&_data);

If this reads all 6 bytes then you one-byte buffer will overflow. If it reads one byte then:

        Serial.println(_data);

This will display the input one byte at a time, each byte on a separate line. Are you getting strange characters or numbers between 0 and 255?

johnwasser:

  pinMode(7, INPUT); // Define the arcade switch NANO pin as an Input using Internal Pullups

pinMode(8, INPUT);
  pinMode(9, INPUT);



Either the comment is lying or you should use INPUT_PULLUP.




radio.write( Inputpin, sizeof(Inputpin) );



This sends 6 bytes.



_radio.readData(&_data);



If this reads all 6 bytes then you one-byte buffer will overflow. If it reads one byte then:


Serial.println(_data);



This will display the input one byte at a time, each byte on a separate line. Are you getting strange characters or numbers between 0 and 255?

it is input pullup the first code works very well as is .

i have 3 buttons defined "inputpin[3]" and when you press either it will light up the corresponding led on the receive end unit.

just that i want to port it to a ttiny85 since it is smaller

does this make sense for the TS part?

/*

  Demonstrates transmitting data with an ATtiny84.  ATtiny's have a Universal Serial Interface
  peripheral (USI) that can be used for SPI communication, and NRFLite utilizes this capability.

  Radio    ATtiny84
  CE    -> Physical Pin 10, Arduino 2
  CSN   -> Physical Pin 10, Arduino 3
  MOSI  -> Physical Pin 8 , Arduino 5 (Hardware USI_DO)
  MISO  -> Physical Pin 7 , Arduino 6 (Hardware USI_DI)
  SCK   -> Physical Pin 9 , Arduino 4 (Hardware USI_SCK)
  IRQ   -> No connection
  VCC   -> No more than 3.6 volts
  GND   -> GND

*/

#include <NRFLite.h>

const static uint8_t RADIO_ID = 3;             // Our radio's id.
const static uint8_t DESTINATION_RADIO_ID = 0; // Id of the radio we will transmit to.
const static uint8_t PIN_RADIO_CE = 2;
const static uint8_t PIN_RADIO_CSN = 3;

struct RadioPacket // Any packet up to 32 bytes can be sent.
{
  uint8_t FromRadioId;
  int Inputpin[3];
};

NRFLite _radio;
RadioPacket _radioData;

void setup()
{
  pinMode(7, INPUT_PULLUP); // Define the arcade switch NANO pin as an Input using Internal Pullups
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  if (!_radio.init(RADIO_ID, PIN_RADIO_CE, PIN_RADIO_CSN))
  {
    while (1); // Cannot communicate with radio.
  }

  _radioData.FromRadioId = RADIO_ID;
}

void loop()
{
  _radioData.Inputpin[0] = digitalRead(7);
  _radioData.Inputpin[1] = digitalRead(8);
  _radioData.Inputpin[2] = digitalRead(9);

  _radio.send(DESTINATION_RADIO_ID, &_radioData, sizeof(_radioData)); // Note how '&' must be placed in front of the variable name.

}

I have not used the NRFLite library - only the TMRh20 RF24 library.

If the three variables are the same datatype then put them in an array and send the array. If they have different datatypes put them in a struct and send the struct.

The examples in my Tutorial send arrays.

...R
Simple nRF24L01+ Tutorial

Robin2:
I have not used the NRFLite library - only the TMRh20 RF24 library.

If the three variables are the same datatype then put them in an array and send the array. If they have different datatypes put them in a struct and send the struct.

The examples in my Tutorial send arrays.

...R
Simple nRF24L01+ Tutorial

Like I said the original first code work well it is just the way to port it to the second library way.
Each button has high or low bit x 3 buttons

i tried in reply2 to modify to see if it made sense.

destiny2008:
i tried in reply2 to modify to see if it made sense.

Did it work?

Struggling to get the RX code end to work so they can communicate- so no

Looking at the library on GitHub, I see that the Basic_TX_ATtiny84 example shows you how to send a struct. Interestingly, there is no Basic_RX_ATtiny84 example, but you should be able to modfiy the Basic_RX one for ATtiny84.

gfvalvo:
Looking at the library on GitHub, I see that the Basic_TX_ATtiny84 example shows you how to send a struct. Interestingly, there is no Basic_RX_ATtiny84 example, but you should be able to modfiy the Basic_RX one for ATtiny84.

i am working to get it to use the 2pin version is what i am interested in.
3 button input high/low trigger on TX
3 led output high/low on RX .

tx:

/*
Demonstrates simple RX and TX operation using 2 pins for the radio.
Only AVR architectures (ATtiny/ATmega) support 2 pin operation.
Please read the notes in NRFLite.h for a description of all library features.
Radio circuit
* Follow the 2-Pin Hookup Guide on https://github.com/dparson55/NRFLite
Connections
* Arduino 9  > MOMI of 2-pin circuit
* Arduino 10 > SCK of 2-pin circuit
*/

#include <NRFLite.h>

const static uint8_t RADIO_ID = 2;             // Our radio's id.
const static uint8_t DESTINATION_RADIO_ID = 0; // Id of the radio we will transmit to.
const static uint8_t PIN_RADIO_MOMI = 9;
const static uint8_t PIN_RADIO_SCK = 10;

struct RadioPacket // Any packet up to 32 bytes can be sent.
{
    uint8_t FromRadioId;
    uint32_t OnTimeMillis;
    uint32_t FailedTxCount;
};

NRFLite _radio;
RadioPacket _radioData;

void setup()
{
    Serial.begin(115200);

    if (!_radio.initTwoPin(RADIO_ID, PIN_RADIO_MOMI, PIN_RADIO_SCK))
    {
        Serial.println("Cannot communicate with radio");
        while (1); // Wait here forever.
    }

    _radioData.FromRadioId = RADIO_ID;
}

void loop()
{
    _radioData.OnTimeMillis = millis();

    Serial.print("Sending ");
    Serial.print(_radioData.OnTimeMillis);
    Serial.print(" ms");

    if (_radio.send(DESTINATION_RADIO_ID, &_radioData, sizeof(_radioData))) // Note how '&' must be placed in front of the variable name.
    {
        Serial.println("...Success");
    }
    else
    {
        Serial.println("...Failed");
        _radioData.FailedTxCount++;
    }

    delay(1000);
}

RX:

/*
Demonstrates simple RX and TX operation using 2 pins for the radio.
Only AVR architectures (ATtiny/ATmega) support 2 pin operation.
Please read the notes in NRFLite.h for a description of all library features.
Radio circuit
* Follow the 2-Pin Hookup Guide on https://github.com/dparson55/NRFLite
Connections
* Arduino 9  > MOMI of 2-pin circuit
* Arduino 10 > SCK of 2-pin circuit
*/

#include <NRFLite.h>

const static uint8_t RADIO_ID = 0;       // Our radio's id.  The transmitter will send to this id.
const static uint8_t PIN_RADIO_MOMI = 9;
const static uint8_t PIN_RADIO_SCK = 10;

struct RadioPacket // Any packet up to 32 bytes can be sent.
{
    uint8_t FromRadioId;
    uint32_t OnTimeMillis;
    uint32_t FailedTxCount;
};

NRFLite _radio;
RadioPacket _radioData;

void setup()
{
    Serial.begin(115200);

    if (!_radio.initTwoPin(RADIO_ID, PIN_RADIO_MOMI, PIN_RADIO_SCK))
    {
        Serial.println("Cannot communicate with radio");
        while (1); // Wait here forever.
    }
}

void loop()
{
    while (_radio.hasData())
    {
        _radio.readData(&_radioData); // Note how '&' must be placed in front of the variable name.

        String msg = "Radio ";
        msg += _radioData.FromRadioId;
        msg += ", ";
        msg += _radioData.OnTimeMillis;
        msg += " ms, ";
        msg += _radioData.FailedTxCount;
        msg += " Failed TX";

        Serial.println(msg);
    }
}

So, do the examples work as-is, right out of the box?

gfvalvo:
So, do the examples work as-is, right out of the box?

yes

Good, then you know the library is correctly doing the heavy lifting with the radio hardware. Seems to me the basics steps you now need to do:

  • Modify the declaration of the data ‘struct’ to contain the button information you need to communicate.

  • Implement the ‘State Change’ example from the Arduino IDE (perhaps with debounce) for the three buttons on the TX side. You only want to send a new radio packet when the state of a button changes, not every time through loop.

  • Get rid of the ‘delay(1000);’ in the TX code.

  • Modify the RX code to receive the new packet (when state of a TX button changes) and set the appropriate outputs HIGH or LOW.

gfvalvo:
Good, then you know the library is correctly doing the heavy lifting with the radio hardware. Seems to me the basics steps you now need to do:

  • Modify the declaration of the data ‘struct’ to contain the button information you need to communicate.

  • Implement the ‘State Change’ example from the Arduino IDE (perhaps with debounce) for the three buttons on the TX side. You only want to send a new radio packet when the state of a button changes, not every time through loop.

  • Get rid of the ‘delay(1000);’ in the TX code.

  • Modify the RX code to receive the new packet (when state of a TX button changes) and set the appropriate outputs HIGH or LOW.

this is what i am having a hard time with .. the data struct. perhaps if you have an example or help with the code.?

i tried so far.

#include <NRFLite.h>

const static uint8_t RADIO_ID = 3;             // Our radio's id.
const static uint8_t DESTINATION_RADIO_ID = 0; // Id of the radio we will transmit to.
const static uint8_t PIN_RADIO_CE = 2;
const static uint8_t PIN_RADIO_CSN = 3;

struct RadioPacket // Any packet up to 32 bytes can be sent.
{
  uint8_t FromRadioId;
  int Inputpin[3];
};

NRFLite _radio;
RadioPacket _radioData;

void setup()
{
  pinMode(7, INPUT_PULLUP); 
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  if (!_radio.init(RADIO_ID, PIN_RADIO_CE, PIN_RADIO_CSN))
  {
    while (1); // Cannot communicate with radio.
  }

  _radioData.FromRadioId = RADIO_ID;
}

void loop()
{
  _radioData.Inputpin[0] = digitalRead(7);
  _radioData.Inputpin[1] = digitalRead(8);
  _radioData.Inputpin[2] = digitalRead(9);

  _radio.send(DESTINATION_RADIO_ID, &_radioData, sizeof(_radioData)); // Note how '&' must be placed in front of the variable name.

}

Well, that ‘struct’ is pretty inefficient. You’re using a 3 element ‘int’ array (6 bytes, 48 bits) to hold would could be held in a uint8_t (8 bits) by assigning one bit in the byte to each button. But, it would work nonetheless.

The big problem with this code is that you’re sending a radio packet every time loop() executes whether or not any button has changed state. As I pointed out, that will be hundreds (perhaps thousands) of times per second. That’s completely unnecessary. As I said, go to Arduino IDE: File --> Examples --> 02.Digital --> StateChangeDetection and study the code. You should only send a packet when at least one of the buttons change. Then, only send it once. Then wait again for the next state change.

When a packet comes in on the RX side, look at the values in the struct and set the outputs as appropriate.

gfvalvo:
Well, that ‘struct’ is pretty inefficient. You’re using a 3 element ‘int’ array (6 bytes, 48 bits) to hold would could be held in a uint8_t (8 bits) by assigning one bit in the byte to each button. But, it would work nonetheless.

The big problem with this code is that you’re sending a radio packet every time loop() executes whether or not any button has changed state. As I pointed out, that will be hundreds (perhaps thousands) of times per second. That’s completely unnecessary. As I said, go to Arduino IDE: File --> Examples --> 02.Digital --> StateChangeDetection and study the code. You should only send a packet when at least one of the buttons change. Then, only send it once. Then wait again for the next state change.

When a packet comes in on the RX side, look at the values in the struct and set the outputs as appropriate.

so if i understand correctly is that TX and RX keep sending 0 in the interim that it goes high.. your way i agree with makes sense but my question is that is it an issue for the TX if power is not a concern?

i will look at the digital example.

but i would need help with the code to modify the current one as we go :slight_smile: , thanks again

gfvalvo:
Well, that ‘struct’ is pretty inefficient. You’re using a 3 element ‘int’ array (6 bytes, 48 bits) to hold would could be held in a uint8_t (8 bits) by assigning one bit in the byte to each button. But, it would work nonetheless.

The big problem with this code is that you’re sending a radio packet every time loop() executes whether or not any button has changed state. As I pointed out, that will be hundreds (perhaps thousands) of times per second. That’s completely unnecessary. As I said, go to Arduino IDE: File --> Examples --> 02.Digital --> StateChangeDetection and study the code. You should only send a packet when at least one of the buttons change. Then, only send it once. Then wait again for the next state change.

When a packet comes in on the RX side, look at the values in the struct and set the outputs as appropriate.

updated code works. do you think it is optimal , i am testing just 1 button for now.
can you assist the array part?

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

int Inputpin[3]; // Used to store value before being sent through the NRF24L01
RF24 radio(2, 3); // NRF24L01 used pins 2 and 3 on the ATTINY84
const uint64_t pipe = 0xE8E8F0F0E1LL; // Needs to be the same for communicating between 2 NRF24L01

// this constant won't change:
const int  buttonPin = 7;    // the pin that the pushbutton is attached to

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button


void setup()
{
  pinMode(buttonPin, INPUT); // Define the arcade switch NANO pin as an Input using Internal Pullups
  //pinMode(8, INPUT);
  //pinMode(9, INPUT);
  //***************************************************
  radio.begin(); // Start the NRF24L01
  radio.setPALevel(RF24_PA_HIGH);
  radio.setDataRate(RF24_1MBPS);
  radio.setCRCLength(RF24_CRC_16);
  radio.openWritingPipe(pipe); // Get NRF24L01 ready to transmit
}

void loop()
{
  // read the pushbutton input pin:
  if (Inputpin[0] = digitalRead(buttonPin))
  {
    buttonState = digitalRead(buttonPin);
  }

  //Inputpin[1] = digitalRead(8);
  //Inputpin[2] = digitalRead(9);


  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH)
    {
      // if the current state is HIGH then the button went from off to on:
      buttonPushCounter++;
    }
    // Delay a little bit to avoid bouncing
    delay(40);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;


  // turns on the LED every four button pushes by checking the modulo of the
  // button push counter. the modulo function gives you the remainder of the
  // division of two numbers:
  if (buttonPushCounter % 2 == 0)
  {
    radio.write( Inputpin, sizeof(Inputpin) );
  }
}

any feedback?