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