8pinoでモーターを回してみる
今回も
研修で戴いた、部材を使って8pinoの活用方法を考えます。
で、こちらのセットを使います。 初心者向けなので、既に研修講師によって配線されたものが配られました。 何てありがたい
ざっと確認して、モーターと電池は何となくわかりますが、コネクタ2つと金属が飛び出ている黒いIC?はよく解りません。 こちらを深堀してみます。
黒いICの理解
目を凝らしてみると、
TOSHIBA JAPAN
TA7291P 1314G
と読み取れました。早速調べます。
メーカーのサイト や、仕様書 は見れたのですが、イマイチ理解が深まらず。
結局、こちらのサイト が一番良く解説してくれてました。
要は、GPIO 2本でStart, Stop, 回転方向の制御を、PWM 1本で回転速度の制御を、それぞれ行う為のICの様です。
GPIO : 回転方向制御
コネクタとの結線を確認する
より、詳しく見るために、ICの裏面に番号をふりました。 対応表はこちら。
ピン番号 | ピン名 | 8pino側 | 備考 |
---|---|---|---|
1 | GND | GND | Ground |
2 | OUT 1 | - | モーターに繋ぐ |
3 | - | - | 未使用 |
4 | Vref | PWM | モーター速度制御 |
5 | IN 1 | GPIO | 回転方向制御 |
6 | IN 2 | GPIO | 回転方向制御 |
7 | Vcc | 5.0v | IC駆動用電源 |
8 | Vs | - | モーター駆動用電源 |
9 | - | - | 未使用 |
10 | OUT 2 | - | モーターに繋ぐ |
8pinoと繋ぐ
GPIOはPin3,4を、PWMにはPin0をそれぞれアサインしてみました。
回転制御をシリアル経由で指示してみたかったので、Pin1,2はシリアル接続しています。
Pin数ギリギリ!
制御仕様
ターミナルから下記の様に指示出します。
char | コマンド |
---|---|
m | Start motor |
x | Stop motor |
+ | Speed up |
- | Speed down |
これで、思うように、モーターを制御する事が出来ました。
デモ 1(レゴ StarWars)
何をデモに使おうかなと、思ったのですが、今年はStarWars yearですし、棚に飾ってあったMaster Yodaに、Episode 2を再現させる事にしました。
結果、やっぱり最強のJediです。
ベイダー卿倒す前に、フォース(回転数)を大きくしています。
楽しくて、止まりません。息子とStarWarsごっこ。
何度、ヨーダが外れて、飛んでいったことか。
デモ 2(レゴ ヘリコプター)
レゴで回ると言えばヘリコプター。
羽の部分を取り外して、モーターに取り付けてみました。
こっちはイマイチ。
以上!
次回は、残り物の部材、最後の一点を使った開発となります。
忘れてた。
コードはこちら。
/* 8pino Motor Control Test */ #include <SoftwareSerial.h> #define _8PINO_SOFTWARE_SERIAL_PIN_RX ( 1 ) #define _8PINO_SOFTWARE_SERIAL_PIN_TX ( 2 ) #define _8PINO_PROMPT_STRING ( "\r\n8pino > " ) SoftwareSerial mySerial( _8PINO_SOFTWARE_SERIAL_PIN_RX, _8PINO_SOFTWARE_SERIAL_PIN_TX ); #define _8PINO_MOTOR_SPEED_CTRL_PIN ( 0 ) #define _8PINO_MOTOR_ROTATION_CTRL_PIN1 ( 3 ) #define _8PINO_MOTOR_ROTATION_CTRL_PIN2 ( 4 ) #define _8PINO_MOTOR_DEFAULT_SPEED ( 10 ) #define _8PINO_MOTOR_SPEED_MAX ( 100 ) #define _8PINO_MOTOR_SPEED_MIN ( 10 ) int motor_speed = _8PINO_MOTOR_DEFAULT_SPEED; void setup(){ // set the data rate for the SoftwareSerial port mySerial.begin(4800); mySerial.println(""); mySerial.println("--- Hello! from 8pino... ---"); mySerial.write( _8PINO_PROMPT_STRING ); pinMode( _8PINO_MOTOR_SPEED_CTRL_PIN, OUTPUT ); pinMode( _8PINO_MOTOR_ROTATION_CTRL_PIN1, OUTPUT ); pinMode( _8PINO_MOTOR_ROTATION_CTRL_PIN2, OUTPUT ); analogWrite( _8PINO_MOTOR_SPEED_CTRL_PIN, motor_speed ); stopMotor(); /* // TEST 1 setRotationCW(); delay( 1000 ); stopMotor(); delay( 3000 ); setRotationCCW(); delay( 1000 ); stopMotor(); */ } void loop(){ int tmp_char = 0; if ( mySerial.available() ){ tmp_char = mySerial.read(); if( tmp_char == '\r' ){ mySerial.write( _8PINO_PROMPT_STRING ); }else if( tmp_char == '+' ){ if( motor_speed < _8PINO_MOTOR_SPEED_MAX ){ motor_speed += 10; mySerial.write( tmp_char ); mySerial.write( "\r\nSpeed Up! : " ); mySerial.print( motor_speed ); mySerial.write( _8PINO_PROMPT_STRING ); analogWrite( _8PINO_MOTOR_SPEED_CTRL_PIN, motor_speed ); } }else if( tmp_char == '-' ){ if( motor_speed > _8PINO_MOTOR_SPEED_MIN ){ motor_speed -= 10; mySerial.write( tmp_char ); mySerial.write( "\r\nSpeed Down! : " ); mySerial.print( motor_speed ); mySerial.write( _8PINO_PROMPT_STRING ); analogWrite( _8PINO_MOTOR_SPEED_CTRL_PIN, motor_speed ); } }else if( tmp_char == 'm' ){ setRotationCW(); mySerial.write( tmp_char ); mySerial.write( "\r\nStart Motor!" ); mySerial.write( _8PINO_PROMPT_STRING ); }else if( tmp_char == 'x' ){ stopMotor(); mySerial.write( tmp_char ); mySerial.write( "\r\nStop Motor..." ); mySerial.write( _8PINO_PROMPT_STRING ); }else{ mySerial.write( tmp_char ); } } } void stopMotor(){ digitalWrite( _8PINO_MOTOR_ROTATION_CTRL_PIN1, LOW ); digitalWrite( _8PINO_MOTOR_ROTATION_CTRL_PIN2, LOW ); } void setRotationCW(){ digitalWrite( _8PINO_MOTOR_ROTATION_CTRL_PIN1, HIGH ); digitalWrite( _8PINO_MOTOR_ROTATION_CTRL_PIN2, LOW ); } void setRotationCCW(){ digitalWrite( _8PINO_MOTOR_ROTATION_CTRL_PIN1, LOW ); digitalWrite( _8PINO_MOTOR_ROTATION_CTRL_PIN2, HIGH ); }
8pinoでI2C液晶パネルを使ってみる
一年位前に
自分の中でIoTブームが来た事があって、社内のRaspberryPi講座を受けさせてもらいました。
そのときに、教材として、色々と電子工作部品を戴いたなと、ハタと思い出したので、埃を被っていた袋をこじ開けて、これを見つけました。 初心者には、大変嬉しい完成版。
今回のゴール
液晶パネルが2行×8文字なので、
1行目 : 起動時間表示
2行目 : お店の看板みたいな文字列スクロール
をやってみようかと思います。
動かないんです
結線については、I2Cなので、V、GND、SDA、SCLを8pinoのそれらの専用端子に繋ぐだけです。何て、簡単。
iの24~28に差し込みます
差し込んだ後の図
で、格闘する事、小一時間。 うんともすんとも言ってくれません。 おんなじ部品で、Arduinoで実現している人沢山いるのに。
あまりに放置したから、壊れた?
原因を探る
原因1 : pull-up抵抗足りなかった
こちらのサイト曰く、
The pull-up resistors are necessary when using the ATtiny85. They are not necessary on the arduino because the arduino has internal pull-ups enabled when using the I2C interface.
SDA, SCLの共に、10kΩの抵抗を結線する必要がありました。
嬉しいことに、こちらの基板、その抵抗が実装済みで、ちょっとハンダ盛るだけで、実現可能です。
対応前
対応後
原因2 : スレーブアドレス間違い
だって、説明書に0x7Cって。
なんか世の中のサンプルコード見てたら、みんな0x3Eで実装している人が沢山いて、薄々おかしいなとは思っていました。
0x7C(0111 1100)を右に1ビットずらしたら、0x3E(0011 1110)となることに気が付いて、試してみたら動作しました!
調べてみたら、I2Cのアドレスは7bitだそうで。うーん、果たして誰が悪いのか。俺か。
ソフトウェアの準備
TinyWireM
ArduinoでI2Cを使うには、通常、Wire Libraryを使う様ですが、ATTiny85 では非対応な様で、 8pino公式サイトにもあるように
[I2C通信について]
下記のTinyWireMライブラリをご利用ください。
TinyWireM
https://github.com/adafruit/TinyWireM
TinyWireMライブラリを使います。 インストール方法等は、下記を参考にさせていただきました。
LCD表示のためのライブラリ
上で紹介したblogのコードを見てみたのですが、割りとマジックナンバー系の調整?が沢山必要そうでした。
それもそのはず、表示のための仕様書がこうですもの
とても、気軽に実装できる内容ではありません。
Arduinoには、LiquidCrystalというライブラリがありますが、私の環境では、何かが不満らしく、動作しません。
探してみると、神様が現れました。 こちらのblogで、本LCDパネルをサポートした、Arduino向けのライブラリ(しかも、LiquidCrystal api コンパチ!)が公開されていました!
ただ、これは、Arduino向けのライブラリですので、TinyWireM向けに、修正します。
→ どこかで見つけた、修正方法
LCD Test
Test 1
とにかく表示させてみる。
カーソルの点滅がそれらしさを醸し出します。
Test 2
Test 1に加えて、scrollDisplayLeft()を確認。
そういう事ね。
Test 3
目的の1つだった、autoscroll()を試します。
スクロールはしてくれるのですが、インターフェースがわかりにくいのと、行毎のスクロール非対応っぽいので、使わないと、判断。
スクロールはAPI使わず実現すれば良いです。
本対応
出来ました。
起動開始からの時刻の表示は、millis() を利用しています。
LCD使えると、とたんに表現力が上がるなと感じます。デバッグにも良いでしょうし。
コードはこちら
#include <TinyWireM.h> #include <ST7032.h> // ST7032 lcd( int i2c_addr ); // i2c_addr: slave address // omit i2c_addr -> 0x3E will be set. // AE-AQM0802 works well with the default setting above. ST7032 lcd; #define _8PINO_LCD_NUM_OF_COLUMNS ( 8 ) #define _8PINO_LCD_NUM_OF_ROWS ( 2 ) #define _8PINO_LCD_CONTRAST ( 30 ) #define _8PINO_LCD_TEXT_SCROLL_DELAY ( 200 ) void setup(){ // For LCD Panel. lcd.begin( _8PINO_LCD_NUM_OF_COLUMNS, _8PINO_LCD_NUM_OF_ROWS ); lcd.setContrast( _8PINO_LCD_CONTRAST ); /* // TEST 1 lcd.print("8pino:"); lcd.setCursor(0, 1); lcd.print("Awesome"); lcd.cursor(); lcd.blink(); */ /* // TEST 2 lcd.print("8pino:"); lcd.setCursor(0, 1); lcd.print("Awesome"); lcd.cursor(); lcd.blink(); lcd.scrollDisplayLeft(); */ /* // TEST 3 lcd.setCursor(0, 0); for (int thisChar = 0; thisChar < 8; thisChar++) { lcd.print(thisChar); delay( _8PINO_LCD_TEXT_SCROLL_DELAY ); } lcd.setCursor(8, 1); // set the display to automatically scroll: lcd.autoscroll(); for (int thisChar = 9; thisChar < 8; thisChar++) { lcd.print(thisChar); delay( _8PINO_LCD_TEXT_SCROLL_DELAY ); } // turn off automatic scrolling lcd.noAutoscroll(); lcd.clear(); */ } void loop(){ int i = 0; int str_head_pos = 0; char teststr[] = " 8pino -> The minimalist's arduino/trinket compatible! "; while( 1 ){ // Text Scroll lcd.setCursor( 0, 1 ); for ( i = str_head_pos; i < str_head_pos + _8PINO_LCD_NUM_OF_COLUMNS; i++ ){ lcd.print( teststr[i] ); } str_head_pos++; if( str_head_pos > sizeof( teststr ) - _8PINO_LCD_NUM_OF_COLUMNS ){ str_head_pos = 0; } // Time unsigned long time; time = millis(); lcd.setCursor( 0, 0 ); lcd.print( "Sec:" ); lcd.print( ( time / 10000 ) % 10 ); lcd.print( ( time / 1000 ) % 10 ); lcd.print( "." ); lcd.print( ( time / 100 ) % 10 ); delay( _8PINO_LCD_TEXT_SCROLL_DELAY ); } }
まだ
他にも、RaspberryPi研修でもらった部品があるので、次回はそちらを深堀してみます。
8pinoでタクトスイッチを使う
先日、
8pinoで遊ぶための部品を仕入れに、人生で二度目の秋月に足を運びました。
一通り、見終わって、さぁ、お会計という時に、レジ横にあったのがこちら。
10円って。
ごそっと適当に掴んで、5、6個購入したと思います。
ずっと放置していましたが、今回のテーマはこれです。
やりたいこと
前回、Software Serialで実現した、ピアノみたいなものを、タクトスイッチで、作ってみたいです。
簡単かと思ったら…
タクトスイッチの状態は、ArduinoのDigitalRead()で取れば、楽勝だなとタカをくくっていたら、、、
8pinoはピンの数が圧倒的に少ない事に気がつきました。
とてもピアノなんか作れない。 これは困る。
世界には、他にもこれに困っている人がいるはずです。
探しました、見つけました。
ほんと、頭のいい人っているものだ。と、心底思います。
こちら
に、「各スイッチに異なるΩの抵抗をつけて、それら全てを結線したPinについて、AnalogRead()で得られた電圧をもって、どのスイッチが押されたか?を判断する方式」
が載っていました。
具体的な図はこちら。
真似してみます
とはいっても、家にそんなに沢山の種類の抵抗はありません。
8pinoのusbコネクタ保護の為に購入した1.5kΩの抵抗は100個wあったので、これを活用します。
まさか、陽の目を見るとは…
結線図
いくつか抵抗を繋ぎ、それらをブレッドボードの+に繋ぎます。
Software Serialも繋いでいます。理由は後述
最もイライラしたのは
この、タクトスイッチが、なんとも腹の立つ感じで、「ピヨッ」って跳ね上がって、外れてしまうのです。
どんなに強く押しても。
ググったら、対策としてスイッチの足を90度ねじ曲げる方法がありました。画像は無かったので、正解か解りませんが、下記のように曲げると、いい感じにささるようになりました。
(左)対策前, (右)対策後
そろそろコード書きたいけど
我慢です。そもそもAnalogRead()でいくつが返ってくるのか、わかりません。
ほんとは先に計算すべきですが、ここで便利なSoftware Serialの登場です。 とにかく値を読んで見ました。
おぉ、おぉ。
ちゃんと、押したスイッチ応じて、違う値が取得出来るではないか!
うーん?でも、なんか、想像とちょっと違う値…
抵抗一個の時は、1023 / 2 位じゃないの?
(USBのD-のpullup抵抗分が加算されているからですね。ポートの選択を完全に誤りました。)
計算を正しくやることが目的ではないのでさらっと流します。
気力の問題
と、ブレッドボードの余白の問題で、ピアノは断念して、単純にLEDをピからせるだけにしました。
動画はこちら。
わりと、素早くボタン押しても、誤動作しませんでした。
うーん。苦労したわりにアウトプットがショボいと、なえます。
コードはこちら
ピンのアサインがいけてないので、参考程度ですが。
/* Tact Switch test */ #define _8PINO_SOFTWARE_SERIAL_DEBUG #include <SoftwareSerial.h> /************************************************* * For Adafruit NeoPixel *************************************************/ #include <Adafruit_NeoPixel.h> #ifdef __AVR_ATtiny85__ // Trinket, Gemma, etc. #include <avr/power.h> #endif #define NEOPIXEL_IN_PIN 0 #define NUM_OF_PIXELS 16 Adafruit_NeoPixel pixels = Adafruit_NeoPixel( NUM_OF_PIXELS, NEOPIXEL_IN_PIN ); #ifdef _8PINO_SOFTWARE_SERIAL_DEBUG #define _8PINO_SOFTWARE_SERIAL_PIN_RX ( 1 ) #define _8PINO_SOFTWARE_SERIAL_PIN_TX ( 2 ) #define _8PINO_PRINT_NEOPIXEL_RING_CONTROL ( "\r\n Neopixel Ring -> " ) #define _8PINO_PROMPT_STRING ( "\r\n8pino > " ) SoftwareSerial mySerial( _8PINO_SOFTWARE_SERIAL_PIN_RX, _8PINO_SOFTWARE_SERIAL_PIN_TX ); #endif #define TACT_SWITCHES_PIN 3 #define TACT_SWITCH_1_VAL ( 762 ) #define TACT_SWITCH_2_VAL ( 874 ) #define TACT_SWITCH_3_VAL ( 920 ) #define TACT_SWITCH_4_VAL ( 944 ) #define TACT_SWITCH_OFFSET ( 5 ) void setup() { pinMode( NEOPIXEL_IN_PIN, OUTPUT ); pinMode( TACT_SWITCHES_PIN, INPUT ); #ifdef __AVR_ATtiny85__ // Trinket, Gemma, etc. if( F_CPU == 16000000 ) clock_prescale_set( clock_div_1 ); #endif pixels.begin(); pixels.setBrightness(30); pixels.show(); // Initialize all pixels to "off" #ifdef _8PINO_SOFTWARE_SERIAL_DEBUG // set the data rate for the SoftwareSerial port mySerial.begin(4800); //mySerial.println(""); //mySerial.println("--- Hello! from 8pino... ---"); #endif } void loop() // run over and over { int i = 0; char tmpStr[5]; int tact_switches_pin_val = analogRead( TACT_SWITCHES_PIN ); itoa( tact_switches_pin_val, tmpStr, 10 ); #ifdef _8PINO_SOFTWARE_SERIAL_DEBUG mySerial.write( "\r\n" ); mySerial.write( tmpStr ); #endif if( abs( tact_switches_pin_val - TACT_SWITCH_1_VAL ) < TACT_SWITCH_OFFSET ){ for( i = 0; i < NUM_OF_PIXELS; i++ ){ pixels.setPixelColor( i, 255, 0, 0 ); } }else if( abs( tact_switches_pin_val - TACT_SWITCH_2_VAL ) < TACT_SWITCH_OFFSET ){ for( i = 0; i < NUM_OF_PIXELS; i++ ){ pixels.setPixelColor( i, 0, 255, 0 ); } }else if( abs( tact_switches_pin_val - TACT_SWITCH_3_VAL ) < TACT_SWITCH_OFFSET ){ for( i = 0; i < NUM_OF_PIXELS; i++ ){ pixels.setPixelColor( i, 0, 0, 255 ); } }else if( abs( tact_switches_pin_val - TACT_SWITCH_4_VAL ) < TACT_SWITCH_OFFSET ){ for( i = 0; i < NUM_OF_PIXELS; i++ ){ pixels.setPixelColor( i, Wheel( ( i * 256 / pixels.numPixels() ) & 255 ) ); } } pixels.show(); // Initialize all pixels to "off" delay( 30 ); } uint32_t Wheel(byte WheelPos) { if(WheelPos < 85) { return pixels.Color(WheelPos * 3, 255 - WheelPos * 3, 0); } else if(WheelPos < 170) { WheelPos -= 85; return pixels.Color(255 - WheelPos * 3, 0, WheelPos * 3); } else { WheelPos -= 170; return pixels.Color(0, WheelPos * 3, 255 - WheelPos * 3); } }
こんな簡単な機能なのに、HWで多くを対応するっていうのは本当に難しい。
8pinoでSoftwareSerialを使う その2
以前の投稿
で
ただ、あまりUART経由で指示を出すと、電子工作の勉強からは外れてしまうので、それほど深堀しない予定です。
と言ったはずですが、ソフト屋さんとしては、ちょっとだけ、パチコチやりたくなってしまうわけです。
と言うわけで
まずは対話型のインターフェースの基礎をテストすべく、Neopixelの制御を実装してみました。
動画はこちら
仕様は下記の通り
- r → 赤く光る
- g → 緑色に光る
- b → 青く光る
- 8 → 七色に光る
- x → 消灯
ターミナル上はこんな感じ。
うん、想定通り動いています。
※ コードは一番下に記載。
もう一個くらい、デモしたい
せっかくベースを作ったので、他の例も試してみたいです。
この間
とかのシリーズで、圧電スピーカーを制覇したので、これを応用してみたい!
そんな前提で辺りを見回すと、こんなものがありました。
子供向け(おもちゃ)のピアノ絵本です。
これを作ってみましょう。
キーボードに対して、白鍵・黒鍵をこのようにマッピングします。
そして、結果
できました。
今回も音階に合わせて、LED光らせています。
ピアノを習っている六歳児に渡すと、それなりに弾ける様でした。
ターミナルの様子。
考察
ピアノ絵本は楽天価格で、2000円以上するみたいなので、わりとリーズナブルに同程度の環境が構築出来たことになります。
だから、何?
後、やっぱり、出来そうなことをやって、
結果、出来ても、成長はしないですね。
次回は電子工作寄りの話に戻します。
LEDのコードはこちら。
/* Software serial test Control Adafruit Neopixel Ring */ #include <SoftwareSerial.h> /************************************************* * For Adafruit NeoPixel *************************************************/ #include <Adafruit_NeoPixel.h> #ifdef __AVR_ATtiny85__ // Trinket, Gemma, etc. #include <avr/power.h> #endif #define NEOPIXEL_IN_PIN 0 #define NUM_OF_PIXELS 16 Adafruit_NeoPixel pixels = Adafruit_NeoPixel( NUM_OF_PIXELS, NEOPIXEL_IN_PIN ); #define _8PINO_SOFTWARE_SERIAL_PIN_RX ( 1 ) #define _8PINO_SOFTWARE_SERIAL_PIN_TX ( 2 ) #define _8PINO_PRINT_NEOPIXEL_RING_CONTROL ( "\r\n Neopixel Ring -> " ) #define _8PINO_PROMPT_STRING ( "\r\n8pino > " ) SoftwareSerial mySerial( _8PINO_SOFTWARE_SERIAL_PIN_RX, _8PINO_SOFTWARE_SERIAL_PIN_TX ); void setup() { pinMode( NEOPIXEL_IN_PIN, OUTPUT ); #ifdef __AVR_ATtiny85__ // Trinket, Gemma, etc. if( F_CPU == 16000000 ) clock_prescale_set( clock_div_1 ); #endif pixels.begin(); pixels.setBrightness(30); pixels.show(); // Initialize all pixels to "off" // set the data rate for the SoftwareSerial port mySerial.begin(4800); mySerial.println(""); mySerial.println("--- Hello! from 8pino... ---"); mySerial.write( _8PINO_PROMPT_STRING ); } void loop() // run over and over { int tmp_char = 0; int i = 0; if ( mySerial.available() ){ tmp_char = mySerial.read(); if( tmp_char == '\r' ){ mySerial.write( _8PINO_PROMPT_STRING ); }else if( tmp_char == 'r' ){ mySerial.write( tmp_char ); mySerial.write( _8PINO_PRINT_NEOPIXEL_RING_CONTROL); mySerial.write( "Red!" ); for( i = 0; i < NUM_OF_PIXELS; i++ ){ pixels.setPixelColor( i, 255, 0, 0 ); } pixels.show(); mySerial.write( _8PINO_PROMPT_STRING ); }else if( tmp_char == 'g' ){ mySerial.write( tmp_char ); mySerial.write( _8PINO_PRINT_NEOPIXEL_RING_CONTROL); mySerial.write( "Green!" ); for( i = 0; i < NUM_OF_PIXELS; i++ ){ pixels.setPixelColor( i, 0, 255, 0 ); } pixels.show(); mySerial.write( _8PINO_PROMPT_STRING ); }else if( tmp_char == 'b' ){ mySerial.write( tmp_char ); mySerial.write( _8PINO_PRINT_NEOPIXEL_RING_CONTROL); mySerial.write( "Blue!" ); for( i = 0; i < NUM_OF_PIXELS; i++ ){ pixels.setPixelColor( i, 0, 0, 255 ); } pixels.show(); mySerial.write( _8PINO_PROMPT_STRING ); }else if( tmp_char == '8' ){ mySerial.write( tmp_char ); mySerial.write( _8PINO_PRINT_NEOPIXEL_RING_CONTROL); mySerial.write( "Rainbow!" ); for( i = 0; i < NUM_OF_PIXELS; i++ ){ pixels.setPixelColor( i, Wheel( ( i * 256 / pixels.numPixels() ) & 255 ) ); } pixels.show(); mySerial.write( _8PINO_PROMPT_STRING ); }else if( tmp_char == 'x' ){ mySerial.write( tmp_char ); mySerial.write( _8PINO_PRINT_NEOPIXEL_RING_CONTROL); mySerial.write( "Off!" ); for( i = 0; i < NUM_OF_PIXELS; i++ ){ pixels.setPixelColor( i, 0, 0, 0 ); } pixels.show(); mySerial.write( _8PINO_PROMPT_STRING ); }else{ mySerial.write( tmp_char ); } } } uint32_t Wheel(byte WheelPos) { if(WheelPos < 85) { return pixels.Color(WheelPos * 3, 255 - WheelPos * 3, 0); } else if(WheelPos < 170) { WheelPos -= 85; return pixels.Color(255 - WheelPos * 3, 0, WheelPos * 3); } else { WheelPos -= 170; return pixels.Color(0, WheelPos * 3, 255 - WheelPos * 3); } }
ピアノのコードはこちら。
/* Software serial test Control Buzzer */ #include <SoftwareSerial.h> /************************************************* * For Adafruit NeoPixel *************************************************/ #include <Adafruit_NeoPixel.h> #ifdef __AVR_ATtiny85__ // Trinket, Gemma, etc. #include <avr/power.h> #endif #define NEOPIXEL_IN_PIN 0 #define NUM_OF_PIXELS 16 Adafruit_NeoPixel pixels = Adafruit_NeoPixel( NUM_OF_PIXELS, NEOPIXEL_IN_PIN ); #define _8PINO_SOFTWARE_SERIAL_PIN_RX ( 1 ) #define _8PINO_SOFTWARE_SERIAL_PIN_TX ( 2 ) #define _8PINO_PROMPT_STRING ( "\r\n8pino > " ) SoftwareSerial mySerial( _8PINO_SOFTWARE_SERIAL_PIN_RX, _8PINO_SOFTWARE_SERIAL_PIN_TX ); #define _8PINO_TONE_DELAY_TIME ( 150 ) #define _8PINO_TONE_SPEAKER_PIN_1 ( 1 ) #define _8PINO_TONE_SPEAKER_PIN_2 ( 4 ) #define _8PINO_TONE_START ( 0x00 ) #define _8PINO_TONE_STOP ( 0x01 ) #define _8PINO_TONE_NOT_USED ( 0 ) #define _8PINO_TONE_DO_2 ( 238 ) #define _8PINO_TONE_RE_2 ( 212 ) #define _8PINO_TONE_MI_2 ( 189 ) #define _8PINO_TONE_FA_2 ( 178 ) #define _8PINO_TONE_FA_SH_2 ( 168 ) #define _8PINO_TONE_SO_2 ( 158 ) #define _8PINO_TONE_SO_SH_2 ( 150 ) #define _8PINO_TONE_RA_2 ( 141 ) #define _8PINO_TONE_SI_FL_2 ( 133 ) #define _8PINO_TONE_SI_2 ( 126 ) #define _8PINO_TONE_DO_3 ( 118 ) #define _8PINO_TONE_DO_SH_3 ( 112 ) #define _8PINO_TONE_RE_3 ( 106 ) #define _8PINO_TONE_RE_SH_3 ( 99 ) #define _8PINO_TONE_MI_3 ( 94 ) #define _8PINO_TONE_FA_3 ( 89 ) #define _8PINO_TONE_FA_SH_3 ( 83 ) #define _8PINO_TONE_SO_3 ( 79 ) #define _8PINO_TONE_SO_SH_3 ( 74 ) #define _8PINO_TONE_RA_3 ( 70 ) #define _8PINO_TONE_SI_FL_3 ( 66 ) #define _8PINO_TONE_SI_3 ( 62 ) #define _8PINO_TONE_DO_4 ( 59 ) #define _8PINO_TONE_DO_SH_4 ( 55 ) #define _8PINO_TONE_RE_4 ( 52 ) #define _8PINO_TONE_MI_4 ( 46 ) #define _8PINO_TONE_FA_4 ( 44 ) #define _8PINO_TONE_SO_4 ( 39 ) #define _8PINO_TONE_RA_4 ( 34 ) void setup() { pinMode( NEOPIXEL_IN_PIN, OUTPUT ); pinMode( _8PINO_TONE_SPEAKER_PIN_2, OUTPUT ); #ifdef __AVR_ATtiny85__ // Trinket, Gemma, etc. if( F_CPU == 16000000 ) clock_prescale_set( clock_div_1 ); #endif pixels.begin(); pixels.setBrightness(15); pixels.show(); // Initialize all pixels to "off" // Configure Registers for PWM of PB4(PIN No.4) // 1. Comparator A Mode -> Set the OC1A output line. // 2. Time/Counter1 Prescale Select -> 8MHz/256 = 32KHz. // 3. Enable Pulse Width Modulator B. // 4. Comparator B Mode -> Set the OC1B output line TCCR1 = _BV (COM1A1) | _BV (COM1A0) | _BV (CS13) | _BV (CS10); GTCCR = _BV (PWM1B) | _BV (COM1B1) | _BV (COM1B0); // set the data rate for the SoftwareSerial port mySerial.begin(4800); // mySerial.println(""); // mySerial.println("--- Hello! from 8pino... ---"); mySerial.write( _8PINO_PROMPT_STRING ); } void loop() // run over and over { int tmp_char = 0; int i = 0; int note = 0; int light_index = 0; if ( mySerial.available() ){ tmp_char = mySerial.read(); if( tmp_char == '\r' ){ mySerial.write( _8PINO_PROMPT_STRING ); }else{ mySerial.write( tmp_char ); mySerial.write( "\r\n " ); switch( tmp_char ){ case 'q': mySerial.write( "FA# 2" ); note = _8PINO_TONE_FA_SH_2; light_index = 1; break; case 'a': mySerial.write( "SO 2" ); note = _8PINO_TONE_SO_2; light_index = 2; break; case 'w': mySerial.write( "SO# 2" ); note = _8PINO_TONE_SO_SH_2; light_index = 2; break; case 's': mySerial.write( "RA 2" ); note = _8PINO_TONE_RA_2; light_index = 3; break; case 'e': mySerial.write( "SIb 2" ); note = _8PINO_TONE_SI_FL_2; light_index = 3; break; case 'd': mySerial.write( "SI 2" ); note = _8PINO_TONE_SI_2; light_index = 4; break; case 'f': mySerial.write( "DO 3" ); note = _8PINO_TONE_DO_3; light_index = 5; break; case 't': mySerial.write( "DO# 3" ); note = _8PINO_TONE_DO_SH_3; light_index = 5; break; case 'g': mySerial.write( "RE 3" ); note = _8PINO_TONE_RE_3; light_index = 6; break; case 'y': mySerial.write( "RE# 3" ); note = _8PINO_TONE_RE_SH_3; light_index = 6; break; case 'h': mySerial.write( "MI 3" ); note = _8PINO_TONE_MI_3; light_index = 7; break; case 'j': mySerial.write( "FA 3" ); note = _8PINO_TONE_FA_3; light_index = 8; break; case 'i': mySerial.write( "FA# 3" ); note = _8PINO_TONE_FA_SH_3; light_index = 8; break; case 'k': mySerial.write( "SO 3" ); note = _8PINO_TONE_SO_3; light_index = 9; break; case 'o': mySerial.write( "SO# 3" ); note = _8PINO_TONE_SO_SH_3; light_index = 9; break; case 'l': mySerial.write( "RA 3" ); note = _8PINO_TONE_RA_3; light_index = 10; break; case 'p': mySerial.write( "SIb 3" ); note = _8PINO_TONE_SI_FL_3; light_index = 10; break; case ';': mySerial.write( "SI 3" ); note = _8PINO_TONE_SI_3; light_index = 11; break; case ':': mySerial.write( "DO 4" ); note = _8PINO_TONE_DO_4; light_index = 12; break; case '[': mySerial.write( "DO# 4" ); note = _8PINO_TONE_DO_SH_4; light_index = 12; break; case ']': mySerial.write( "RE 4" ); note = _8PINO_TONE_RE_4; light_index = 13; break; default : mySerial.write( tmp_char ); return; } _8pinoTone( _8PINO_TONE_SPEAKER_PIN_2, note, _8PINO_TONE_START ); for( i = 0; i < light_index; i++ ){ pixels.setPixelColor( i, 255, 255, 255 ); } pixels.show(); delay( _8PINO_TONE_DELAY_TIME ); _8pinoTone( _8PINO_TONE_SPEAKER_PIN_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP ); for( i = 0; i < NUM_OF_PIXELS; i++ ){ pixels.setPixelColor( i, 0, 0, 0 ); } pixels.show(); mySerial.write( _8PINO_PROMPT_STRING ); } } } void _8pinoTone( int pin_speaker, uint8_t freq, uint8_t startstop ){ if( startstop == _8PINO_TONE_START ){ pinMode( pin_speaker, OUTPUT ); // if( pin_speaker == _8PINO_TONE_SPEAKER_PIN_1 ){ // OCR0A = freq; // OCR0B = OCR0A - 1; // }else{ OCR1C = freq; OCR1B = OCR1C - 1; // } }else{ pinMode( pin_speaker, INPUT ); } }
8pinoでSoftwareSerialを使う その1
困っていること
8pinoさんには、USBシリアルなどの手段がデフォルトで用意されていないため、デバッグが非常に困難です。
外部のセンサ情報を観察したい場合などで、困ることになります。 (注意:普通のarduinoでやれば、シリアル使えると思います。本ページでは8pino固執していまして…)
じゃあ、どうするか
策はありそうです。以前も参照した8pino+の方が、SoftwareSerialが使えたと記載されています。 これを試してみます。
SoftwareSerialを使うための部材
上記では変換基板を使われていますが、普通の家庭にはありません。
ですので、今回はこちらを仕入れました。
ただ
Compatible with Raspberry Pi A+,B,B+/2.
と言われると、arduino/trinket/8pinoに使えるのか不安だったのですが、UARTなんか共通仕様だろっ、とエイヤで。
(→結果、使えました)
接続トポロジー
Pin1を緑色、Pin2を白色に接続しています。勿論、黒はGND。
ジャンパピン接続の拡大図。
8pinoから見て、それぞれ
緑色(Pin1) : RX、白色(Pin2) : TX
となります。
重要なポイントは、赤い線を接続していないこと。
この赤線は、USBからの電源供給用ですので、こっちのV系に入れちゃうと、電圧がぶつかるのかな?とブルったので結線せず。
上から俯瞰した図。
USBポートが2つあれば、満足いく開発が可能です。
Windowsでdriverのinstall
USBケーブルを挿すだけで、自動的にインストールが始まりました。特に他には何もせず、すぐに完了。私の環境では、COM5にアサインされました。
ターミナルの準備
みんな大好きteratermを使います。 新規接続すると、先程インストール済の「COM5 : Prolific …」が出てきますので、これでOK押します。 また、別途、ボーレートを4800に設定下さい。
SoftwareSerialを実装
対話型のサンプルアプリができました。 1発であまりにも上手く動いてしまい、teratermのローカルエコーか?と思ってしまったので、デバッグ的に'%'入力時だけ出力変えています。深い意味はありません。
コードはこちら
/* Software serial test */ #include <SoftwareSerial.h> #define _8PINO_SOFTWARE_SERIAL_PIN_RX ( 1 ) #define _8PINO_SOFTWARE_SERIAL_PIN_TX ( 2 ) SoftwareSerial mySerial( _8PINO_SOFTWARE_SERIAL_PIN_RX, _8PINO_SOFTWARE_SERIAL_PIN_TX ); void setup() { // set the data rate for the SoftwareSerial port mySerial.begin(4800); mySerial.println(""); mySerial.println("--- Hello! from 8pino... ---"); mySerial.write( "\r\n > " ); } void loop() // run over and over { int tmp_char = 0; if ( mySerial.available() ){ tmp_char = mySerial.read(); if( tmp_char == '\r' ){ mySerial.write( "\r\n > " ); }else if( tmp_char == '%' ){ mySerial.write( tmp_char ); mySerial.write( "\r\n" ); mySerial.write( " % : Percentage sign \r\n" ); mySerial.write( " Percentage : In mathematics, a percentage is a number or ratio expressed as a fraction of 100. \r\n" ); mySerial.write( " It is often denoted using the percent sign. \"%\" \r\n" ); mySerial.write( " Sometimes the abbreviation \"pc\" is used in the case of quantities in economics. \r\n"); mySerial.write( " From Wikipedia... \r\n" ); mySerial.write( "\r\n > " ); }else{ mySerial.write( tmp_char ); } } }
これで
UART経由で、外部から指示が出せるようになりました。
ただ、あまりUART経由で指示を出すと、電子工作の勉強からは外れてしまうので、それほど深堀しない予定です。
8pinoで圧電スピーカーを鳴らす その5
もう、飽きましたよね
8pinoで圧電スピーカーから曲を流すのはこれが最終回です。
発端は
前回の輪唱 を家族に自慢しに行った時の話です。
(私)「スゴいでしょ、これ!」
(家)「ウーン、すごさがよくわからないよ。輪唱もそんなに好きじゃないし」
(私)「…じゃあ、なんなら良いのさ!」
(家)「やっぱり、別々の旋律/和音を聞きたいでしょう。合唱とか、ピアノの曲とか」
(私)「ほぅ。例えば?」
(家)「合唱なら『ふるさと』、ピアノは『 パッフェルベルのカノン 』が好き」
と言うわけで 今度は、上記の2つを実現してみます。
早速、結果からどうぞ。
文部省唱歌 故郷(ふるさと) 合唱Ver.
ブザー音なのに、哀愁漂います。
パッフェルベルのカノン 両手Ver.
Johann Pachelbel : Canon in C.
エンドレスリピートな曲に仕上がりました。ちょっとペース早いかなぁ。
苦労した点とか
輪唱は良かったんです。だって、演奏するデータは、どっちのスピーカーも同じで良いので。
別々の旋律と言うことは、メモリも2倍、データ入力作業も2倍必要です。 例えばカノンの例だと、入力作業に1時間程かかっています。
「ふるさと」のコードはこちら
#include <Adafruit_NeoPixel.h> #ifdef __AVR_ATtiny85__ // Trinket, Gemma, etc. #include <avr/power.h> #endif #define NEOPIXEL_IN_PIN 0 #define NUM_OF_PIXELS 16 #define NEOPIXEL_BRIGHTNESS 30 Adafruit_NeoPixel pixels = Adafruit_NeoPixel( NUM_OF_PIXELS, NEOPIXEL_IN_PIN ); // Definitions #define _8PINO_TONE_START ( 0x00 ) #define _8PINO_TONE_STOP ( 0x01 ) #define _8PINO_TONE_NOT_USED ( 0 ) #define _8PINO_TONE_SO_2 ( 158 ) #define _8PINO_TONE_RA_2 ( 141 ) #define _8PINO_TONE_SI_2 ( 126 ) #define _8PINO_TONE_DO_3 ( 118 ) #define _8PINO_TONE_RE_3 ( 106 ) #define _8PINO_TONE_MI_3 ( 94 ) #define _8PINO_TONE_FA_3 ( 89 ) #define _8PINO_TONE_FA_SH_3 ( 83 ) #define _8PINO_TONE_SO_3 ( 79 ) #define _8PINO_TONE_RA_3 ( 70 ) #define _8PINO_TONE_SI_3 ( 62 ) #define _8PINO_TONE_DO_4 ( 59 ) #define _8PINO_TONE_RE_4 ( 52 ) #define _8PINO_TONE_MI_4 ( 46 ) // Global variables #define _8PINO_TONE_SPEAKER_PIN_1 ( 1 ) #define _8PINO_TONE_SPEAKER_PIN_2 ( 4 ) #define SIZE_OF_TONE_ARRAY ( 192 ) PROGMEM prog_uint16_t noteArray1[] = { // U-Sa-Gi O-I-Shi Ka-No-Ya-Ma- _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_RA_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SI_3, _8PINO_TONE_STOP, _8PINO_TONE_RA_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SI_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SI_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_DO_4, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_RE_4, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, // Ko-Bu-Na-Tsu-Ri-Shi Ka-No-Ka-Wa- _8PINO_TONE_DO_4, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_RE_4, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_MI_4, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SI_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_DO_4, _8PINO_TONE_STOP, _8PINO_TONE_SI_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_RA_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_RA_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_FA_SH_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, // Yu-Me-Ha-I-Ma-Mo-Me-Gu-Ri-Te _8PINO_TONE_RA_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_SO_3, _8PINO_TONE_STOP, _8PINO_TONE_RA_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_RE_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_RA_3, _8PINO_TONE_STOP, _8PINO_TONE_SI_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SI_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_DO_4, _8PINO_TONE_NOT_USED, _8PINO_TONE_SI_3, _8PINO_TONE_STOP, _8PINO_TONE_DO_4, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_MI_4, _8PINO_TONE_STOP, _8PINO_TONE_RE_4, _8PINO_TONE_NOT_USED, _8PINO_TONE_DO_4, _8PINO_TONE_STOP, _8PINO_TONE_SI_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, // Wa-Su-Re-Ga-Ta-Ki Hu-Ru-Sa-To _8PINO_TONE_RE_4, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_RE_4, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_RE_4, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_RA_3, _8PINO_TONE_STOP, _8PINO_TONE_SI_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_DO_4, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_DO_4, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_RA_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, }; PROGMEM prog_uint16_t noteArray2[] = { // U-Sa-Gi O-I-Shi Ka-No-Ya-Ma- _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_FA_SH_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_STOP, _8PINO_TONE_FA_SH_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_RA_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SI_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, // Ko-Bu-Na-Tsu-Ri-Shi Ka-No-Ka-Wa- _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_RA_3, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_FA_SH_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_FA_SH_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_RE_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, // Yu-Me-Ha-I-Ma-Mo-Me-Gu-Ri-Te _8PINO_TONE_FA_SH_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_MI_3, _8PINO_TONE_STOP, _8PINO_TONE_FA_SH_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_RE_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_FA_SH_3, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_RA_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_SO_3, _8PINO_TONE_STOP, _8PINO_TONE_RA_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_DO_4, _8PINO_TONE_STOP, _8PINO_TONE_SI_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_RA_3, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, // Wa-Su-Re-Ga-Ta-Ki Hu-Ru-Sa-To _8PINO_TONE_SI_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SI_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SI_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_FA_SH_3, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_RA_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_RA_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_FA_SH_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, }; void setup(){ // Initialize PIN mode. pinMode( _8PINO_TONE_SPEAKER_PIN_1, OUTPUT ); pinMode( _8PINO_TONE_SPEAKER_PIN_2, OUTPUT ); // Configure Registers for PWM of PB1(PIN No.1) // 1. Waveform Generation Mode -> Fast PWM // 2. Clock Select -> 8MHz/256 = 32KHz. // 3. Compare Match Output B Mode // -> Clear OC0A/OC0B on Compare Match, // set OC0A/OC0B at BOTTOM TCCR0A = _BV (COM0B1) | _BV (WGM01) | _BV (WGM00); TCCR0B = _BV (WGM02) | _BV (CS02); // Configure Registers for PWM of PB4(PIN No.4) // 1. Comparator A Mode -> Set the OC1A output line. // 2. Time/Counter1 Prescale Select -> 8MHz/256 = 32KHz. // 3. Enable Pulse Width Modulator B. // 4. Comparator B Mode -> Set the OC1B output line TCCR1 = _BV (COM1A1) | _BV (COM1A0) | _BV (CS13) | _BV (CS10); GTCCR = _BV (PWM1B) | _BV (COM1B1) | _BV (COM1B0); // NeoPixel LED pinMode( NEOPIXEL_IN_PIN, OUTPUT ); #ifdef __AVR_ATtiny85__ // Trinket, Gemma, etc. if( F_CPU == 16000000 ) clock_prescale_set( clock_div_1 ); #endif pixels.begin(); pixels.setBrightness( NEOPIXEL_BRIGHTNESS ); pixels.show(); // Initialize all pixels to "off" } void loop(){ for( int count = 0; count < SIZE_OF_TONE_ARRAY; count++ ) { if( pgm_read_word( ¬eArray1[count] ) == _8PINO_TONE_NOT_USED ){ // Do Nothing. }else if( pgm_read_word( ¬eArray1[count] ) == _8PINO_TONE_STOP ){ _8pinoTone( _8PINO_TONE_SPEAKER_PIN_1, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP ); _8pinoTone( _8PINO_TONE_SPEAKER_PIN_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP ); setNeopixelColor( _8PINO_TONE_SPEAKER_PIN_1, _8PINO_TONE_STOP ); setNeopixelColor( _8PINO_TONE_SPEAKER_PIN_2, _8PINO_TONE_STOP ); }else{ _8pinoTone( _8PINO_TONE_SPEAKER_PIN_1, pgm_read_word( ¬eArray1[count] ), _8PINO_TONE_START ); _8pinoTone( _8PINO_TONE_SPEAKER_PIN_2, pgm_read_word( ¬eArray2[count] ), _8PINO_TONE_START ); setNeopixelColor( _8PINO_TONE_SPEAKER_PIN_1, pgm_read_word( ¬eArray1[count] ) ); setNeopixelColor( _8PINO_TONE_SPEAKER_PIN_2, pgm_read_word( ¬eArray2[count] ) ); } pixels.show(); delay( 8000 / OCR0A ); } } void _8pinoTone( int pin_speaker, uint8_t freq, uint8_t startstop ){ if( startstop == _8PINO_TONE_START ){ pinMode( pin_speaker, OUTPUT ); if( pin_speaker == _8PINO_TONE_SPEAKER_PIN_1 ){ OCR0A = freq; OCR0B = OCR0A - 1; }else{ OCR1C = freq; OCR1B = OCR1C - 1; } }else{ pinMode( pin_speaker, INPUT ); } } void setNeopixelColor( int speaker_id, int tone ){ uint8_t led_index = 0; int i = 0; if( speaker_id == _8PINO_TONE_SPEAKER_PIN_1 ){ switch( tone ){ case _8PINO_TONE_RE_3: led_index = 12; break; case _8PINO_TONE_FA_SH_3: led_index = 14; break; case _8PINO_TONE_SO_3: led_index = 15; break; case _8PINO_TONE_RA_3: led_index = 0; break; case _8PINO_TONE_SI_3: led_index = 1; break; case _8PINO_TONE_DO_4: led_index = 2; break; case _8PINO_TONE_RE_4: led_index = 3; break; case _8PINO_TONE_MI_4: led_index = 3; break; } if( tone == _8PINO_TONE_STOP ){ for( i = 0; i < 4; i++ ){ pixels.setPixelColor( i, 0, 0, 0 ); } for( i = 12; i < 16; i++ ){ pixels.setPixelColor( i, 0, 0, 0 ); } }else{ for( i = 0; i < 4; i++ ){ pixels.setPixelColor( i, 0, 0, 0 ); } for( i = 12; i < 16; i++ ){ pixels.setPixelColor( i, 0, 0, 0 ); } if( led_index < 4 ){ for( i = 0; i < led_index + 1; i++ ){ pixels.setPixelColor( i, 255, 0, 0 ); } for( i = 12; i < 16; i++ ){ pixels.setPixelColor( i, 255, 0, 0 ); } }else{ for( i = 12; i < led_index + 1; i++ ){ pixels.setPixelColor( i, 255, 0, 0 ); } } } }else{ switch( tone ){ case _8PINO_TONE_RE_3: led_index = 11; break; case _8PINO_TONE_MI_3: led_index = 10; break; case _8PINO_TONE_FA_SH_3: led_index = 9; break; case _8PINO_TONE_SO_3: led_index = 8; break; case _8PINO_TONE_RA_3: led_index = 7; break; case _8PINO_TONE_SI_3: led_index = 6; break; case _8PINO_TONE_DO_4: led_index = 5; break; } if( tone == _8PINO_TONE_STOP ){ for( i = 5; i < 12; i++ ){ pixels.setPixelColor( i, 0, 0, 0 ); } }else{ for( i = 5; i < 12; i++ ){ pixels.setPixelColor( i, 0, 0, 0 ); } for( i = led_index; i < 12; i++ ){ pixels.setPixelColor( i, 0, 255, 0); } } } }
「カノン」のコードはこちら
#include <Adafruit_NeoPixel.h> #ifdef __AVR_ATtiny85__ // Trinket, Gemma, etc. #include <avr/power.h> #endif #define NEOPIXEL_IN_PIN 0 #define NUM_OF_PIXELS 16 #define NEOPIXEL_BRIGHTNESS 30 Adafruit_NeoPixel pixels = Adafruit_NeoPixel( NUM_OF_PIXELS, NEOPIXEL_IN_PIN ); // Definitions #define _8PINO_TONE_START ( 0x00 ) #define _8PINO_TONE_STOP ( 0x01 ) #define _8PINO_TONE_NOT_USED ( 0 ) #define _8PINO_TONE_DO_2 ( 238 ) #define _8PINO_TONE_RE_2 ( 212 ) #define _8PINO_TONE_MI_2 ( 189 ) #define _8PINO_TONE_FA_2 ( 178 ) #define _8PINO_TONE_SO_2 ( 158 ) #define _8PINO_TONE_RA_2 ( 141 ) #define _8PINO_TONE_SI_2 ( 126 ) #define _8PINO_TONE_DO_3 ( 118 ) #define _8PINO_TONE_RE_3 ( 106 ) #define _8PINO_TONE_MI_3 ( 94 ) #define _8PINO_TONE_FA_3 ( 89 ) #define _8PINO_TONE_FA_SH_3 ( 83 ) #define _8PINO_TONE_SO_3 ( 79 ) #define _8PINO_TONE_RA_3 ( 70 ) #define _8PINO_TONE_SI_3 ( 62 ) #define _8PINO_TONE_SI_FL_3 ( 66 ) #define _8PINO_TONE_DO_4 ( 59 ) #define _8PINO_TONE_RE_4 ( 52 ) #define _8PINO_TONE_MI_4 ( 46 ) #define _8PINO_TONE_FA_4 ( 44 ) #define _8PINO_TONE_SO_4 ( 39 ) #define _8PINO_TONE_RA_4 ( 34 ) // 35 // Global variables #define _8PINO_TONE_SPEAKER_PIN_1 ( 1 ) #define _8PINO_TONE_SPEAKER_PIN_2 ( 4 ) #define SIZE_OF_TONE_ARRAY ( 12 * 16 ) PROGMEM prog_uint16_t noteArray1[] = { // 1 _8PINO_TONE_SO_4, _8PINO_TONE_STOP, _8PINO_TONE_MI_4, _8PINO_TONE_FA_4, _8PINO_TONE_SO_4, _8PINO_TONE_STOP, _8PINO_TONE_MI_4, _8PINO_TONE_FA_4, _8PINO_TONE_SO_4, _8PINO_TONE_SO_3, _8PINO_TONE_RA_3, _8PINO_TONE_SI_3, _8PINO_TONE_DO_4, _8PINO_TONE_RE_4, _8PINO_TONE_MI_4, _8PINO_TONE_FA_4, _8PINO_TONE_MI_4, _8PINO_TONE_STOP, _8PINO_TONE_DO_4, _8PINO_TONE_RE_4, _8PINO_TONE_MI_4, _8PINO_TONE_STOP, _8PINO_TONE_MI_3, _8PINO_TONE_FA_3, _8PINO_TONE_SO_3, _8PINO_TONE_RA_3, _8PINO_TONE_SO_3, _8PINO_TONE_FA_3, _8PINO_TONE_SO_3, _8PINO_TONE_MI_3, _8PINO_TONE_FA_3, _8PINO_TONE_SO_3, _8PINO_TONE_FA_3, _8PINO_TONE_STOP, _8PINO_TONE_RA_3, _8PINO_TONE_SO_3, _8PINO_TONE_FA_3, _8PINO_TONE_STOP, _8PINO_TONE_MI_3, _8PINO_TONE_RE_3, _8PINO_TONE_MI_3, _8PINO_TONE_RE_3, _8PINO_TONE_DO_3, _8PINO_TONE_RE_3, _8PINO_TONE_MI_3, _8PINO_TONE_FA_3, _8PINO_TONE_SO_3, _8PINO_TONE_RA_3, _8PINO_TONE_FA_3, _8PINO_TONE_STOP, _8PINO_TONE_RA_3, _8PINO_TONE_SO_3, _8PINO_TONE_RA_3, _8PINO_TONE_STOP, _8PINO_TONE_SI_3, _8PINO_TONE_DO_3, _8PINO_TONE_SO_3, _8PINO_TONE_RA_3, _8PINO_TONE_SI_3, _8PINO_TONE_DO_4, _8PINO_TONE_RE_4, _8PINO_TONE_MI_4, _8PINO_TONE_FA_4, _8PINO_TONE_SO_4, // 5 _8PINO_TONE_MI_4, _8PINO_TONE_STOP, _8PINO_TONE_DO_4, _8PINO_TONE_RE_4, _8PINO_TONE_MI_4, _8PINO_TONE_STOP, _8PINO_TONE_RE_4, _8PINO_TONE_DO_4, _8PINO_TONE_RE_4, _8PINO_TONE_SI_3, _8PINO_TONE_DO_4, _8PINO_TONE_RE_4, _8PINO_TONE_MI_4, _8PINO_TONE_RE_4, _8PINO_TONE_DO_4, _8PINO_TONE_SI_3, _8PINO_TONE_DO_4, _8PINO_TONE_STOP, _8PINO_TONE_RA_3, _8PINO_TONE_SI_3, _8PINO_TONE_DO_4, _8PINO_TONE_STOP, _8PINO_TONE_DO_3, _8PINO_TONE_RE_3, _8PINO_TONE_MI_3, _8PINO_TONE_FA_3, _8PINO_TONE_MI_3, _8PINO_TONE_RE_3, _8PINO_TONE_MI_3, _8PINO_TONE_DO_4, _8PINO_TONE_SI_3, _8PINO_TONE_DO_4, _8PINO_TONE_RA_3, _8PINO_TONE_STOP, _8PINO_TONE_DO_4, _8PINO_TONE_SI_3, _8PINO_TONE_RA_3, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_FA_3, _8PINO_TONE_SO_3, _8PINO_TONE_FA_3, _8PINO_TONE_MI_3, _8PINO_TONE_FA_3, _8PINO_TONE_SO_3, _8PINO_TONE_RA_3, _8PINO_TONE_SI_3, _8PINO_TONE_DO_4, _8PINO_TONE_RA_3, _8PINO_TONE_STOP, _8PINO_TONE_DO_4, _8PINO_TONE_SI_3, _8PINO_TONE_DO_4, _8PINO_TONE_STOP, _8PINO_TONE_SI_3, _8PINO_TONE_RA_3, _8PINO_TONE_SI_3, _8PINO_TONE_DO_4, _8PINO_TONE_RE_4, _8PINO_TONE_DO_4, _8PINO_TONE_SI_3, _8PINO_TONE_DO_4, _8PINO_TONE_RA_3, _8PINO_TONE_SI_3, // 9 _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_4, _8PINO_TONE_STOP, _8PINO_TONE_SO_4, _8PINO_TONE_STOP, _8PINO_TONE_RA_4, _8PINO_TONE_STOP, _8PINO_TONE_SO_4, _8PINO_TONE_STOP, _8PINO_TONE_FA_4, _8PINO_TONE_STOP, _8PINO_TONE_MI_4, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_MI_4, _8PINO_TONE_STOP, _8PINO_TONE_MI_4, _8PINO_TONE_STOP, _8PINO_TONE_FA_4, _8PINO_TONE_STOP, _8PINO_TONE_MI_4, _8PINO_TONE_STOP, _8PINO_TONE_RE_4, _8PINO_TONE_STOP, _8PINO_TONE_DO_4, _8PINO_TONE_STOP, _8PINO_TONE_SI_FL_3, _8PINO_TONE_STOP, _8PINO_TONE_RA_3, _8PINO_TONE_STOP, _8PINO_TONE_SI_FL_3, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_STOP, _8PINO_TONE_FA_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_DO_4, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SI_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SI_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, }; PROGMEM prog_uint16_t noteArray2[] = { // 1 _8PINO_TONE_DO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_RA_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_MI_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_FA_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_DO_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_FA_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, // 5 _8PINO_TONE_DO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_RA_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_MI_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_FA_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_DO_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_FA_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, // 9 _8PINO_TONE_DO_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_MI_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SI_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_RA_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_DO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_MI_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_FA_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_RA_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_DO_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_MI_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_FA_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_RA_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SI_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, }; void setup(){ // Initialize PIN mode. pinMode( _8PINO_TONE_SPEAKER_PIN_1, OUTPUT ); pinMode( _8PINO_TONE_SPEAKER_PIN_2, OUTPUT ); // Configure Registers for PWM of PB1(PIN No.1) // 1. Waveform Generation Mode -> Fast PWM // 2. Clock Select -> 8MHz/256 = 32KHz. // 3. Compare Match Output B Mode // -> Clear OC0A/OC0B on Compare Match, // set OC0A/OC0B at BOTTOM TCCR0A = _BV (COM0B1) | _BV (WGM01) | _BV (WGM00); TCCR0B = _BV (WGM02) | _BV (CS02); // Configure Registers for PWM of PB4(PIN No.4) // 1. Comparator A Mode -> Set the OC1A output line. // 2. Time/Counter1 Prescale Select -> 8MHz/256 = 32KHz. // 3. Enable Pulse Width Modulator B. // 4. Comparator B Mode -> Set the OC1B output line TCCR1 = _BV (COM1A1) | _BV (COM1A0) | _BV (CS13) | _BV (CS10); GTCCR = _BV (PWM1B) | _BV (COM1B1) | _BV (COM1B0); // NeoPixel LED pinMode( NEOPIXEL_IN_PIN, OUTPUT ); #ifdef __AVR_ATtiny85__ // Trinket, Gemma, etc. if( F_CPU == 16000000 ) clock_prescale_set( clock_div_1 ); #endif pixels.begin(); pixels.setBrightness( NEOPIXEL_BRIGHTNESS ); pixels.show(); // Initialize all pixels to "off" } void loop(){ for( int count = 0; count < SIZE_OF_TONE_ARRAY; count++ ) { if( pgm_read_word( ¬eArray1[count] ) == _8PINO_TONE_NOT_USED ){ // Do Nothing. }else if( pgm_read_word( ¬eArray1[count] ) == _8PINO_TONE_STOP ){ _8pinoTone( _8PINO_TONE_SPEAKER_PIN_1, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP ); setNeopixelColor( _8PINO_TONE_SPEAKER_PIN_1, _8PINO_TONE_STOP ); }else{ _8pinoTone( _8PINO_TONE_SPEAKER_PIN_1, pgm_read_word( ¬eArray1[count] ), _8PINO_TONE_START ); setNeopixelColor( _8PINO_TONE_SPEAKER_PIN_1, pgm_read_word( ¬eArray1[count] ) ); } if( pgm_read_word( ¬eArray2[count] ) == _8PINO_TONE_NOT_USED ){ // Do Nothing. }else if( pgm_read_word( ¬eArray2[count] ) == _8PINO_TONE_STOP ){ _8pinoTone( _8PINO_TONE_SPEAKER_PIN_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP ); setNeopixelColor( _8PINO_TONE_SPEAKER_PIN_2, _8PINO_TONE_STOP ); }else{ _8pinoTone( _8PINO_TONE_SPEAKER_PIN_2, pgm_read_word( ¬eArray2[count] ), _8PINO_TONE_START ); setNeopixelColor( _8PINO_TONE_SPEAKER_PIN_2, pgm_read_word( ¬eArray2[count] ) ); } pixels.show(); delay( 8000 / OCR0A ); } } void _8pinoTone( int pin_speaker, uint8_t freq, uint8_t startstop ){ if( startstop == _8PINO_TONE_START ){ pinMode( pin_speaker, OUTPUT ); if( pin_speaker == _8PINO_TONE_SPEAKER_PIN_1 ){ OCR0A = freq; OCR0B = OCR0A - 1; }else{ OCR1C = freq; OCR1B = OCR1C - 1; } }else{ pinMode( pin_speaker, INPUT ); } } void setNeopixelColor( int speaker_id, int tone ){ uint8_t led_index = 0; int i = 0; int highlight = 0; if( speaker_id == _8PINO_TONE_SPEAKER_PIN_1 ){ switch( tone ){ case _8PINO_TONE_DO_3: led_index = 12; break; case _8PINO_TONE_RE_3: led_index = 12; highlight = 1; break; case _8PINO_TONE_MI_3: led_index = 13; break; case _8PINO_TONE_FA_3: led_index = 13; highlight = 1; break; case _8PINO_TONE_SO_3: led_index = 14; break; case _8PINO_TONE_RA_3: led_index = 14; highlight = 1; break; case _8PINO_TONE_SI_3: led_index = 15; break; case _8PINO_TONE_DO_4: led_index = 15; highlight = 1; break; case _8PINO_TONE_RE_4: led_index = 0; break; case _8PINO_TONE_MI_4: led_index = 0; highlight = 1; break; case _8PINO_TONE_FA_4: led_index = 1; break; case _8PINO_TONE_SO_4: led_index = 1; highlight = 1; break; case _8PINO_TONE_RA_4: led_index = 2; break; default: led_index = 12; break; } if( tone == _8PINO_TONE_STOP ){ for( i = 0; i < 4; i++ ){ pixels.setPixelColor( i, 0, 0, 0 ); } for( i = 12; i < 16; i++ ){ pixels.setPixelColor( i, 0, 0, 0 ); } }else{ for( i = 0; i < 4; i++ ){ pixels.setPixelColor( i, 0, 0, 0 ); } for( i = 12; i < 16; i++ ){ pixels.setPixelColor( i, 0, 0, 0 ); } if( led_index < 4 ){ for( i = 0; i < led_index + 1; i++ ){ pixels.setPixelColor( i, 255, 0, 0 ); } for( i = 12; i < 16; i++ ){ pixels.setPixelColor( i, 255, 0, 0 ); } }else{ for( i = 12; i < led_index + 1; i++ ){ pixels.setPixelColor( i, 255, 0, 0 ); } } if( highlight == 1 ){ pixels.setPixelColor( led_index, 255, 255, 255 ); } } }else{ switch( tone ){ case _8PINO_TONE_DO_2: led_index = 11; break; case _8PINO_TONE_MI_2: led_index = 10; break; case _8PINO_TONE_FA_2: led_index = 9; break; case _8PINO_TONE_SO_2: led_index = 8; break; case _8PINO_TONE_RA_2: led_index = 7; break; case _8PINO_TONE_SI_2: led_index = 6; break; case _8PINO_TONE_DO_3: led_index = 5; break; default: led_index = 11; break; } if( tone == _8PINO_TONE_STOP ){ for( i = 5; i < 12; i++ ){ pixels.setPixelColor( i, 0, 0, 0 ); } }else{ for( i = 5; i < 12; i++ ){ pixels.setPixelColor( i, 0, 0, 0 ); } for( i = led_index; i < 12; i++ ){ pixels.setPixelColor( i, 0, 255, 0); } } } }
以上で
8pinoコンサートは終演となります。
お付き合い頂き、ありがとうございました。
8pinoで圧電スピーカーを鳴らす その4
もう1つ輪唱
前回の投稿 で、輪唱の基礎は構築したので、応用は大変容易です。
目標の1つだった、「静かな湖畔」の輪唱にもチャレンジしてみましょう。
といってもやることは、ネットに落ちていた楽譜をデータ列に起こすだけです。 約30分で完了しました。
では、どうぞ
こちらも、輪唱パート毎にLEDを分けて光らせています。
基礎を1つ作ると、その後は超簡単ですね!
コードはこちら
#include <Adafruit_NeoPixel.h> #ifdef __AVR_ATtiny85__ // Trinket, Gemma, etc. #include <avr/power.h> #endif #define NEOPIXEL_IN_PIN 0 #define NUM_OF_PIXELS 16 #define NEOPIXEL_BRIGHTNESS 30 Adafruit_NeoPixel pixels = Adafruit_NeoPixel( NUM_OF_PIXELS, NEOPIXEL_IN_PIN ); // Definitions #define _8PINO_TONE_START ( 0x00 ) #define _8PINO_TONE_STOP ( 0x01 ) #define _8PINO_TONE_NOT_USED ( 0 ) #define _8PINO_TONE_SO_2 ( 158 ) #define _8PINO_TONE_RA_2 ( 141 ) #define _8PINO_TONE_SI_2 ( 126 ) #define _8PINO_TONE_DO_3 ( 118 ) #define _8PINO_TONE_RE_3 ( 106 ) #define _8PINO_TONE_MI_3 ( 94 ) #define _8PINO_TONE_FA_3 ( 89 ) #define _8PINO_TONE_SO_3 ( 79 ) #define _8PINO_TONE_RA_3 ( 70 ) #define _8PINO_TONE_SI_3 ( 62 ) #define _8PINO_TONE_DO_4 ( 59 ) // Global variables #define _8PINO_TONE_SPEAKER_PIN_1 ( 1 ) #define _8PINO_TONE_SPEAKER_PIN_2 ( 4 ) #define SIZE_OF_TONE_ARRAY ( 160 ) PROGMEM prog_uint16_t noteArray[] = { // Wait... _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, // Shi-Zu-Ka-Na-Ko-Han-No _8PINO_TONE_DO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_DO_3, _8PINO_TONE_DO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_RE_3, _8PINO_TONE_MI_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_MI_3, _8PINO_TONE_MI_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_MI_3, // Mo-Ri-No-Ka-Ge-Ka-Ra _8PINO_TONE_RE_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_DO_3, _8PINO_TONE_RE_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_MI_3, _8PINO_TONE_DO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_DO_3, _8PINO_TONE_SO_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, // Mou-Oki-Tya-I-Ka-Ga-To-Kakko-Ga-Na-Ku Ka- _8PINO_TONE_MI_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_MI_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_FA_3, _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_SO_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_FA_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_MI_3, _8PINO_TONE_FA_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_MI_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, //Kko Ka-Kko Ka-Kko Ka-Kko Ka-Kko _8PINO_TONE_MI_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_SO_3, _8PINO_TONE_MI_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_SO_3, _8PINO_TONE_MI_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_MI_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_SO_3, _8PINO_TONE_MI_3, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, // Wait... _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, _8PINO_TONE_NOT_USED, }; void setup(){ // Initialize PIN mode. pinMode( _8PINO_TONE_SPEAKER_PIN_1, OUTPUT ); pinMode( _8PINO_TONE_SPEAKER_PIN_2, OUTPUT ); // Configure Registers for PWM of PB1(PIN No.1) // 1. Waveform Generation Mode -> Fast PWM // 2. Clock Select -> 8MHz/256 = 32KHz. // 3. Compare Match Output B Mode // -> Clear OC0A/OC0B on Compare Match, // set OC0A/OC0B at BOTTOM TCCR0A = _BV (COM0B1) | _BV (WGM01) | _BV (WGM00); TCCR0B = _BV (WGM02) | _BV (CS02); // Configure Registers for PWM of PB4(PIN No.4) // 1. Comparator A Mode -> Set the OC1A output line. // 2. Time/Counter1 Prescale Select -> 8MHz/256 = 32KHz. // 3. Enable Pulse Width Modulator B. // 4. Comparator B Mode -> Set the OC1B output line TCCR1 = _BV (COM1A1) | _BV (COM1A0) | _BV (CS13) | _BV (CS10); GTCCR = _BV (PWM1B) | _BV (COM1B1) | _BV (COM1B0); // NeoPixel LED pinMode( NEOPIXEL_IN_PIN, OUTPUT ); #ifdef __AVR_ATtiny85__ // Trinket, Gemma, etc. if( F_CPU == 16000000 ) clock_prescale_set( clock_div_1 ); #endif pixels.begin(); pixels.setBrightness( NEOPIXEL_BRIGHTNESS ); pixels.show(); // Initialize all pixels to "off" } void loop(){ for( int count = 32; count < SIZE_OF_TONE_ARRAY; count++ ) { if( pgm_read_word( ¬eArray[count] ) == _8PINO_TONE_NOT_USED ){ // Do Nothing. }else if( pgm_read_word( ¬eArray[count] ) == _8PINO_TONE_STOP ){ _8pinoTone( _8PINO_TONE_SPEAKER_PIN_1, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP ); setNeopixelColor( _8PINO_TONE_SPEAKER_PIN_1, _8PINO_TONE_STOP ); }else{ _8pinoTone( _8PINO_TONE_SPEAKER_PIN_1, pgm_read_word( ¬eArray[count] ), _8PINO_TONE_START ); setNeopixelColor( _8PINO_TONE_SPEAKER_PIN_1, pgm_read_word( ¬eArray[count] ) ); } if( pgm_read_word( ¬eArray[count-32] ) == _8PINO_TONE_NOT_USED ){ // Do Nothing. }else if( pgm_read_word( ¬eArray[count-32] ) == _8PINO_TONE_STOP ){ _8pinoTone( _8PINO_TONE_SPEAKER_PIN_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP ); setNeopixelColor( _8PINO_TONE_SPEAKER_PIN_2, _8PINO_TONE_STOP ); }else{ _8pinoTone( _8PINO_TONE_SPEAKER_PIN_2, pgm_read_word( ¬eArray[count-32] ), _8PINO_TONE_START ); setNeopixelColor( _8PINO_TONE_SPEAKER_PIN_2, pgm_read_word( ¬eArray[count-32] ) ); } pixels.show(); delay( 8000 / OCR0A ); } } void _8pinoTone( int pin_speaker, uint8_t freq, uint8_t startstop ){ if( startstop == _8PINO_TONE_START ){ pinMode( pin_speaker, OUTPUT ); if( pin_speaker == _8PINO_TONE_SPEAKER_PIN_1 ){ OCR0A = freq; OCR0B = OCR0A - 1; }else{ OCR1C = freq; OCR1B = OCR1C - 1; } }else{ pinMode( pin_speaker, INPUT ); } } void setNeopixelColor( int speaker_id, int tone ){ uint8_t led_index = 0; int i = 0; if( speaker_id == _8PINO_TONE_SPEAKER_PIN_1 ){ switch( tone ){ case _8PINO_TONE_SO_2: led_index = 12; break; case _8PINO_TONE_DO_3: led_index = 13; break; case _8PINO_TONE_RE_3: led_index = 14; break; case _8PINO_TONE_MI_3: led_index = 15; break; case _8PINO_TONE_FA_3: led_index = 0; break; case _8PINO_TONE_SO_3: led_index = 1; break; } if( tone == _8PINO_TONE_STOP ){ for( i = 0; i < 2; i++ ){ pixels.setPixelColor( i, 0, 0, 0 ); } for( i = 12; i < 16; i++ ){ pixels.setPixelColor( i, 0, 0, 0 ); } }else{ for( i = 0; i < 2; i++ ){ pixels.setPixelColor( i, 0, 0, 0 ); } for( i = 12; i < 16; i++ ){ pixels.setPixelColor( i, 0, 0, 0 ); } if( led_index < 2 ){ for( i = 0; i < led_index + 1; i++ ){ pixels.setPixelColor( i, 255, 0, 0 ); } for( i = 12; i < 16; i++ ){ pixels.setPixelColor( i, 255, 0, 0 ); } }else{ for( i = 12; i < led_index + 1; i++ ){ pixels.setPixelColor( i, 255, 0, 0 ); } } } }else{ switch( tone ){ case _8PINO_TONE_SO_2: led_index = 11; break; case _8PINO_TONE_DO_3: led_index = 10; break; case _8PINO_TONE_RE_3: led_index = 9; break; case _8PINO_TONE_MI_3: led_index = 8; break; case _8PINO_TONE_FA_3: led_index = 7; break; case _8PINO_TONE_SO_3: led_index = 6; break; } if( tone == _8PINO_TONE_STOP ){ for( i = 6; i < 12; i++ ){ pixels.setPixelColor( i, 0, 0, 0 ); } }else{ for( i = 6; i < 12; i++ ){ pixels.setPixelColor( i, 0, 0, 0 ); } for( i = led_index; i < 12; i++ ){ pixels.setPixelColor( i, 0, 255, 0); } } } }
まだまだ
圧電スピーカーハックは続きます。