RaspberryとArduinoの無線通信(nRF24L01+ATtiny861)

これまでATtiny84とATtiny4313で試しましたが、なんとなく法則がつかめたのでATtiny861で試してみました。
最初に、ライブラリのコードを一部変更します。

【RF24_config.h 修正前】
{前略}
//ATTiny  
#elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny2313__) || defined(__AVR_ATtiny4313__)
 
  #define RF24_TINY
  #include "utility/ATTiny/RF24_arch_config.h"

【RF24_config.h 修正後】 赤字部分を追加
{前略}
//ATTiny  
#elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny2313__) || defined(__AVR_ATtiny4313__) || defined(__AVR_ATtiny861__)
 
  #define RF24_TINY
  #include "utility/ATTiny/RF24_arch_config.h"



【RF24.cpp 修正前】
{前略}
//ATTiny support code pulled in from https://github.com/jscrane/RF24

#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
// see http://gammon.com.au/spi
#    define DI   0  // D0, pin 5  Data In
#    define DO   1  // D1, pin 6  Data Out (this is *not* MOSI)
#    define USCK 2  // D2, pin 7  Universal Serial Interface clock
#    define SS   3  // D3, pin 2  Slave Select
#elif defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
// these depend on the core used (check pins_arduino.h)
// this is for jeelabs' one (based on google-code core)
#    define DI   4   // PA6
#    define DO   5   // PA5
#    define USCK 6   // PA4
#    define SS   3   // PA7
#elif defined(__AVR_ATtiny2313__) || defined(__AVR_ATtiny4313__)
// these depend on the core used (check pins_arduino.h)
// tested with google-code core
#    define DI   14  // PB5
#    define DO   15  // PB6
#    define USCK 16  // PB7
#    define SS   13  // PB4
#endif


【RF24.cpp 修正後】 赤字部分を追加
{前略}
//ATTiny support code pulled in from https://github.com/jscrane/RF24

#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
// see http://gammon.com.au/spi
#    define DI   0  // D0, pin 5  Data In
#    define DO   1  // D1, pin 6  Data Out (this is *not* MOSI)
#    define USCK 2  // D2, pin 7  Universal Serial Interface clock
#    define SS   3  // D3, pin 2  Slave Select
#elif defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
// these depend on the core used (check pins_arduino.h)
// this is for jeelabs' one (based on google-code core)
#    define DI   4   // PA6
#    define DO   5   // PA5
#    define USCK 6   // PA4
#    define SS   3   // PA7
#elif defined(__AVR_ATtiny2313__) || defined(__AVR_ATtiny4313__)
// these depend on the core used (check pins_arduino.h)
// tested with google-code core
#    define DI   14  // PB5
#    define DO   15  // PB6
#    define USCK 16  // PB7
#    define SS   13  // PB4
#elif defined(__AVR_ATtiny861__)
// these depend on the core used (check pins_arduino.h)
// tested with google-code core
#    define DI   9   // PB0
#    define DO   8   // PB1
#    define USCK 7   // PB2
#    define SS   6   // PB3

#endif

<追記>
Enhance Requestを出していましたが、2016年3月23日に、上記の修正は本家にマージされました。
</追記>

「Software Driven SPI」に切り替えていた場合は、オリジナルの「Hardware Driven SPI」に戻します。
ATtiny861とnRF24L01の結線は以下の様に なります。
ATtiny861への供給電圧は5Vです。
nRF24L01モジュールのVCCは3.3Vなので、 5V→3.3Vのレギュレータ+バイパスコンデンサーを使って3.3Vを供給しています。



最初はRaspberry側がサーバ、Tiny側がクライアントの確認です。
Raspberry側のプログラムはこちらで紹介しているものを使いました。

ATtiny861側のスケッチは以下の様になります。

