Nゲージ(ホールICでスピード計測)

以前作った赤外線LEDとフォトトランジスターによるスピード計測はセンサー部が大きくて邪魔なのでホールICを使ったスピード計測を作ってみました。

ホールICを使うので、車両に磁石を付ける必要があります。

回路図は次のようになります。
赤外線LEDが無くなったので、さらにシンプルになってます。

回路図

ホールIC(SK8552G-G03-K)は線路の継ぎ目に挟み込む事にします。

線路の繋ぎ目のホールIC(表)
線路の繋ぎ目のホールIC(裏)
ホールICの足の形
ホールICにケーブルを接続

車両の下に付ける磁石はセリアで見つけた「超強力マグネット ミニ 8P」を使いました。

磁石を車両の下にセロテープで固定した

スケッチは次のようになります。

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define LOGO_HEIGHT   16
#define LOGO_WIDTH    16
static const unsigned char PROGMEM logo_off[] =
{ B00000000, B00000000,
  B00000000, B00000000,
  B00000000, B00000000,
  B00000000, B00000000,
  B00000000, B00000000,
  B11111111, B11111110,
  B00000001, B11111110,
  B00000001, B11111110,
  B00000001, B11111110,
  B00000001, B11111110,
  B00000001, B11111110,
  B00000001, B11111110,
  B00000001, B11111110,
  B00000000, B00000000,
  B00000000, B00000000,
  B00000000, B00000000 };

static const unsigned char PROGMEM logo_on[] =
{ B00000000, B00000000,
  B11111111, B00000000,
  B11111111, B00000000,
  B11111111, B00000000,
  B11111111, B00000000,
  B11111111, B00000000,
  B11111111, B00000000,
  B11111111, B00000000,
  B11111111, B00000000,
  B10000000, B00000000,
  B10000000, B00000000,
  B10000000, B00000000,
  B10000000, B00000000,
  B10000000, B00000000,
  B10000000, B00000000,
  B10000000, B00000000 };

#define FLAG_ON_VALUE (900)

int digitalPin1 = 2;
int digitalPin2 = 3;

int val1 = 0;
int val2 = 0;

unsigned char prev_flag1 = 0;
unsigned char curr_flag1 = 0;
unsigned char chng_flag1 = 0;
unsigned char prev_flag2 = 0;
unsigned char curr_flag2 = 0;
unsigned char chng_flag2 = 0;
unsigned char need_draw  = 0;

unsigned long time0 = 0;
unsigned long time1 = 0;
unsigned long time2 = 0;
float val_speed = 0.0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("SSD1306 OLED 128x64 i2c");

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(2000); // Pause for 2 seconds

  // Clear the buffer
  display.clearDisplay();

  pinMode(digitalPin1, INPUT);
  pinMode(digitalPin2, INPUT);
  
  drawflags();
  delay(1000);
}

void drawbitmap_off(int x, int y) {
  display.drawBitmap(
    x, y,
    logo_off, LOGO_WIDTH, LOGO_HEIGHT, 1);
}

void drawbitmap_on(int x, int y) {
  display.drawBitmap(
    x, y,
    logo_on, LOGO_WIDTH, LOGO_HEIGHT, 1);
}

void drawflags() {
  int x, y;
  y = LOGO_HEIGHT / 2;
  //y = (display.height() - LOGO_HEIGHT) / 4;
  display.clearDisplay();

  x = display.width() / 4  - LOGO_WIDTH / 2;
  if (val1 == HIGH) {
    drawbitmap_on(x, y);    // Draw a small bitmap image
  } else {
    drawbitmap_off(x, y);    // Draw a small bitmap image
  }

  x = display.width() * 3 / 4  - LOGO_WIDTH / 2;
  if (val2 == HIGH) {
    drawbitmap_on(x, y);    // Draw a small bitmap image
  } else {
    drawbitmap_off(x, y);    // Draw a small bitmap image
  }

  display.setTextSize(2); // Draw 2X-scale text
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(25, display.height() / 2);
  int speed_int = (int)(val_speed * 3.6 + 0.5);
  if (speed_int < 100) {
    display.print(F(" "));
  }
  if (speed_int < 10) {
    display.print(F(" "));
  }
  display.print(speed_int);
  display.print(F(" km/h"));
  
  display.display();
}

void loop() {
  // put your main code here, to run repeatedly:
  val1 = digitalRead(digitalPin1);
  val2 = digitalRead(digitalPin2);

  need_draw = 0;
  time0 = millis();
  if (time0 - time1 > 15000) {
    val_speed = 0;
    time1 = time2 = time0;
    need_draw = 1;
  }
  if (time0 - time2 > 15000) {
    val_speed = 0;
    time1 = time2 = time0;
    need_draw = 1;
  }
  if (val1 == HIGH) {
    curr_flag1 = 1;
  } else {
    curr_flag1 = 0;
  }
  if (prev_flag1 != curr_flag1) {
    chng_flag1 = 1;
    if (curr_flag1 > 0) {
      time1 = millis();
    }
  } else {
    chng_flag1 = 0;
  }
  
  if (val2 == HIGH) {
    curr_flag2 = 1;
  } else {
    curr_flag2 = 0;
  }
  if (prev_flag2 != curr_flag2) {
    chng_flag2 = 1;
    if (curr_flag2 > 0) {
      time2 = millis();
      if (time2 > time1) {
        float delta_t = time2 - time1;
        val_speed = 150.0 * 124.0 / delta_t;
      }
    }
  } else {
    chng_flag2 = 0;
  }

  if (chng_flag1 + chng_flag2 + need_draw > 0) {
    drawflags();
  }
  delay(10);
  prev_flag1 = curr_flag1;
  prev_flag2 = curr_flag2;
}
カテゴリー: Arduino, Nゲージ, センサー, 作ったモノ タグ: , , , パーマリンク

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA