In this post, I want to explain how to set up a wireless communication between an Arduino and an ATtiny84 using the ping example of the Mirf library. The Arduino sends a ping signal, the ATtiny receives the signal and sends it back.
Before you start, you have to install the ATtiny cores for the Arduino IDE like I explained HERE.
Libraries needed
The wireless module nrf24l01+ uses SPI to communicate with the microcontroller. Unfortunately, the ATtiny has no hardware SPI so you have to use software to emulate the SPI connection. This is done using the so called Universal Serial Interface (USI). As usual there is a library for this, so you don't have to worry about that. Besides that, you need a modified version of the Mirf library. Both libs can be downloaded HERE. After extracting the folders "Mirf" and "SPI85" to the "libraries" folder of the Arduino IDE, you can use these libs.
Hardware
The wiring is pretty similar to the one in the example with the ATmega. CSN, CE, SCK, MOSI and MISO as well as VCC and GND have to be connected. Don't forget that the module runs with a voltage of 3,3V! The follwoing picture shows how the connect the wireless module to the ATtiny84.
Important: in the datasheet of the ATtiny you will find some pins called MISO, MOSI and SCK. These pins are only for connecting your programmer (e.g. the USBasp). The module has to be connected to USI-DI (corresponds to MISO), USI-DO (MOSI) and USCK (SCK). By default, the pins D4 to D6 are used for these pins. If you want, you can change these pins but you must not set USI-DI to the MISO pin of your programmer. The same applies for USI-DO and MOSI pin.
Software
The original "ping_client" example of the Mirf library runs on the Arduino. For the ATtiny, you have to use a slightly changed version of the "ping_server" example:
#include <SPI85.h> #include <Mirf.h> #include <MirfHardwareSpi85Driver.h> // This USI was defined in SPI85.cpp // Not to be confused with SPI (MOSI/MISO) used by ICSP pins // Refer to page 61 of attiny84 datahseet // USI pins could be redefined here //#define USI-DO 5 //#define USI-DI 4 //#define USCK 6 #define CE 7 #define CSN 3 void setup(){ /* * Set the SPI Driver. */ Mirf.spi = &MirfHardwareSpi85; /* * Setup pins / SPI. */ Mirf.cePin = CE; Mirf.csnPin = CSN; Mirf.init(); /* * Configure reciving address. */ Mirf.setRADDR((byte *)"serv1"); /* * Set the payload length to sizeof(unsigned long) the * return type of millis(). * * NB: payload on client and server must be the same. */ Mirf.payload = sizeof(unsigned long); /* * Write channel and payload config then power up reciver. */ Mirf.config(); } void loop(){ /* * A buffer to store the data. */ byte data[Mirf.payload]; /* * If a packet has been recived. * * isSending also restores listening mode when it * transitions from true to false. */ if(!Mirf.isSending() && Mirf.dataReady()){ /* * Get load the packet into the buffer. */ Mirf.getData(data); /* * Set the send address. */ Mirf.setTADDR((byte *)"clie1"); /* * Send the data back to the client. */ Mirf.send(data); /* * Wait untill sending has finished * * NB: isSending returns the chip to receving after returning true. */ } }The only difference to the version for ATmega is that SPI85.h and MirfHardwareSpi85Driver.h are included and MirfHardwareSpi85 is chosen as SPI driver in the setup():
Mirf.spi = &MirfHardwareSpi85;
When you upload the code to the ATtiny using a programmer, the pinging Arduino should get a response from the ATtiny.
I had some problems flashing the ATtiny with the USBasp as soon as the wireless module was connected to the ATtiny. I think this happend because the module and the programmer use the same pins. I have to disconnect the voltage supply of the module while flashing, then everything works fine.