SSブログ

ATtiny13 で Arduino [Arduino]

以前にATtiny45/85にArduinoのスケッチを書き込む方法を紹介させていただきました。

ArduinoISPを使う
http://www.geocities.jp/arduino_diecimila/use/attiny.html
Areduino IDEで ATtiny/ATmega開発環境を作る
http://www.geocities.jp/arduino_diecimila/use/arduino_dev.html

しかし、ATtiny45/85 はちっちゃい割にそこそこ高価、、。
秋月さんには同じ8ピンで1個120円の、ATtiny13Aがあります。

AVRマイコン  ATTINY13A-PU
http://akizukidenshi.com/catalog/g/gI-02911/
attiny13a.jpg

何とかならないかなぁ、、と、いじっていたら何とかなりました。
あまりよく分かってやっているわけではないので、とりあえず動いた程度です。

「ArduinoISPを使う」がちゃんとインストールできた状態が前提です。

boards.txt に追加
############################################
avrtiny13.name=ATtiny13 / Int.9.6MHz
avrtiny13.upload.using=arduino:arduinoisp
avrtiny13.upload.maximum_size=1024

avrtiny13.bootloader.low_fuses=0x7A
avrtiny13.bootloader.high_fuses=0xFF
avrtiny13.bootloader.path=dummy
avrtiny13.bootloader.file=dummy.hex
avrtiny13.bootloader.unlock_bits=0x3F
avrtiny13.bootloader.lock_bits=0x3F

avrtiny13.build.mcu=attiny13
avrtiny13.build.f_cpu=9600000L
avrtiny13.build.core=attiny13

############################################

そして coresフォルダ内にattiny13 というフォルダをつくり cores\attiny45_85 のフォルダ内をすべてコピーします。
つづいて、attiny13 フォルダ内の下記の4つのファイルをテキストエディタで、指定行の部分だけ書き換えます。

pins_arduino.c
  89 |	TIMER0B,	// ★ 変更箇所:TIMER1 → TIMER0B

wiring.c
 189 |	sbi(TIMSK0, TOIE0);		// ★変更箇所:TIMSK → TIMSK0

 196 | //	sbi(TCCR1, CS11);	// ★変更箇所:コメントアウト
 197 | //	sbi(TCCR1, CS10);	// ★変更箇所:コメントアウト
 198 | //	sbi(TCCR1, PWM1A);	// ★変更箇所:コメントアウト

wiring_digital.c
  57 | 	//if (timer == TIMER1) cbi(TCCR1, COM1A1);	// ★変更箇所:コメントアウト
  58 |	//if (timer == TIMER1) cbi(TCCR1, COM1B1);	// ★変更箇所:コメントアウト

