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

Arduino Bluetooth Camera (ABC): передача изображений с камеры OV7670 на Android-смартфон по Bluetooth

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

Arduino UNO×1
Bluetooth-модуль HC-05 (или HC-06)×1
Камера OV7670×1
Уникальный TFT Shield для Arduino×1

О проекте

Сложно удивить кого-то смартфоном с камерой и беспроводными гаджетами. Благодаря платформе Arduino миллионы людей открыли для себя электронику и программирование. Написано сотни инструкций по обмену данными между телефоном и Arduino по Bluetooth... Но я хочу передать не просто символы и числа, а изображения.

Кто-то скажет, что это невозможно — Arduino слишком медленный для обработки больших объёмов данных. И он будет прав. Но что, если переложить «тяжёлую» работу на другое устройство? Оно существует!

Это уникальный TFT Shield для Arduino. Подробнее о нём в статьях: статья 1, статья 2. В этом руководстве показано, как соединить Arduino и Android-телефон по Bluetooth, получить изображение с камеры OV7670 на Arduino UNO и передать его на телефон. И наоборот — передать фото с телефона на Arduino и вывести на экран TFT Shield.

Для Android написано специальное приложение.

Характеристики TFT Shield

Список необходимых компонентов

Arduino Bluetooth Camera (ABC): передача изображений с камеры OV7670 на Android-смартфон по Bluetooth

Железо:

Внимание: Обязательно используйте внешний блок питания 6–12 В! Ток USB (макс. 500 мА) недостаточен для нормальной работы TFT Shield.

Софт:

Подготовка

Софт

Все скетчи для Arduino IDE. Сначала установите Arduino IDE: arduino.cc.

Затем установите библиотеку TFT Shield: github.com/YATFT/YATFT (скачайте, распакуйте в папку libraries в директории Arduino IDE).

Прошейте Arduino UNO без TFT Shield (для простоты):

  1. Подключите USB к Arduino UNO
  2. Запустите Arduino IDE, выберите порт
  3. Скачайте демо-скетч ArduinoBluetoothCamera.ino и файл ov7670_regs.h для инициализации камеры
  4. Нажмите Upload

Если прошивка прошла успешно — переходите к сборке.

Скетч ArduinoBluetoothCamera.ino

/********************************************************************** 
 * SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY...
 ***********************************************************************/
#include <YATFT.h>
#include <util/yacam.h>
#include <util/yacodec.h>
#include <util/yasrl.h>
#include "ov7670_regs.h"

JPEG_DECODE jpeg_decode;
YATFT tft(0);
INTRFC ifc;
CAM cam;
CODEC codec;
SRL srl;

#define IMG_SizeX 320
#define IMG_SizeY 240
uint8_t mode = 0;
uint8_t last_mode = 0;
uint8_t start_capt = 0;
uint16_t err;

void setup() {
  Serial.begin(115200);
  tft.begin();
  tft.SetColor(BRIGHTRED);
  tft.ClearDevice();
}

