OV2640 will not work at all...SPI Interface Error (sometimes)
I have tried using both an Arduino Mega and an Arduino UNO to interface the Arducam (OV2640) and both have proven to not work. The farthest I got was with the Mega. I would open the Host application with everything configured and pinned properly and it would say "COM is open!" then "OV2640 detected" then "SPI Interface Error......".
Currently all I can get is "COM is open!" and that's it. I have tried contacting support but they have since stopped responding to my emails for some reason; Tried a completely different OV2640 unit; Tried interfacing with the Arduino UNO R3. All avenues of troubleshooting seem to not be yielding any results. I NEED HELP!!!
My pin configuration with the Mega2560 is as follows:
CS -> Communication pin10 MOSI -> ICSP pin4 MISO -> ICSP pin1 SCK -> ICSP pin3 GND -> GND VCC -> 5V SDA -> A5 SCL -> A4
A little background on what im doing is I need to take a picture using the camera. I then need to take the RGB values of each individual picture and create some conditional logic with it. Im running out of time and Im truly baffled as to why this has been so hard to setup as everybody else seems to be having such an easy time using the ArduCam.
After running this code (it fails) I am able to run the Host application and get to this:
COM is open! ArduCAM Start!
SPI Interface Error! SPI Interface Error! SPI Interface Error! .................... ....................
Code I ran:
// ArduCAM Mini demo (C)2017 Lee // Web: http://www.ArduCAM.com // This program is a demo of how to use most of the functions // of the library with ArduCAM Mini camera, and can run on any Arduino platform. // This demo was made for ArduCAM_Mini_5MP_Plus. // It needs to be used in combination with PC software. // It can take photo continuously as video streaming. // // The demo sketch will do the following tasks: // 1. Set the camera to JPEG output mode. // 2. Read data from Serial port and deal with it // 3. If receive 0x00-0x08,the resolution will be changed. // 4. If receive 0x10,camera will capture a JPEG photo and buffer the image to FIFO.Then write datas to Serial port. // 5. If receive 0x20,camera will capture JPEG photo and write datas continuously.Stop when receive 0x21. // 6. If receive 0x30,camera will capture a BMP photo and buffer the image to FIFO.Then write datas to Serial port. // 7. If receive 0x11 ,set camera to JPEG output mode. // 8. If receive 0x31 ,set camera to BMP output mode. // This program requires the ArduCAM V4.0.0 (or later) library and ArduCAM_Mini_5MP_Plus // and use Arduino IDE 1.6.8 compiler or above #include <Wire.h> #include <ArduCAM.h> #include <SPI.h> #include "memorysaver.h" //This demo can only work on OV2640_MINI_2MP or OV5642_MINI_5MP or OV5642_MINI_5MP_BIT_ROTATION_FIXED platform. #if !(defined OV5642_MINI_5MP || defined OV5642_MINI_5MP_BIT_ROTATION_FIXED || defined OV2640_MINI_2MP) #error Please select the hardware platform and camera module in the ../libraries/ArduCAM/memorysaver.h file #endif #define BMPIMAGEOFFSET 66 const char bmp_header[BMPIMAGEOFFSET] PROGMEM = { 0x42, 0x4D, 0x36, 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x58, 0x02, 0x00, 0xC4, 0x0E, 0x00, 0x00, 0xC4, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00 }; // set pin 7 as the slave select for the digital pot: const int CS = 7; bool is_header = false; int mode = 0; uint8_t start_capture = 0; #if defined (OV2640_MINI_2MP) ArduCAM myCAM( OV2640, CS ); #else ArduCAM myCAM( OV5642, CS ); #endif uint8_t read_fifo_burst(ArduCAM myCAM); void setup() { // put your setup code here, to run once: uint8_t vid, pid; uint8_t temp; #if defined(SAM3X8E) Wire1.begin(); Serial.begin(115200); #else Wire.begin(); Serial.begin(921600); #endif Serial.println(F("ACK CMD ArduCAM Start!")); // set the CS as an output: pinMode(CS, OUTPUT); // initialize SPI: SPI.begin(); while(1){ //Check if the ArduCAM SPI bus is OK myCAM.write_reg(ARDUCHIP_TEST1, 0x55); temp = myCAM.read_reg(ARDUCHIP_TEST1); if (temp != 0x55){ Serial.println(F("ACK CMD SPI interface Error!")); delay(1000);continue; }else{ Serial.println(F("ACK CMD SPI interface OK."));break; } }
#if defined (OV2640_MINI_2MP)
while(1){
//Check if the camera module type is OV2640
myCAM.wrSensorReg8_8(0xff, 0x01);
myCAM.rdSensorReg8_8(OV2640_CHIPID_HIGH, &vid);
myCAM.rdSensorReg8_8(OV2640_CHIPID_LOW, &pid);
if ((vid != 0x26 ) && (( pid != 0x41 ) || ( pid != 0x42 ))){
Serial.println(F("ACK CMD Can't find OV2640 module!"));
delay(1000);continue;
}
else{
Serial.println(F("ACK CMD OV2640 detected."));break;
}
}
#else
while(1){
//Check if the camera module type is OV5642
myCAM.wrSensorReg16_8(0xff, 0x01);
myCAM.rdSensorReg16_8(OV5642_CHIPID_HIGH, &vid);
myCAM.rdSensorReg16_8(OV5642_CHIPID_LOW, &pid);
if((vid != 0x56) || (pid != 0x42)){
Serial.println(F("ACK CMD Can't find OV5642 module!"));
delay(1000);continue;
}
else{
Serial.println(F("ACK CMD OV5642 detected."));break;
}
}
#endif
//Change to JPEG capture mode and initialize the OV5642 module
myCAM.set_format(JPEG);
myCAM.InitCAM();
#if defined (OV2640_MINI_2MP)
myCAM.OV2640_set_JPEG_size(OV2640_320x240);
#else
myCAM.write_reg(ARDUCHIP_TIM, VSYNC_LEVEL_MASK); //VSYNC is active HIGH
myCAM.OV5642_set_JPEG_size(OV5642_320x240);
#endif
delay(1000);
myCAM.clear_fifo_flag();
#if !(defined (OV2640_MINI_2MP))
myCAM.write_reg(ARDUCHIP_FRAMES,0x00);
#endif
}
void loop() {
// put your main code here, to run repeatedly:
uint8_t temp = 0xff, temp_last = 0;
bool is_header = false;
if (Serial.available())
{
temp = Serial.read();
switch (temp)
{
case 0:
#if defined (OV2640_MINI_2MP)
myCAM.OV2640_set_JPEG_size(OV2640_160x120);delay(1000);
Serial.println(F("ACK CMD switch to OV2640_160x120"));
#else
myCAM.OV5642_set_JPEG_size(OV5642_320x240);delay(1000);
Serial.println(F("ACK CMD switch to OV5642_320x240"));
#endif
temp = 0xff;
break;
case 1:
#if defined (OV2640_MINI_2MP)
myCAM.OV2640_set_JPEG_size(OV2640_176x144);delay(1000);
Serial.println(F("ACK CMD switch to OV2640_176x144"));
#else
myCAM.OV5642_set_JPEG_size(OV5642_640x480);delay(1000);
Serial.println(F("ACK CMD switch to OV5642_640x480"));
#endif
temp = 0xff;
break;
case 2:
#if defined (OV2640_MINI_2MP)
myCAM.OV2640_set_JPEG_size(OV2640_320x240);delay(1000);
Serial.println(F("ACK CMD switch to OV2640_320x240"));
#else
myCAM.OV5642_set_JPEG_size(OV5642_1024x768);delay(1000);
Serial.println(F("ACK CMD switch to OV5642_1024x768"));
#endif
temp = 0xff;
break;
case 3:
temp = 0xff;
#if defined (OV2640_MINI_2MP)
myCAM.OV2640_set_JPEG_size(OV2640_352x288);delay(1000);
Serial.println(F("ACK CMD switch to OV2640_352x288"));
#else
myCAM.OV5642_set_JPEG_size(OV5642_1280x960);delay(1000);
Serial.println(F("ACK CMD switch to OV5642_1280x960"));
#endif
break;
case 4:
temp = 0xff;
#if defined (OV2640_MINI_2MP)
myCAM.OV2640_set_JPEG_size(OV2640_640x480);delay(1000);
Serial.println(F("ACK CMD switch to OV2640_640x480"));
#else
myCAM.OV5642_set_JPEG_size(OV5642_1600x1200);delay(1000);
Serial.println(F("ACK CMD switch to OV5642_1600x1200"));
#endif
break;
case 5:
temp = 0xff;
#if defined (OV2640_MINI_2MP)
myCAM.OV2640_set_JPEG_size(OV2640_800x600);delay(1000);
Serial.println(F("ACK CMD switch to OV2640_800x600"));
#else
myCAM.OV5642_set_JPEG_size(OV5642_2048x1536);delay(1000);
Serial.println(F("ACK CMD switch to OV5642_2048x1536"));
#endif
break;
case 6:
temp = 0xff;
#if defined (OV2640_MINI_2MP)
myCAM.OV2640_set_JPEG_size(OV2640_1024x768);delay(1000);
Serial.println(F("ACK CMD switch to OV2640_1024x768"));
#else
myCAM.OV5642_set_JPEG_size(OV5642_2592x1944);delay(1000);
Serial.println(F("ACK CMD switch to OV5642_2592x1944"));
#endif
break;
#if defined (OV2640_MINI_2MP)
case 7:
temp = 0xff;
myCAM.OV2640_set_JPEG_size(OV2640_1280x1024);delay(1000);
Serial.println(F("ACK CMD switch to OV2640_1280x1024"));
break;
case 8:
temp = 0xff;
myCAM.OV2640_set_JPEG_size(OV2640_1600x1200);delay(1000);
Serial.println(F("ACK CMD switch to OV2640_1600x1200"));
break;
#endif
case 0x10:
mode = 1;
temp = 0xff;
start_capture = 1;
Serial.println(F("ACK CMD CAM start single shoot."));
break;
case 0x11:
temp = 0xff;
myCAM.set_format(JPEG);
myCAM.InitCAM();
#if !(defined (OV2640_MINI_2MP))
myCAM.set_bit(ARDUCHIP_TIM, VSYNC_LEVEL_MASK);
#endif
break;
case 0x20:
mode = 2;
temp = 0xff;
start_capture = 2;
Serial.println(F("ACK CMD CAM start video streaming."));
break;
case 0x30:
mode = 3;
temp = 0xff;
start_capture = 3;
Serial.println(F("CAM start single shoot."));
break;
case 0x31:
temp = 0xff;
myCAM.set_format(BMP);
myCAM.InitCAM();
#if !(defined (OV2640_MINI_2MP))
myCAM.clear_bit(ARDUCHIP_TIM, VSYNC_LEVEL_MASK);
#endif
myCAM.wrSensorReg16_8(0x3818, 0x81);
myCAM.wrSensorReg16_8(0x3621, 0xA7);
break;
default:
break;
}
}
if (mode == 1)
{
if (start_capture == 1)
{
myCAM.flush_fifo();
myCAM.clear_fifo_flag();
//Start capture
myCAM.start_capture();
start_capture = 0;
}
if (myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK))
{
Serial.println(F("ACK CMD CAM Capture Done."));
read_fifo_burst(myCAM);
//Clear the capture done flag
myCAM.clear_fifo_flag();
}
}
else if (mode == 2)
{
while (1)
{
temp = Serial.read();
if (temp == 0x21)
{
start_capture = 0;
mode = 0;
Serial.println(F("ACK CMD CAM stop video streaming."));
break;
}
if (start_capture == 2)
{
myCAM.flush_fifo();
myCAM.clear_fifo_flag();
//Start capture
myCAM.start_capture();
start_capture = 0;
}
if (myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK))
{
uint32_t length = 0;
length = myCAM.read_fifo_length();
if ((length >= MAX_FIFO_SIZE) | (length == 0))
{
myCAM.clear_fifo_flag();
start_capture = 2;
continue;
}
myCAM.CS_LOW();
myCAM.set_fifo_burst();//Set fifo burst mode
temp = SPI.transfer(0x00);
length --;
while ( length-- )
{
temp_last = temp;
temp = SPI.transfer(0x00);
if (is_header == true)
{
Serial.write(temp);
}
else if ((temp == 0xD8) & (temp_last == 0xFF))
{
is_header = true;
Serial.println(F("ACK IMG"));
Serial.write(temp_last);
Serial.write(temp);
}
if ( (temp == 0xD9) && (temp_last == 0xFF) ) //If find the end ,break while,
break;
delayMicroseconds(15);
}
myCAM.CS_HIGH();
myCAM.clear_fifo_flag();
start_capture = 2;
is_header = false;
}
}
}
else if (mode == 3)
{
if (start_capture == 3)
{
//Flush the FIFO
myCAM.flush_fifo();
myCAM.clear_fifo_flag();
//Start capture
myCAM.start_capture();
start_capture = 0;
}
if (myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK))
{
Serial.println(F("ACK CMD CAM Capture Done."));
uint8_t temp, temp_last;
uint32_t length = 0;
length = myCAM.read_fifo_length();
if (length >= MAX_FIFO_SIZE )
{
Serial.println(F("ACK CMD Over size."));
myCAM.clear_fifo_flag();
return;
}
if (length == 0 ) //0 kb
{
Serial.println(F("ACK CMD Size is 0."));
myCAM.clear_fifo_flag();
return;
}
myCAM.CS_LOW();
myCAM.set_fifo_burst();//Set fifo burst mode
Serial.write(0xFF);
Serial.write(0xAA);
for (temp = 0; temp < BMPIMAGEOFFSET; temp++)
{
Serial.write(pgm_read_byte(&bmp_header[temp]));
}
SPI.transfer(0x00);
char VH, VL;
int i = 0, j = 0;
for (i = 0; i < 240; i++)
{
for (j = 0; j < 320; j++)
{
VH = SPI.transfer(0x00);;
VL = SPI.transfer(0x00);;
Serial.write(VL);
delayMicroseconds(12);
Serial.write(VH);
delayMicroseconds(12);
}
}
Serial.write(0xBB);
Serial.write(0xCC);
myCAM.CS_HIGH();
//Clear the capture done flag
myCAM.clear_fifo_flag();
} } } uint8_t read_fifo_burst(ArduCAM myCAM) { uint8_t temp = 0, temp_last = 0; uint32_t length = 0; length = myCAM.read_fifo_length(); Serial.println(length, DEC); if (length >= MAX_FIFO_SIZE) //512 kb { Serial.println(F("Over size.")); return 0; } if (length == 0 ) //0 kb { Serial.println(F("Size is 0.")); return 0; } myCAM.CS_LOW(); myCAM.set_fifo_burst();//Set fifo burst mode temp = SPI.transfer(0x00); length --; while ( length-- ) { temp_last = temp; temp = SPI.transfer(0x00); if (is_header == true) { Serial.write(temp); } else if ((temp == 0xD8) & (temp_last == 0xFF)) { is_header = true; Serial.println(F("ACK IMG")); Serial.write(temp_last); Serial.write(temp); } if ( (temp == 0xD9) && (temp_last == 0xFF) ) //If find the end ,break while, break; delayMicroseconds(15); } myCAM.CS_HIGH(); is_header = false; return 1; }
@coolb2200 Hi, the SCk is pin 3 and in the code you have set the CS to 7 instead of 10. Pease check it again. Let us know if you need more help. Regards, ArduCAM support team.
I guess my problem is that I can't even get the Host app to do anything with the camera much less, get the code to even work. I changed the CS pin to both 7 and 10, swapping the pin configuration for both cases.
I can't even get the host app to work.
Here is a picture of my hardware setup:

Hello?
@coolb2200 Hi,
Don't worry and we will try our best to help you. Can your camera work on other platform? Please attach us some pictures about how do you use the host V2 software.
Let us know if you need more help. Regards, ArduCAM support team.
Well I got it to somehow "work" on the Arduino UNO R3.
How would I go about getting individual RGB values from each pixel?
Also, why can't I just run the example code and have it work without using the Host app? Isn't your code supposed to work after uploading it? I shouldn't have to keep using the Host app.
I have been trying to get your code to work but every time I try to use it, it spits back a bunch of errors.
@coolb2200 Hi, The hardware connnection you have attached is right. Do you have our adapter board?We suggest you use our adapter board which will ensure the connection is stable. About getting RGB values form each pixel,please refer to this code : //Read 320x240x2 byte from FIFO //Save as RGB565 bmp format for (i = 0; i < 240; i++) for (j = 0; j < 320; j++) { VH = myCAM.read_fifo(); VL = myCAM.read_fifo(); buf[k++] = VL; buf[k++] = VH; #if defined(ESP8266) yield(); #endif //Write image data to bufer if not full if (k >= 256) { //Write 256 bytes image data to file from buffer outFile.write(buf, 256); k = 0; } }
Let us know if you need more help. Regards, ArduCAM support team.
Thank you! Should that code just work? I've yet to test it.
Are you talking about one of these? https://smile.amazon.com/Arducam-Multi-Cameras-Adapter-Board/dp/B01735GYWC?sa-no-redirect=1
Is there anyway I could have code JUST for the OV2640 and nothing else? I notice that a lot of your example code accommodates for both the OV2640 and the OV5640. Do you have live streaming code for JUST the OV2640? It's a lot to go through and the API doesn't really help me all that much.
@coolb2200
Hi,
Yes,if you want to use OV2640,you just should enable OV2640_MINI_2MP and disable others in the memorysaver.h file.Then you can use our examples in MINI folder for OV2640. IF you want to only have OV2640,you can delete other sensor by yourself. This link is our demo . https://github.com/ArduCAM/Arduino/tree/master/ArduCAM/examples/mini
Let us know if you need more help. Regards, ArduCAM suport team.
Thanks for the advice!
Where exactly do I put in the RGB reading code? Also, anyway I could just run this code without having to use the host app every time? Is that possible?
@coolb2200 Hi,
Yes, after you get the RGB datas,you can write it to your LCD screen or other device. After start capture and capture down, you can read the RGB data from the FIFO.
Let us know if you need more help. Regards, ArduCAM support team.
I can't read the RGB values with the given code. I keep getting an "invalid type" error when adding the code in. What is wrong with the code?
// 1. Set the camera to JPEG output mode. // 2. Read data from Serial port and deal with it // 3. If receive 0x00-0x08,the resolution will be changed. // 4. If receive 0x10,camera will capture a JPEG photo and buffer the image to FIFO.Then write datas to Serial port. // 5. If receive 0x20,camera will capture JPEG photo and write datas continuously.Stop when receive 0x21. // 6. If receive 0x30,camera will capture a BMP photo and buffer the image to FIFO.Then write datas to Serial port. // 7. If receive 0x11 ,set camera to JPEG output mode. // 8. If receive 0x31 ,set camera to BMP output mode. #include <Wire.h> #include <ArduCAM.h> #include <SPI.h> #include "memorysaver.h" #include <ov2640_regs.h> //This demo can only work on OV2640_MINI_2MP or OV5642_MINI_5MP or OV5642_MINI_5MP_BIT_ROTATION_FIXED platform. #if !(defined OV2640_MINI_2MP) #error Please select the hardware platform and camera module in the ../libraries/ArduCAM/memorysaver.h file #endif #define BMPIMAGEOFFSET 66 const char bmp_header[BMPIMAGEOFFSET] PROGMEM = { 0x42, 0x4D, 0x36, 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x58, 0x02, 0x00, 0xC4, 0x0E, 0x00, 0x00, 0xC4, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00 }; // set pin 10 as the slave select for the digital pot: const int CS = 10; bool is_header = false; int mode = 0; uint8_t start_capture = 0; #if defined (OV2640_MINI_2MP) ArduCAM myCAM( OV2640, CS ); #endif uint8_t read_fifo_burst(ArduCAM myCAM); void setup() { // put your setup code here, to run once: uint8_t vid, pid; uint8_t temp; #if defined(SAM3X8E) Wire1.begin(); Serial.begin(115200); #else Wire.begin(); Serial.begin(921600); #endif Serial.println(F("ACK CMD ArduCAM Start!")); // set the CS as an output: pinMode(CS, OUTPUT); // initialize SPI: SPI.begin(); while(1){ //Check if the ArduCAM SPI bus is OK myCAM.write_reg(ARDUCHIP_TEST1, 0x55); temp = myCAM.read_reg(ARDUCHIP_TEST1); if (temp != 0x55){ Serial.println(F("ACK CMD SPI interface Error!")); delay(1000);continue; }else{ Serial.println(F("ACK CMD SPI interface OK."));break; } }
#if defined (OV2640_MINI_2MP)
while(1){
//Check if the camera module type is OV2640
myCAM.wrSensorReg8_8(0xff, 0x01);
myCAM.rdSensorReg8_8(OV2640_CHIPID_HIGH, &vid);
myCAM.rdSensorReg8_8(OV2640_CHIPID_LOW, &pid);
if ((vid != 0x26 ) && (( pid != 0x41 ) || ( pid != 0x42 ))){
Serial.println(F("ACK CMD Can't find OV2640 module!"));
delay(1000);continue;
}
else{
Serial.println(F("ACK CMD OV2640 detected."));break;
}
}
#else
while(1){
//Check if the camera module type is OV5642
myCAM.wrSensorReg16_8(0xff, 0x01);
myCAM.rdSensorReg16_8(OV5642_CHIPID_HIGH, &vid);
myCAM.rdSensorReg16_8(OV5642_CHIPID_LOW, &pid);
if((vid != 0x56) || (pid != 0x42)){
Serial.println(F("ACK CMD Can't find OV5642 module!"));
delay(1000);continue;
}
else{
Serial.println(F("ACK CMD OV5642 detected."));break;
}
}
#endif
//Change to JPEG capture mode and initialize the OV5642 module
myCAM.set_format(JPEG);
myCAM.InitCAM();
#if defined (OV2640_MINI_2MP)
myCAM.OV2640_set_JPEG_size(OV2640_320x240);
#else
myCAM.write_reg(ARDUCHIP_TIM, VSYNC_LEVEL_MASK); //VSYNC is active HIGH
myCAM.OV5642_set_JPEG_size(OV5642_320x240);
#endif
delay(1000);
myCAM.clear_fifo_flag();
#if !(defined (OV2640_MINI_2MP))
myCAM.write_reg(ARDUCHIP_FRAMES,0x00);
#endif
}
void loop() {
// put your main code here, to run repeatedly:
uint8_t temp = 0xff, temp_last = 0;
bool is_header = false;
if (Serial.available())
{
temp = Serial.read();
switch (temp)
{
case 0:
#if defined (OV2640_MINI_2MP)
myCAM.OV2640_set_JPEG_size(OV2640_160x120);delay(1000);
Serial.println(F("ACK CMD switch to OV2640_160x120"));
#endif
temp = 0xff;
break;
case 1:
#if defined (OV2640_MINI_2MP)
myCAM.OV2640_set_JPEG_size(OV2640_176x144);delay(1000);
Serial.println(F("ACK CMD switch to OV2640_176x144"));
#endif
temp = 0xff;
break;
case 2:
#if defined (OV2640_MINI_2MP)
myCAM.OV2640_set_JPEG_size(OV2640_320x240);delay(1000);
Serial.println(F("ACK CMD switch to OV2640_320x240"));
#endif
temp = 0xff;
break;
case 3:
temp = 0xff;
#if defined (OV2640_MINI_2MP)
myCAM.OV2640_set_JPEG_size(OV2640_352x288);delay(1000);
Serial.println(F("ACK CMD switch to OV2640_352x288"));
#endif
break;
case 4:
temp = 0xff;
#if defined (OV2640_MINI_2MP)
myCAM.OV2640_set_JPEG_size(OV2640_640x480);delay(1000);
Serial.println(F("ACK CMD switch to OV2640_640x480"));
#endif
break;
case 5:
temp = 0xff;
#if defined (OV2640_MINI_2MP)
myCAM.OV2640_set_JPEG_size(OV2640_800x600);delay(1000);
Serial.println(F("ACK CMD switch to OV2640_800x600"));
#endif
break;
case 6:
temp = 0xff;
#if defined (OV2640_MINI_2MP)
myCAM.OV2640_set_JPEG_size(OV2640_1024x768);delay(1000);
Serial.println(F("ACK CMD switch to OV2640_1024x768"));
#endif
break;
#if defined (OV2640_MINI_2MP)
case 7:
temp = 0xff;
myCAM.OV2640_set_JPEG_size(OV2640_1280x1024);delay(1000);
Serial.println(F("ACK CMD switch to OV2640_1280x1024"));
break;
case 8:
temp = 0xff;
myCAM.OV2640_set_JPEG_size(OV2640_1600x1200);delay(1000);
Serial.println(F("ACK CMD switch to OV2640_1600x1200"));
break;
#endif
case 0x10:
mode = 1;
temp = 0xff;
start_capture = 1;
Serial.println(F("ACK CMD CAM start single shoot."));
break;
case 0x11:
temp = 0xff;
myCAM.set_format(JPEG);
myCAM.InitCAM();
#if !(defined (OV2640_MINI_2MP))
myCAM.set_bit(ARDUCHIP_TIM, VSYNC_LEVEL_MASK);
#endif
break;
case 0x20:
mode = 2;
temp = 0xff;
start_capture = 2;
Serial.println(F("ACK CMD CAM start video streaming."));
break;
case 0x30:
mode = 3;
temp = 0xff;
start_capture = 3;
Serial.println(F("CAM start single shoot."));
break;
case 0x31:
temp = 0xff;
myCAM.set_format(BMP);
myCAM.InitCAM();
#if !(defined (OV2640_MINI_2MP))
myCAM.clear_bit(ARDUCHIP_TIM, VSYNC_LEVEL_MASK);
#endif
myCAM.wrSensorReg16_8(0x3818, 0x81);
myCAM.wrSensorReg16_8(0x3621, 0xA7);
/*
* Start Pixel RGB Read
*/
break;
default:
break;
} } if (mode == 1) { if (start_capture == 1) { myCAM.flush_fifo(); myCAM.clear_fifo_flag(); //Start capture myCAM.start_capture(); start_capture = 0; } if (myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK)) { Serial.println(F("ACK CMD CAM Capture Done.")); read_fifo_burst(myCAM); //Clear the capture done flag myCAM.clear_fifo_flag(); } } else if (mode == 2) { while (1) { temp = Serial.read(); if (temp == 0x21) { start_capture = 0; mode = 0; Serial.println(F("ACK CMD CAM stop video streaming.")); break; } if (start_capture == 2) { myCAM.flush_fifo(); myCAM.clear_fifo_flag(); //Start capture
char VH, VL, buf, k; //Read 320x240x2 byte from FIFO //Save as RGB565 bmp format for (int i = 0; i < 240; i++) for (int j = 0; j < 320; j++) { VH = myCAM.read_fifo(); VL = myCAM.read_fifo(); buf[k++] = VL; buf[k++] = VH; #if defined(ESP8266) yield(); #endif //Write image data to bufer if not full if (k >= 256) { //Write 256 bytes image data to file from buffer outFile.write(buf, 256); k = 0; } }
myCAM.start_capture();
start_capture = 0;
}
if (myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK))
{
uint32_t length = 0;
length = myCAM.read_fifo_length();
if ((length >= MAX_FIFO_SIZE) | (length == 0))
{
myCAM.clear_fifo_flag();
start_capture = 2;
continue;
}
myCAM.CS_LOW();
myCAM.set_fifo_burst();//Set fifo burst mode
temp = SPI.transfer(0x00);
length --;
while ( length-- )
{
temp_last = temp;
temp = SPI.transfer(0x00);
if (is_header == true)
{
Serial.write(temp);
}
else if ((temp == 0xD8) & (temp_last == 0xFF))
{
is_header = true;
Serial.println(F("ACK IMG"));
Serial.write(temp_last);
Serial.write(temp);
}
if ( (temp == 0xD9) && (temp_last == 0xFF) ) //If find the end ,break while,
break;
delayMicroseconds(15);
}
myCAM.CS_HIGH();
myCAM.clear_fifo_flag();
start_capture = 2;
is_header = false;
}
} } else if (mode == 3) { if (start_capture == 3) { //Flush the FIFO myCAM.flush_fifo(); myCAM.clear_fifo_flag(); //Start capture myCAM.start_capture(); start_capture = 0; } if (myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK)) { Serial.println(F("ACK CMD CAM Capture Done.")); uint8_t temp, temp_last; uint32_t length = 0; length = myCAM.read_fifo_length(); if (length >= MAX_FIFO_SIZE ) { Serial.println(F("ACK CMD Over size.")); myCAM.clear_fifo_flag(); return; } if (length == 0 ) //0 kb { Serial.println(F("ACK CMD Size is 0.")); myCAM.clear_fifo_flag(); return; } myCAM.CS_LOW(); myCAM.set_fifo_burst();//Set fifo burst mode
Serial.write(0xFF);
Serial.write(0xAA);
for (temp = 0; temp < BMPIMAGEOFFSET; temp++)
{
Serial.write(pgm_read_byte(&bmp_header[temp]));
}
SPI.transfer(0x00);
char VH, VL;
int i = 0, j = 0;
for (i = 0; i < 240; i++)
{
for (j = 0; j < 320; j++)
{
VH = SPI.transfer(0x00);;
VL = SPI.transfer(0x00);;
Serial.write(VL);
delayMicroseconds(12);
Serial.write(VH);
delayMicroseconds(12);
}
}
Serial.write(0xBB);
Serial.write(0xCC);
myCAM.CS_HIGH();
//Clear the capture done flag
myCAM.clear_fifo_flag();
} } } uint8_t read_fifo_burst(ArduCAM myCAM) { uint8_t temp = 0, temp_last = 0; uint32_t length = 0; length = myCAM.read_fifo_length(); Serial.println(length, DEC); if (length >= MAX_FIFO_SIZE) //512 kb { Serial.println(F("Over size.")); return 0; } if (length == 0 ) //0 kb { Serial.println(F("Size is 0.")); return 0; } myCAM.CS_LOW(); myCAM.set_fifo_burst();//Set fifo burst mode temp = SPI.transfer(0x00); length --; while ( length-- ) { temp_last = temp; temp = SPI.transfer(0x00); if (is_header == true) { Serial.write(temp); } else if ((temp == 0xD8) & (temp_last == 0xFF)) { is_header = true; Serial.println(F("ACK IMG")); Serial.write(temp_last); Serial.write(temp); } if ( (temp == 0xD9) && (temp_last == 0xFF) ) //If find the end ,break while, break; delayMicroseconds(15); } myCAM.CS_HIGH(); is_header = false; return 1; }
@coolb2200 Hi, Please attach us some picture about your phenomenon. we send 0x30 and read the RGB data by the serial port and we have test it.
let us know if you need more help. Regards, ArduCAM suppor team.
Pictures? I just sent you the code Im using and it won't work due to some "invalid type" errors. You said if I just put in the RGB data code "after start capture" it should work........Could you send me the full code that you're using since it works?
@coolb2200 Hi, Please try this code :
#include <Wire.h> #include <ArduCAM.h> #include <SPI.h> #include "memorysaver.h" #define BMPIMAGEOFFSET 66 const char bmp_header[BMPIMAGEOFFSET] PROGMEM = { 0x42, 0x4D, 0x36, 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x58, 0x02, 0x00, 0xC4, 0x0E, 0x00, 0x00, 0xC4, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00 }; // set pin 7 as the slave select for the digital pot: const int CS = 7; bool is_header = false; int mode = 0; uint8_t start_capture = 0; ArduCAM myCAM( OV2640, CS ); void setup() { // put your setup code here, to run once: uint8_t vid, pid; uint8_t temp;
Wire.begin(); Serial.begin(921600); Serial.println(F("ACK CMD ArduCAM Start!")); // set the CS as an output: pinMode(CS, OUTPUT); // initialize SPI: SPI.begin(); while(1){ //Check if the ArduCAM SPI bus is OK myCAM.write_reg(ARDUCHIP_TEST1, 0x55); temp = myCAM.read_reg(ARDUCHIP_TEST1); if (temp != 0x55){ Serial.println(F("ACK CMD SPI interface Error!")); delay(1000);continue; }else{ Serial.println(F("ACK CMD SPI interface OK."));break; } } while(1){ //Check if the camera module type is OV2640 myCAM.wrSensorReg8_8(0xff, 0x01); myCAM.rdSensorReg8_8(OV2640_CHIPID_HIGH, &vid); myCAM.rdSensorReg8_8(OV2640_CHIPID_LOW, &pid); if ((vid != 0x26 ) && (( pid != 0x41 ) || ( pid != 0x42 ))){ Serial.println(F("ACK CMD Can't find OV2640 module!")); delay(1000);continue; } else{ Serial.println(F("ACK CMD OV2640 detected."));break; } }
myCAM.set_format(BMP);
myCAM.InitCAM();
myCAM.wrSensorReg16_8(0x3818, 0x81);
myCAM.wrSensorReg16_8(0x3621, 0xA7);
} void loop() { // put your main code here, to run repeatedly: uint8_t temp = 0xff, temp_last = 0; bool is_header = false; if (Serial.available()) { temp = Serial.read(); switch (temp) { case 0x30: mode = 3; temp = 0xff; start_capture = 3; Serial.println(F("CAM start single shoot.")); break; } }
if (mode == 3) { if (start_capture == 3) { //Flush the FIFO myCAM.flush_fifo(); myCAM.clear_fifo_flag(); //Start capture myCAM.start_capture(); start_capture = 0; } if (myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK)) { Serial.println(F("ACK CMD CAM Capture Done.")); Serial.println(F("ACK IMG")); uint8_t temp, temp_last; uint32_t length = 0; length = myCAM.read_fifo_length(); if (length >= MAX_FIFO_SIZE ) { Serial.println(F("ACK CMD Over size.")); myCAM.clear_fifo_flag(); return; } if (length == 0 ) //0 kb { Serial.println(F("ACK CMD Size is 0.")); myCAM.clear_fifo_flag(); return; } myCAM.CS_LOW(); myCAM.set_fifo_burst();//Set fifo burst mode
Serial.write(0xFF);
Serial.write(0xAA);
for (temp = 0; temp < BMPIMAGEOFFSET; temp++)
{
Serial.write(pgm_read_byte(&bmp_header[temp]));
}
SPI.transfer(0x00);
char VH, VL;
int i = 0, j = 0;
for (i = 0; i < 240; i++)
{
for (j = 0; j < 320; j++)
{
VH = SPI.transfer(0x00);;
VL = SPI.transfer(0x00);;
Serial.write(VL);
delayMicroseconds(12);
Serial.write(VH);
delayMicroseconds(12);
}
}
Serial.write(0xBB);
Serial.write(0xCC);
myCAM.CS_HIGH();
//Clear the capture done flag
myCAM.clear_fifo_flag();
} } }
Let us know if you need more help. ArduCAM support team.
I ran your code....it doesn't read or print the RGB values of each pixel and it doesn't automatically launch, let alone work. That's all I need the camera to do. I don't know what it is about this camera but it doesn't want to work. Either that or the API needs updating.
@coolb2200 Hi, What's your baud rate? It seems your baud rate is not right. Regards, ARduCAM support team.
Hi, recently purchased OV2640 and followed guide on how to connect to mega 2560 board - but can not make it work at all. SPI test passes but vid and pid are both set to 0 so the code throws an error as module is not recognized.
I tried multiple mega boards - the same result.
// initialize arducam myCAM.write_reg(ARDUCHIP_TEST1, 0x55); uint8_t temp = myCAM.read_reg(ARDUCHIP_TEST1); if (temp != 0x55) { Serial.println(F("SPI1 interface Error!")); } else { CAM_EXIST = true; Serial.println(F("SPI1 interface OK.")); }
while(1){ //Check if the camera module type is OV2640 myCAM.wrSensorReg8_8(0xff, 0x01); myCAM.rdSensorReg8_8(OV2640_CHIPID_HIGH, &vid); myCAM.rdSensorReg8_8(OV2640_CHIPID_LOW, &pid); Serial.print("vid is: "); Serial.println(vid, HEX); Serial.print("pid is: "); Serial.println(pid, HEX); if ((vid != 0x26 ) && (( pid != 0x41 ) || ( pid != 0x42 ))){ Serial.println(F("Can't find OV2640 module!")); delay(1000);continue; }else{ Serial.println(F("OV2640 detected."));break; } }
@DigitalSocrates Hi, How do you connect the camera? Please attach us some pictures for your hardware connection. You‘d better check your I2C bus with an oscilloscope. Arducam support team.
thank you for you response. i opened a different issue for this see https://github.com/ArduCAM/Arduino/issues/278
will include more info there
i need help on how to connect OV2640 18 pin camera to Arduino Uno and also the code. i try using the code for ArduCam mini OV2640 the message i got is a continues SPI interface Error