While getting Arduino or Raspberry Pi to talk to nRF24L01 was fun and challenging, trying to make it work for a 8-pin attiny85 is a whole different experience... without serial monitor or printf debugging to the display, after the firmware was flash into the attiny85, you could only guess what is happenning or not happening when nothing was received on the nRF24L01 receiver side...
Initially, I just assume that since the Atmel attiny85 does not have hardware SPI, getting nRF24L01 talking to the attiny was not so possible... but after a few searches and reading up some blogs and forums, things seems to look brighter...
The second challenge was the usable pins on the attiny85, with 8 pins and two used by power and ground, only six pins are available... and the nRF24L01 radios uses the usual SPI - MOSI, MISO, CLK plus another two pins for SS/CSN and CE leaving only the reset pin unused.
The third challenge was size of the firmware, unlike Arduino UNO using atmega328 with 32Kb of flash, the attiny85 only have 8Kb of flash, so optimizing the code was really important, and this is the largest flash size of the attiny x5 series. See this link for the attiny comparison chart.
With the help of Alex from Insidegadgets.com, I start from a scaled down mirf codes ( mirf was the initial libraries for nRF24L01 written in C for the AVR ) using notepad, WinAVR and avrdude to compile and flash the firmware into the attiny85. Then I was using a ported version to Arduino IDE that makes things much more easier as Arduino IDE can still support USBtinyISP, the programmer I was using to flash firmware into the attiny85.
After a few unsuccessful retries, I decide to use a different approach and found on Arduino forum that someone had modified the Arduino SPI and mirf into ther attiny85 version called SPI85 and mirf85. After matching all the channels, data rate and CRC, I manage to get some packets on Serial Monitor with a mirf library on the Arduino UNO.
Since all my libraries are using RF24 for both the Arduino & Raspberry Pi, having a mirf library isn't too much useful for me. I went through all the codes and default settings and managed to configure the mirf to be compatible with RF24 library.
Here are a summary of differences between both the mirf and RF24 library :-
Data rate :
mirf : 2Mbps as it uses the default registry setting of the nRF24L01
RF24 : configurable via setDataRate()
CRC length :
mirf : 8bit CRC length
To make it work for the RF24, change the following header files directly :-
mirf85.h
#define mirf_CONFIG ((1<<EN_CRC) | (1<<CRCO) )
RF24 : configurable via setCRCLength()
Node addressing :
mirf : serv1 or clie1 ( 5 bytes in ascii format )
To talk to RF24 receiver, use the following format, :-
byte RADDR[] = {0xe2, 0xf0, 0xf0, 0xf0, 0xf0};
byte TADDR[] = {0xe3, 0xf0, 0xf0, 0xf0, 0xf0};
RF24: f0f0f0f0e2 format ( 5 bytes in hex format )
Optional settings :-
Enable Dynamic Payload :
I had my RF24 receiver with dynamic payload enabled so that I only need to set the payload size on transmitter only and can use different payload length instead of the max length.. set the below to mirf codes to enable dynamic payload.
mirf :
Mirf.configRegister( FEATURE, 1<<EN_DPL );
Mirf.configRegister( DYNPD, 1<<DPL_P0 | 1<<DPL_P1 | 1<<DPL_P2 | 1<<DPL_P3 | 1<<DPL_P4 | 1<<DPL_P5 );
I've compiled all the SPI85 and mirf85 files at github repo at the summary links below.
Summary Links :-
- https://github.com/stanleyseow/arduino-nrf24l01
- Insidegadgets.com
- Arduino forum
Initially, I just assume that since the Atmel attiny85 does not have hardware SPI, getting nRF24L01 talking to the attiny was not so possible... but after a few searches and reading up some blogs and forums, things seems to look brighter...
attiny85 pinout |
The second challenge was the usable pins on the attiny85, with 8 pins and two used by power and ground, only six pins are available... and the nRF24L01 radios uses the usual SPI - MOSI, MISO, CLK plus another two pins for SS/CSN and CE leaving only the reset pin unused.
The third challenge was size of the firmware, unlike Arduino UNO using atmega328 with 32Kb of flash, the attiny85 only have 8Kb of flash, so optimizing the code was really important, and this is the largest flash size of the attiny x5 series. See this link for the attiny comparison chart.
With the help of Alex from Insidegadgets.com, I start from a scaled down mirf codes ( mirf was the initial libraries for nRF24L01 written in C for the AVR ) using notepad, WinAVR and avrdude to compile and flash the firmware into the attiny85. Then I was using a ported version to Arduino IDE that makes things much more easier as Arduino IDE can still support USBtinyISP, the programmer I was using to flash firmware into the attiny85.
After a few unsuccessful retries, I decide to use a different approach and found on Arduino forum that someone had modified the Arduino SPI and mirf into ther attiny85 version called SPI85 and mirf85. After matching all the channels, data rate and CRC, I manage to get some packets on Serial Monitor with a mirf library on the Arduino UNO.
Since all my libraries are using RF24 for both the Arduino & Raspberry Pi, having a mirf library isn't too much useful for me. I went through all the codes and default settings and managed to configure the mirf to be compatible with RF24 library.
attiny85 nRF24L01 USBtinyISP |
Here are a summary of differences between both the mirf and RF24 library :-
Data rate :
mirf : 2Mbps as it uses the default registry setting of the nRF24L01
RF24 : configurable via setDataRate()
CRC length :
mirf : 8bit CRC length
To make it work for the RF24, change the following header files directly :-
mirf85.h
#define mirf_CONFIG ((1<<EN_CRC) | (1<<CRCO) )
RF24 : configurable via setCRCLength()
Node addressing :
mirf : serv1 or clie1 ( 5 bytes in ascii format )
To talk to RF24 receiver, use the following format, :-
byte RADDR[] = {0xe2, 0xf0, 0xf0, 0xf0, 0xf0};
byte TADDR[] = {0xe3, 0xf0, 0xf0, 0xf0, 0xf0};
RF24: f0f0f0f0e2 format ( 5 bytes in hex format )
Optional settings :-
Enable Dynamic Payload :
I had my RF24 receiver with dynamic payload enabled so that I only need to set the payload size on transmitter only and can use different payload length instead of the max length.. set the below to mirf codes to enable dynamic payload.
mirf :
Mirf.configRegister( FEATURE, 1<<EN_DPL );
Mirf.configRegister( DYNPD, 1<<DPL_P0 | 1<<DPL_P1 | 1<<DPL_P2 | 1<<DPL_P3 | 1<<DPL_P4 | 1<<DPL_P5 );
I've compiled all the SPI85 and mirf85 files at github repo at the summary links below.
Summary Links :-
- https://github.com/stanleyseow/arduino-nrf24l01
- Insidegadgets.com
- Arduino forum
No comments:
Post a Comment