Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Детектор жестов и движения на PIR-сенсоре и Arduino Nano

Компоненты и материалы

Arduino Nano R3 × 1
TPA81 Devantech 8-пиксельный термический массив × 1
PIR-датчик движения HC-SR505 (ElectroPeak) × 8
OLED-дисплей 0.96" SPI 128x64 (ElectroPeak) × 1
Макетная плата × 1
Перемыжки Male/Female × 1

Приложения и сервисы

О проекте

В статье показано, как сделать детектор жестов из простых компонентов: PIR-сенсор и Arduino Nano. Вы научитесь:

Детектор жестов и движения на PIR-сенсоре и Arduino Nano

Пассивный инфракрасный сенсор: как это работает?

PIR-сенсор измеряет инфракрасное излучение от объектов в поле зрения. Все объекты выше абсолютного нуля излучают тепло в ИК-диапазоне. PIR не излучает энергию сам — он пассивно детектирует излучение. (Источник: Wikipedia)

Детектор жестов и движения на PIR-сенсоре и Arduino Nano

TPA81 — термопильный массив, чувствителен к 2–22 мкм (тепловое излучение). В отличие от пироэлектрических датчиков (только изменение тепла), TPA81 измеряет абсолютную температуру 8 точек одновременно. Угол обзора ~12° (с линзой). Может обнаружить пламя свечи на 2 м. Независим от видимого света.

Детектор жестов и движения на PIR-сенсоре и Arduino Nano

PIR-сенсоры — как камеры, видящие только тепло. TPA81 — тепловизор 8 пикселей. Человеческое тело всегда излучает тепло. Контролируя сенсор и определяя паттерны, можно распознавать жесты.

В проекте используется TPA81 (I2C, совместим с Nano). Экономия: можно заменить на 8 обычных PIR без линз, опрашивая их последовательно.

Схема подключения

Детектор жестов и движения на PIR-сенсоре и Arduino Nano

Вариант с 8 отдельными PIR:

Детектор жестов и движения на PIR-сенсоре и Arduino Nano

Код

Для работы с TPA81 нужна библиотека TPA81.h. Установка: Sketch → Include Library → Add .ZIP Library.

1. Базовое чтение температур

#include "Wire.h"
#include "TPA81.h"
TPA81 tpa;
void setup() {
  Serial.begin(9600);
  Wire.begin();
}
void loop() {
  Serial.print(tpa.getAmbient()); Serial.print(" ");
  for (int i = 1; i <= 8; i++) {
    Serial.print(tpa.getPoint(i)); Serial.print(" ");
  }
  Serial.println();
  delay(100);
}

Откройте Serial Plotter. Первое число — общая температура. Поднесите руку — увидите изменение.

2. Визуализация движения руки (порог 29°C)

#include "Wire.h"
#include "TPA81.h"
TPA81 tpa;
void setup() {
  Serial.begin(9600);
  Wire.begin();
}
void loop() {
  Serial.print(tpa.getAmbient()); Serial.print(" ");
  for (int i = 1; i <= 8; i++) {
    if (tpa.getPoint(i) > 29) Serial.print("# ");
    else Serial.print(". ");
  }
  Serial.println();
  delay(100);
}

