Friday 2 September 2016

Arduino Uno and ov7670 camera - a complete working example



You can get the complete description and sources from the link below:


It is in Russian so I had translated some of them here. I keep the original sources because of the links.
You can download the sources and programs here:

The code is based on that used by Computernerd. Refer to his posts in order to explain the ways of connecting and warnings.
 One important warning is to disable internal resistor pullup for 5V Arduino such as Nano and Uno.

 Disable pullup for VC7670
The connections are simple. Start by plugging in SIO_C to A5 and SIO_D to A4 since this is i2c/twi you must have a 4k7 resistor 10k also works. Make sure you have the resistor to pull up 3.3v not 5v. Also edit twi.c  in the arduino ide folder/libraries/Wire/utility search for these lines and comment them out or remove them

// activate internal pullups for twi.
  digitalWrite(SDA, 1);
  digitalWrite(SCL, 1);
At C:\Program Files\Arduino\hardware\arduino\avr\libraries\Wire\src\utility for Arduino V1.6.
This is to remove the internel pullup resistor by not removing these 2 lines you could cause damage to the sensor. Then plug d7 to digital pin 7 d6 to 6 d5 to 5 d4 to 4 d3 to A3 d2 to A2 d1 to A1 and d0 to A0 now plug in VSYNC to digital pin 3 and PCLK to pin 2. Now change the fuse bits to be exactly the same except enable the CLKOUT pin. This will output a clock run this through a buffer or level shifter to 3.3v if you do not get the 5v signal down to 3.3v it could damage the sensor. The sd card and spi ram is just standard spi wiring nothing special.


 
Arduino Uno и камера ov7670 — пример использования
 
В настоящий момент камера ov7670 является самым доступным модулем получения изображения для любителей Arduino. Когда-то она стоила около 49.00 MYR (12$), сейчас же её цена упала до менее 20.41 MYR (5$).
ov7670 (datasheet) имеет хорошие возможности для своей цены:
  • различные разрешение VGA (640 х 480); — QVGA (320 х 240); — CIF (352 х 240); — QCIF (176 × 144);
  • скорость передачи до 30 fps,
  • несколько способов кодирование изображения RAW RGB, RGB 565/555, YUV/YCbCr 4:2:2
  • интерфейс взаимодействия I2C.
Она была бы идеальна если бы не одна проблема — подключение и получение хотя бы тестового изображения, как и в любой мало-мальски сложной железке. В интернете много обсуждений, статей, рекомендаций, но четких шагов найти не получается: кто-то ленится их писать, кто-то выкладывает только схему или код, кто-то вообще ничего не выкладывает, а рапортует только об успешном подключении. Особо хочется отметить ComputerNerd, который выложил прекрасный пример с небольшим описанием, но для начинающего этого мало.
Данная статья призвана показать, как подключить, настроить и получить тестовое изображение с помощью  небольшой программки на java, что станет превосходной отправной точкой для дальнейших экспериментов.
Свои эксперименты я проводил на Arduino Uno, тк она лучше всего была описана — схемы подключения и статьи. Была попытка настроить на Arduino Mega, но закончилась она плачевно. Оказалось, что на ножнах A4 и A5 данная плата имеет уже опорное напряжение в 5v, которое спалило камеру.
В моём примере будет использована камера
  • AtmelStudio + arduino plugin
  • ov7670 без буфера, режим работы qvga (320×240), кодирование YUV
  • Arduino Uno
  • 2 резистора на 10кОм
  • 2 резистора на 4.7кОм
  • компьютер.
1. Схема подключения ov7670 к Arduino Uno
Программирование камеры нужно начать с правильно подключения.  Напряжение входов камеры местами отличается от напряжения Arduino, поэтому нужны резисторы.
Currently ov7670 camera is the affordable image acquisition module for Arduino lovers. Once upon a time it cost about 49.00 MYR ( $ 12), but now its price has fallen to less than 20.41 MYR ( $ 5). ov7670 (datasheet) is well positioned for the price:
different resolution VGA (640 x 480); - QVGA (320 x 240); - CIF (352 x 240); - QCIF (176 × 144);
 transfer rate up to 30 fps,
 several ways RAW RGB image encoding, RGB 565/555, YUV / YCbCr 4: 2: 2
 I2C interface interaction.
It would have been perfect if not for one problem - connecting and receiving at least a test image, as in any more or less complex piece of iron. On the Internet, a lot of discussions, articles, recommendations but clear steps it is impossible to find: someone is too lazy to write them, someone just puts scheme or code, someone puts nothing at all, and only report to his successful connection. I would like to mention Computernerd, who posted a perfect example of a small description, but for a beginner it is not enough.
This article aims to show how to connect, configure and get a test image using a small program on java, it will be an excellent starting point for further experiments.
His experiments I conducted on the Arduino Uno, maybe it is best described - wiring diagrams and articles. There was an attempt to adjust to the Arduino Mega, but it ended in failure. It turned out that on the A4 and A5 scabbard, this board has already a reference voltage to 5v, who was sleeping chamber.
In my example, the camera will be used
    AtmelStudio + arduino plugin
    ov7670 without buffer qvga operation mode (320 × 240), encoding YUV
    Arduino Uno
    2 resistor 10k
    2 resistor 4.7kOm
    a computer.
