ラベル ラップタイマー の投稿を表示しています。 すべての投稿を表示
ラベル ラップタイマー の投稿を表示しています。 すべての投稿を表示

2016年3月30日水曜日

Multi-function Shield と超音波距離センサーを使ったラップタイマー(操作編)

Multi-function Shieldは、Amazon.com などで1000円程度で購入できる Arduino UNO用のプログラミング学習用シールドです。Arduino UNOに、このボートと超音波距離センサー(HC-SR04)を取り付けて、マイコンカー用のラップライマーを制作したので紹介します。

1. 動作
  • ラップタイマーと反射ブロックの間をマイコンカーが走り抜けると、ラップタイマーがスタートします。そして再度、マイコンカーがラップタイマーの前を通過したときにタイマーがストップします。
  • Arduino Unoは超音波距離センサーと反射ブロックまでの距離を計測していますが、マイコンカーが超音波を遮ると計測距離が短くなります。この原理を利用してラップライマーを起動・停止させます。

2. 設置方法
  • ラップタイマー(このボード)を、マイコンカーのコーストラックの右サイドにを設置してください。
  • 反射ブロックをコーストラックの左サイドに配置してください。このとき、反射ブロックと超音波距離センサーの距離は30cm以下にしてください。
  • そして、ラップタイマーに電源を投入してください。
3. 操作方法
  • キャリブレーションモード: 電源がオンすると、LED1から4がオンしブザー音がして、このモードになります。このときLED1(D1)がオンします。 そして、4桁セグメントLEDには反射ブロックまでの距離が表示(単位:センチメートル)されます。反射ブロックを動かすと表示距離が変化します。マイコンカーのガイド用センターラインが反射ブロックと超音波距離センサーのちょうど中間に来るように反射ブロックを配置してください。このモードでSW1を押すと計測モードに移行します。
  • 計測モード: このモードでは、LED2(D2)がオンします。 4桁セグメントLEDにはラップタイマーのカウント値が秒で表示(0.1秒まで)されます。表示は"000.0"でストップしています。この状態で、マイコンカーがセンサーの前を横切るとカウントがスタートします。そして再度マイコンカーがセンサーの前に来たときカウントがストップします。この表示値がラップタイム(秒)です。SW2スイッチを押すと、ラップタイムが"000.0"にリセットされカウントスタート状態になります。 "000.0" 以外のカウント停止状態では、マイコンカーがセンサーを通過してもカウントはスタートしませんので注意してください。このモードでSW1を押すとキャリブレーションモードに移行します。


2014年12月16日火曜日

くるみラップライマー

概要

GR-KURUMIマイコンボードを使て、くるみラップタイマーを制作しました。


これは、マイコンカーレース等でマイコンカーのラップライムを計測するために使用します。赤外線距離センサーを使って、マイコンカーがラップタイマーの前を通過すると赤外線距離センサーの計測値が変化するので、それを利用してラップライムのオン・オフを制御します。くるみラップタイマーの前をマイコンカーが通過した時点からラップタイムがスタートし、またマイコンカーが返って来てセンサーの前を横切りるとタイマーがストップします。ラップライムクリアスイッチでリセットでき、カウントスタートの状態に戻ります。


赤外線距離センサーには、写真のような箱のような反射壁が必要で40cmほど離して置いてください。

プログラムは外部割込みやタイマー割込みは使用せず、millis( )タイマーでLEDをダイナミック点灯しています。赤外線距離センサーは,loop() 内で計測していますが、毎回1ms以内に計測しています。ソフトウェアの変更なしで、Arduino-ProMini等への移植も可能で確認済みです。


部品

赤外線センサー: SHARP GP2Y0A21YK
8セグメントLEDモジュール: WSN233 (www.wsnak.com)
プッシュスイッチ: A0ピン(アナログ値で読む)

ソースコード

// Applicable Segment LED Module: WSN233 (www.wsnak.com)
//  LED Pin <--> KURUMI Pin
#define COM1 11
#define COM2 12
#define COM3 13
#define COM4 5
#define SEG_A 2
#define SEG_B 3
#define SEG_C 4
#define SEG_D 6
#define SEG_E 7
#define SEG_F 8
#define SEG_G 9
#define DOT A3

