Рубрики
Схемы на Arduino

Подключение камеры OV7670 к Arduino Uno

Видеокамеры (камеры) в настоящее время находят широкое применение в электронной промышленности и имеют множество применений, таких как система мониторинга посетителей, система наблюдения, система учета посещаемости и т.д. Камеры, которые мы используем сегодня, умны и имеют множество функций, которых не было в предыдущих моделях камер. Современные цифровые камеры не только захватывают изображения, но также захватывают и высокоуровневые описания изображений и анализируют то, что они видят. Они широко используются в робототехнике, искусственном интеллекте, машинном обучении и т. д. Захваченные кадры обрабатываются с помощью искусственного интеллекта и машинного обучения, а затем используются во многих приложениях, таких как обнаружение номерных знаков, обнаружение объектов, обнаружение движения, распознавание лиц и т. д.

В этой статье мы рассмотрим подключение наиболее часто используемого сейчас модуля камеры OV7670 к плате Arduino Uno. Аналогичным образом ее можно подключить и к плате Arduino Mega. Модуль камеры достаточно тяжел в подключении поскольку он имеет большое количество контактов. Также при использовании камеры достаточно важен выбор проводов, которыми вы ее подключаете, поскольку качество проводов может значительно влиять на качество картинки и уровень зашумленности видеоизображения.

Камера OV7670 работает от напряжения 3.3V, поэтому следует избегать прямого ее подключения к обычным контактам ввода/вывода Arduino, которые работают с напряжением 5V. OV7670 является камерой с буфером FIFO (first in, first out – первым пришел, первым вышел). Но в этом проекте мы будем захватывать изображения без использования данного буфера. Мы постарались максимально упростить данный проект чтобы его можно было повторить даже начинающим радиолюбителям.

Необходимые компоненты

Аппаратное обеспечение

  1. Плата Arduino Uno (купить на AliExpress).
  2. Модуль камеры (Camera Module) OV7670 (купить на AliExpress).
  3. Резистор 10 кОм – 2 шт. (купить на AliExpress).
  4. Резистор 4,7 кОм – 2 шт. (купить на AliExpress).
  5. Соединительные провода.

Программное обеспечение

Arduino IDE
Serial Port Reader (для анализа выходного изображения)

Некоторые особенности модуля камеры OV7670

OV7670 представляет собой модуль камеры с буфером типа FIFO. В настоящее время он производится несколькими фирмами и доступен с различной распиновкой. OV7670 обеспечивает полномасштабное (full frame) 8 битовое изображение в окне. OV7670 умеет работать с различными форматами видео изображения. В VGA разрешении камера обеспечивает до 30 кадров в секунду.

Модуль камеры OV7670 включает:

  • массив датчиков изображений (разрешения примерно 656 x 488 пикселов);
  • тактовый генератор;
  • процессор обработки сигналов;
  • аналого-цифровые преобразователи;
  • генератор тестовых шаблонов;
  • цифровой сигнальный процессор;
  • устройство для масштабирования изображений;
  • цифровой видео порт;
  • светодиод и выход управления стробоскопической вспышкой.

Датчик изображения камеры OV7670 управляется с помощью шины SCCB (Serial Camera Control Bus — последовательная шина управления камерой) по протоколу I2C (контакты SIOC, SIOD) с максимальной частотой синхронизации 400 кГц.

Внешний вид модуля камеры OV7670 показан на следующих рисунках.

OV7670 модуль VGA камеры

Модуль камеры OV7670 (со снятой линзой)

Модуль камеры OV7670 (нижняя сторона платы)

