цифровая электроника
вычислительная техника
встраиваемые системы

 

Камера на основе Arduino с передачей видео по Bluetooth

Автор: Mike(admin) от 1-07-2019, 05:35

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


Камера на основе Arduino с передачей видео по Bluetooth

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


Это уникальный TFT-щилд для Arduino. В этом уроке мы покажем, как можно подключиться через Bluetooth к Arduino и телефону Android, получить изображение с камеры OV7670 на Arduino UNO и перенести его на телефон Android. Затем, наоборот, перенесем изображение с камеры телефона Android на Arduino UNO и отобразим его на экране специального TFT-экрана.


Помимо Arduino и TFT-щилда основными компонентами данного проекта также являются камера OV7670 и Bluetooth-модуль HC-06 (HC-05).


Камера на основе Arduino с передачей видео по Bluetooth

Все демонстрационные скетчи написаны в среде Arduino IDE, поэтому вначале необходимо установить Arduino IDE – https://www.arduino.cc/en/main/software. Затем необходимо установить библиотеку для TFT-щилда – github.com/YATFT/YATFT. После установки Arduino IDE необходимо запрограммировать плату Arduino UNO. Для простоты рекомендуем прошивать отдельно, без экрана TFT. Код основного файла ArduinoBluetoothCamera.ino следующий:



#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 == true)
       {
           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}, // Reset_Enable_N, 7|6|5|4|3|Vsync Invert|Hsync Invert|0
   {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}, // Reset_Enable_N, 7|6|5|4|3|Vsync Invert|Hsync Invert|0
   {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 (https://cdn.instructables.com/ORIG/FP9/HGMG/JUINB9LK/FP9HGMGJUINB9LK.apk) и разрешить приложению использовать Bluetooth и камеру.


В модуле Bluetooth необходимо установить скорость передачи данных 115200 (команда «AT + UART = 115200, 0, 0»). Это оптимальная скорость, с которой Arduino UNO удается получать и обрабатывать данные. (Теоретически вы можете увеличить скорость, оптимизировать прием и обработку данных, но для этого требуется больший объем оперативной памяти). Обратите внимание, что модуль Bluetooth подключается к порту отладки Arduino UNO. Таким образом, при работе с Bluetooth порт отладки недоступен. А перед программированием Arduino UNO (в комплекте с модулем Bluetooth) необходимо отключить модуль Bluetooth. И после программирования подключите его обратно.


Процесс сборки:


Камера на основе Arduino с передачей видео по Bluetooth

Камера на основе Arduino с передачей видео по Bluetooth

Камера на основе Arduino с передачей видео по Bluetooth

Камера на основе Arduino с передачей видео по Bluetooth

Камера на основе Arduino с передачей видео по Bluetooth

Камера на основе Arduino с передачей видео по Bluetooth

Камера на основе Arduino с передачей видео по Bluetooth

Камера на основе Arduino с передачей видео по Bluetooth

Камера на основе Arduino с передачей видео по Bluetooth

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


Камера на основе Arduino с передачей видео по Bluetooth

Камера на основе Arduino с передачей видео по Bluetooth

Камера на основе Arduino с передачей видео по Bluetooth

Выполните следующие операции на телефоне Android:


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

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


  • В верхнем правом окне находится окно видоискателя камеры телефона
  • Большое левое окно - полученные или отправленные изображения

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


  • Передача одного изображения с телефона Android на Arduino;
  • Непрерывная передача изображений с телефона Android на Arduino;
  • Передача одного изображения из Arduino на телефон Android;
  • Непрерывная передача изображений с Arduino на телефон Android.

Размер изображения составляет 320x240 пикселей (2-5 кБ).


Камера на основе Arduino с передачей видео по Bluetooth



© digitrode.ru


Теги: Arduino, камера



   Благодарим Вас за интерес к информационному проекту digitrode.ru.
   Если Вы хотите, чтобы интересные и полезные материалы выходили чаще, и было меньше рекламы,
   Вы можее поддержать наш проект, пожертвовав любую сумму на его развитие.


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

Комментарии:

Оставить комментарий