Arduino icon indicating copy to clipboard operation
Arduino copied to clipboard

OV2640 will not work at all...SPI Interface Error (sometimes)

Open br548 opened this issue 8 years ago • 22 comments

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.

br548 avatar Apr 03 '17 22:04 br548

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; }


br548 avatar Apr 03 '17 22:04 br548

@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.

supprot avatar Apr 04 '17 00:04 supprot

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:

img_20170314_113837 img_20170314_113901 img_20170314_113933

br548 avatar Apr 04 '17 16:04 br548

Hello?

br548 avatar Apr 07 '17 22:04 br548

@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.

supprot avatar Apr 08 '17 06:04 supprot

Well I got it to somehow "work" on the Arduino UNO R3.

How would I go about getting individual RGB values from each pixel?

br548 avatar Apr 12 '17 15:04 br548

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.

br548 avatar Apr 12 '17 21:04 br548

@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.

supprot avatar Apr 13 '17 01:04 supprot

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.

br548 avatar Apr 18 '17 20:04 br548

@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.

supprot avatar Apr 19 '17 00:04 supprot

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?

br548 avatar Apr 21 '17 02:04 br548

@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.

supprot avatar Apr 21 '17 02:04 supprot

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; }

br548 avatar Apr 21 '17 02:04 br548

@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.

supprot avatar Apr 21 '17 03:04 supprot

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?

br548 avatar Apr 21 '17 09:04 br548

@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.

supprot avatar Apr 21 '17 09:04 supprot

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. notworking notworking2

br548 avatar Apr 21 '17 15:04 br548

@coolb2200 Hi, What's your baud rate? It seems your baud rate is not right. Regards, ARduCAM support team.

supprot avatar Apr 22 '17 11:04 supprot

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 avatar Nov 21 '17 06:11 DigitalSocrates

@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.

UCTRONICS avatar Nov 21 '17 07:11 UCTRONICS

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

DigitalSocrates avatar Nov 21 '17 08:11 DigitalSocrates

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

Gaby-8886 avatar Jun 11 '22 21:06 Gaby-8886