チラシのうら

レゴとか、工作とか。

8pinoで測距センサーを使ってみる

本日も

研修でもらった部材で勉強します。 今回は最後の一点、こちらの測距センサーです。 本当の事を言うと、先週の時点で真っ先に試していたのですが、何をどうしても動作せず、部品が故障していると思っていました。

一緒の研修に行った会社の後輩から、同じ部品を貸してもらって、再チャレンジしてみました。

で、

それでも、動きません

これは故障では無いなと感じたものの、接続先のピンを変えても、ケーブルを変えても、一向にセンサーの値っぽいものは出てきません。

落ち着いて、先人の知恵を借りましょう。

間違えてた

こちらの投稿にヒント(と言うか答え)が。

AD変換といえば、8pinoのGPIOのピン番号は違うっていうのにさっきハマりました。#2のポートだからanalogRead(2);ってすると間違い。 #2はA1なのでanalogRead(1);

ん?

どうやら、

pinMode()と、analogRead()で指定するピン番号は、意味合いが違う様だ。
確かに、今まで気にしていなかったが、8pinoのケースに、ちゃんと書いてあるではないか。 f:id:tetunori_lego:20150608072732j:plain 8pinoのピン番号とアナログピン?対応の図

どうりで、動かないはずです。 ピン番号のdefineを両方にぶちこんでましたから。

距離がとれた

仕組みが解ると、今までが嘘のように簡単に動かす事が出来ました。
私の環境では、PB2(A1)を使っています。
デバック的に、SoftwareSerialに値を出力させてみると見事それらしい値が出てきました。

取得した値から距離への変換は、こちらのblogにあった、以下の変換式をで行います。

distance = (6762/(dist_sensor_pin_val-9))-4;

5cm~25cm位まで割りと正しく取得出来ます!

配線時の注意

こちらのモジュール、一件何も問題ない様に見えますが、 f:id:tetunori_lego:20150608074321j:plain
実は、黒:V、オレンジ:GNDとなっています。
大変気持ちが悪いので、私はジャンパケーブルで色を逆にしています。 f:id:tetunori_lego:20150608074838j:plain

デモ

距離に伴って、LEDを光らせ、さらにブザーから音を出します!
結果、子供ウケは今までの中で一番良かったです。

動画

テルミンっぽい、何かが出来上がりました。
後半、素早く手を降ったときの音は、中高の頃必死に練習したが全然弾けなかった、洋楽のギターソロ(インペリテリ的な) を彷彿とさせます。

配線図

f:id:tetunori_lego:20150608074221j:plain

コードはこちら

/*
  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を出していきたいと思います。