// Applicable Infra-red Distance Sensor: Sharp GP2Y0A21YK
#define IRD A1      // Infeared Distance Sensor Port

// Super Sonic Distance Sensor
#define Echo 10
#define Trg A2



// Applicable Tact-switch: SFE-COM-00097 (Switch-Science)
#define PUSH_SW A0  // Push Switch Port.  Read the switch state by analog. Push < 10 
#define PUSH_SW1 A1

#define CALIB 0   // Calibration Mode
#define WAIT_CAR 1
#define GO 2      // Car cross the sensor and wrap-timer started
#define FINISH 3  // Car cross the sensor and wrap-timer stopped
#define AGAIN  4  // Switch to GO mode


unsigned long Blinking = 0;
unsigned long Interval = 0;
int Seg1 = 17, Seg2 = 17, Seg3=17, Seg4 = 17; // Display Value for Segment LEDs
int SegPoint = 1;
unsigned long Sec1 = 0;
int Mode;                               // Flow Control with SW and IRD
int IrdLevel = 0x100;
int CarIsHere = 0;                // 1 -- Car is Here


void setup( ) {    
  Serial.begin(9600);  
  Init_Led_Seg();
  Mode = CALIB;        // Set Caribration mode 
}

void loop() {      // Do not use delay()  in loop()
  LedDrive();        // Seg-LED driver. 
  RunMode();
}

void RunMode(){
  switch (Mode) {
    case CALIB:
      CalibrationMode();
      break;
    case WAIT_CAR:
      WaitCar();
      break;
    case GO:
      GoMode();
      break;
    case FINISH:
      FinishMode();
      break;
    default:
      break;
  }
}

void CalibrationMode(){
  Seg1 = 17;
  Seg2 = 17;
  Seg3 = 17;
  Seg4 = 17;
  if (analogRead(PUSH_SW) > 10) {
     if((millis() - Interval > 100) ) {
          Interval = millis();
          Serial.println(analogRead(IRD));
     }
     Mode = CALIB;
  } else {
   Seg1 = 0;
   Seg2 = 0;
   Seg3 = 0;
   Seg4 = 0;
   Mode = WAIT_CAR;
  } 
}
void WaitCar(){
  if (analogRead(IRD) > 200) {
    CarIsHere = 1;
  }
  if (analogRead(IRD) < 200 && CarIsHere == 1){
    CarIsHere = 0;
    Mode = GO;
  }
}
  
void GoMode() {
    if (analogRead(IRD)> 200){
      Mode = FINISH;
    } else {
      if((millis() - Interval > 10) ) {
          Interval = millis();
          if (++Seg1 > 9){
            Seg1 = 0;
            Seg2++;
          }
          if (Seg2 > 9){
            Seg2 = 0;
            Seg3++;
          }
          if(Seg3 > 9) {
            Seg3 = 0;
            Seg4++;
          }
          if (Seg4 > 6){
            Seg4 = 0;
          }
        }
    }
}

void FinishMode(){
  if (analogRead(PUSH_SW) < 10) {
    Mode = CALIB;  
  }
}
      
void LedDrive(){
  if(micros() - Blinking > 1000) {
    Blinking = micros();
    switch (SegPoint++){
      case 1:
        Led(1, Seg1);
        break;
      case 2:
        Led(2, Seg2);
        break;
      case 3:
        Led(3, Seg3);
        break;
      case 4:
        Led(4, Seg4);
        break;
      case 5:
        Led(4, Seg4);
        break;
      default:
        SegPoint = 1;
    }
  }
}