В Serial Monitor увидите анимацию движения руки (# — горячее, . — фон).

3. Распознавание жеста «громкость вверх/вниз» с выводом на OLED

#include "Wire.h"
#include "TPA81.h"
#include "ssd1306.h"
#include "DHT.h"

TPA81 tpa;
#define VCCSTATE SSD1306_SWITCHCAPVCC
#define WIDTH 128
#define HEIGHT 64
#define PAGES 8
#define OLED_RST 9
#define OLED_DC 8
#define OLED_CS 10
#define SPI_MOSI 11
#define SPI_SCK 13
uint8_t oled_buf[WIDTH * HEIGHT / 8];

int gesture[8][20];
int tgesture[8];
int sum = 0, sflag = 0, gcount = 0, c = 0, ex = 0, vol = 5;

//.Bitmap-иконки громкости v1..v11 хранятся в PROGMEM (массивы const uint8_t v1[] ... v11[])
// ... (код массивов опущен для краткости, см. исходник)

void dsply(int input) {
  int n1, n2;
  if (input < 10) {
    SSD1306_char3216(10, 25, '0', oled_buf);
    SSD1306_char3216(26, 25, '0' + input, oled_buf);
  } else {
    n1 = input / 10; n2 = input % 10;
    SSD1306_char3216(10, 25, '0' + n1, oled_buf);
    SSD1306_char3216(26, 25, '0' + n2, oled_buf);
  }
}

void setup() {
  Serial.begin(9600);
  Wire.begin();
  SSD1306_begin();
  SSD1306_clear(oled_buf);
}

void loop() {
  // Чтение 8 пикселей
  for (int i = 0; i <= 7; i++) {
    if (tpa.getPoint(i+1) > 29) { Serial.print("# "); gesture[i][0] = 1; }
    else { Serial.print(". "); gesture[i][0] = 0; }
  }
  for (int y = 0; y <= 7; y++) sum += gesture[y][0];
  Serial.println(sum);
  Serial.println();
  delay(100);

  // Standby: все 8 пикселей горячие
  if (sum == 8) { sflag = 1; Serial.println("standby"); }
  else { sum = 0; }

  // Обнаружение жеста
  if (sflag == 1 && sum != 8) {
    Serial.println("start gesture");
    gcount = 0; c = 0; sum = 0;
    while (sum < 8) {
      sum = 0;
      for (int i = 0; i <= 7; i++) {
        if (tpa.getPoint(i+1) > 29) { Serial.print("# "); gesture[i][gcount] = 1; }
        else { Serial.print(". "); gesture[i][gcount] = 0; }
      }
      for (int y = 0; y <= 7; y++) { sum += gesture[y][gcount]; delay(5); }
      Serial.println(); delay(50);
      gcount++;
    }
    Serial.print("sum: "); Serial.println(sum);
    Serial.print("gesture length: "); Serial.println(gcount); delay(5);

    // Суммирование по сенсорам за время жеста
    for (c = 0; c <= 7; c++) {
      for (int z = 0; z <= gcount; z++) { tgesture[c] += gesture[c][z]; delay(5); }
      Serial.println("processing");
    }
    tgesture[0] += tgesture[1];
    tgesture[2] += tgesture[3];
    tgesture[4] += tgesture[5];
    tgesture[6] += tgesture[7];
    tgesture[0] += tgesture[2]; // левая половина
    tgesture[4] += tgesture[6]; // правая половина

    if (tgesture[0] < tgesture[4]) { vol += (gcount / 2); Serial.println("volume up"); }
    if (tgesture[4] < tgesture[0]) { vol -= (gcount / 2); Serial.println("volume down"); }
    sflag = 0;
  }
  sum = 0;

  // Отображение уровня громкости на OLED
  SSD1306_clear(oled_buf);
  switch (vol) {
    case 1: SSD1306_bitmap(0, 0, v1, 128, 64, oled_buf); break;
    case 2: SSD1306_bitmap(0, 0, v2, 128, 64, oled_buf); break;
    case 3: SSD1306_bitmap(0, 0, v3, 128, 64, oled_buf); break;
    case 4: SSD1306_bitmap(0, 0, v4, 128, 64, oled_buf); break;
    case 5: SSD1306_bitmap(0, 0, v5, 128, 64, oled_buf); break;
    case 6: SSD1306_bitmap(0, 0, v6, 128, 64, oled_buf); break;
    case 7: SSD1306_bitmap(0, 0, v7, 128, 64, oled_buf); break;
    case 8: SSD1306_bitmap(0, 0, v8, 128, 64, oled_buf); break;
    case 9: SSD1306_bitmap(0, 0, v9, 128, 64, oled_buf); break;
    case 10: SSD1306_bitmap(0, 0, v10, 128, 64, oled_buf); break;
    case 11: SSD1306_bitmap(0, 0, v11, 128, 64, oled_buf); break;
  }
  SSD1306_display(oled_buf);
}
Детектор жестов и движения на PIR-сенсоре и Arduino Nano

Что дальше?

Метод можно расширить для распознавания тапов, свайпов, растяжений и т.д. Определив команды для каждого жеста, можно управлять различными устройствами.

Библиотеки

Производственный процесс

  1. Arduino-датчики: типы, применения и реальные проекты
  2. Как работают схемы на PIR-датчиках: проектирование, принцип работы и реальные применения
  3. Управление светодиодом с PIR-датчиком движения на Raspberry Pi
  4. Мастерство GPIO Raspberry Pi: подключение PIR-датчика движения на B+/Model 2
  5. Подключение, калибровка и программирование PIR-датчика HC‑SR501 с Raspberry Pi
  6. Проект с датчиком DHT11: индикация температуры светодиодами и пьезо-динамиком на Arduino
  7. Робот для поиска людей на базе Arduino Uno: пошаговая интеграция датчиков
  8. Умная банка на ESP8266 + Arduino: мониторинг наполненности в реальном времени
  9. Интерактивный LED-дисплей в двери с PIR-датчиком — новогоднее приветствие на Arduino
  10. Сенсорная башня на Arduino Cloud: Мониторинг температуры, движения и газа