Go Down

Topic: NRF24L01, ATTiny84 and Arduino Nano - Communication OK, Programming Not OK. (Read 318 times) previous topic - next topic

PSteward

Hey Guys,

I've jumped back into tinkering lately I am trying to create a node to communicate with household sensors and relays.
My first attempt is controlling a ATTiny84+NRF24L01 from an Arduino Nano+NRF24L01, and while I did get the communication happening, it doesn't seem to take my programming changes.
I am using this library: http://tmrh20.github.io/RF24/
My ATTiny84 started with the included example sketch: rf24ping85
My Nano start with the included example sketch: GettingStarted

I set it up so if I enter "L" into the serial monitor it should send the number 14 over to the ATTIny84, and once received should bring pin 2 high and then send back 14 to the Nano. Once the Nano receives 14 it'll resume what it was doing, if not it'll keep trying. Currently I cannot get the ATTIny84 to bring PIN 2 High or send back 14 to the Nano.



Here is my wiring (ignore the colors):
--- NRF24 -----------NANO--ATTINY 84
1- Black (Ground) --- GND -- GND
2 - Red (VCC 3.3v) -- 3.3V -- 3.3V
3 -Green (CE) -- D9 -- 11 (PA2)
4- White (CSN) -- D10 -- 10 (PA3)
5- Blue (SCK) -- D13 -- 9 (PA4)
6 -Orange (MOSI) -- D11 -- 7 (PA6)
7-Yellow (MISO) -- D12 -- 8 (PA5)
8 - Purple (IRQ)

Here is the Attiny84 Sketch currently:
Code: [Select]


int Lock = 2;
int Press12 = 3;
int Press78 = 4;
bool locked = 0;

// CE and CSN are configurable, specified values for ATtiny85 as connected above
#define CE_PIN 8
#define CSN_PIN 7
//#define CSN_PIN 3 // uncomment for ATtiny85 3 pins solution

#include "RF24.h"

RF24 radio(CE_PIN, CSN_PIN);

byte addresses[][6] = {
  "1Node","2Node"};
unsigned long payload = 0;

void setup() {
  // Setup and configure rf radio
  radio.begin(); // Start up the radio
  radio.setAutoAck(1); // Ensure autoACK is enabled
  radio.setRetries(15,15); // Max delay between retries & number of retries
  radio.openWritingPipe(addresses[1]); // Write to device address '2Node'
  radio.openReadingPipe(1,addresses[0]); // Read on pipe 1 for device address '1Node'
  radio.startListening(); // Start listening
  pinMode(Lock, OUTPUT);
  pinMode(Press12, OUTPUT);
  pinMode(Press78, OUTPUT);
}

void loop(void){

  if (locked == 0)
  {
 radio.stopListening(); // First, stop listening so we can talk.
  payload++;
  radio.write( &payload, sizeof(unsigned long) );
  radio.startListening(); // Now, continue listening
  }
  else
  if (locked == 1)
  {
 radio.stopListening(); // First, stop listening so we can talk.
  radio.write( 14, sizeof(14) );
  radio.startListening(); // Now, continue listening
  locked = 0;
  }
    unsigned long started_waiting_at = micros(); // Set up a timeout period, get the current microseconds
  boolean timeout = false; // Set up a variable to indicate if a response was received or not

  while ( !radio.available() ){ // While nothing is received
    if (micros() - started_waiting_at > 200000 ){ // If waited longer than 200ms, indicate timeout and exit while loop
      timeout = true;
      break;
    }

  }

  if ( !timeout ){ // Describe the results
    unsigned long got_time; // Grab the response, compare, and send to debugging spew
    radio.read( &got_time, sizeof(unsigned long) );
     if (got_time == 14)
     {
  digitalWrite(Lock,HIGH);
  delay(500);
  digitalWrite(Lock,LOW);
  locked = 1;
 
     }
  }

  // Try again 1s later
  delay(1000);
}



Here is the Nano sketch currently:
Code: [Select]



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

/***      Set this radio as radio number 0 or 1         ***/
bool radioNumber = 0;

/* Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 7 & 8 */
RF24 radio(7,8);


byte addresses[][6] = {"1Node","2Node"};

// Used to control whether this node is sending or receiving
bool role = 0;
bool lock = 0;
bool unlocked = 0;