void Led(int com, int n){        // 'n' must be 0x0 to 0x10 (OFF)                            
  digitalWrite(COM1, LOW);          // 'com' must be 1 to 3, and other number is OFF  
  digitalWrite(COM2, LOW); 
  digitalWrite(COM3, LOW); 
  digitalWrite(COM3, LOW); 
  switch(n){
    case 0:
      digitalWrite(SEG_A, HIGH);
      digitalWrite(SEG_B, HIGH);    
      digitalWrite(SEG_C, HIGH);    
      digitalWrite(SEG_D, HIGH);
      digitalWrite(SEG_E, HIGH);    
      digitalWrite(SEG_F, HIGH);    
      digitalWrite(SEG_G, LOW);    
      digitalWrite(DOT, LOW);      
      break;
     case 1:
      digitalWrite(SEG_A, LOW);
      digitalWrite(SEG_B, HIGH);    
      digitalWrite(SEG_C, HIGH);    
      digitalWrite(SEG_D, LOW);
      digitalWrite(SEG_E, LOW);    
      digitalWrite(SEG_F, LOW);    
      digitalWrite(SEG_G, LOW);    
      digitalWrite(DOT, LOW);      
      break;
    case 2:
      digitalWrite(SEG_A, HIGH);
      digitalWrite(SEG_B, HIGH);    
      digitalWrite(SEG_C, LOW);    
      digitalWrite(SEG_D, HIGH);
      digitalWrite(SEG_E, HIGH);    
      digitalWrite(SEG_F, LOW);    
      digitalWrite(SEG_G, HIGH);    
      digitalWrite(DOT, LOW);      
      break;
    case 3:
      digitalWrite(SEG_A, HIGH);
      digitalWrite(SEG_B, HIGH);    
      digitalWrite(SEG_C, HIGH);    
      digitalWrite(SEG_D, HIGH);
      digitalWrite(SEG_E, LOW);    
      digitalWrite(SEG_F, LOW);    
      digitalWrite(SEG_G, HIGH);    
      digitalWrite(DOT, LOW);      
      break;
    case 4:
      digitalWrite(SEG_A, LOW);
      digitalWrite(SEG_B, HIGH);    
      digitalWrite(SEG_C, HIGH);    
      digitalWrite(SEG_D, LOW);
      digitalWrite(SEG_E, LOW);    
      digitalWrite(SEG_F, HIGH);    
      digitalWrite(SEG_G, HIGH);    
      digitalWrite(DOT, LOW);      
      break;
    case 5:
      digitalWrite(SEG_A, HIGH);
      digitalWrite(SEG_B, LOW);    
      digitalWrite(SEG_C, HIGH);    
      digitalWrite(SEG_D, HIGH);
      digitalWrite(SEG_E, LOW);    
      digitalWrite(SEG_F, HIGH);    
      digitalWrite(SEG_G, HIGH);    
      digitalWrite(DOT, LOW);      
      break;
    case 6:
      digitalWrite(SEG_A, HIGH);
      digitalWrite(SEG_B, LOW);    
      digitalWrite(SEG_C, HIGH);    
      digitalWrite(SEG_D, HIGH);
      digitalWrite(SEG_E, HIGH);    
      digitalWrite(SEG_F, HIGH);    
      digitalWrite(SEG_G, HIGH);    
      digitalWrite(DOT, LOW);      
      break;
    case 7:
      digitalWrite(SEG_A, HIGH);
      digitalWrite(SEG_B, HIGH);    
      digitalWrite(SEG_C, HIGH);    
      digitalWrite(SEG_D, LOW);
      digitalWrite(SEG_E, LOW);    
      digitalWrite(SEG_F, LOW);    
      digitalWrite(SEG_G, LOW);    
      digitalWrite(DOT, LOW);      
      break;
    case 8:
      digitalWrite(SEG_A, HIGH);
      digitalWrite(SEG_B, HIGH);    
      digitalWrite(SEG_C, HIGH);    
      digitalWrite(SEG_D, HIGH);
      digitalWrite(SEG_E, HIGH);    
      digitalWrite(SEG_F, HIGH);    
      digitalWrite(SEG_G, HIGH);    
      digitalWrite(DOT, LOW);      
      break;
    case 9:
      digitalWrite(SEG_A, HIGH);
      digitalWrite(SEG_B, HIGH);    
      digitalWrite(SEG_C, HIGH);    
      digitalWrite(SEG_D, HIGH);
      digitalWrite(SEG_E, LOW);    
      digitalWrite(SEG_F, HIGH);    
      digitalWrite(SEG_G, HIGH);    
      digitalWrite(DOT, LOW);      
      break;
    case 10:  // Charracter A
      digitalWrite(SEG_A, HIGH);
      digitalWrite(SEG_B, HIGH);    
      digitalWrite(SEG_C, HIGH);    
      digitalWrite(SEG_D, LOW);
      digitalWrite(SEG_E, HIGH);    
      digitalWrite(SEG_F, HIGH);    
      digitalWrite(SEG_G, LOW);    
      digitalWrite(DOT, LOW);      
      break;
    case 11:    // Character B
      digitalWrite(SEG_A, LOW);
      digitalWrite(SEG_B, LOW);    
      digitalWrite(SEG_C, HIGH);    
      digitalWrite(SEG_D, HIGH);
      digitalWrite(SEG_E, HIGH);    
      digitalWrite(SEG_F, HIGH);    
      digitalWrite(SEG_G, HIGH);    
      digitalWrite(DOT, LOW);      
      break;
    case 12:    // Character C
      digitalWrite(SEG_A, HIGH);
      digitalWrite(SEG_B, LOW);    
      digitalWrite(SEG_C, LOW);    
      digitalWrite(SEG_D, HIGH);
      digitalWrite(SEG_E, HIGH);    
      digitalWrite(SEG_F, HIGH);    
      digitalWrite(SEG_G, LOW);    
      digitalWrite(DOT, LOW);      
      break;
    case 13:    // Character d
      digitalWrite(SEG_A, LOW);
      digitalWrite(SEG_B, HIGH);    
      digitalWrite(SEG_C, HIGH);    
      digitalWrite(SEG_D, HIGH);
      digitalWrite(SEG_E, HIGH);    
      digitalWrite(SEG_F, LOW);    
      digitalWrite(SEG_G, HIGH);    
      digitalWrite(DOT, LOW);      
      break;
    case 14:    // Character E
      digitalWrite(SEG_A, HIGH);
      digitalWrite(SEG_B, LOW);    
      digitalWrite(SEG_C, LOW);    
      digitalWrite(SEG_D, HIGH);
      digitalWrite(SEG_E, HIGH);    
      digitalWrite(SEG_F, HIGH);    
      digitalWrite(SEG_G, HIGH);    
      digitalWrite(DOT, LOW);      
      break;
    case 15:     // Character F
      digitalWrite(SEG_A, HIGH);
      digitalWrite(SEG_B, LOW);    
      digitalWrite(SEG_C, LOW);    
      digitalWrite(SEG_D, LOW);
      digitalWrite(SEG_E, HIGH);    
      digitalWrite(SEG_F, HIGH);    
      digitalWrite(SEG_G, HIGH);    
      digitalWrite(DOT, LOW);      
      break;
    case 16:    // Chareacter .
      digitalWrite(SEG_A, LOW);
      digitalWrite(SEG_B, LOW);    
      digitalWrite(SEG_C, LOW);    
      digitalWrite(SEG_D, LOW);
      digitalWrite(SEG_E, LOW);    
      digitalWrite(SEG_F, LOW);    
      digitalWrite(SEG_G, LOW);    
      digitalWrite(DOT, HIGH);      
      break;
    case 17:    // '-' Minus
      digitalWrite(SEG_A, LOW);
      digitalWrite(SEG_B, LOW);    
      digitalWrite(SEG_C, LOW);    
      digitalWrite(SEG_D, LOW);
      digitalWrite(SEG_E, LOW);    
      digitalWrite(SEG_F, LOW);    
      digitalWrite(SEG_G, HIGH);    
      digitalWrite(DOT, LOW);      
      break;    
    default:    // OFF
      digitalWrite(SEG_A, LOW);
      digitalWrite(SEG_B, LOW);    
      digitalWrite(SEG_C, LOW);    
      digitalWrite(SEG_D, LOW);
      digitalWrite(SEG_E, LOW);    
      digitalWrite(SEG_F, LOW);    
      digitalWrite(SEG_G, LOW);    
      digitalWrite(DOT, LOW);      
      break;
  }
  switch(com){ 
    case 1:
      digitalWrite(COM1, HIGH); 
      digitalWrite(COM2, LOW); 
      digitalWrite(COM3, LOW); 
      digitalWrite(COM4, LOW);
      break; 
    case 2:
      digitalWrite(COM1, LOW); 
      digitalWrite(COM2, HIGH); 
      digitalWrite(COM3, LOW); 
      digitalWrite(COM4, LOW);
      break; 
    case 3:
      digitalWrite(COM1, LOW); 
      digitalWrite(COM2, LOW); 
      digitalWrite(COM3, HIGH); 
      digitalWrite(COM4, LOW);
      break; 
    case 4:
      digitalWrite(COM1, LOW); 
      digitalWrite(COM2, LOW); 
      digitalWrite(COM3, LOW); 
      digitalWrite(COM4, HIGH);
      break; 
    default:
      digitalWrite(COM1, LOW); 
      digitalWrite(COM2, LOW); 
      digitalWrite(COM3, LOW); 
      digitalWrite(COM4, LOW);
      break; 
    }
}
  
