8pinoで測距センサーを使ってみる
本日も
研修でもらった部材で勉強します。 今回は最後の一点、こちらの測距センサーです。 本当の事を言うと、先週の時点で真っ先に試していたのですが、何をどうしても動作せず、部品が故障していると思っていました。
一緒の研修に行った会社の後輩から、同じ部品を貸してもらって、再チャレンジしてみました。
で、
それでも、動きません
これは故障では無いなと感じたものの、接続先のピンを変えても、ケーブルを変えても、一向にセンサーの値っぽいものは出てきません。
落ち着いて、先人の知恵を借りましょう。
間違えてた
こちらの投稿にヒント(と言うか答え)が。
AD変換といえば、8pinoのGPIOのピン番号は違うっていうのにさっきハマりました。#2のポートだからanalogRead(2);ってすると間違い。 #2はA1なのでanalogRead(1);
ん?
どうやら、
pinMode()と、analogRead()で指定するピン番号は、意味合いが違う様だ。
確かに、今まで気にしていなかったが、8pinoのケースに、ちゃんと書いてあるではないか。
8pinoのピン番号とアナログピン?対応の図
どうりで、動かないはずです。 ピン番号のdefineを両方にぶちこんでましたから。
距離がとれた
仕組みが解ると、今までが嘘のように簡単に動かす事が出来ました。
私の環境では、PB2(A1)を使っています。
デバック的に、SoftwareSerialに値を出力させてみると見事それらしい値が出てきました。
取得した値から距離への変換は、こちらのblogにあった、以下の変換式をで行います。
distance = (6762/(dist_sensor_pin_val-9))-4;
5cm~25cm位まで割りと正しく取得出来ます!
配線時の注意
こちらのモジュール、一件何も問題ない様に見えますが、
実は、黒:V、オレンジ:GNDとなっています。
大変気持ちが悪いので、私はジャンパケーブルで色を逆にしています。
デモ
距離に伴って、LEDを光らせ、さらにブザーから音を出します!
結果、子供ウケは今までの中で一番良かったです。
動画
テルミンっぽい、何かが出来上がりました。
後半、素早く手を降ったときの音は、中高の頃必死に練習したが全然弾けなかった、洋楽のギターソロ(インペリテリ的な) を彷彿とさせます。
配線図
コードはこちら
/* Distance Sensor 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 ( 3 ) #define _8PINO_SOFTWARE_SERIAL_PIN_TX ( 1 ) #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 DISTANCE_MEASURE_SENSOR_PIN 2 #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( DISTANCE_MEASURE_SENSOR_PIN, INPUT ); 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(10); 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("--- 8pino. Distance Sensor Test. ---"); #endif // 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); } void loop() // run over and over { int i = 0; char tmpStr[5]; int dist_sensor_pin_val = analogRead( 1 ); int distance = 0; if( dist_sensor_pin_val < 10 ){ distance = 6758; }else{ distance = (6762/(dist_sensor_pin_val-9))-4; } itoa( distance, tmpStr, 10 ); #ifdef _8PINO_SOFTWARE_SERIAL_DEBUG mySerial.write( "\r\n" ); mySerial.write( tmpStr ); #endif // Show LED showIndicator( distance ); delay( 100 ); } // From 5 to 30 void showIndicator( int distance ){ int i = 0; // Initialize for( i = 0; i < NUM_OF_PIXELS; i++ ){ pixels.setPixelColor( i, 0, 0, 0 ); } // Clipping.. int top_index = distance / 2; if( top_index < 1 ){ top_index = 1; }else if( top_index > 15 ){ top_index = 15; } top_index = NUM_OF_PIXELS - top_index; // sound soundIndicator( top_index ); // LED for( i = 0; i < top_index; i++ ){ pixels.setPixelColor( i, 255, 255, 255 ); } pixels.show(); } void soundIndicator( int index ){ int note = 0; switch( index ){ case 1: default : note = _8PINO_TONE_DO_3; break; case 2: note = _8PINO_TONE_DO_SH_3; break; case 3: note = _8PINO_TONE_RE_3; break; case 4: note = _8PINO_TONE_RE_SH_3; break; case 5: note = _8PINO_TONE_MI_3; break; case 6: note = _8PINO_TONE_FA_3; break; case 7: note = _8PINO_TONE_FA_SH_3; break; case 8: note = _8PINO_TONE_SO_3; break; case 9: note = _8PINO_TONE_SO_SH_3; break; case 10: note = _8PINO_TONE_RA_3; break; case 11: note = _8PINO_TONE_SI_FL_3; break; case 12: note = _8PINO_TONE_SI_3; break; case 13: note = _8PINO_TONE_DO_4; break; case 14: note = _8PINO_TONE_DO_SH_4; break; case 15: note = _8PINO_TONE_RE_4; break; } // _8pinoTone( _8PINO_TONE_SPEAKER_PIN_2, _8PINO_TONE_NOT_USED, _8PINO_TONE_STOP ); _8pinoTone( _8PINO_TONE_SPEAKER_PIN_2, note, _8PINO_TONE_START ); } 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で勉強してみるシリーズ」は一旦終わりとさせていただきます。
不定期に再開するかもしれませんが。
何となくの使い方は解ったので、今後は、8pinoの小ささを活かしたOutputを出していきたいと思います。