ATtinyの赤外線受信


ATtinyで赤外線受信をしたいと前から考えていました。
ATmega328ではIRremote ライブラリを使って赤外線の受信ができます。
ライブラリの説明ではATtiny84/85もサポートボードになっていますが、
ボードをATtiny85に変更してライブラリサンプルとして付属するIRrecvDumpをコンパイルすると、Flashサイズオーバーフロー のエラーとなります。
ビルドオプションが変更されました。全体をリビルドしています。
c:/users/user/appdata/local/arduino15/packages/arduino/tools/avr-gcc/5.4.0-atmel3.6.1-arduino2/bin/../lib/gcc/avr/5.4.0/../../../../avr/bin/ld.exe: C:\Users\user\AppData\Local\Temp\arduino_build_98840/IRrecvDump.ino.elf section `.text' will not fit in region `text'

c:/users/user/appdata/local/arduino15/packages/arduino/tools/avr-gcc/5.4.0-atmel3.6.1-arduino2/bin/../lib/gcc/avr/5.4.0/../../../../avr/bin/ld.exe: region `text' overflowed by 1014 bytes

collect2.exe: error: ld returned 1 exit status

exit status 1
ボードATtiny25/45/85に対するコンパイル時にエラーが発生しました。


ライブラリ内の「IRremote.h」を変更し、特定の赤外線フォーマットだけを有効にすることで、Flashサイズを減らすことができます。
今回はNECフォーマットの送受信だけを有効にしました。
//------------------------------------------------------------------------------
// Supported IR protocols
// Each protocol you include costs memory and, during decode, costs time
// Disable (set to 0) all the protocols you do not need/want!
//
#define DECODE_RC5           0
#define SEND_RC5             0

#define DECODE_RC6           0
#define SEND_RC6             0

#define DECODE_NEC           1
#define SEND_NEC             1

#define DECODE_SONY          0
#define SEND_SONY            0

#define DECODE_PANASONIC     0
#define SEND_PANASONIC       0

#define DECODE_JVC           0
#define SEND_JVC             0

#define DECODE_SAMSUNG       0
#define SEND_SAMSUNG         0

#define DECODE_WHYNTER       0
#define SEND_WHYNTER         0

#define DECODE_AIWA_RC_T501  0
#define SEND_AIWA_RC_T501    0

#define DECODE_LG            0
#define SEND_LG              0

#define DECODE_SANYO         0
#define SEND_SANYO           0 // NOT WRITTEN

#define DECODE_MITSUBISHI    0
#define SEND_MITSUBISHI      0 // NOT WRITTEN

#define DECODE_DISH          0 // NOT WRITTEN
#define SEND_DISH            0

#define DECODE_SHARP         0 // NOT WRITTEN
#define SEND_SHARP           0

#define DECODE_DENON         0
#define SEND_DENON           0

#define DECODE_PRONTO        0 // This function doe not logically make sense
#define SEND_PRONTO          0

#define DECODE_LEGO_PF       0 // NOT WRITTEN
#define SEND_LEGO_PF         0


これでATtiny84/85でもコンパイルが通りますが、クロックを1MHz→8MHzに変更する必要が有ります。
クロックを8MHz(Internal)にするためには、こ ちらで紹介されているように、
ダミーのブートローダ書き込みでATtinyのヒューズビット書き換えを行う必要が有ります。
サンプルスケッチの「IRremoteinfo」を使うと、有効なフォーマットを一覧で表示します。
IRremoteInfo - by AnalysIR (http://www.AnalysIR.com/)
             - A helper sketch to assist in troubleshooting issues with the library by reviewing the settings within the IRremote library
             - Prints out the important settings within the library, which can be configured to suit the many supported platforms
             - When seeking on-line support, please post or upload the output of this sketch, where appropriate

IRremote Library Settings
=========================
RAWBUF: 101
Timer defined for use: Timer_TINY0
IR Tx Pin: 1
MCU Clock: 8000000
MCU Platform: ATtiny85
Mark Excess: 100 uSecs
Microseconds per tick: 50 uSecs
Measurement tolerance: 25%
Minimum Gap between IR Signals: 5000 uSecs
Arduino IDE version: 1.8.5
Debug Mode: OFF (Normal)

IR PROTOCOLS  SEND     DECODE
============= ======== ========
RC5:          Disabled Disabled
RC6:          Disabled Disabled
NEC:          Enabled  Enabled
SONY:         Disabled Disabled
PANASONIC:    Disabled Disabled
JVC:          Disabled Disabled
SAMSUNG:      Disabled Disabled
WHYNTER:      Disabled Disabled
AIWA_RC_T501: Disabled Disabled
LG:           Disabled Disabled
SANYO:        Disabled Disabled
MITSUBISHI:   Disabled Disabled
DISH:         Disabled Disabled
SHARP:        Disabled Disabled
DENON:        Disabled Disabled
PRONTO:       Disabled (Not Applicable)

Notes:
     - Most of the seetings above can be configured in the following files included as part of the library
     - IRremteInt.h
     - IRremote.h
     - You can save SRAM by disabling the Decode or Send features for any protocol (Near the top of IRremoteInt.h)
     - Some Timer conflicts, with other libraries, can be easily resolved by configuring a differnt Timer for your platform


以下のスケッチをMega328/Tiny84/Tiny85に書き込んでみました。
#include <IRremote.h> // https://github.com/z3t0/Arduino-IRremote

#if defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__)
 #define MODEL "ATmega328"
 #define recvPin 2

#elif defined(__AVR_ATtiny84__)
 #define MODEL "ATtiny84"
 #define recvPin 3

#elif defined(__AVR_ATtiny85__)
 #define MODEL "ATtiny85"
 #define recvPin 2
#endif

IRrecv irrecv(recvPin);

decode_results results;

void setup()
{
  Serial.begin(9600);
  // In case the interrupt driver crashes on setup, give a clue
  // to the user what's going on.
  Serial.println("Enabling IRin");
  irrecv.enableIRIn(); // Start the receiver
  Serial.println("Enabled IRin");
}

void loop() {
  if (irrecv.decode(&results)) {
   Serial.print("MODEL=");
   Serial.println(MODEL);
   if (results.decode_type == NEC) {
     Serial.print("NEC: ");
   } else if (results.decode_type == UNKNOWN) {
     Serial.print("UNKNOWN: ");
   }

    Serial.println(results.value, HEX);
    irrecv.resume(); // Receive the next value
  }
}

8KのFlashでも60%ぐらいのスケッチサイズで収まりますが、RAMが結構きついです。
最大8192バイトのフラッシュメモリのうち、スケッチが4826バイト(58%) を使っています。
最大512バイトのRAMのうち、グローバル変数が366バイト(71%)を使っていて、ローカル変数で146バイト使うこ とができます。

【ATmega328@16MHz】
手元にあったON/OFFのリモコンを発射してみました。


【ATtiny85@8MHz(Internal)】
同じコードが受信できました。
ATtiny84/85のシリアル出力ポートはこち らで 紹介しています。
リピートコード(0xFFFFFFFF)は受信できないようです。


【ATtiny84@8MHz(Internal)】
赤外線受信のポートを2→3に変えると受信できました。
正しく受信できるポートとできないポートが有ります。


続く...