void  Init_Led_Seg(){
  pinMode(COM1, OUTPUT);  
  digitalWrite(COM1, LOW); 
  pinMode(COM2, OUTPUT);  
  digitalWrite(COM2, LOW); 
  pinMode(COM3, OUTPUT);  
  digitalWrite(COM3, LOW); 
  pinMode(COM3, OUTPUT);  
  digitalWrite(COM3, LOW); 
   
  pinMode(SEG_A, OUTPUT);  
  digitalWrite(SEG_A, LOW);   
  pinMode(SEG_B, OUTPUT); 
  digitalWrite(SEG_B, LOW);     
  pinMode(SEG_C, OUTPUT);  
  digitalWrite(SEG_C, LOW);       
  pinMode(SEG_D, OUTPUT); 
  digitalWrite(SEG_D, LOW);        
  pinMode(SEG_E, OUTPUT);  
  digitalWrite(SEG_E, LOW);     
  pinMode(SEG_F, OUTPUT); 
  digitalWrite(SEG_F, LOW);     
  pinMode(SEG_G, OUTPUT);  
  digitalWrite(SEG_G, LOW);       
  pinMode(DOT, OUTPUT); 
  digitalWrite(DOT, LOW);      
 }    




2014年6月14日土曜日

KURUMIボードをリアルタイムに動作させる