void setup() {
  Serial.begin(115200);
  Serial.println(F("RF24/examples/GettingStarted"));
  Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
 
  radio.begin();

  radio.setPALevel(RF24_PA_LOW);
 
  // Open a writing and reading pipe on each radio, with opposite addresses
  if(radioNumber){
    radio.openWritingPipe(addresses[1]);
    radio.openReadingPipe(1,addresses[0]);
  }else{
    radio.openWritingPipe(addresses[0]);
    radio.openReadingPipe(1,addresses[1]);
  }
 
  // Start the radio listening for data
  radio.startListening();
}

void loop() {
 
 
if (role == 1)  {
   
    radio.stopListening();                                    // First, stop listening so we can talk.
   
   
    Serial.println(F("Now sending"));

    unsigned long start_time = micros();                             // Take the time, and send it.  This will block until complete
if (lock == 0)

     
     if (!radio.write( &start_time, sizeof(unsigned long) )){
       Serial.println(F("failed"));
     }
}
else
if (lock == 1)
{
    if (!radio.write(14, sizeof(14) )){
       Serial.println(F("failed"));
     }
     Serial.println(F("Locking..."));
}
    radio.startListening();                                    // Now, continue listening
   
    unsigned long started_waiting_at = micros();               // Set up a timeout period, get the current microseconds
    boolean timeout = false;                                   // Set up a variable to indicate if a response was received or not
   
    while ( ! radio.available() ){                             // While nothing is received
      if (micros() - started_waiting_at > 200000 ){            // If waited longer than 200ms, indicate timeout and exit while loop
          timeout = true;
          break;
      }     
    }
       
    if ( timeout ){                                             // Describe the results
        Serial.println(F("Failed, response timed out."));
    }else{
        unsigned long got_time;                                 // Grab the response, compare, and send to debugging spew
        radio.read( &got_time, sizeof(unsigned long) );
        unsigned long end_time = micros();
       
        // Spew it
        Serial.print(F("Sent "));
        if (lock == 0)
        {
         Serial.print(start_time);
         
        }
        else if (lock == 1)
        {
         Serial.print(14);
          if (got_time == 14)
          {
            lock = 0;
           Serial.print(F(", Got response "));
           Serial.print(F("Locked"));
           Serial.print(got_time);
          }
          else
          if (got_time != 14)
          {
           Serial.print(F(", Got response "));
           Serial.print(F("Not Locked - Will Try Again "));
           Serial.print(got_time);
       
          }
       
        }
       
     
        Serial.print(F(", Round-trip delay "));
        Serial.print(end_time-start_time);
        Serial.println(F(" microseconds"));
    }

    // Try again 1s later
    delay(1000);
  }



  if ( role == 0 )
  {
    unsigned long got_time;
   
    if( radio.available()){
                                                                    // Variable for the received timestamp
      while (radio.available()) {                                   // While there is data ready
        radio.read( &got_time, sizeof(unsigned long) );             // Get the payload
      }
     
      radio.stopListening();                                        // First, stop listening so we can talk   
      radio.write( &got_time, sizeof(unsigned long) );              // Send the final one back.     
      radio.startListening();                                       // Now, resume listening so we catch the next packets.     
      Serial.print(F("Sent response "));
      Serial.println(got_time); 
   }
 }



  if ( Serial.available() )
  {
    char c = toupper(Serial.read());
    if ( c == 'T' && role == 0 ){     
      Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
      role = 1;                  // Become the primary transmitter (ping out)
   
   }else
    if ( c == 'R' && role == 1 ){
      Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));     
       role = 0;                // Become the primary receiver (pong back)
       radio.startListening();
       
    }
    else
    if ( c == 'L' && role == 1 ){
      Serial.println(F("*** SENDING LOCK SIGNAL"));     
       lock = 1;                // Send Lock Signal
       
    }
  }


} // Loop



Any help is appreciated!

Thanks!

Robin2

Debugging wireless problems can be very difficult. Your title suggests that the wireless part is working OK but your description of the problem does not support that.

Can you connect up the Attiny so that you can display debug messages in the Arduino Serial Monitor and confirm that it is actually receiving data reliably.

Have a look at the second example in this Simple nRF24L01+ Tutorial. It uses the ackPayload feature that makes sending a message and receiving a response a lot simpler because there is no need to change the roles of the wireless devices.


...R
Two or three hours spent thinking and reading documentation solves most programming problems.

PSteward

Hey Robin,

It did appear that I was, I played around a bit and am now assuming that I am not receiving anything from the ATTiny...not sure where I am getting responses from.

Also I noticed that my pinout set up for CE and CSN appeared wrong and should have been defined as 2 (CE) and 3 (CSN) , which is physical pins 11 and 10.

Either way none of that resolved the communication issue.

