ホールICは単純なので数を増やすのが簡単という事で、ホールIC6つにケーブルをつけてレイアウト上に配置して、車両の位置を表示してみた。
実際に動かした様子。
回路図はこちら。
スケッチはこちら。
#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); }