Камера использует следующие квитирующие (подтверждающие) сигналы:

  • VSYNC: Vertical Sync Output (выход вертикальной синхронизации (для строк) – низкий уровень во время кадра;
  • HREF: Horizontal Reference (горизонтальная синхронизация (для колонок) – высокий уровень во время активных пикселов ряда (строки);
  • PCLK: Pixel Clock Output (пиксельная синхронизация (тактовый сигнал передачи байта из параллельного порта D0–D7) – независимый генератор синхронизирующих импульсов. Данные правильны на нарастающем фронте.

В дополнение к этому камера оперирует еще следующими сигналами:

  • D0-D7: параллельный цифровой 8-битный видеовыход в формате YUV/RGB;
  • PWDN: Power Down Mode Selection — включение (лог. 0) и выключение (лог. 1) камеры;
  • XCLK: внешнее тактирование (синхронизация);
  • Reset: сигнал сброса.

Камера OV7670 синхронизируется с помощью генератора на 24 МГц. Это обеспечивает выход пиксельной синхронизации (PCLK) 24 МГц. Буфер типа FIFO имеет память на 3 Мбит. Генератор тестовых шаблонов формирует шаблон цветовых полос – с 8 полосами, с постепенным уменьшением к серому цвету (fade-to-gray).

Схема проекта

Схема подключения модуля камеры OV7670 к плате Arduino Uno представлена на следующем рисунке.

Внешний вид получившейся у нас конструкции проекта показан на следующем рисунке.

Объяснение программы для Arduino

Полный текст программы приведен в конце в статьи, здесь же мы рассмотрим его наиболее важные фрагменты.

Для работы с камерой OV7670 нам понадобится встроенная в Arduino IDE библиотека. Никаких внешних библиотек, которые необходимо скачивать, мы в этом проекте использовать не будем, только встроенные библиотеки.

После подключения в программе необходимых библиотек нам необходимо сконфигурировать регистры для работы с камерой OV7670.

Функция Setup() в нашем проекте будет включать все необходимые установки, необходимые для захвата изображений. Первой функцией, которую мы применим, будет arduinoUnoInut() – она используется для инициализации платы Arduino Uno. Она отключает все глобальные прерывания и устанавливает настройки для интерфейсов связи, такие как синхронизацию для ШИМ (широтно-импульсная модуляция), выбор контактов прерывания, настройки предделителя, добавление бита четности и стоповых битов.

После конфигурирования платы Arduino необходимо сконфигурировать камеру. Для инициализации камеры нам необходимо всего лишь изменить значения регистров (с тех, которые в них по умолчанию). Также необходимо добавить задержку, зависящую от того, какую частоту микроконтроллера мы используем. Чем медленнее микроконтроллер, тем большая задержка необходима между захватом кадров.

Мы в нашем проекте будем использовать формат видеоизображения QVGA (320 × 240), поэтому нам необходимо установить необходимое разрешение для камеры. Это можно сделать с помощью следующей команды:

В этом проекте мы будем работать с монохромными изображениями, поэтому в регистрах необходимо установить соответствующие значения с помощью команды:

С помощью следующей функции мы также будем записывать необходимое шестнадцатеричное значение в регистр. Если после этого вы будете получать зашифрованные изображения, то можете попробовать изменить второй параметр в представленной команде с 10 на 9/11/12. Но в большинстве случаев параметр 10 работает превосходно, поэтому у вас не будет необходимости изменять его.

Следующая используемая нами функция предназначена для получения разрешения изображения – в этом проекте мы будем использовать разрешение 320 x 240 пикселов.

Также в программе присутствуют функции для конфигурирования протокола I2C для получения данных с камеры. Они включают инициализацию связи по данному протоколу (Read), установку адреса, передачу и считывание данных. Более подробно про это можно прочитать в статье про использование интерфейса I2C в Arduino.

Загрузите представленный в конце статьи код программы в плату Arduino, затем откройте программу Serial Port Reader и после этого вы сможете захватывать кадры.

Как использовать Serial Port Reader для считывания изображений

Программа Serial Port Reader имеет интуитивно понятный интерфейс пользователя и ее можно скачать по следующей ссылке. Она захватывает изображения в формате base64 и затем декодирует их чтобы сформировать изображение на экране. Для работы с данной программой выполните следующую последовательность шагов.

Шаг 1. Подсоедините вашу плату Arduino к одному из USB портов вашего компьютера.

Шаг 2. Нажмите на “Check” чтобы найти COM порт, к которому подключена плата Arduino.

Шаг 3. Нажмите на кнопку “Start” чтобы начать считывать изображения последовательно.

Шаг 4. Можно сохранить необходимое изображение, нажав на кнопку “Save Picture”.

Далее приведены примеры изображений, полученные с помощью камеры OV7670.

Меры предосторожности при работе с камерой OV7670

  1. Старайтесь для соединения с камерой использовать как можно более короткие провода.
  2. Избегайте “неплотных” соединений на всех контактах Arduino и OV7670.
  3. Поскольку в данном случае вы используете достаточно много соединений остерегайтесь короткого замыкания.
  4. Если плата Arduino UNO формирует напряжение 5V на своих портах ввода-вывода, то используйте понижение уровня этого напряжения.
  5. Используйте для OV7670 входное напряжение 3.3V поскольку более высокое напряжение может повредить модуль камеры.

Представленная статья является лишь примером работы платы Arduino с модулем камеры. Поскольку плата Arduino имеет достаточно мало памяти, то работа с изображениями камеры может быть не такой “идеальной”, на какую вы рассчитывали. Для улучшения изображений с модуля камеры в этом случае рекомендуется использовать более мощные микроконтроллеры с большим объемом памяти.

Исходный код программы (скетча)

Комментарии к тексту программу оставил в оригинале (на английском языке), но если потребуется (статья вызовет интерес), могу перевести их для вас.

Видео, демонстрирующее работу проекта

40 ответов к “Подключение камеры OV7670 к Arduino Uno”

У меня есть проблема, порт подключён, всё нормально, ошибок нет, но изображение не выводится, при повторной попытке говорит что закрыт порт, сохранял, а сохранялся чёрный квадрат, помогите пожалуйста!

Попробуйте посмотреть в диспетчере устройств Windows нормально ли у вас опознается плата Ардуино при этих обоих попытках

Только после того как ты смотришь на 500-строчный код ты наконец-то начинаешь понимать, насколько мало ты знаешь, и сколько проэктов тебе ещё надо будет построить перед тем как написать этот. =)

Да, это точно.)) На мой взгляд плата Arduino Uno не самый удачный вариант для подключения к ней камеры. Лучше тогда посмотреть более старшие и более производительные модели плат Arduino, но лично мне для простых проектов с камерой больше всего нравится модуль ESP32-CAM — стоит дешево и идет в коробке уже с камерой, а функционал обеспечивает приличный