wiring_analog.c
  96 |  } else if (digitalPinToTimer(pin) == TIMER0B ) {	// ★変更箇所:TIMER1 → TIMER0B

 101 |	  sbi(TCCR0A, COM0B1);	  // ★変更箇所:TCCR1 → TCCR0A, COM1A1 → COM0B1

 103 |	  OCR0B = val;	// ★変更箇所:OCR1A → OCR0B

ATtiny13のFUSE BITを書き込みます。
 low=0x7A, high=0xFF

これで、ATtiny45 などと同じように使うことができます。
しかし、ATtiny13 はプログラムメモリ 1kByteなので、油断しているとすぐにオーバーしてしまいます。

先日の虹色イルミネーションもオーバーしてしまいました。
そこで対策としては、

digitalWriteなどのオーバーヘッドが多そうな関数を使わず、ポートを直接操作したり (890 bytes)
#define GET_RAINBOW(TONE,COLOR) (max( min( 510 - abs( ( (TONE) + 510 * (COLOR) ) % 1530 - 510 ), 255 ), 0 ))
    // TONE(色調) 0-1529, COLOR(RGBの選択) 0-2

void setup()   {
  DDRB |= B00000111;
}

void loop()                     
{
  int r, g, b, t, i, d;
  for( t = 0; t < 1530; t++ ) {
    r = GET_RAINBOW( t, 0 );
    g = GET_RAINBOW( t, 1 );
    b = GET_RAINBOW( t, 2 );
    for( d = 0; d < 10; d++ ) {    // 擬似PWMの繰り返し回数(delayに相当)
      // 擬似PWM   
     if( b )  PORTB |= B00000001;
     if( g )  PORTB |= B00000010;
     if( r )  PORTB |= B00000100;
     for(i = 1; i <= 255; i++ ) {
        if( i == b )  PORTB ^= B00000001;
        if( i == g )  PORTB ^= B00000010;
        if( i == r )  PORTB ^= B00000100;
       }
    }
  }
}

負の値をとらないように、intではなくunsigned intを使うようにスケッチを変更する (894 bytes)
#define GET_RAINBOW(TONE) (((TONE)<256) ? (TONE):((TONE)<768) ? 255:(((TONE)<1024) ? (1023-(TONE)):0))

void setup()   {
  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  pinMode(2, OUTPUT);
}

void loop()
{
  unsigned int r, g, b, t, i, d;
  for( t = 0; t < 1536; t++ ) {
    r = GET_RAINBOW(  t );
    g = GET_RAINBOW( (t +  512) % 1536 );
    b = GET_RAINBOW( (t + 1024) % 1536 );
    for( d = 0; d < 10; d++ ) {    // 擬似PWMの繰り返し回数(delayに相当)
     // 擬似PWM
     if( b )  digitalWrite(0, HIGH);
     if( g )  digitalWrite(1, HIGH);
     if( r )  digitalWrite(2, HIGH);
     for(i = 1; i <= 255; i++ ) {
        if( i == b )  digitalWrite(0, LOW);
        if( i == g )  digitalWrite(1, LOW);
        if( i == r )  digitalWrite(2, LOW);
       }
    }
  }
}

などで対応してみました。

rb_tn13.jpg

AVR省電力化への挑戦 [Arduino]

AVRマイコンを省電力化することを調べてみました。

Arduino playground - ArduinoSleepCode
http://www.arduino.cc/playground/Learning/ArduinoSleepCode

SLEEP_MODE_PWR_DOWN で一番省電力になるようです。

Arduino playground - Enerlib
http://www.arduino.cc/playground/Code/Enerlib

こんなライブラリもあるようです。

でも、もっと根本的に省電力化をしたいと思いました。物理的に回路を切断できないかと。
リレーを使ってなんとかしたいと思ったのですが、マイコンから直接リレーを駆動するのはまずいらしい。
そこで、今回のキーデバイス、、

フォトモスリレー HSR312 (2個入)
http://akizukidenshi.com/catalog/g/gI-01098/

hsr312.png
これを使って、こんな感じにしてみました。
selfpoweoff_circ.png
selfpoweoff_bb.jpg
スケッチは、ICクリップを使ってArduinoISPで書き込みです。
ATtiny2313 のFUSEはたしか、Low 0xC4, High 0xDF, Ex 0xFF としたと思います。
// Self Power Off テストプログラム (ATtiny2313, 8MHz)
int pin, time = 10;
long previousMillis = 0;

void setup() {
  pinMode( 14,  INPUT );      // 電源ON延長スイッチ
  pinMode( 15, OUTPUT );      // 電源ON保持リレー出力ピン
  digitalWrite( 15, HIGH );     // リレーON
  for(pin = 0; pin < 10; pin++) pinMode( pin, OUTPUT );  // 残り時間表示LED
}

void loop() {
  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis > 200) {
    previousMillis = currentMillis;
    if(time == 0) digitalWrite( 15, LOW );  // 残り時間 0ならリレーOFF
    for(pin =  0; pin < time; pin++) digitalWrite( pin, HIGH );  // 残り時間表示
    for(pin = time; pin < 10; pin++) digitalWrite( pin, LOW  );
    time--;
  }
  
  if( digitalRead(14) == HIGH ) {     // スイッチが押されたら残り時間リセット
    time = 10;
    previousMillis = 0;
  }
}