/*
 * nRF24L01 Send Program for ATtiny84/85/4313/861
 * Build with FemtoCow AddOn
 *
 * for ATtiny84
 *  VCC  3.3V
 *  MISO PA6(Pin#7)
 *  MOSI PA5(Pin#8)
 *  SCK  PA4(Pin#9)
 *  CE   PA2(Pin#11)
 *  CSN  PA3(Pin#10)
 *
 * for ATtiny85
 *  VCC  3.3V
 *  MISO PB0(Pin#5)
 *  MOSI PB1(Pin#6)
 *  SCK  PB2(Pin#7)
 *  CE   PB3(Pin#2)
 *  CSN  PB4(Pin#3)
 *
 * for ATtiny4313
 *  VCC  3.3V
 *  MISO PB5(Pin#17)
 *  MOSI PB6(Pin#18)
 *  SCK  PB7(Pin#19)
 *  CE   PB3(Pin#15)
 *  CSN  PB4(Pin#16)
 * 
 * for ATtiny861
 *  VCC  3.3V
 *  MISO PB0(Pin#1)
 *  MOSI PB1(Pin#2)
 *  SCK  PB2(Pin#3)
 *  CE   PA6(Pin#12)
 *  CSN  PA7(Pin#11)
 */
//#include <SPI.h>
//#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"

// Set up nRF24L01 radio on SPI bus plus pins
#if defined(__AVR_ATtiny84__)
  RF24 radio(8,7);
#elif defined(__AVR_ATtiny85__)
  RF24 radio(3,4);
#elif defined(__AVR_ATtiny4313__)
  RF24 radio(12,13);
#elif defined(__AVR_ATtiny861__)
  RF24 radio(12,13);
#endif

// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };

void setup(void)
{
  //
  // Setup and configure rf radio
  //
  radio.begin();
  radio.openWritingPipe(pipes[1]);
  radio.openReadingPipe(1,pipes[0]);
  radio.printDetails();
}

void loop(void)
{
  static int value = 0;
  uint8_t sdata[32];

  // Take the time, and send it.  This will block until complete
  sdata[0]=value;
  value++;

#if 1
  radio.write( sdata, sizeof(sdata) );
#else
  bool ok = false;
  while(!ok) {
    ok = radio.write( sdata, sizeof(sdata) );
    if (ok) {
      Serial.println("ok...");
    } else {
      Serial.println("failed.");
    }
  }
#endif
  delay(1000);

}


ATtiny84と同様に問題なく動作しました。
なお、ATtiny861の場合、D6(PB3)はSSピン(Slave Select)として使うため制御不能になります。

次に、Raspberry側から の応答を待つようにしてみました。
Raspberry側のプログラムはこちらで紹介しているものを使いました。

Raspberryからの応答データが正しく受信できているかどうか確認するために、
受信したデータを次の送信データとしています。
Tiny ---0--> Raspberry
Tiny <--1--- Raspberry(受信したデータを+1して応答)
Tiny -->1--> Raspberry
Tiny <--2--- Raspberry(受信したデータを+1して応答)
ATtiny861側のスケッチは以下の様になります。

/*
 * nRF24L01 Send And Receive Program for ATtiny84/85/4313/861
 * Build with FemtoCow AddOn
 *
 * for ATtiny84
 *  VCC  3.3V
 *  MISO PA6(Pin#7)
 *  MOSI PA5(Pin#8)
 *  SCK  PA4(Pin#9)
 *  CE   PA2(Pin#11)
 *  CSN  PA3(Pin#10)
 *
 * for ATtiny85
 *  VCC  3.3V
 *  MISO PB0(Pin#5)
 *  MOSI PB1(Pin#6)
 *  SCK  PB2(Pin#7)
 *  CE   PB3(Pin#2)
 *  CSN  PB4(Pin#3)
 *
 * for ATtiny4313
 *  VCC  3.3V
 *  MISO PB5(Pin#17)
 *  MOSI PB6(Pin#18)
 *  SCK  PB7(Pin#19)
 *  CE   PB3(Pin#15)
 *  CSN  PB4(Pin#16)
 * 
 * for ATtiny861
 *  VCC  3.3V
 *  MISO PB0(Pin#1)
 *  MOSI PB1(Pin#2)
 *  SCK  PB2(Pin#3)
 *  CE   PA6(Pin#12)
 *  CSN  PA7(Pin#11)
 */
//#include <SPI.h>
//#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"

// Set up nRF24L01 radio on SPI bus plus pins
#if defined(__AVR_ATtiny84__)
  RF24 radio(8,7);
#elif defined(__AVR_ATtiny85__)
  RF24 radio(3,4);
#elif defined(__AVR_ATtiny4313__)
  RF24 radio(12,13);
#elif defined(__AVR_ATtiny861__)
  RF24 radio(12,13);
#endif

// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };

void setup(void)
{
  //
  // Setup and configure rf radio
  //
  radio.begin();
  radio.openWritingPipe(pipes[1]);
  radio.openReadingPipe(1,pipes[0]);
  radio.printDetails();
}

void loop(void)
{
  static int value = 0;
  uint8_t sdata[32];
  uint8_t rdata[32];

  // Take the time, and send it.  This will block until complete
  sdata[0]=value;

#if 1
  radio.write( sdata, sizeof(sdata) );
#else
  bool ok = false;
  while(!ok) {
    ok = radio.write( data, sizeof(data) );
    if (ok)
      Serial.println("ok...");
    else
      Serial.println("failed.");
  }
#endif

  // Now, continue listening
  radio.startListening();
  while ( ! radio.available() ) {
  }
  radio.read( &rdata, sizeof(rdata) );
  radio.stopListening();

  value=rdata[0]; // Next send data
  delay(1000);

}


こちらも、ATtiny84と同様に問題なく動作しました。

次にRaspberry側がクライアント、Tiny側がサーバーの確認です。
Raspberry側のプログラムはこちらで紹介しているものを使いました。
ATtiny861側のスケッチは以下の様になります。
クライアント側から受け取ったデータを+1して送り返す簡単なものです。

/*
 * nRF24L01 Receive And Send for ATtiny84/85/4313/861
 * Build with FemtoCow AddOn
 *
 * for ATtiny84
 *  VCC  3.3V
 *  MISO PA6(Pin#7)
 *  MOSI PA5(Pin#8)
 *  SCK  PA4(Pin#9)
 *  CE   PA2(Pin#11)
 *  CSN  PA3(Pin#10)
 *
 * for ATtiny85
 *  VCC  3.3V
 *  MISO PB0(Pin#5)
 *  MOSI PB1(Pin#6)
 *  SCK  PB2(Pin#7)
 *  CE   PB3(Pin#2)
 *  CSN  PB4(Pin#3)
 *
 * for ATtiny4313
 *  VCC  3.3V
 *  MISO PB5(Pin#17)
 *  MOSI PB6(Pin#18)
 *  SCK  PB7(Pin#19)
 *  CE   PB3(Pin#15)
 *  CSN  PB4(Pin#16)
 * 
 * for ATtiny861
 *  VCC  3.3V
 *  MISO PB0(Pin#1)
 *  MOSI PB1(Pin#2)
 *  SCK  PB2(Pin#3)
 *  CE   PA6(Pin#12)
 *  CSN  PA7(Pin#11)
 */
//#include <SPI.h>
//#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"

// Set up nRF24L01 radio on SPI bus plus pins
#if defined(__AVR_ATtiny84__)
  RF24 radio(8,7);
#elif defined(__AVR_ATtiny85__)
  RF24 radio(3,4);
#elif defined(__AVR_ATtiny4313__)
  RF24 radio(12,13);
#elif defined(__AVR_ATtiny861__)
  RF24 radio(12,13);
#endif

// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t pipes[2] = { 0xE0E0E0E0E0LL, 0xE0E0E0E0E1LL };

void setup(void)
{
  //
  // Setup and configure rf radio
  //
  radio.begin();
  radio.openWritingPipe(pipes[0]);
  radio.openReadingPipe(1,pipes[1]);
  radio.startListening();
  radio.printDetails();
}

void loop(void)
{
  uint8_t rdata[32];
  uint8_t sdata[32];

  // if there is data ready
  if ( radio.available() )
  {
    // Fetch the payload, and see if this was the last one.
    radio.read( rdata, sizeof(rdata) );

    // Spew it
    sdata[0]=rdata[0]+1;
    radio.stopListening();
    radio.write( &sdata, sizeof(sdata) );
    radio.startListening();   
  } // end if
}


こちらも、ATtiny84と同様に問題なく動作しました。
ATtiny84とATtiny861は送受信ともに正常に動くようです。
ATtiny4313は受信が動きません。


ATtiny84
ATtiny4313
ATtiny861
Raspberry←ATtiny



Raspberry←ATtiny
Raspberry→ATtiny

×

Raspberry→ATtiny
Raspberry←ATtiny

×


最初にも書きましたが、nRF24L01モジュールは技術基準適合証明等のマーク(通称技適マーク)が交付されていませんので
あくまでも実験レベルと考えてください。

たぶん...おしまい