Добрый день.
Насколько будет отличаться реализация подобного проекта на ESP8266?
У меня есть Wemos D1 в форм-факторе UNO, и захотелось сделать свою WI-FI камеру.

Добрый вечер. К сожалению, не знаю. Но если вы хотите делать компактные проекты с камерой, то я бы советовал использовать для этого модуль ESP32-CAM, он значительно упрощает использование камеры.

Я пытаюсь написать собственный «Serial Port Reader» для отображения изображения и не могу понять как мне конвертировать полученные байты в yuv пиксели.
UDR0 = (PINC & 15) | (PIND & 240);
Если я правильно понимаю, то это мы в аутпут посылаем первые 4 бита из пина С объединенные последними 4 битами пина Д.
И каждый такой байт содержит в себе один пиксель yuv422 закодированный по схеме YVYU. Но как мне раскодировать этот байт обратно на составляющие y, u & v? Может быть вы знаете?

Нет, к сожалению здесь я не могу вам помочь, не разбирался в этих вопросах

Serial Port Reader выдает, что com порт 7, где подключена ардуина уно с камерой закрыт.
Сначала я компилирую и выгружаю на плату код, затем запускаю Serial Port Reader и выдает такое.
Если сначала запустить Serial Port Reader и подключиться с порту 7, то ардуино не сможет выгрузить скетч в память. В общем картинка не отображается.

А через диспетчер устройств вы проверяли точно ли ваша плата Ардуино подключена к порту 7? Тут возможен какой то конфликт между вашей операционной системой и программой Serial Port Reader. Попробуйте загрузиться с другой операционной системой (если у вас есть такая возможность) или запустить все это на другом компьютере

