Arducam library!

Hey spark community!

I’m trying to get an OV7670 camera interfaced with the core but the library has some AVR specifics that’s beyond my porting.

http://www.arducam.com/downloads/ArduCAM_v3.3.1.zip

Thanks for the help in advance! :smiley:

2 Likes

@kennethlimcp, I take a shot at porting for the OV7670 specifically. If you cut through the AVR/ARM stuff you will see that it just uses SPI and I2C. What I have not figured out is the LCD interface, for now. :smile:

2 Likes

I’m exploring this camera too, but I bought one with the AL422 FIFO memory that makes reading the image easier.

1 Like

@peekay123 thanks! I’ll just need the camera code for now :wink:

@kennethlimcp, I have the library ported but I get errors when I try and compile the 7670 playback example. Stay tuned.

1 Like

Awesome I just wired up everything (too many pins!) but one problem is the required CLK signal to be supplied to the camera…

The camera should only take SPI and I2C lines I believe. Also, the example I ported uses an SD card to store an image. I was written to play back to a display but that is another story. The last thing I need to fix is a call to itoa() which, for some reason, is not working.

@kennethlimcp, the library is available here. You will need to add the SD library files to compile as it stores the image to SD. The port is untested but was straight forward. HAVE FUN! :stuck_out_tongue:

2 Likes

Thanks man I’ll try it out! Seems like it might not be so straightforward as the Ardushield has more stuff and takes care of the D0-D7 pixel bits data and your mcu won’t need to read that in.

Will see how it goes thanks @peekay123!

1 Like

@kennethlimcp, which cam module do you have?

I bought the really basic OV7670 camera module that doesn’t come with the FIFO buffer IC as well.

The datasheet is here: http://www.voti.nl/docs/OV7670.pdf

One article that i’m basing it off: http://www.rpg.fi/desaster/blog/2012/05/07/ov7670-camera-sensor-success/


@peekay123, i’m using a customized way to generate a 10Mhz CLK for the OV7670 so my question is, is there a way for me to read the raw pin status? (using PWM on A7)

The code needs to read in the bits from the parallel interface following the clock for synchronisation.

This definitely sounds hacky for now but i’m trying to see how far i can push to and retrieve a success image without adding an FIFO or extra mcu :wink:

@kennethlimcp, you really enjoy punishment don’t you :stuck_out_tongue: Here is a link for arduino code that reads the sensor data and dumps it to a PC. The clock is generated by the code and it samples an entire frame. With careful pin/port selection, the Core could capture just as fast I think. I also sounds like the I2C may need some tweaking to work. :smile:

I managed to get I2C working already but haven’t measured the frequency of the CLK signal that i’m clocking it with. :wink: (measure tomorrow in the lab…1am now)

Working with some cost constraints (not set by me of course) and yeah thanks for the code! Been checking out another repo as well and it’s not that difficult actually.

One interesting thing to use might be a parallel in serial out for the 8 bit data but let’s see how far i can push this! :smiley:

Thanks for the help man. Hope to get this working on the Spark platform so that cameras no longer cost us too much for our projects!

@kennethlimcp, the only problem with a parallel in/serial out approach is that the sampling clock will need to be 8x faster (and synchronized) than the clock going to the camera since it presents the entire 8 bits at once. You are better off sampling those bits directly. Cool project to play with dude!

2 Likes

@peekay123 is there a fast read command for the pins that i can use?

it would be much faster if all the pins are from one PORT and i can wire correctly to fast read the port value but sadly that’s not going to happen :wink:

@kennethlimcp, by referring to the IDR register, you can read a whole port:

uint32_t portval = PIN_MAP[_pin].gpio_peripheral->IDR;  //I think they are 32bit registers!!?

Unfortunately, the pins are not all on one port so you will have to do a couple of port reads then mask, shift and combine to get the 8 bit value.

This is what @ScruffR did to speed up the port writes in the RGBMatrixPanel code even more than I did. :smile:

3 Likes

@peekay123 is right, these are accessed as 32bit register, but each GPIO port only sports 16 pins/bits

Some interesting read about this states:

GPIO port input data register (GPIOx _IDR)

This is a 16-bit read-only register. Each bit represents the input value on a corresponding pin. Reading a ‘0’ in bit 8 of this GPIOC _IDR register indicates that the voltage on PC8 is 0V (GND). While reading a ‘1’ in bit 8 of this GPIOC _IDR register indicates that the voltage on PC8 is 3.3V (VDD)

If you are free to move about the needed pins to all fit on one port, you might get around some mask-shift-or business. The best candidates to get eight consecutive bits/pins on the Core for this would be A0,A1,TX,RX,A2,A3,A4,A5 on GPIOA. If you need SPI and serial ports in parallel you could go for SoftSPI and Serial2. (Edit: had TX/RX swapped)

3 Likes

@ScruffR,

I’m guessing an uint16_t is sufficient?

uint32_t portval = PIN_MAP[_pin].gpio_peripheral->IDR;

Wow things are getting a little messy but i wired them in sequence using A0-A6 then D2 but still a little bit shuffling over there :wink:

Digging digging: https://github.com/spark/core-common-lib/blob/9e611a4e58ad82921a9f6e966f887b8d4cb25b17/STM32F10x_StdPeriph_Driver/src/stm32f10x_gpio.c#L283

Things are getting fun using a Serial baud rate of 921600 and reading GPIOA using

#define portInputRegister(_port)  (_port->IDR)

portInputRegister(GPIOA);
1 Like

@kennethlimcp is there a particular reason why you went for A0…A6 + D2 and not my suggested set of pins including RX/TX?
These two are just “normal” pins as any other GPIO pins on the Core, they just happen to be labled differently.

@ScruffR, no other reason other than me having the soldering done before i hear your input :stuck_out_tongue:

I’ll change the wiring to make it simpler for testing purposes later! Thanks man :wink:

Also need to figure out how to set those pins as INPUT but should be just one line of code :smiley:


@ScruffR, i’m done re-wiring and assuming the lowest bit goes to A0 and so on?