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); } } } }
まだまだ
圧電スピーカーハックは続きます。