Так сходу сложно сразу подсказать в чем может быть проблема. Пробовали что либо сменить из аппаратного обеспечения проекта: камеру, плату или компьютер? У данной статьи уже очень много просмотров и никто больше не пожаловался на такую проблему, поэтому маловероятно что проблема заключается в коде программы для платы Ардуино

while ((reg_addr != 0xff) | (reg_val != 0xff)){
reg_addr = pgm_read_byte(&next->reg_num);
reg_val = pgm_read_byte(&next->value);
writeReg(reg_addr, reg_val);
next++;
плохо работает так как конец массива отправится тоже — проверка идет после отправки

Иногда, как говорится, лучшее — враг хорошего. Возможно, данный фрагмент кода работает не оптимально, но все же работает. Если можете, предложите как его усовершенствовать, был бы признателен

камера дебильная как сделать фотоаппарат так admin-new дайте ссылку там где будет фотоаппарат из ардуино

Вычислительная мощность платы Arduino слишком мала для того чтобы к ней можно было подключить камеру с хорошим разрешением. Для этого используйте платы помощнее, например, Raspberry Pi или ESP32

А в диспетчере устройств что показано по поводу данного порта? У вас плата Ардуино подключена к COM2 или какому либо другому порту?

В диспетчере устройств есть этот порт, компьютер его видит и никаких проблем нет. Сама плата Ардуино подключена к порту COM2. Уже практически всё перепробовал: менял настройки порта в диспетчере устройств, перезагружал программу/компьютер, подключал во все порты USB на компьютере, менял компьютер, но проблема не ушла.
Проблема заключается ещё в том, что при загрузке и компиляции самой программы никаких проблем нет, но при работе SerialPortReader происходит странное: после выбора порта нажимаю на кнопку «Start», запускается работа программы и в статусе программы указывается «COM2 port opened», но ничего не происходит (пытался сохранять изображение, но сохранялся «Квадрат Малевича»). Если нажать «Stop», а потом опять запустить программу, то в статусе работы программы пишет «Opening COM2 port» и выдаёт ошибку, где пишет:

Подробная информация об использовании оперативной
(JIT) отладки вместо данного диалогового
окна содержится в конце этого сообщения.

************** Текст исключения **************
System.UnauthorizedAccessException: Доступ к порту ‘COM4’ закрыт.
в System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
в System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout, Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean rtsEnable, Boolean discardNull, Byte parityReplace)
в System.IO.Ports.SerialPort.Open()
в ReadSerialPortWin.frmPrinc.btnStart_Click(Object sender, EventArgs e)
в System.Windows.Forms.Control.OnClick(EventArgs e)
в System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
в System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
в System.Windows.Forms.Control.WndProc(Message& m)
в System.Windows.Forms.ButtonBase.WndProc(Message& m)
в System.Windows.Forms.Button.WndProc(Message& m)
в System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
в System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

************** Загруженные сборки **************
mscorlib
Версия сборки: 2.0.0.0
Версия Win32: 2.0.50727.9151 (WinRelRS6.050727-9100)
CodeBase: file:///C:/Windows/Microsoft.NET/Framework64/v2.0.50727/mscorlib.dll
—————————————-
ReadSerialPortWin
Версия сборки: 1.0.0.0
Версия Win32: 1.0.0.0
CodeBase: file:///C:/Users/Илья/OneDrive/Desktop/SerialPortReader.exe
—————————————-
System.Windows.Forms
Версия сборки: 2.0.0.0
Версия Win32: 2.0.50727.9149 (WinRelRS6.050727-9100)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Windows.Forms/2.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
—————————————-
System
Версия сборки: 2.0.0.0
Версия Win32: 2.0.50727.9149 (WinRelRS6.050727-9100)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System/2.0.0.0__b77a5c561934e089/System.dll
—————————————-
System.Drawing
Версия сборки: 2.0.0.0
Версия Win32: 2.0.50727.9149 (WinRelRS6.050727-9100)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Drawing/2.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
—————————————-
System.resources
Версия сборки: 2.0.0.0
Версия Win32: 2.0.50727.9149 (WinRelRS6.050727-9100)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.resources/2.0.0.0_ru_b77a5c561934e089/System.resources.dll
—————————————-
System.Windows.Forms.resources
Версия сборки: 2.0.0.0
Версия Win32: 2.0.50727.9149 (WinRelRS6.050727-9100)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Windows.Forms.resources/2.0.0.0_ru_b77a5c561934e089/System.Windows.Forms.resources.dll
—————————————-
mscorlib.resources
Версия сборки: 2.0.0.0
Версия Win32: 2.0.50727.9151 (WinRelRS6.050727-9100)
CodeBase: file:///C:/Windows/Microsoft.NET/Framework64/v2.0.50727/mscorlib.dll
—————————————-
System.Xml
Версия сборки: 2.0.0.0
Версия Win32: 2.0.50727.9149 (WinRelRS6.050727-9100)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Xml/2.0.0.0__b77a5c561934e089/System.Xml.dll
—————————————-

