Closed TylerW-Robotics closed 3 years ago
Now I am farther from the answer then I was before. I am just trying to take a snapshot from the OV5642 camera and now the data I get comes out like this
I just want o take a snapshot and put it into a CSV. I'll looked at playback ino codes in your Github and I'm not finding good results. Our team don't want to invest more time and money into a different product. My new code is below.
#include <Arduino.h>
#include <Wire.h>
#include <ArduCAM.h>
#include <SPI.h>
#include "memorysaver.h"
#define CS_Cam D0
#define BMPIMAGEOFFSET 66
const unsigned int 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
};
ArduCAM myCAM(OV5642, CS_Cam);
bool is_header = false;
//Important Arrays
uint8 VH_[320];
uint8 VL_[320];
char buf[4]; // Used for converting int into char array
//
//Functions
void take_photo();
void arduCam_setup();
void print_values();
void collect_values();
uint8_t read_fifo_burst(ArduCAM myCAM);
//--
void setup() {
Wire.begin();
Serial.begin(115200);
pinMode(CS_Cam, OUTPUT);
digitalWrite(CS_Cam, 0);
Serial.println("Here");
delay(100);
arduCam_setup();
take_photo();
Serial.print("\nDone\n");
}
void loop() {
}
void arduCam_setup(){
uint8_t vid, pid;
uint8_t temp;
Serial.println(F("ArduCAM Start!"));
SPI.begin();
myCAM.write_reg(0x07, 0x80); // RESET the CPLD
delay(100);
myCAM.write_reg(0x07, 0x00);
delay(100); //--
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("SPI interface Error!"));
delay(1000); continue;
} else{
Serial.println(F("SPI interface OK"));break;
}
}
while(1){
//Check if the camera module type is OV5642
myCAM.rdSensorReg16_8(OV5642_CHIPID_HIGH, &vid);
myCAM.rdSensorReg16_8(OV5642_CHIPID_LOW, &pid);
if ((vid != 0x56) || (pid != 0x42)){
Serial.println(F("Can't find OV5642 module!"));
delay(1000);continue;
} else{
Serial.println(F("OV5642 detected."));break;
}
}
//Change to JPEG capture mode and initialize the OV5642 module
myCAM.set_format(MCU2LCD_MODE);
myCAM.InitCAM();
myCAM.write_reg(ARDUCHIP_TIM, VSYNC_LEVEL_MASK); //VSYNC is active HIGH
myCAM.OV5642_set_JPEG_size(OV5642_320x240);
myCAM.clear_fifo_flag();
delay(500);
}
void take_photo(){
myCAM.set_mode(MCU2LCD_MODE); //Switch to MCU, freeze the screen
myCAM.flush_fifo();
myCAM.start_capture();
//Polling the capture done flag
while (!myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK));
delay(100);
/* if (myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK)){
Serial.println(F("ACK CMD CAM Capture Done. END"));
delay(50);
read_fifo_burst(myCAM);
//Clear the capture done flag
myCAM.clear_fifo_flag();
}*/
//myCAM.CS_LOW();
//myCAM.set_fifo_burst();
delay(100);
myCAM.read_fifo();
collect_values();
myCAM.clear_fifo_flag();
}
void print_values(){
uint16 num;
for (int count = 0; count < 320; count++){
//VH_[count]; = R4, R3, R2, R1, R0, G5, G4, G3
//VL_[count]; = G2, G1, G0, B4, B3, B2, B1, B0
num = (VH_[count] << 8) | (VL_[count] & 0xff);
Serial.print(num);
if (count == 319) {
Serial.println();
}
else {
Serial.print(",");
}
}
delay(10);
}
//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("ACK CMD Over size. END"));
// return 0;
// }
// if (length == 0 ){ //0 kb
// Serial.println(F("ACK CMD Size is 0. END"));
// 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 END"));
// 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;
//}
void collect_values() {
uint8_t VH,VL;
for (int i = 0; i < 240; i++){
for (int j = 0; j < 320; j++){
VH = myCAM.read_fifo();
delayMicroseconds(12);
VL = myCAM.read_fifo();
delayMicroseconds(12);
VH_[j] = VH;
VL_[j] = VL;
}
print_values();
}
}
If you're trying to extract RGB from image pixels, it's much easier to work with bitmap rather than jpeg. I did this a couple of years ago with a 2MP ArduCAM and NodeMCU ESP8266.
The complication with jpeg is that the images stored in the buffer are compressed, and vary in size. This makes jpeg images faster to transfer, and smaller for storage. However, if you want to know the RGB of pixel[87,119], for example, you'll need additional code to first uncompress that pixel location.
It looks like your code to collect and print values is exceeding the size of the jpeg image stored in the buffer, resulting in bad images. After the image capture, add one line as follows:
while (!myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK));
size_t len = myCAM.read_fifo_length(); //read camera FIFO length
Your loops to collect and print values should then iterate to 'len', and not 320x240.
I am sorry if I seem un-experienced in my coding, but my intent is to create a bitmap. Am I using the wrong commands in the code for asking for a bitmap?
It looks like your code was intended to be used with an LCD display, which might be adding to your problems. There's a relevant discussion, with links to OV5642 only demonstration code, in the ArduCAM forum:
https://www.arducam.com/forums/topic/bmp-mode-problems/
In your setup function, set the image format to bitmap with the following:
myCAM.set_format(BMP);
myCAM.InitCAM();
and delete myCAM.OV5642_set_JPEG_size(OV5642_320x240). The bitmap resolution is set in the bitmap header byte array at the beginning of your code.
In your print_values() function, you need to first print the contents of the header, followed by the pixel values. You can find this in the demonstration code links at the bottom of that forum discussion.
I followed your istructions and even used the test code that was mentioned in the referenced forms and I think we have some progress. The image I received from both my new code and from "ArduCAM_Mini_5MP_Plus_Video_Streaming.ino" are nearly the exact some, the problem is that they both show a black screen with little gray pixels. I did check and the screen cap is on and the jpeg mode on the host app is working perfectly. This is great progress, but I don't know why the code provided for ArduCam isn't working in bitmap mode.
Same result from the Host App V2 I'll post new code below, but I am really starting to feel the my camera has a problem if the ArduCam code isn't working. Code for Arduino:
`#include
const unsigned int 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 };
ArduCAM myCAM(OV5642, CS_Cam);
bool is_header = false;
//Important Arrays uint8t VH[320]; uint8t VL[320]; // //Functions void take_photo(); void arduCam_setup(); void print_values();
//--
void setup() {
Wire.begin();
Serial.begin(115200); pinMode(CS_Cam, OUTPUT); digitalWrite(CS_Cam, 0); Serial.println("Here"); delay(100);
arduCam_setup();
take_photo();
Serial.print("\nDone\n"); }
void loop() {
}
void arduCam_setup(){ uint8_t vid, pid; uint8_t temp;
Serial.println(F("ArduCAM Start!"));
SPI.begin();
myCAM.write_reg(0x07, 0x80); // RESET the CPLD delay(100); myCAM.write_reg(0x07, 0x00); delay(100); //--
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("SPI interface Error!"));
delay(1000); continue;
} else{
Serial.println(F("SPI interface OK"));break;
}
}
while(1){
//Check if the camera module type is OV5642
myCAM.rdSensorReg16_8(OV5642_CHIPID_HIGH, &vid);
myCAM.rdSensorReg16_8(OV5642_CHIPID_LOW, &pid);
if ((vid != 0x56) || (pid != 0x42)){
Serial.println(F("Can't find OV5642 module!"));
delay(1000);continue;
} else{
Serial.println(F("OV5642 detected."));break;
}
}
//Change to JPEG capture mode and initialize the OV5642 module myCAM.set_format(BMP);
myCAM.InitCAM();
myCAM.clear_bit(ARDUCHIP_TIM, VSYNC_LEVEL_MASK); myCAM.wrSensorReg16_8(0x3818, 0x81); myCAM.wrSensorReg16_8(0x3621, 0xA7);
delay(500); }
void take_photo(){
myCAM.flush_fifo(); myCAM.clear_fifo_flag();
myCAM.start_capture();
//Polling the capture done flag while (!myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK));
uint32_t length = 0; length = myCAM.read_fifo_length(); if (length >= MAX_FIFO_SIZE ) { Serial.println(F("ACK CMD Over size. END")); myCAM.clear_fifo_flag(); return; } if (length == 0 ) //0 kb { Serial.println(F("ACK CMD Size is 0. END")); myCAM.clear_fifo_flag(); return; } myCAM.CS_LOW(); myCAM.set_fifo_burst();//Set fifo burst mode
delay(100); for (int temp = 0; temp < BMPIMAGEOFFSET; temp++) { Serial.write(pgm_read_byte(&bmp_header[temp])); } Serial.println(); uint8_t VH,VL;
myCAM.read_fifo();
for (int i = 0; i < 240; i++){ for (int j = 0; j < 320; j++){ VH = myCAM.read_fifo(); VL = myCAM.readfifo(); VH[j] = VH; VL_[j] = VL;
}
print_values();
} myCAM.CS_HIGH(); myCAM.clear_fifo_flag();
}
void print_values(){ uint16_t num; for (int count = 0; count < 320; count++){
//VH_[count]; = R4, R3, R2, R1, R0, G5, G4, G3
//VL_[count]; = G2, G1, G0, B4, B3, B2, B1, B0
num = (VH_[count] << 8) | (VL_[count] & 0xff);
Serial.print(num);
if (count == 319) {
Serial.println();
}
else {
Serial.print(", ");
}
} delay(10); } `
Python Photo Code: https://stackoverflow.com/questions/52027382/how-do-i-convert-a-csv-file-16bit-high-color-to-image-in-python
You need to change the baud rate in the Host App to 115200 to match what you're using for serial
Serial.begin(115200);
Does it work now?
It doesn't seem to make a difference. I'm sorry. I'm not sure why the BMP mode is having problems
I'd focus on getting the example ArduCAM_Mini_5MP_Plus_Video_Streaming.ino working first, and then modify it for your own code.
Now I remember there are some subtle modifications to be made for ESP8266. In that demo code above, uncomment SPI.transfer(0x00) on line 355. Then add a couple of yields in the loops below as follows:
VH = SPI.transfer(0x00);; yield(); VL = SPI.transfer(0x00);; yield();
I am only trying to try a photo and then collect the RGB565 data from it. I've been through the examples in this Github and I can only get a broken photo of a test photo, and I am not even try to load the test pattern. Here is my code. (I'm using an ESP8266) //----------------------------------------------------------
include
include
include
include
include "memorysaver.h"
define CS_Cam D0
define BMPIMAGEOFFSET 66
const unsigned int 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 };
ArduCAM myCAM(OV5642, CS_Cam);
bool is_header = false;
//Important Arrays uint8 VH[320]; uint8 VL[320]; char buf[4]; // Used for converting int into char array // //Functions void take_photo(); void arduCam_setup(); void print_values(); void collect_values(); uint8_t read_fifo_burst(ArduCAM myCAM); //--
void setup() {
Wire.begin();
Serial.begin(115200); pinMode(CS_Cam, OUTPUT);
Serial.println("Here"); delay(100);
arduCam_setup();
take_photo();
Serial.print("\nDone\n"); }
void loop() {
}
void arduCam_setup(){ uint8_t vid, pid; uint8_t temp;
Serial.println(F("ArduCAM Start!"));
SPI.begin();
myCAM.write_reg(0x07, 0x80); // RESET the CPLD delay(100); myCAM.write_reg(0x07, 0x00); delay(100); //--
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("SPI interface Error!")); delay(1000); continue;
} else{ Serial.println(F("SPI interface OK"));break; }
}
while(1){ //Check if the camera module type is OV5642 myCAM.rdSensorReg16_8(OV5642_CHIPID_HIGH, &vid); myCAM.rdSensorReg16_8(OV5642_CHIPID_LOW, &pid); if ((vid != 0x56) || (pid != 0x42)){ Serial.println(F("Can't find OV5642 module!")); delay(1000);continue; } else{ Serial.println(F("OV5642 detected."));break;
} }
//Change to JPEG capture mode and initialize the OV5642 module myCAM.set_format(JPEG); myCAM.InitCAM();
myCAM.write_reg(ARDUCHIP_TIM, VSYNC_LEVEL_MASK); //VSYNC is active HIGH myCAM.OV5642_set_JPEG_size(OV5642_320x240); myCAM.clear_fifo_flag();
delay(500); }
void take_photo(){
//myCAM.flush_fifo(); myCAM.clear_fifo_flag(); //Start capture myCAM.start_capture(); delay(100);
if (myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK)){ Serial.println(F("ACK CMD CAM Capture Done. END")); delay(50); read_fifo_burst(myCAM); //Clear the capture done flag myCAM.clear_fifo_flag(); } collect_values();
myCAM.clear_fifo_flag();
}
void print_values(){ uint16 num; for (int count = 0; count < 320; count++){
} delay(50); }
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("ACK CMD Over size. END")); return 0; } if (length == 0 ){ //0 kb Serial.println(F("ACK CMD Size is 0. END")); 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 END")); 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; }
void collect_values() { uint8_t VH,VL;
for (int i = 0; i < 240; i++){ for (int j = 0; j < 320; j++){ VH = myCAM.read_fifo(); VL = myCAM.read_fifo();
} } //--------------------------------------------------------------
I've been at this for 2 weeks and I need help. I can't, for some reason, use my SD card reader so I need to use the serial monitor to put it into a CSV file and then I use a python file I made to create a PNG of it. I'll also post the photo for reference. Please help me. I feel like this is a simple request, but I can't seem to figure it out.