前回の記事では、delay(1000) を使って順番にLEDを点滅させました。しかしdelay( )関数を使うと、delay(1000) を実行している約1秒間(1000m秒)は、KURUMIボードは他の処理ができません。

ここで、millis( )関数を使ってリアルタイムに色んなタスクを実行する方法を説明します。

millis( ) 関数とは1ミリ秒を刻むストップウォッチ関数です。Kurumiボードに電源が供給され動作を開始するとmillis( )関数はリセットされそのタイマーをスタートします。 KURUMIマイコンが動作している限り止まることなく時を刻みます。 この関数は現在までの時間をミリ秒単位で値 (unsigned long) を返します。この関数は約50日間でオーバーフローしゼロに戻ります。

リアルタイム制御の方法
現在時間 「 millis() 関数 」と「過去に取得した時間」を比較し、決められた時間を過ぎたら特定の処理を実行する方法で実現できます。

下記にGR-KURUMIの赤いLEDを1秒ごとに点滅させる方法を添付します。

/* GR-KURUMI Hair-pin LED Blink with millis( ) function */

#include <RLduino78.h>
#define LED_R 22
#define LED_G 23
#define LED_B 24
#define LED_OFF 1
#define LED_ON 0

unsigned long myLastTimeStamp;
int toggle = 0;

void setup()
{
    pinMode(LED_R, OUTPUT);
    pinMode(LED_G, OUTPUT);
    pinMode(LED_B, OUTPUT);
    digitalWrite(LED_R, LED_OFF);
    digitalWrite(LED_G, LED_OFF);
    digitalWrite(LED_B, LED_OFF);    
}

void loop()
{
    if(millis() - myLastTimeStamp > 1000) {
       myLastTimeStamp = millis();
       if (toggle == 0) {
         toggle = 1;
         digitalWrite(LED_R, LED_ON);      
       } else {
         toggle = 0;
         digitalWrite(LED_R, LED_OFF);      
       }
    }
    
    // You make other operation here.
}