1. Wiring ov7670 to the Arduino Uno
camera programming should start with the right connections. Voltage inputs places the camera is different from the Arduino voltage, so you need resistors.
 

2. Программа для ov7670 и Arduino Uno
Для составления программы был использован пример от ComputerNerd, который пришлось немного обрезать и доделать местами. Код можно скачать по ссылке.
Основные шаги в коде следующие:
1. Настройка ШИМ Arduino Uno, чтоб она выдавала 8mhz на 11 ножке.
2. The program for the Arduino Uno and ov7670
To compile the program from ComputerNerd example was used, which had a little trim and finish locations. The code can be downloaded here. http://privateblog.info/files/arduino_uno_ov7670.ino
The basic steps in the following code:
1. Configure the PWM Arduino Uno, that she betrayed 8mhz 11 leg.
DDRB |= (1 << 3); //pin 11
ASSR &= ~(_BV(EXCLK) | _BV(AS2));
TCCR2A = (1 << COM2A0) | (1 << WGM21) | (1 << WGM20);
TCCR2B = (1 << WGM22) | (1 << CS20);
OCR2A = 0;//(F_CPU)/(2*(X+1))
DDRC &= ~15; //low d0-d3 camera
DDRD &= ~252; //d7-d4 and interrupt pins
2. Настройка интерфейса I2C
2. Setting the I2C interface
TWSR &= ~3;//disable prescaler for TWI
TWBR = 72;//set to 100khz
3. Настройка RS232.
3. RS232 Setting.
UBRR0H = 0;
UBRR0L = 1;//0 = 2M baud rate. 1 = 1M baud. 3 = 0.5M. 7 = 250k 207 is 9600 baud rate.
UCSR0A |= 2;//double speed aysnc
UCSR0B = (1 << RXEN0) | (1 << TXEN0);//Enable receiver and transmitter
UCSR0C = 6;//async 1 stop bit 8bit char no parity bits
4. Настройка камеры
4. Adjust the camera
….
wrReg(0x12, 0x80);
_delay_ms(100);
wrSensorRegs8_8(ov7670_default_regs);
wrReg(REG_COM10, 32);//PCLK does not toggle on HBLANK.
5. Получение изображения
Режим работы камеры передачи изображения был задан YUV. В этом случае каждый пиксель кодируется двумя байтами. Первый байт кодирует градацию серого, второй — цветоразностная составляющая.
5. Getting images
image transmission mode of the camera was set to YUV. In this case, each pixel is encoded in two bytes. The first byte codes the gradation of gray, the second - color difference component.
 
Задача у нас — получить хотя бы черно-белое изображения, поэтому второй байт можно отбросить.
Далее следует привести осциллограмму из которой станет ясно, каких сигналов мы ожидаем с high и low значением.
The problem with us - to get at least a black and white image, so the second byte can be discarded.
The following is the waveform result of which it will become clear what we expect signals from the high and low value.
 
  1. StringPgm(PSTR("*RDY*"));  
  2.   
  3. //VSYNC  
  4. while (!(PIND & 8));//wait for high  
  5. while ((PIND & 8));//wait for low  
  6.   
  7. y = hg;  
  8. while (y--){  
  9.    x = wg;  
  10.    while (x--){  
  11.       //PCLK  
  12.       while ((PIND & 4));//wait for low  
  13.       UDR0 = (PINC & 15) | (PIND & 240);  
  14.       while (!(UCSR0A & (1 << UDRE0)));//wait for byte to transmit  
  15.       while (!(PIND & 4));//wait for high  
  16.       while ((PIND & 4));//wait for low  
  17.       while (!(PIND & 4));//wait for high  
  18.    }  
  19. }  
  20. _delay_ms(100);  
3. Программа на java для получения изображения с ov7670 через Arduino Uno
Программа для получения изображения предельно простая. Она получает данные с порта COM9, используя Java Communication API и сохраняет в виде bmp. Все переменные заданы прямо в коде, поэтому придётся поменять на ваши.
4. Результаты
3. The program in java to produce an image with ov7670 through Arduino Uno
The program for imaging extremely simple. It receives data from COM9 port using Java Communication API (http://privateblog.info/files/javacomm20-win32.zip) and stores as bmp. All variables are set directly in the code, so you have to change your.
grabber (http://privateblog.info/files/FrameGrabber.7z)
4. results
 
На основе полученных изображений сразу можно сделать вывод о недостатках:
1. Отсутствие внутреннего буфера приводит к смазывание картинки, тк она сразу передается на компьютер, а это занимает время.
2. Наблюдаются артефакты в виде горизонтальных полосок — сбой синхронизации в получении картинки. Вместо градации серого отправляется цветоразностная составляющая.
3. Объект должен быть в фокусе камеры для четкого изображения
На этом статью можно закончить. Жду замечаний и предложений.

Based on the images at once, you can draw a conclusion about the shortcomings:
1. Lack of internal buffer leads to blurring the picture, maybe, it is immediately transmitted to a computer, and it takes time.
2. artifacts are observed in the form of horizontal stripes - a failure of synchronization in obtaining images. Instead grayscale color difference component is sent.
3. The object is to be the focus of the camera for clear images
This article can be completed. I look forward to comments and suggestions.

No comments:

Post a Comment