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/
何とかならないかなぁ、、と、いじっていたら何とかなりました。
あまりよく分かってやっているわけではないので、とりあえず動いた程度です。
「ArduinoISPを使う」がちゃんとインストールできた状態が前提です。
boards.txt に追加
そして coresフォルダ内にattiny13 というフォルダをつくり cores\attiny45_85 のフォルダ内をすべてコピーします。
つづいて、attiny13 フォルダ内の下記の4つのファイルをテキストエディタで、指定行の部分だけ書き換えます。
pins_arduino.c
wiring.c
wiring_digital.c
wiring_analog.c
ATtiny13のFUSE BITを書き込みます。
low=0x7A, high=0xFF
これで、ATtiny45 などと同じように使うことができます。
しかし、ATtiny13 はプログラムメモリ 1kByteなので、油断しているとすぐにオーバーしてしまいます。
先日の虹色イルミネーションもオーバーしてしまいました。
そこで対策としては、
digitalWriteなどのオーバーヘッドが多そうな関数を使わず、ポートを直接操作したり (890 bytes)
負の値をとらないように、intではなくunsigned intを使うようにスケッチを変更する (894 bytes)
などで対応してみました。
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/
何とかならないかなぁ、、と、いじっていたら何とかなりました。
あまりよく分かってやっているわけではないので、とりあえず動いた程度です。
「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); } } } }
などで対応してみました。
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/
これを使って、こんな感じにしてみました。
スケッチは、ICクリップを使ってArduinoISPで書き込みです。
ATtiny2313 のFUSEはたしか、Low 0xC4, High 0xDF, Ex 0xFF としたと思います。
赤のLED点灯が、実際にAVRマイコンに電流が流れていることの確認です。
再生できない場合、ダウンロードは🎥こちら
ボタンを押すと、ATtiny2313の電源と、スイッチの入力ピンに電流が流れます。(ダイオードを1本かませているので電源電圧が、スイッチの入力ピンにかかる電圧より低くなってしまいますが、動いています。)
すると、ATtiny2313が起動し、電源ON保持の出力がHIGHになり、リレーをONにして、ATtiny2313に電源が供給される状態を維持します。
作動中、スイッチを押されることを関知するため、スイッチの信号入力ピンがありますが、リレーでONになった電流がスイッチの信号入力ピンに入り込まないように、ダイオードでせき止めてあります。
スケッチで、電源ON保持の出力をLOWにすると、リレーが切れて、電源OFFとなります。
(Off-State Leakage Currentが最大でも1μA、、ほぼ0ということだと思う、、)
とりあえず動いた、、けど、こんな使い方をしていいのかどうか、、定格範囲で使用できているのかどうか、調べてはいません、、あくまでホビーユースです。
そろそろ電流がちゃんと測れるテスターがほしいな。
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/
これを使って、こんな感じにしてみました。
スケッチは、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回の「カ-ン」が途切れないようになっています。
あいかわらず見苦しいスケッチですが、前回のを少し改変
ここまできたので目標であったこいつに組み込みを、、、。
・・・
アレっ、意外と小屋が狭い、、。
単4電池2本が入りそうだと思っていたのですが、小屋の中の柱が邪魔で入りませんでした。
外付け電池ボックスも格好が悪いし、ボタン電池は子供のおもちゃには心配だし、容量が少なく交換のたびに小屋のネジを開け閉めするのは面倒だし。
スイッチを押したときに鳴るようにしました。1回の「カ-ン」が途切れないようになっています。
あいかわらず見苦しいスケッチですが、前回のを少し改変
// 踏切くん (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"); } } }
ダウンロードは🎥こちら
ここまできたので目標であったこいつに組み込みを、、、。
・・・
アレっ、意外と小屋が狭い、、。
単4電池2本が入りそうだと思っていたのですが、小屋の中の柱が邪魔で入りませんでした。
外付け電池ボックスも格好が悪いし、ボタン電池は子供のおもちゃには心配だし、容量が少なく交換のたびに小屋のネジを開け閉めするのは面倒だし。