図1:とりあえず形になった状態 |
前回の3×3×3LedCube(LED27個)に引き続き、Arduino pro miniのピンが9本も余っていることから4×4×5LedCube(LED80個)の作製に挑戦してみました。
1.材料
表1:購入品一覧 | ||||
部品名 | 必要数 | 購入先 | 単価 | 費用 |
Arduino pro mini 5V版 | 1個 | Chipworld | 380円/個 | 380円 |
1kΩ抵抗 | 5本 | マルツ | 100円/100本 | 5円 |
10kΩ抵抗 | 1本 | マルツ | 100円/100本 | 1円 |
Cdsセル 5mmタイプ | 1個 | 秋月電子 | 30円/個 | 30円 |
トグルスイッチ | 1個 | マルツ | 100円/個 | 100円 |
ユニバーサル基板 Bタイプ | 1枚 | 秋月電子 | 120円/枚 | 120円 |
LED光拡散キャップ3mm白 | 80個 | 秋月電子 | 200円/50個 | 320円 |
白色3mmLED | 80個 | マルツ | 500円/100個 | 400円 |
電池ボックス 単3×4本 | 1個 | 秋月電子 | 80円/個 | 80円 |
単三乾電池eneloop | 4本 | amazon | 1000円/4本 | 1000円 |
ICソケット(24P)600mil | 1個 | 秋月電子 | 200円/10個 | 20円 |
M2.6×10なべ小ねじ | 2本 | ホームセンター | 250円/10本 | 50円 |
合計 | 2506円 |
図4:LEDの足を曲げた状態 |
3.2治具の作製
LEDの頭を固定する治具を作ります。プラダンが有ったので図5の様に20.32mm(そこまで正確に出来ません8/10inchですのでインチ定規が欲しい・・・)の間隔で16個φ4mmの穴を開けた物を作ります。
図6:LEDを治具にセット |
図7:16個半田付けした状態 |
図8:5セット完成 |
3.4Arduinoの準備
前回記事よりArduinoに表面実装されている電源用の赤色LEDは待機電流を4.67mA増加させてしまい、取り外せば待機電流は0.33mAへと大幅に減少することから、図9の様に半田ごて2本を使ってLEDを取り外した状態(図10)にします。
また今回はArduino pro miniに備わっている全ての出力ピンをもれなく使用する為、図11の様にArduino基盤裏面にピンソケットを無理やり半田点けしました。(完成後A6,7はマイコンの構造上出力出来ない事が判明)
図9:半田ごて二刀流! |
図10:LED取り外し後 |
図11:Arduino裏面A4,5,6,7にピンソケット半田付け |
3.5組立
図3回路図を元に図12の様に2箇所穴開け(φ3mmのドリル使用)と、錫めっき線と被覆線で配線をしておきます。
図12の基盤表に、用意したArduino(赤白の被覆線に、ピンヘッダを1/3位に切った物を半田付けし裏面ピンソケットに差し込む。その後ICソケットに差し込みます)・LED(被覆線を使って各LED段毎に基盤の該当するGNDへ空中配線をします。写真は配線前です)・ICソケット・CdS・抵抗を図4回路図に従って図13の様に半田付けします。
図13の基盤から出た緑の+と-の配線に電池ボックスを図14の様に半田点け後、φ2.6×10mmのねじとナットで基盤に図15の様に固定します。
図12:基盤裏配線後 |
図13:基盤表部品取り付け後 |
図14:電池ボックス半田付け |
図15:電池ボックスねじ止め |
3.6完成?状態
一日掛かってやっと形になりました。
図16:表面 |
図17:裏面 |
図18:斜め1 |
図19:斜め2 |
4.スケッチ
Arduino制御用のスケッチはこのようになっています。int BASE_0 = 5; //6変更前 int BASE_1 = 9; //7変更前 int BASE_2 = 8; //8変更前 int BASE_3 = 7; //9変更前 int BASE_4 = 6; //5変更前 int LED_0 = 4; int LED_1 = 3; int LED_2 = 2; int LED_3 = 20; //A6 int LED_4 = 12; int LED_5 = 11; int LED_6 = 10; int LED_7 = 21; //A7 int LED_8 = 16; //A2(A3はcdsの電圧読み取り) int LED_9 = 14; //A0 int LED_10 = 13; int LED_11 = 18; //A4 int LED_12 = 1; //Tx int LED_13 = 0; //Rx int LED_14 = 15; //A1 int LED_15 = 19; //A5 int BASE_LIST[5] = {BASE_0,BASE_1,BASE_2,BASE_3,BASE_4}; int LED_LIST[16] = {LED_0,LED_1,LED_2,LED_3,LED_4,LED_5,LED_6,LED_7,LED_8,LED_9,LED_10,LED_11,LED_12,LED_13,LED_14,LED_15}; int val =0; // LEDキューブの状態.HIGH or LOWを格納 int led_state[5][4][4]; int LED_NUM = 80; float COUNT_MAX = 30;//66行目で変化 int count = 0; void setup(){ // 各pinのIN/OUT設定 pinMode(BASE_0,OUTPUT); pinMode(BASE_1,OUTPUT); pinMode(BASE_2,OUTPUT); pinMode(BASE_3,OUTPUT); pinMode(BASE_4,OUTPUT); pinMode(LED_0 ,OUTPUT); pinMode(LED_1 ,OUTPUT); pinMode(LED_2 ,OUTPUT); pinMode(LED_3 ,OUTPUT); pinMode(LED_4 ,OUTPUT); pinMode(LED_5 ,OUTPUT); pinMode(LED_6 ,OUTPUT); pinMode(LED_7 ,OUTPUT); pinMode(LED_8 ,OUTPUT); pinMode(LED_9 ,OUTPUT); pinMode(LED_10 ,OUTPUT); pinMode(LED_11 ,OUTPUT); pinMode(LED_12 ,OUTPUT); pinMode(LED_13 ,OUTPUT); pinMode(LED_14 ,OUTPUT); pinMode(LED_15 ,OUTPUT); // LEDキューブの状態初期化 int i=0,j=0,k=0; for(i=0; i<5; i++){ for(j=0; j<4; j++){ for(k=0; k<4; k++){ led_state[i][j][k] = LOW; } } } randomSeed(analogRead(0)); } // openFrameworks風にループ内を分割 void loop(){ update(); action(); } // 状態の更新 void update(){ if(count >= COUNT_MAX){ COUNT_MAX=random(10,50); if (analogRead(3)>500){ //壱番は500、弐番は670、参番は500 // LEDキューブの状態初期化 int i=0,j=0,k=0; for(i=0; i<5; i++){ for(j=0; j<4; j++){ for(k=0; k<4; k++){ led_state[i][j][k] = LOW; } } } randomSeed(analogRead(3)); action(); delayWDT(9); }else{ // ランダムに状態変化 led_toggle(random(LED_NUM)); count = 0; } } else { count++; } } // 状態の反映 void action(){ blink_cube(); } // LEDキューブをダイナミック点灯 void blink_cube(){ int i=0,j=0,k=0; for(i=0; i<5; i++){ // i番目の段以外はHIGH digitalWrite(BASE_0,HIGH); digitalWrite(BASE_1,HIGH); digitalWrite(BASE_2,HIGH); digitalWrite(BASE_3,HIGH); digitalWrite(BASE_4,HIGH); digitalWrite(BASE_LIST[i],LOW); // 同一段内の9つのLEDを制御 for(j=0; j<4; j++){ for(k=0; k<4; k++){ digitalWrite(LED_LIST[j+k*4], led_state[i][j][k]); } } // 気持ち程度delay.なくてもok delay(1); } } // 指定番号のLEDの状態をトグル void led_toggle(int num){ int i,j,k; i = num / 16; // 元「i = num / 9」要検討 j = (num % 16) / 4; //元「(num % 9) / 3」要検討 k = num % 4; //元「num % 3」要検討 if(led_state[i][j][k] == HIGH){ led_state[i][j][k] = LOW; } else { led_state[i][j][k] = HIGH; } } //delayWDTここから #include <avr/sleep.h> #include <avr/wdt.h> void delayWDT(unsigned long t) { // パワーダウンモードでdelayを実行 delayWDT_setup(t); // ウォッチドッグタイマー割り込み条件設定 ADCSRA &= ~(1 << ADEN); // ADENビットをクリアしてADCを停止(120μA節約) set_sleep_mode(SLEEP_MODE_PWR_DOWN); // パワーダウンモード sleep_enable(); sleep_mode(); // ここでスリープに入る sleep_disable(); // WDTがタイムアップでここから動作再開 ADCSRA |= (1 << ADEN); // ADCの電源をON (|=が!=になっていたバグを修正2014/11/17) } void delayWDT_setup(unsigned int ii) { // ウォッチドッグタイマーをセット。 // 引数はWDTCSRにセットするWDP0-WDP3の値。設定値と動作時間は概略下記 // 0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms, 5=500ms // 6=1sec, 7=2sec, 8=4sec, 9=8sec byte bb; if (ii > 9 ){ // 変な値を排除 ii = 9; } bb =ii & 7; // 下位3ビットをbbに if (ii > 7){ // 7以上(7.8,9)なら bb |= (1 << 5); // bbの5ビット目(WDP3)を1にする } bb |= ( 1 << WDCE ); MCUSR &= ~(1 << WDRF); // MCU Status Reg. Watchdog Reset Flag ->0 // start timed sequence WDTCSR |= (1 << WDCE) | (1<<WDE); // ウォッチドッグ変更許可(WDCEは4サイクルで自動リセット) // set new watchdog timeout value WDTCSR = bb; // 制御レジスタを設定 WDTCSR |= _BV(WDIE); } ISR(WDT_vect) { // WDTがタイムアップした時に実行される処理 // wdt_cycle++; // 必要ならコメントアウトを外す } //delayWDTここまで
5.動作確認
Arduinoに4.スケッチを書き込み、動作確認した結果、正常に動作を確・・・認・・・出来ませんでした。
図20:一応動作? |
ArduinoのD13からは弱々しく(ほぼ見えない)出力されており、A6,7からは出力されていない御様子。
原因としてはArduinoのD13は表面実装LEDによる電圧降下で点灯せず(前回D13は避けていたのに忘れていました。電源LEDの様に除去せねば、しかし見たところ難易度が高い。OUTではなくGNDにすれば・・・いける?)、A6,A7についてはAnalogReadだけの機能しかなかった為、DigitalWriteとしては機能しないそうです。
詳細はhttp://www.atmel.com/images/doc8161.pdfの1.1.9に書いてありました。
〇原文
ADC7:6(TQFP and QFN/MLF Package Only)In the TQFP and QFN/MLF package, ADC7:6 serve as analog inputs to the A/D converter.These pins are powered from the analog supply and serve as 10-bit ADC channels.
ADC7:6(TQFP and QFN/MLF Package Only)In the TQFP and QFN/MLF package, ADC7:6 serve as analog inputs to the A/D converter.These pins are powered from the analog supply and serve as 10-bit ADC channels.
〇Google先生翻訳
ADC7:6(TQFPとQFN/MLFパッケージのみ)TQFPとQFN/MLFパッケージでは、ADC7:6は、A/Dコンバータのアナログ入力として機能します。これらのピンはアナログ電源から給電され、10ビットのADCチャネルとして機能しています。
ADC7:6(TQFPとQFN/MLFパッケージのみ)TQFPとQFN/MLFパッケージでは、ADC7:6は、A/Dコンバータのアナログ入力として機能します。これらのピンはアナログ電源から給電され、10ビットのADCチャネルとして機能しています。
〇自己理解
A0~5はAnalogReadもDigitalWriteも可能だが、A6,7はAnalogReadのみ可。
A0~5はAnalogReadもDigitalWriteも可能だが、A6,7はAnalogReadのみ可。
6.まとめ
D13についてはGNDとして機能させれば行けるのではないかと楽観、D6についてはD3(CdSのAnalogReadに使用)と入れ替えれば行けそう。D7についてはArduino単体で行けそうにありません・・・(泣)。しばらく解決策を考えてみます。(そのまま放置になりそう)励みになりますのでよければクリック下さい(^o^)/