ESP8266:Примеры/Использование ESP8266 вместе с позиционной ИК-камерой

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску

Перевод: Максим Кузьмин (Cubewriter) Контакты:</br>* Skype: cubewriter</br>* E-mail: cubewriter@gmail.com</br>* Максим Кузьмин на freelance.ru
Проверка/Оформление/Редактирование: Мякишев Е.А.


Cat poo.png Черновик


Использование ESP8266 вместе с позиционной ИК-камерой[1]

Датчик, о котором я хочу поговорить в этой статье, применим в огромном количестве проектов. Вполне возможно, что он даже встроен в какую-нибудь систему, стоящую у вас дома. Речь о позиционной ИК-камере производства DFRobot, использующей тот же (или похожий) модуль, встроенный в контроллер Nintendo Wiimote. Этот модуль способен одновременно определять до 4 источников ИК-излучения, а затем отправлять эти данные по интерфейсу I2C.

Позиционная ИК-камера производства DFRobot

Технические характеристики:

  • Рабочее напряжение – от 3,3 до 5 вольт
  • ИнтерфейсI2C
  • Дистанция обнаружения ИК-излучения – от 0 до 3 метров
  • Горизонтальный угол обнаружения – 33 градуса
  • Вертикальный угол обнаружения – 23 градуса
  • Размеры – 32 на 16 мм
  • Разрешение – 128 х 96 пикселей с 8 субпикселями; т.е. в результате 1024 х 768
  • Количество отслеживаемых объектов – 4 (излучение или отражение ИК-излучения)
  • Цена – около 23,55 долларов США

Принцип работы

Чип, которым оснащен датчик, выполняет за вас всю самую тяжелую работу. Фильтрует шум, выясняет месторасположение сильнейших источников света, который проходит через ИК-фильтр, стоящий перед камерой. Затем камера передает – на ESP8266 (или какой-то другой микроконтроллер) через интерфейс I2C – четыре пары значений с координатами X и Y (для разрешения 1024 х 768). Если камера не обнаружит никакого источника ИК-излучения, то вернет пару максимальных значений с 2^10 = 1023.

Подключение ESP8266

Просто подключите красный контакт к 3,3 вольтам, черный – к GND, а зеленый и желтый – к свободным GPIO-контактам.

Код

Код для проекта показан ниже. Если необходимо, отредактируйте его, если используете другие GPIO-контакты. Затем загрузите его на ESP8266.

// * Тестовый код для ИК-датчика Wii от kako (http://www.kako.com)
// * Модифицирован RobotFreak для программы Wii-BlobTrack 
//   (http://www.letsmakerobots.com/user/1433)
// * Модифицирован Lumi для http://DFRobot.com (январь 2014)
// * Адаптирован Д. Эйкхорном (D. Eichhorn) для ESP8266 (2016)
//   (http://blog.squix.ch)
 
#include <Wire.h>
 
int IRsensorAddress = 0xB0;
//int IRsensorAddress = 0x58;
int slaveAddress;
int ledPin = 13;
boolean ledState = false;
byte data_buf[16];
int i;
 
int Ix[4];
int Iy[4];
int s;
 
void Write_2bytes(byte d1, byte d2)
{
    Wire.beginTransmission(slaveAddress);
    Wire.write(d1); Wire.write(d2);
    Wire.endTransmission();
}
 
void setup()
{
    slaveAddress = IRsensorAddress >> 1
    // это станет адресом 0x21 для использования в шине TWI
    Serial.begin(115200);
    pinMode(ledPin, OUTPUT);
    // выставляем контакт для светодиода в режим вывода данных
    Wire.begin(D5, D6);
    // инициализация ИК-датчика:
    Write_2bytes(0x30,0x01); delay(10);
    Write_2bytes(0x30,0x08); delay(10);
    Write_2bytes(0x06,0x90); delay(10);
    Write_2bytes(0x08,0xC0); delay(10);
    Write_2bytes(0x1A,0x40); delay(10);
    Write_2bytes(0x33,0x33); delay(10);
    delay(100);
}
void loop()
{
    ledState = !ledState;
    if (ledState) { digitalWrite(ledPin,HIGH); } else { digitalWrite(ledPin,LOW); }
 
    // считываем данные с ИК-датчика:
    Wire.beginTransmission(slaveAddress);
    Wire.write(0x36);
    Wire.endTransmission();
 
    Wire.requestFrom(slaveAddress, 16);    
    // запрашиваем 2-байтный заголовок (первым идет самый старший бит)
    for (i=0;i<16;i++) { data_buf[i]=0; }
    i=0;
    while(Wire.available() && i < 16) { 
        data_buf[i] = Wire.read();
        i++;
    }
 
    Ix[0] = data_buf[1];
    Iy[0] = data_buf[2];
    s   = data_buf[3];
    Ix[0] += (s & 0x30) <<4;
    Iy[0] += (s & 0xC0) <<2;
 
    Ix[1] = data_buf[4];
    Iy[1] = data_buf[5];
    s   = data_buf[6];
    Ix[1] += (s & 0x30) <<4;
    Iy[1] += (s & 0xC0) <<2;
 
    Ix[2] = data_buf[7];
    Iy[2] = data_buf[8];
    s   = data_buf[9];
    Ix[2] += (s & 0x30) <<4;
    Iy[2] += (s & 0xC0) <<2;
 
    Ix[3] = data_buf[10];
    Iy[3] = data_buf[11];
    s   = data_buf[12];
    Ix[3] += (s & 0x30) <<4;
    Iy[3] += (s & 0xC0) <<2;
 
    for(i=0; i<4; i++)
    {
      if (Ix[i] < 1000)
        Serial.print("");
      if (Ix[i] < 100)  
        Serial.print("");
      if (Ix[i] < 10)  
        Serial.print("");
      Serial.print( int(Ix[i]) );
      Serial.print(",");
      if (Iy[i] < 1000)
        Serial.print("");
      if (Iy[i] < 100)  
        Serial.print("");
      if (Iy[i] < 10)  
        Serial.print("");
      Serial.print( int(Iy[i]) );
      if (i<3)
        Serial.print(",");
    }
    Serial.println("");
    delay(15);
}

Визуализация результатов

Для визуализации данных-точек, возвращаемых ESP8266 по последовательному порту, я решил воспользоваться скриптом Processing. Вот он:

import processing.serial.*;

int lf = 10;    // перевод строки в ASCII-таблице
String myString = null;
Serial myPort;  // последовательный порт
int rad = 5;    // ширина фигуры

void setup() {
  size(1024, 768);
  noStroke();
  frameRate(30);
  ellipseMode(RADIUS);
  // выводим список доступных последовательных портов:
  printArray(Serial.list());
  // открываем используемый порт на выбранной скорости:
  myPort = new Serial(this, Serial.list()[5], 115200);
  myPort.clear();
  // если начали считывать данные с середины строки,
  // то игнорируем первую считанную порцию данных:
  myString = myPort.readStringUntil(lf);
  myString = null;
}

void draw() {
  background(102);
  while (myPort.available() > 0) {
    myString = myPort.readStringUntil(lf);
    String[] list = split(myString, ',');
    ellipse(float(list[0]), float(list[1]), rad, rad);
    ellipse(float(list[2]), float(list[3]), rad, rad);
    ellipse(float(list[4]), float(list[5]), rad, rad);
    ellipse(float(list[6]), float(list[7]), rad, rad);
    if (myString != null) {
      println(myString);
    }
  }
 
}

Затем я взял ИК-панель, которая осталась у меня от Nintendo Wii, и помахал ею перед камерой.

Беспроводная ИК-панель от Wii

И вот результат:

Видео

Для чего можно использовать этот датчик?

Лично я купил его для того, чтобы собрать навигационную систему для своего робота, но пока не решил, какой метод выбрать. Во-первых, камеру можно поставить на робота, а источники ИК-излучения расставить по комнате. Во-вторых, можно поступить наоборот – расставить по камере несколько камер, чтобы они отслеживали источники ИК-излучения на роботе, а затем отправляли роботы данные с координатами.

Но этот датчик можно использовать и для других целей. К примеру, для отслеживания движений головы или для электронной учебной доски. Если вбить в Google «Wiimote hack», можно найти еще кучу идей для того, как можно применить этот датчик.

Где купить

Этот датчик можно купить, к примеру, на официальном сайте DFRobot или на Aliexpress.

Дополнительные материалы

Более подробно о позиционной ИК-камере от DFRobot можно почитать тут.

См.также

Внешние ссылки