Where should I start with your tutorial?
I only have an Arduino Nano and the Attiny84 at the moment while I'm waiting for my other orders to be received (it'll be a while...). I found a quick way to swap jumpers to reprogram the Attiny then switch both Nano and ATTiny back to their NRFs but it's still inconvenient.
How with my setup can I monitor the ATTiny while having the Arduino receive or send data?

Thanks again!

PSteward

I tried the tutorial code to see if I could get anywhere and set up the Arduino as the transmitter.
It just gets to SimpleTX Starting and nothing more, seems to freeze at: rslt = radio.write( &dataToSend, sizeof(dataToSend) );.

On the ATTiny84 I put (with minor change so I could see if something was coming in):
Code: [Select]
// SimpleRx - the slave or the receiver

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

#define CE_PIN 2
#define CSN_PIN 3
int led = 10;

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

RF24 radio(CE_PIN, CSN_PIN);

char dataReceived[10]; // this must match dataToSend in the TX
bool newData = false;

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

void setup() {

    Serial.begin(9600);

    Serial.println("SimpleRx Starting");
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.openReadingPipe(1, thisSlaveAddress);
    radio.startListening();
    pinMode(led, OUTPUT);
}

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

void loop() {

    getData();
    showData();
}

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

void getData() {
    if ( radio.available() ) {
        radio.read( &dataReceived, sizeof(dataReceived) );
        newData = true;
    }
}

void showData() {
    if (newData == true) {
        if (dataReceived == 14)
        {
            digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
         delay(125);               // wait for a second
          digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
         delay(125);
        } else
        if (dataReceived != 14)
        {
        digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
         delay(1000);               // wait for a second
          digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
         delay(1000);
        }
        Serial.print("Data received ");
        Serial.println(dataReceived);
        newData = false;
    }
}



I did a printdetails on the NRF24 attached to the Arduino and got this:
Code: [Select]


STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 = 0x4141417852 0xf0f0f0f0d2
RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0x4141417852
RX_PW_P0-6 = 0x20 0x20 0x00 0x00 0x00 0x00
EN_AA = 0x3f
EN_RXADDR = 0x02
RF_CH = 0x4c
RF_SETUP = 0x23
CONFIG = 0x0e
DYNPD/FEATURE = 0x00 0x00
Data Rate = 250KBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_LOW


Robin2

The details you printed from your Nano in Reply #3 did not come from my Tutorial program. The Tutorial will only work if you have the tutorial code on both devices.

The Attiny84 does not have a UART so my Tutorial programs won't work on it without modification. Can you add some form of SoftwareSerial to the Attiny so  you can get the print messages.

Putting huge delay()s into the Rx program is not helpful.


My suggestion is to get the wireless comms working between two Unos or Nanos and then you will have some useful experience for working with an Attiny.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

PSteward

The Nano had unmodified code from your tutorial as a simpletx. I added in code for the print out after it failed to progress further than "SimpleTX starting".

Also as I said before do not have 2 Arduinos...

I'll see if I can figure out a way to serial output from the attiny to the Arduino... Assuming the Arduino is even functioning properly with your code (Should it show it more than SimpleTX starting even when it fails?).

Robin2

The Nano had unmodified code from your tutorial as a simpletx. I added in code for the print out after it failed to progress further than "SimpleTX starting".
Sorry. I did not recognize the address - but it seems to to have been printed backwards.

For the future always post the actual code you use - it avoids confusion.

Best of luck with your Attiny84 - it is possible to get serial output and it should be possible to get the nRF24 working.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

PSteward

Ok I got it! I received another Uno so it gave me another step for troubleshooting.
Ultimately the end result was one NRF24L01 with a cap soldered across VCC/GND attached directly to the UNO (power for the NRF directly from the UNO) running the Radiohead library and the other side an unmodified NRF24L01 directly on the Nano (power for the NRF directly from the Nano) - No Caps this side.
My problem was a BAD NRF24L01!

As I read through your other posts I think you sum it up well:
1. Wiring (Mine was always good)
2. NRF24L01+ -> Make sure it's +, and make sure to have EXTRAS!!!
3. Caps -> Don't always need em, but be prepared
4. Libraries -> Make sure they are up to date (tmrh20 and radiohead both work well)
5. Sketches -> Your simpletx/rx is a good starter, same with thmrh20's GettingStarted and Radiohead server/client

There is lots of information out there but if your equipment is defective it doesn't help!


Itai

Hi PSteward,

Did you ever get the NRF24L01+ working with the attiny84?

I also got my NRF's working with a pair of nano's but had no success with the attiny84. If you managed to get them working together I would love to hear how!

Thanks!

Go Up