************** Оперативная отладка (JIT) **************
Для подключения оперативной (JIT) отладки файл .config данного
приложения или компьютера (machine.config) должен иметь
значение jitDebugging, установленное в секции system.windows.forms.
Приложение также должно быть скомпилировано с включенной
отладкой.

Например:

При включенной отладке JIT любое необрабатываемое исключение
пересылается отладчику JIT, зарегистрированному на данном компьютере,
вместо того чтобы обрабатываться данным диалоговым окном.

Не могу понять из-за чего эта ошибка. Вы сталкивались с подобными проблемами?

Нет, я не сталкивался. У вас в сообщениях выдается ошибка что «Доступ к порту ‘COM4’ закрыт». Вы не путаете случайно COM4 и COM2? Вместо SerialPortReader можно попробовать использовать какое-нибудь аналогичное программное обеспечение. Также рекомендую хотя бы через окно монитора последовательной связи посмотреть что у вас передается в порт.
Еще в сети есть аналогичные проекты подключения камеры OV7670 к плате Arduino Uno с выводом видео на экран TFT дисплея. Если есть такой дисплей, то можете попробовать. У них начало программы точно такое же, как в моей статье, но способ вывода этой информации только отличается. Поскольку такие проекты есть в сети, то я не стал дублировать аналогичный проект для моего сайта

У меня такая же проблема. Если найдете решение, скажите пожалуйста.

D:\Arduino\sketch_jan30a\sketch_jan30a.ino:7:0: warning: «F_CPU» redefined
#define F_CPU 16000000UL

:0:0: note: this is the location of the previous definition
подскажите что значит?

У вас почему то переопределяется частота работы микроконтроллера (F_CPU). Из-за чего это происходит сложно сказать не видя ваш проект

Скачать программу Serial Port Reader, ссылка на ее скачивание есть в статье

У меня запустилось после того, как убрал вывод XCLK на землю, иначе ничего не передаёт (TX не моргает), возможно кто-то столкнётся с подобным.

Да, спасибо что отписались о способе решения вашей проблемы. К сожалению, в подобных проектах возможно достаточно много нюансов, которые один автор (конструктор) просто физически не способен рассмотреть — в подобных случаях очень полезна помощь «коллективного» разума

А одну строку пикселей можно прочитать не перебирая весь массив пикселей?

Честно говоря, затрудняюсь с ответом. Мои студенты давно собирали этот проект, но сейчас он разобран, камеру унесли, не могу протестировать его.

Извините, вы про что? Где должно быть 4 контакта?

Если я не ошибаюсь, не каждый модуль содержит буфер FIFO. Так, обычная OV7670 стоит 100 рублей, а с FIFO — 600 рублей. Например, вот по этой ссылке есть оба варианта для сравнения aliexpress.ru/item/1005001593947384.html

Да, вы правы. Без буфера эта камера действительно стоит всего 100-150 рублей — очень дешевый вариант, на мой взгляд, чтобы получить первый опыт по подключению камеры к микроконтроллеру

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *