Infrarot-Augenbewegungs-Tracking mit Arduino Pro Mini – LED-Steuerungs-Demo
Komponenten und Materialien
| Komponente | Menge | Hinweise |
|---|---|---|
| SparkFun Arduino Pro Mini 328 - 5V/16MHz | 1 | |
| Adafruit LiIon/LiPoly Backpack Add-On für Pro Trinket/ItsyBitsy | 1 | |
| NeoPixel-Streifen | 1 | |
| QTR-1A Reflexionssensor | 1 | |
| 3,7V LiPo-Akku | 1 |
Apps und Online-Dienste
- Arduino IDE
Über dieses Projekt
Ich habe einen Infrarotsensor verwendet, um Augenbewegungen zu erfassen und die LED zu steuern.
NeoPixel LED Augapfel
NeoPixel LED-Band wird verwendet. Das LED-Band hat 68 Einheiten.
Die LED wird mit doppelseitigem Klebeband an der Schale befestigt und in folgender Reihenfolge verdrahtet.
Augenbewegungs-Tracking
Schaltplan
Sensor
Ich habe zwei QTR-1A Sensoren für das Augen-Tracking verwendet. Die QTR-1A Sensoren werden auf einer Kunststoffplatte in einem Abstand von etwa der Augenbreite platziert.
Der Sensorteil und der Mikrocontroller-Teil wurden jeweils mit einer Klemme an der Brille befestigt.
Arduino Code
Wenn sich die Iris einem Sensor nähert, nimmt das reflektierte Licht ab und der Sensorwert steigt. Umgekehrt, wenn sich die Iris entfernt, nimmt das reflektierte Licht zu und der Sensorwert des Foto-Reflektors sinkt.
Die Rechts-Links-Bewegung der Pupille des LED-Augapfels erfasst die Erhöhung und Verringerung eines Sensorwerts und steuert diese.
Beim Blinzeln sinken beide Sensorwerte, daher werden die Augenlider des LED-Augapfels gesenkt, wenn beide Sensorwerte gleichzeitig sinken.
#include
#include
#define NUM_SENSORS 2 // Anzahl der verwendeten Sensoren
#define NUM_SAMPLES_PER_SENSOR 10 // Mittelwertbildung
#define EMITTER_PIN QTR_NO_EMITTER_PIN
int iniSensorValL, sensorValL;
int iniSensorValR, sensorValR;
#define PIN A3
Adafruit_NeoPixel led = Adafruit_NeoPixel(68, PIN, NEO_GRB + NEO_KHZ800);
int blackNum = 24;
int pupilNum = 12;
uint32_t color;
int brightness = 40;
byte eyeColor;
int LR = 7;
boolean lid = false;
int cnt = 0;
// Schwarz-Auge L&R Animation
int blackLED[15][24] = {
{12,32,35,55,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68},
{12,13,31,36,54,55,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68},
{11,13,14,30,37,53,54,56,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68},
{10,11,14,15,29,38,52,53,56,57,68,68,68,68,68,68,68,68,68,68,68,68,68,68},
{9,10,11,12,15,16,28,33,34,39,51,52,55,56,57,58,68,68,68,68,68,68,68,68},
{0,8,9,10,11,12,13,16,17,27,32,35,40,50,51,54,55,56,57,58,59,67,68,68},
{0,1,7,8,9,10,13,14,17,18,26,31,36,41,49,50,53,54,57,58,59,60,66,67},
{1,2,6,7,8,9,14,15,18,19,25,30,37,42,48,49,52,53,58,59,60,61,65,66},
{2,3,5,6,7,8,15,16,19,20,24,29,38,43,47,48,51,52,59,60,61,62,64,65},
{3,4,5,6,7,16,17,20,21,23,28,39,44,46,47,50,51,60,61,62,63,64,68,68},
{4,5,6,17,18,21,22,27,40,45,46,49,50,61,62,63,68,68,68,68,68,68,68,68},
{4,5,18,19,26,41,48,49,62,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68},
{4,19,20,25,42,47,48,63,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68},
{20,21,24,43,46,47,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68},
{21,23,44,46,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68}
};
// Pupille L&R Animation
int pupilLED[15][12] = {
{33,34,68,68,68,68,68,68,68,68,68,68},
{32,33,34,35,68,68,68,68,68,68,68,68},
{12,31,32,33,34,35,36,55,68,68,68,68},
{12,13,30,31,32,33,34,35,36,37,54,55},
{13,14,29,30,31,32,35,36,37,38,53,54},
{14,15,28,29,30,31,36,37,38,39,52,53},
{15,16,27,28,29,30,37,38,39,40,51,52},
{16,17,26,27,28,29,38,39,40,41,50,51},
{17,18,25,26,27,28,39,40,41,42,49,50},
{18,19,24,25,26,27,40,41,42,43,48,49},
{19,20,23,24,25,26,41,42,43,44,47,48},
{20,21,22,23,24,25,42,43,44,45,46,47},
{21,22,23,24,43,44,45,46,68,68,68,68},
{22,23,44,45,68,68,68,68,68,68,68,68},
{22,45,68,68,68,68,68,68,68,68,68,68}
};
// Blinzeln-Animation
int eyelid = 0;
int eyelidNum[8] = {0,4,8,16,24,34,44,56};
int eyelidLED[56] = {
64,65,66,67,58,59,60,61,56,57,62,63,49,50,51,52,47,48,53,54,
38,39,40,41,46,55,36,37,42,43,26,27,28,29,35,44,24,25,30,31,
15,16,17,18,34,45,23,32,13,14,19,20,6,7,8,9
};
QTRSensorsAnalog qtra((unsigned char[]) {0, 1}, NUM_SENSORS, NUM_SAMPLES_PER_SENSOR, EMITTER_PIN);
unsigned int sensorValues[NUM_SENSORS];
void blink(int eyelid, int LR) {
if (eyelid != 8) {
// Zinnfarben für alle Pixel
for (uint16_t i = 0; i < led.numPixels(); i++) {
led.setPixelColor(i, led.Color(66, 66, 66));
}
// Schwarzes Auge
for (uint16_t i = 0; i < blackNum; i++) {
led.setPixelColor(blackLED[LR][i], color);
}
// Pupille
for (uint16_t i = 0; i < pupilNum; i++) {
led.setPixelColor(pupilLED[LR][i], led.Color(0, 0, 66));
}
// Augenlid
for (int i = 0; i < eyelidNum[eyelid]; i++) {
led.setPixelColor(eyelidLED[i], 0);
}
} else if (eyelid == 8) {
led.clear();
}
led.show();
}
void setup() {
Serial.begin(115200);
led.begin();
led.setBrightness(brightness); // Initiale Helligkeit 40
led.show(); // Alle Pixel auf 'aus' initialisieren
color = led.Color(0, 177, 55); // Pupillenfarbe
delay(100);
qtra.read(sensorValues);
iniSensorValL = sensorValues[0];
iniSensorValR = sensorValues[1];
blink(eyelid, LR);
}
void loop() {
// QTR-1A Sensorwerte
qtra.read(sensorValues);
sensorValL = sensorValues[0];
sensorValR = sensorValues[1];
double rasioL = (double)sensorValL / iniSensorValL;
double rasioR = (double)sensorValR / iniSensorValR;
Serial.print(rasioL);
Serial.print(" ");
Serial.println(rasioR);
if (rasioL > 0.985 && rasioR < 0.985) { // Rechts
for (int i = LR; i < 12; i++) {
blink(0, i);
delay(40);
LR = i;
}
} else if (rasioL < 0.985 && rasioR > 0.985) { // Links
for (int i = LR; i > 2; i--) {
blink(0, i);
delay(40);
LR = i;
}
} else if (lid == false && rasioL < 0.96 && rasioR < 0.96) { // Blinzeln schließen
for (int i = 1; i < 9; i++) {
blink(i, LR);
delay(40);
lid = true;
}
} else if (lid == true && rasioL > 0.96 && rasioR > 0.96) { // Blinzeln öffnen
for (int i = 8; i > 0; i--) {
blink(i, LR);
delay(40);
lid = false;
}
} else if (lid == false && rasioL > 0.96 && rasioR > 0.96) { // Normal
// cnt++;
// eyelid = 0;
if (LR <= 7) {
for (int i = LR; i <= 7; i++) {
blink(0, i);
delay(40);
LR = i;
}
} else {
for (int i = LR; i >= 7; i--) {
blink(0, i);
delay(40);
LR = i;
}
}
Serial.println("Normal");
}
// Anfangswerte aktualisieren
if (cnt > 10) {
iniSensorValL = sensorValL;
iniSensorValR = sensorValR;
cnt = 0;
}
}
Betrieb
Das System verfolgt Augenbewegungen über zwei Infrarot-Reflexionssensoren und steuert einen NeoPixel-LED-Augapfel entsprechend: Pupillenbewegung links/rechts und Blinzeln werden erkannt und visuell nachgebildet.
Herstellungsprozess
- Warum Designer zu natürlichen Materialien im Produktdesign zurückkehren
- Gepulster Lichtsensor: LED-Lichtimpulse in hörbaren Ton verstärken
- TMP006 Infrarot-Temperatursensor mit Raspberry Pi: Python Library & Setup Guide
- Fern-Temperatursensor mit Raspberry Pi & Python bauen – Schritt-für-Schritt-Anleitung
- Line-Tracking-Sensor mit Raspberry Pi – Einfacher KY-033 Tür/Line Detektor
- Sicheres Home Monitoring mit Home Assistant auf Raspberry Pi: Bewegung, Alarm & Video-Capture
- DIY Infrarot-Bewegungsmelder für Raspberry Pi – Schritt-für-Schritt-Anleitung
- LED mit PIR-Bewegungsmelder am Raspberry Pi steuern
- Leap Motion-gesteuerter Laser-Panzer bauen – Arduino, Raspberry Pi, RGB-LEDs
- Präzise Infrarot-Temperaturmessung für farbempfindliche Prozesse