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

Материал из ВикиСправочника
Перейти к: навигация, поиск

Перевод: Максим Кузьмин (Cubewriter)
Перевел 1819 статей для сайта.

Контакты:

Проверка/Оформление/Редактирование: Мякишев Е.А.


Ambox content.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.

  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 можно почитать тут.

См.также

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

  1. blog.squix.org - ESP8266 Peripherals: Indoor Positioning with IR Camera