赤のLED点灯が、実際にAVRマイコンに電流が流れていることの確認です。


ボタンを押すと、ATtiny2313の電源と、スイッチの入力ピンに電流が流れます。(ダイオードを1本かませているので電源電圧が、スイッチの入力ピンにかかる電圧より低くなってしまいますが、動いています。)
すると、ATtiny2313が起動し、電源ON保持の出力がHIGHになり、リレーをONにして、ATtiny2313に電源が供給される状態を維持します。
作動中、スイッチを押されることを関知するため、スイッチの信号入力ピンがありますが、リレーでONになった電流がスイッチの信号入力ピンに入り込まないように、ダイオードでせき止めてあります。
スケッチで、電源ON保持の出力をLOWにすると、リレーが切れて、電源OFFとなります。
(Off-State Leakage Currentが最大でも1μA、、ほぼ0ということだと思う、、)

とりあえず動いた、、けど、こんな使い方をしていいのかどうか、、定格範囲で使用できているのかどうか、調べてはいません、、あくまでホビーユースです。

そろそろ電流がちゃんと測れるテスターがほしいな。



踏切組み込み計画の挫折 [Arduino]

前回の踏切カンカンを ATtiny45V (8MHz) に移植してみました。
スイッチを押したときに鳴るようにしました。1回の「カ-ン」が途切れないようになっています。
fk_45v_bb.jpg
fk_45v_circ.png
あいかわらず見苦しいスケッチですが、前回のを少し改変
// 踏切くん (ATtiny45, 8MHz)
byte sigLED = 0;      // LEDの状態
byte railSW = 0;      // スイッチの状態

void setup() {
  DDRB |= B00000100;      // ピン2を出力に設定
  pinMode(0, INPUT);      // SW
  pinMode(3, OUTPUT);     // LED (Signal R)
  pinMode(4, OUTPUT);     // LED (Signal L)
}

void loop() {
    // 新たにスイッチを押した場合と、音が鳴っているときにスイッチが押されてた場合
  if( railSW || digitalRead(0) ) {
    railSW = 0;
    digitalWrite( 3, sigLED );           // LEDを交互に光らせる
    digitalWrite( 4, sigLED = 1 - sigLED );
    ding();
  } else {
    digitalWrite( 3, LOW );
    digitalWrite( 4, LOW );
  }
}

void ding() {
  unsigned int t;
  byte  pwm, rep, smp;
  for(t = 1; t < 750; t++) {            // 音を鳴らす
    railSW |= PINB & B00000001;             // ピン0が1回でもHIGHならSWがONと記録
    smp = (t % 5) * 4 * (1000 - t) / 1000;  // 波形を作る
    for(rep = 0; rep < 50; rep++) {           // 高速PWMで擬似アナログ出力
      PORTB |= B00000100;                       // ピン2をHIGH
      for(pwm =   0; pwm < smp; pwm++)  asm("nop");
      PORTB ^= B00000100;                       // ピン2をLOW (反転)
      for(pwm = smp; pwm <  16; pwm++)  asm("nop");
    }
  }
}


ここまできたので目標であったこいつに組み込みを、、、。
fk_45v_pr.jpg
 ・・・
アレっ、意外と小屋が狭い、、。
単4電池2本が入りそうだと思っていたのですが、小屋の中の柱が邪魔で入りませんでした。
外付け電池ボックスも格好が悪いし、ボタン電池は子供のおもちゃには心配だし、容量が少なく交換のたびに小屋のネジを開け閉めするのは面倒だし。


プラレール 音入り踏切 J18

プラレール 音入り踏切 J18

  • 出版社/メーカー: タカラトミー
  • メディア: おもちゃ&ホビー



プラレール J-18 小さな踏切

プラレール J-18 小さな踏切

  • 出版社/メーカー: タカラトミー
  • メディア: おもちゃ&ホビー


この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。