ИК-трекинг движений глаз на Arduino Pro Mini — демо управления светодиодами
Компоненты и расходные материалы
| SparkFun Arduino Pro Mini 328 — 5В/16 МГц | × | 1 |
| Adafruit LiIon/LiPoly Backpack для Pro Trinket/ItsyBitsy | × | 1 |
| Лента NeoPixel | × | 1 |
| Датчик отражения QTR-1A | × | 1 |
| LiPo-аккумулятор 3,7 В | × | 1 |
Приложения и онлайн-сервисы
Arduino IDE
О проекте
Использовал инфракрасный датчик для отслеживания движений глаз и управления светодиодами.
Светодиодный глаз на NeoPixel
Использована лента NeoPixel — 68 светодиодов.

Лента закреплена на чашечке двусторонним скотчем и подключена по схеме:

Трекинг движений глаза
Схема

Датчики
Использовано два датчика QTR-1A для трекинга глаз. Они установлены на пластиковом листе на расстоянии, примерно равном ширине глаза.

Сенсорная часть и микроконтроллер закреплены на очках с помощью клипс.

Код Arduino
Когда радужка приближается к датчику, отражённый свет уменьшается, а показания датчика растут. При удалении — наоборот. Движение зрачка светодиодного глаза управляется изменением показаний одного датчика.
При моргании показания обоих датчиков падают — если оба снижаются одновременно, век светодиодного глаза опускаются.
#include <QTRSensors.h>
#include <Adafruit_NeoPixel.h>
#define NUM_SENSORS 2
#define NUM_SAMPLES_PER_SENSOR 10
#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;
// Анимации: черный глаз, зрачок, веки (массивы координат LED)
// ... (полные массивы blackLED[15][24], pupilLED[15][12], eyelidLED[56] в исходном коде)
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) {
// Серый фон
for (uint16_t i = 0; i < led.numPixels(); i++) {
led.setPixelColor(i, led.Color(66, 66, 66));
}
// Чёрный глаз
for (uint16_t i = 0; i < blackNum; i++) {
led.setPixelColor(blackLED[LR][i], color);
}
// Зрачок
for (uint16_t i = 0; i < pupilNum; i++) {
led.setPixelColor(pupilLED[LR][i], led.Color(0, 0, 66));
}
// Веки
for (int i = 0; i < eyelidNum[eyelid]; i++) {
led.setPixelColor(eyelidLED[i], 0);
}
} else {
led.clear();
}
led.show();
}
void setup() {
Serial.begin(115200);
led.begin();
led.setBrightness(brightness);
led.show();
color = led.Color(0, 177, 55); // цвет зрачка
delay(100);
qtra.read(sensorValues);
iniSensorValL = sensorValues[0];
iniSensorValR = sensorValues[1];
blink(eyelid, LR);
}
void loop() {
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) { // вправо
for (int i = LR; i < 12; i++) { blink(0, i); delay(40); LR = i; }
} else if (rasioL < 0.985 && rasioR > 0.985) { // влево
for (int i = LR; i > 2; i--) { blink(0, i); delay(40); LR = i; }
} else if (!lid && rasioL < 0.96 && rasioR < 0.96) { // моргание закрытие
for (int i = 1; i < 9; i++) { blink(i, LR); delay(40); lid = true; }
} else if (lid && rasioL > 0.96 && rasioR > 0.96) { // моргание открытие
for (int i = 8; i > 0; i--) { blink(i, LR); delay(40); lid = false; }
} else if (!lid && rasioL > 0.96 && rasioR > 0.96) { // норма
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("Норма");
}
// Обновление базовых значений
if (cnt > 10) {
iniSensorValL = sensorValL;
iniSensorValR = sensorValR;
cnt = 0;
}
}
Работа устройства
Устройство отслеживает горизонтальные движения глаза и моргание, передавая их на светодиодный «глаз», который повторяет эти движения в реальном времени.
Производственный процесс
- Почему дизайнеры возвращаются к натуральным материалам в продуктовом дизайне
- Импульсный датчик света: Усиление световых импульсов LED в слышимый звук
- ИК-датчик температуры TMP006 с Raspberry Pi: библиотека Python и руководство по настройке
- Создание удалённого датчика температуры на Raspberry Pi и Python — пошаговое руководство
- Датчик слежения за линией на Raspberry Pi — простой детектор двери/линии KY‑033
- Надёжный домашний мониторинг с Home Assistant на Raspberry Pi: движение, алермы и видеозахват
- Построение DIY инфракрасного датчика движения для Raspberry Pi — пошаговое руководство
- Управление светодиодом с PIR-датчиком движения на Raspberry Pi
- Сборка лазерного танка под управлением Leap Motion — Arduino, Raspberry Pi, RGB-светодиоды
- Точное инфракрасное температурное измерение для цветозависимых процессов