void loop() {
  if (Serial.available()) {
    uint8_t temp = Serial.read();
    switch (temp) {
      case 0x10: // Отправка одного фото
        mode = 1; start_capt = 1;
        if (last_mode != mode && last_mode != 2) {
          tft.begin(); tft.SetRGB();
          cam.CamInit(&OV7670_QVGA[0][0]);
          cam.CamVideoPreview(0, 0, 1, true);
          codec.JPEGInit(); codec.JPEGSetRegs(IMG_SizeX, IMG_SizeY);
          delay(1000);
        }
        break;
      case 0x20: // Непрерывная отправка фото
        mode = 2; start_capt = 2;
        if (last_mode != mode && last_mode != 1) {
          tft.begin(); tft.SetRGB();
          cam.CamInit(&OV7670_QVGA[0][0]);
          cam.CamVideoPreview(0, 0, 1, true);
          codec.JPEGInit(); codec.JPEGSetRegs(IMG_SizeX, IMG_SizeY);
        }
        break;
      case 0x30: // Приём одного фото
        mode = 3; start_capt = 3;
        if (last_mode != mode && last_mode != 4) {
          tft.begin(); tft.SetYUV();
        }
        break;
      case 0x40: // Непрерывный приём фото
        mode = 4; start_capt = 4;
        if (last_mode != mode && last_mode != 3) {
          tft.begin(); tft.SetYUV();
        }
        break;
      default: break;
    }
  }
  if (mode == 1) { // Отправка одного фото
    if (start_capt == 1) { start_capt = 0; last_mode = mode; mode = 0; CamCapture(); }
  } else if (mode == 2) { // Непрерывная отправка
    while (1) {
      uint8_t temp = Serial.read();
      if (start_capt == 2) start_capt = 0;
      if (temp == 0x21) { start_capt = 0; last_mode = mode; mode = 0; break; }
      if (CamCapture()) continue;
    }
  } else if (mode == 3) { // Приём одного фото
    if (start_capt == 3) {
      start_capt = 0; last_mode = mode; mode = 0;
      Serial.print("!");
      srl.JPEGReadFromSerial(&jpeg_decode, 0, 0, GetMaxX()+1, GetMaxY()+1, 32000);
    }
  } else if (mode == 4) { // Непрерывный приём
    uint8_t temp = Serial.read();
    while (1) {
      if (start_capt == 4) start_capt = 0;
      if (temp == 0x41) { start_capt = 0; last_mode = mode; mode = 0; break; }
      Serial.print("!");
      srl.JPEGReadFromSerial(&jpeg_decode, 0, 0, GetMaxX()+1, GetMaxY()+1, 32000);
    }
  }
}

uint8_t CamCapture(void) {
  uint8_t temp = 0xff, temp_last = 0;
  bool is_header = false;
  uint32_t length = 0;
  length = codec.JPEGStart();
  uint32_t en_jpeg_address = ifc.rdReg32(0x414) << 2;
  int k = 0;
  if ((length >= 0x5FFFF) || (length == 0)) { start_capt = 2; return 1; }
  temp = ifc.GetMem(en_jpeg_address + k); k++; length--;
  while (length--) {
    temp_last = temp;
    temp = ifc.GetMem(en_jpeg_address + k); k++;
    if (is_header) { Serial.write(temp); }
    else if ((temp == 0xD8) && (temp_last == 0xFF)) {
      is_header = true; Serial.write(temp_last); Serial.write(temp);
    }
    if ((temp == 0xD9) && (temp_last == 0xFF)) break;
  }
  is_header = false;
  return 0;
}

OV7670_regs.h

