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

このページには2015年 11月まではATtiny2313/4313の情報は有りませんでしたが、
2015年12月にATtiny2313/4313の情報が追加されました。
そこで、ATtiny4313を使って、早速試してみます。

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




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

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

/*
 * nRF24L01 Send Program for ATtiny84/85/4313
 * 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)
 */
//#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);
#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と同様に問題なく動作しました。
なお、ATtiny4313の場合、D13(PB4)は制御不能になります。
これはRF24ライブラリの中で以下のように、これらのピンをSSピン(Slave Select)として使っているためです。

#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


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

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

/*
 * nRF24L01 Send And Receive Program for ATtiny84/85/4313
 * 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)
 */
//#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);
#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);

}


動作が非常に不安定でRaspberry側の表示が途中で止まりました。
ATtiny側の受信が動いていないようです。

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

/*
 * nRF24L01 Receive And Send for ATtiny84/85/4313
 * 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)
 */
//#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);
#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
}


Raspberry側で確認しましたが、1度だけ送信データが+1されて戻ってきましたが、
それ以降、全く応答なしとなりました。



ATtiny84ではある程度安定して動きましたが、ATtiny4313では送信は何とか動きますが、
受信は全くだめです。

ATtiny861で試してみました。

続く...