Nゲージ ホールICによる位置表示

ホールICは単純なので数を増やすのが簡単という事で、ホールIC6つにケーブルをつけてレイアウト上に配置して、車両の位置を表示してみた。

レイアウト上に6つのホールICを配置
レイアウト上に6つのホールICを配置

実際に動かした様子。

回路図はこちら。

回路図

スケッチはこちら。

#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 LEN_124 28
#define HALF_124  (LEN_124/2)
#define LEN_117 24
#define HALF_117  (LEN_117/2)
#define SIZE_SENSOR 6
#define MARK_SENSOR 3

#define CENTER_X  (SCREEN_WIDTH/2)
#define CENTER_Y  (SCREEN_HEIGHT/2)

#define NUM_SENSORS 6

typedef struct {
  int x, y;
} Point;
Point pts[NUM_SENSORS] = {
  {CENTER_X-HALF_124, CENTER_Y+LEN_117},
  {CENTER_X+HALF_124, CENTER_Y+LEN_117},
  {CENTER_X+HALF_124+LEN_117, CENTER_Y},
  {CENTER_X+HALF_124, CENTER_Y-LEN_117},
  {CENTER_X-HALF_124, CENTER_Y-LEN_117},
  {CENTER_X-HALF_124-LEN_117, CENTER_Y}};

typedef struct {
  int pin;
  int prev;
  int state;
  unsigned long msec;
} Sensor;
Sensor sensors[NUM_SENSORS] = {
  {2, LOW, LOW, 0}, {3, LOW, LOW, 0}, {4, LOW, LOW, 0}, {5, LOW, LOW, 0}, {6, LOW, LOW, 0}, {7, LOW, LOW, 0}
};

int needUpdate = 0;

void drawRail() {
  // Rail line
  display.drawFastHLine(CENTER_X-HALF_124, CENTER_Y-LEN_117, LEN_124, SSD1306_WHITE);
  display.drawFastHLine(CENTER_X-HALF_124, CENTER_Y+LEN_117, LEN_124, SSD1306_WHITE);
  display.drawCircleHelper(CENTER_X-HALF_124, CENTER_Y, LEN_117, 1, SSD1306_WHITE);
  display.drawCircleHelper(CENTER_X-HALF_124, CENTER_Y, LEN_117, 8, SSD1306_WHITE);
  display.drawCircleHelper(CENTER_X+HALF_124, CENTER_Y, LEN_117, 2, SSD1306_WHITE);
  display.drawCircleHelper(CENTER_X+HALF_124, CENTER_Y, LEN_117, 4, SSD1306_WHITE);
  // sensor points
  display.fillCircle(CENTER_X-HALF_124, CENTER_Y-LEN_117, SIZE_SENSOR, SSD1306_BLACK);
  display.drawCircle(CENTER_X-HALF_124, CENTER_Y-LEN_117, SIZE_SENSOR, SSD1306_WHITE);
  display.fillCircle(CENTER_X+HALF_124, CENTER_Y-LEN_117, SIZE_SENSOR, SSD1306_BLACK);
  display.drawCircle(CENTER_X+HALF_124, CENTER_Y-LEN_117, SIZE_SENSOR, SSD1306_WHITE);
  display.fillCircle(CENTER_X+HALF_124+LEN_117, CENTER_Y, SIZE_SENSOR, SSD1306_BLACK);
  display.drawCircle(CENTER_X+HALF_124+LEN_117, CENTER_Y, SIZE_SENSOR, SSD1306_WHITE);
  display.fillCircle(CENTER_X+HALF_124, CENTER_Y+LEN_117, SIZE_SENSOR, SSD1306_BLACK);
  display.drawCircle(CENTER_X+HALF_124, CENTER_Y+LEN_117, SIZE_SENSOR, SSD1306_WHITE);
  display.fillCircle(CENTER_X-HALF_124, CENTER_Y+LEN_117, SIZE_SENSOR, SSD1306_BLACK);
  display.drawCircle(CENTER_X-HALF_124, CENTER_Y+LEN_117, SIZE_SENSOR, SSD1306_WHITE);
  display.fillCircle(CENTER_X-HALF_124-LEN_117, CENTER_Y, SIZE_SENSOR, SSD1306_BLACK);
  display.drawCircle(CENTER_X-HALF_124-LEN_117, CENTER_Y, SIZE_SENSOR, SSD1306_WHITE);
  // sensor marker
  /*
  display.fillCircle(CENTER_X-HALF_124, CENTER_Y-LEN_117, MARK_SENSOR, SSD1306_WHITE);  // 0->4
  display.fillCircle(CENTER_X+HALF_124, CENTER_Y-LEN_117, MARK_SENSOR, SSD1306_WHITE);  // 1->3
  display.fillCircle(CENTER_X+HALF_124+LEN_117, CENTER_Y, MARK_SENSOR, SSD1306_WHITE);  // 2->2
  display.fillCircle(CENTER_X+HALF_124, CENTER_Y+LEN_117, MARK_SENSOR, SSD1306_WHITE);  // 3->1
  display.fillCircle(CENTER_X-HALF_124, CENTER_Y+LEN_117, MARK_SENSOR, SSD1306_WHITE);  // 4->0
  display.fillCircle(CENTER_X-HALF_124-LEN_117, CENTER_Y, MARK_SENSOR, SSD1306_WHITE);  // 5->5
  */
  for (int i=0; i<NUM_SENSORS; i++) {
    if (sensors[i].state == HIGH) {
      display.fillCircle(pts[i].x, pts[i].y, MARK_SENSOR, SSD1306_WHITE);
    }
  }
}

void initSensors() {
  for (int i=0; i<NUM_SENSORS; i++) {
    pinMode(sensors[i].pin, INPUT);
  }
}

void updateSensors() {
  needUpdate = 0;
  unsigned long msec = millis();
  for (int i=0; i<NUM_SENSORS; i++) {
    sensors[i].prev = sensors[i].state;
    int curr = digitalRead(sensors[i].pin);
    if (curr == HIGH) {
      sensors[i].msec = msec;
    }
    unsigned long delta = msec - sensors[i].msec;
    if (delta < 200) {
      sensors[i].state = HIGH;
    } else {
      sensors[i].state = LOW;
    }
    if (sensors[i].prev != sensors[i].state) {
      needUpdate++;
    }
  }
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("multi-hall-sensor-system");

  // 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
  }
  display.display();
  delay(2000); // Pause for 2 seconds

  initSensors();
  // Clear the buffer
  //display.clearDisplay();
  //display.display();
  display.clearDisplay();
  drawRail();
  display.display();
}

void loop() {
  // put your main code here, to run repeatedly:
  updateSensors();

  if (needUpdate > 0) {
    display.clearDisplay();
    drawRail();
    display.display();
  }

  //delay(1);
}
カテゴリー: Arduino, Nゲージ, センサー, 作ったモノ タグ: , , , , パーマリンク

コメントを残す

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

CAPTCHA