#ifndef OV7670_REGS_H
#define OV7670_REGS_H
const uint8_t OV7670_VGA[][2] PROGMEM = {
  {1, 0x42}, {640/16, 480/16},
  {0b01000010, 0b00000100},
  {0x3a, 0x0C}, {0x40, 0xC0}, {0x12, 0x00}, {0x0c, 0x00}, {0x3e, 0x00},
  {0x70, 0x3A}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xF0}, {0xa2, 0x02},
  {0x11, 0x80}, {0x7a, 0x18}, {0x7b, 0x02}, {0x7c, 0x07}, {0x7d, 0x1F},
  {0x7e, 0x49}, {0x7f, 0x5A}, {0x80, 0x6A}, {0x81, 0x79}, {0x82, 0x87},
  {0x83, 0x94}, {0x84, 0x9F}, {0x85, 0xAF}, {0x86, 0xBB}, {0x87, 0xCF},
  {0x88, 0xEE}, {0x89, 0xEE}, {0x13, 0xE0}, {0x00, 0x00}, {0x10, 0x00},
  {0x0d, 0x00}, {0x24, 0x98}, {0x25, 0x63}, {0x26, 0xD3}, {0x2a, 0x00},
  {0x2b, 0x00}, {0x2d, 0x00}, {0x13, 0xe5}, {0x13, 0xe7}, {0x1e, 0x30},
  {0x74, 0x60}, {0x01, 0x80}, {0x02, 0x80}, {0x15, 0x10}, {0x4f, 0x40},
  {0x50, 0x34}, {0x51, 0x0C}, {0x52, 0x17}, {0x53, 0x29}, {0x54, 0x40},
  {0x57, 0x80}, {0x58, 0x1e}, {0x41, 0x10}, {0x75, 0x60}, {0x76, 0x50},
  {0x77, 0x48}, {0x3d, 0x92}, {0x3b, 0x00}, {0x04, 0x00}, {0xff, 0xff}
};
const uint8_t OV7670_QVGA[][2] PROGMEM = {
  {1, 0x42}, {320/16, 240/16},
  {0b01000010, 0b00000100},
  {0x3a, 0x0C}, {0x40, 0xC0}, {0x12, 0x10}, {0x0c, 0x00}, {0x3e, 0x00},
  {0x70, 0x3A}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xF0}, {0xa2, 0x02},
  {0x11, 0x80}, {0x7a, 0x18}, {0x7b, 0x02}, {0x7c, 0x07}, {0x7d, 0x1F},
  {0x7e, 0x49}, {0x7f, 0x5A}, {0x80, 0x6A}, {0x81, 0x79}, {0x82, 0x87},
  {0x83, 0x94}, {0x84, 0x9F}, {0x85, 0xAF}, {0x86, 0xBB}, {0x87, 0xCF},
  {0x88, 0xEE}, {0x89, 0xEE}, {0x13, 0xE0}, {0x00, 0x00}, {0x10, 0x00},
  {0x0d, 0x00}, {0x24, 0x98}, {0x25, 0x63}, {0x26, 0xD3}, {0x2a, 0x00},
  {0x2b, 0x00}, {0x2d, 0x00}, {0x13, 0xe5}, {0x13, 0xe7}, {0x1e, 0x30},
  {0x74, 0x60}, {0x01, 0x80}, {0x02, 0x80}, {0x15, 0x10}, {0x4f, 0x40},
  {0x50, 0x34}, {0x51, 0x0C}, {0x52, 0x17}, {0x53, 0x29}, {0x54, 0x40},
  {0x57, 0x80}, {0x58, 0x1e}, {0x41, 0x10}, {0x75, 0x60}, {0x76, 0x50},
  {0x77, 0x48}, {0x3d, 0x92}, {0x3b, 0x00}, {0x04, 0x00}, {0xff, 0xff}
};
#endif

Android-приложение

На телефоне установите ArduinoTFT.apk. Разрешите доступ к Bluetooth и камере.

Обновление 26.05.2020: Добавлен исходный код ArduinoTFT.apk. Скачайте ArduinoTFT.zip.h, переименуйте в ArduinoTFT.zip и распакуйте.

Обновление 25.07.2020: «Проблема с Android-приложением решилась после разрешения доступа к камере смартфона».

Настройка Bluetooth-модуля

Установите скорость обмена 115200 бод: команда AT+UART=115200,0,0. Это оптимальная скорость для Arduino UNO. Подробнее: instructables.com.

(!) Bluetooth-модуль подключается к отладочному порту Arduino UNO. При работе с Bluetooth отладочный порт недоступен. Перед прошивкой Arduino с установленным Bluetooth-модулем — отключите модуль! После прошивки установите обратно.

Сборка

Arduino Bluetooth Camera (ABC): передача изображений с камеры OV7670 на Android-смартфон по Bluetooth
Arduino Bluetooth Camera (ABC): передача изображений с камеры OV7670 на Android-смартфон по Bluetooth
Arduino Bluetooth Camera (ABC): передача изображений с камеры OV7670 на Android-смартфон по Bluetooth
Arduino Bluetooth Camera (ABC): передача изображений с камеры OV7670 на Android-смартфон по Bluetooth
Arduino Bluetooth Camera (ABC): передача изображений с камеры OV7670 на Android-смартфон по Bluetooth
Arduino Bluetooth Camera (ABC): передача изображений с камеры OV7670 на Android-смартфон по Bluetooth
Arduino Bluetooth Camera (ABC): передача изображений с камеры OV7670 на Android-смартфон по Bluetooth
Arduino Bluetooth Camera (ABC): передача изображений с камеры OV7670 на Android-смартфон по Bluetooth
Arduino Bluetooth Camera (ABC): передача изображений с камеры OV7670 на Android-смартфон по Bluetooth

Сборка проста:

  1. Соедините Arduino UNO и TFT Shield
  2. Подключите камеру OV7670 к 20-пиновому разъёму на Shield (иногда удобен угловой переходник 18-20 пинов, шаг 2.54 мм)
  3. Подключите Bluetooth HC-05/06 к 4-пиновому разъёму с надписью «Bluetooth» на Shield
  4. Подключите блок питания 6–12 В к разъёму питания Arduino UNO

После включения экран TFT Shield должен стать красным — значит, готовность к приёму команд от Android.

Демонстрация

Arduino Bluetooth Camera (ABC): передача изображений с камеры OV7670 на Android-смартфон по Bluetooth
Arduino Bluetooth Camera (ABC): передача изображений с камеры OV7670 на Android-смартфон по Bluetooth
Arduino Bluetooth Camera (ABC): передача изображений с камеры OV7670 на Android-смартфон по Bluetooth
Arduino Bluetooth Camera (ABC): передача изображений с камеры OV7670 на Android-смартфон по Bluetooth
Arduino Bluetooth Camera (ABC): передача изображений с камеры OV7670 на Android-смартфон по Bluetooth
Arduino Bluetooth Camera (ABC): передача изображений с камеры OV7670 на Android-смартфон по Bluetooth

На Android-телефоне:

  1. Запустите приложение ArduinoTFT
  2. Поверните телефон горизонтально
  3. Включите Bluetooth, выберите найденный модуль (HC-06)

На экране появятся два окна и четыре кнопки:

Функции кнопок:

Размер изображения 320×240 пикселей (2–5 КБ). В главе есть демо-видео.

Если статья понравилась — оцените её. Возможно, это мотивирует меня на новые проекты. :-)

Предыдущие статьи:

  1. Unique TFT Shield for Arduino Uno — Start
  2. Unique Arduino TFT Shield — OV7670 Cam

Планы:

  1. TFT Shield для Arduino Nano — Start
  2. Фото и RGB-видео на SPI-дисплее
  3. Управление смартфоном 4WD робота по Bluetooth

Обновление 01.04.2021: Выпущена обновлённая библиотека для линейки экранов (два шилда и две breakout-платы). Скетч компилируется в зависимости от выбранной версии (1–4) и типа МК (MegaAVR или ESP32). Подробнее: github.com/Ekaburg/EkaTFT.

Программный код

Библиотека для TFT Shield

github.com/YATFT/YATFT

3D-модели и крепления

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

  1. Эволюция и дизайн современных камер
  2. Понимание объективов камер: дизайн, история и будущие инновации
  3. BrickPi Bookreader: Автоматизация чтения Kindle на Raspberry Pi и LEGO Mindstorms
  4. Создание Bluetooth-робота на Raspberry Pi с аудио-обратной связью
  5. Bluetooth-контролируемый моторизированный камерный слайдер на Arduino для плавных кинематографических кадров
  6. Управление светодиодом по Bluetooth с Arduino: простой DIY-гид
  7. Голосовое управление бытовыми приборами: Bluetooth-управление через Google Assistant
  8. Переносная система видеонаблюдения: робот с камерой на Raspberry Pi и Arduino
  9. Продвинутая система обнаружения падений: Arduino + Windows IoT + Azure Cloud
  10. Удалённое управление лампой через Arduino Uno, реле и Android-приложение Blynk