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

Материал из Онлайн справочника
< ESP8266:Примеры
Версия от 20:46, 18 июня 2019; Myagkij (обсуждение | вклад) (→‎См.также)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к навигации Перейти к поиску

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


Pixel Art Mini Meow Animated.gif Черновик


Использование 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.

  1 // * Тестовый код для ИК-датчика Wii от kako (http://www.kako.com)
  2 // * Модифицирован RobotFreak для программы Wii-BlobTrack 
  3 //   (http://www.letsmakerobots.com/user/1433)
  4 // * Модифицирован Lumi для http://DFRobot.com (январь 2014)
  5 // * Адаптирован Д. Эйкхорном (D. Eichhorn) для ESP8266 (2016)
  6 //   (http://blog.squix.ch)
  7  
  8 #include <Wire.h>
  9  
 10 int IRsensorAddress = 0xB0;
 11 //int IRsensorAddress = 0x58;
 12 int slaveAddress;
 13 int ledPin = 13;
 14 boolean ledState = false;
 15 byte data_buf[16];
 16 int i;
 17  
 18 int Ix[4];
 19 int Iy[4];
 20 int s;
 21  
 22 void Write_2bytes(byte d1, byte d2)
 23 {
 24     Wire.beginTransmission(slaveAddress);
 25     Wire.write(d1); Wire.write(d2);
 26     Wire.endTransmission();
 27 }
 28  
 29 void setup()
 30 {
 31     slaveAddress = IRsensorAddress >> 1
 32     // это станет адресом 0x21 для использования в шине TWI
 33     Serial.begin(115200);
 34     pinMode(ledPin, OUTPUT);
 35     // выставляем контакт для светодиода в режим вывода данных
 36     Wire.begin(D5, D6);
 37     // инициализация ИК-датчика:
 38     Write_2bytes(0x30,0x01); delay(10);
 39     Write_2bytes(0x30,0x08); delay(10);
 40     Write_2bytes(0x06,0x90); delay(10);
 41     Write_2bytes(0x08,0xC0); delay(10);
 42     Write_2bytes(0x1A,0x40); delay(10);
 43     Write_2bytes(0x33,0x33); delay(10);
 44     delay(100);
 45 }
 46 void loop()
 47 {
 48     ledState = !ledState;
 49     if (ledState) { digitalWrite(ledPin,HIGH); } else { digitalWrite(ledPin,LOW); }
 50  
 51     // считываем данные с ИК-датчика:
 52     Wire.beginTransmission(slaveAddress);
 53     Wire.write(0x36);
 54     Wire.endTransmission();
 55  
 56     Wire.requestFrom(slaveAddress, 16);    
 57     // запрашиваем 2-байтный заголовок (первым идет самый старший бит)
 58     for (i=0;i<16;i++) { data_buf[i]=0; }
 59     i=0;
 60     while(Wire.available() && i < 16) { 
 61         data_buf[i] = Wire.read();
 62         i++;
 63     }
 64  
 65     Ix[0] = data_buf[1];
 66     Iy[0] = data_buf[2];
 67     s   = data_buf[3];
 68     Ix[0] += (s & 0x30) <<4;
 69     Iy[0] += (s & 0xC0) <<2;
 70  
 71     Ix[1] = data_buf[4];
 72     Iy[1] = data_buf[5];
 73     s   = data_buf[6];
 74     Ix[1] += (s & 0x30) <<4;
 75     Iy[1] += (s & 0xC0) <<2;
 76  
 77     Ix[2] = data_buf[7];
 78     Iy[2] = data_buf[8];
 79     s   = data_buf[9];
 80     Ix[2] += (s & 0x30) <<4;
 81     Iy[2] += (s & 0xC0) <<2;
 82  
 83     Ix[3] = data_buf[10];
 84     Iy[3] = data_buf[11];
 85     s   = data_buf[12];
 86     Ix[3] += (s & 0x30) <<4;
 87     Iy[3] += (s & 0xC0) <<2;
 88  
 89     for(i=0; i<4; i++)
 90     {
 91       if (Ix[i] < 1000)
 92         Serial.print("");
 93       if (Ix[i] < 100)  
 94         Serial.print("");
 95       if (Ix[i] < 10)  
 96         Serial.print("");
 97       Serial.print( int(Ix[i]) );
 98       Serial.print(",");
 99       if (Iy[i] < 1000)
100         Serial.print("");
101       if (Iy[i] < 100)  
102         Serial.print("");
103       if (Iy[i] < 10)  
104         Serial.print("");
105       Serial.print( int(Iy[i]) );
106       if (i<3)
107         Serial.print(",");
108     }
109     Serial.println("");
110     delay(15);
111 }

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

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

 1 import processing.serial.*;
 2 
 3 int lf = 10;    // перевод строки в ASCII-таблице
 4 String myString = null;
 5 Serial myPort;  // последовательный порт
 6 int rad = 5;    // ширина фигуры
 7 
 8 void setup() {
 9   size(1024, 768);
10   noStroke();
11   frameRate(30);
12   ellipseMode(RADIUS);
13   // выводим список доступных последовательных портов:
14   printArray(Serial.list());
15   // открываем используемый порт на выбранной скорости:
16   myPort = new Serial(this, Serial.list()[5], 115200);
17   myPort.clear();
18   // если начали считывать данные с середины строки,
19   // то игнорируем первую считанную порцию данных:
20   myString = myPort.readStringUntil(lf);
21   myString = null;
22 }
23 
24 void draw() {
25   background(102);
26   while (myPort.available() > 0) {
27     myString = myPort.readStringUntil(lf);
28     String[] list = split(myString, ',');
29     ellipse(float(list[0]), float(list[1]), rad, rad);
30     ellipse(float(list[2]), float(list[3]), rad, rad);
31     ellipse(float(list[4]), float(list[5]), rad, rad);
32     ellipse(float(list[6]), float(list[7]), rad, rad);
33     if (myString != null) {
34       println(myString);
35     }
36   }
37  
38 }

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

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

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

Видео

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

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

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

Где купить

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

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

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

См.также

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