Using an ArduCAM OV5642 to print out JPEG data to Serial

Hey guys! I'm using an ArduCAM OV5642 hooked up to an Arduino Nano 33 BLE Sense for this project of mine and I am having a little bit of trouble with getting the images out of the module. Using the example sketches I can get the module and Arduino to interface with the host program but now I just want to have the Arduino spit the bytes of the JPEG image to the Serial monitor so I can use PySerial to read them. I tried reaching out to the ArduCAM forum but have yet to get a response yet so I was hoping someone here had an idea. Currently I have the Arduino spitting out bytes into the Serial starting from when it sees FF D8 (JPEG start) and stopping when it sees FF D9 (JPEG end) and have this small python script to write it to a file. It would be easier to just have the Arduino save the bytes to an SD card, but for my use case I won't be able to do that. Thank you in advance for any and all help!

// Modification of Example: ArduCAM_Mini_5MP_Plus_Multi_Capture2SD
#include "memorysaver.h"
#include <ArduCAM.h>
#include <SPI.h>
#include <Wire.h>
//This demo can only work on OV5640_MINI_5MP_PLUS or OV5642_MINI_5MP_PLUS platform.
#if !(defined(OV5640_MINI_5MP_PLUS) || defined(OV5642_MINI_5MP_PLUS))
#error Please select the hardware platform and camera module in the ../libraries/ArduCAM/memorysaver.h file
#endif

#define FRAMES_NUM 0x00
// set pin 7 as the slave select for the digital port for ArduCam:
const int CS = 7;
#define BYTE_PACKET_SIZE 256

bool is_header = false;
int total_time = 0;
#if defined(OV5640_MINI_5MP_PLUS)
ArduCAM myCAM(OV5640, CS);
#else
ArduCAM myCAM(OV5642, CS);
#endif

uint8_t read_fifo_burst(ArduCAM myCAM);

void dump_buffer(byte buffer[], int index);

int add_to_buffer(byte buffer[], int index, byte elem);

void setup() {
  // put your setup code here, to run once:
  uint8_t vid, pid;
  uint8_t temp;
#if defined(__SAM3X8E__)
  Wire1.begin();
#else
  Wire.begin();
#endif
  Serial.begin(921600);
  Serial.println(F("ArduCAM Start!"));

  // set the CS as an output:
  pinMode(CS, OUTPUT);
  digitalWrite(CS, HIGH);

  // initialize SPI:
  SPI.begin();
  //Reset the CPLD
  myCAM.write_reg(0x07, 0x80);
  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;
    }
  }
#if defined(OV5640_MINI_5MP_PLUS)
  while (1) {
    //Check if the camera module type is OV5640
    myCAM.rdSensorReg16_8(OV5640_CHIPID_HIGH, &vid);
    myCAM.rdSensorReg16_8(OV5640_CHIPID_LOW, &pid);
    if ((vid != 0x56) || (pid != 0x40)) {
      Serial.println(F("Can't find OV5640 module!"));
      delay(1000);
      continue;
    } else {
      Serial.println(F("OV5640 detected."));
      break;
    }
  }
#else
  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;
    }
  }
#endif
  //Change to JPEG capture mode and initialize the OV5640 module
  myCAM.set_format(JPEG);
  myCAM.InitCAM();
  myCAM.set_bit(ARDUCHIP_TIM, VSYNC_LEVEL_MASK);
  myCAM.clear_fifo_flag();
  myCAM.write_reg(ARDUCHIP_FRAMES, FRAMES_NUM);
}

void loop() {

  // put your main code here, to run repeatedly:
  myCAM.flush_fifo();
  myCAM.clear_fifo_flag();

#if defined(OV5640_MINI_5MP_PLUS)
  myCAM.OV5640_set_JPEG_size(OV5640_2592x1944);
  delay(1000);
#else
  myCAM.OV5642_set_JPEG_size(OV5642_320x240);
  delay(1000);
#endif
  if (Serial.available() && Serial.read() == 65) {
    //Start capture
    myCAM.start_capture();
    Serial.println(F("start capture."));
    total_time = millis();
    while (!myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK));
    Serial.println(F("CAM Capture Done."));
    total_time = millis() - total_time;
    Serial.print(F("capture total_time used (in miliseconds):"));
    Serial.println(total_time, DEC);
    total_time = millis();
    read_fifo_burst(myCAM);
    total_time = millis() - total_time;
    Serial.print(F("save capture total_time used (in miliseconds):"));
    Serial.println(total_time, DEC);
    //Clear the capture done flag
    myCAM.clear_fifo_flag();
    delay(5000);
  } else {
    Serial.println("Waiting for command (A to start capture)!");
    delay(1000);
  }
}

uint8_t read_fifo_burst(ArduCAM myCAM) {
  uint8_t currByte = 0;
  uint8_t prevByte = 0;
  uint32_t length = myCAM.read_fifo_length();
  static int i = 0;
  byte buffer[BYTE_PACKET_SIZE];

  Serial.print("The FIFO length is: ");
  Serial.println(length, DEC);

  if (length >= MAX_FIFO_SIZE) {
    Serial.println("Over size image.");
    return 0;
  } else if (length == 0) {
    Serial.println("Empty image");
    return 0;
  } else {
    Serial.println("Begin image processing");

    myCAM.CS_LOW();
    myCAM.set_fifo_burst();

    while (length--) {
      prevByte = currByte;
      currByte = SPI.transfer(0x00);
      Serial.println(currByte, HEX);      
      if ((currByte == 0xD9) && (prevByte == 0xFF)) {
        // buffer[i++] = currByte;
        i = add_to_buffer(buffer, i, currByte);
        myCAM.CS_HIGH();
        dump_buffer(buffer, i);

        Serial.println("End read");
        is_header = false;
        myCAM.CS_LOW();
        myCAM.set_fifo_burst();
        i = 0;
        myCAM.CS_HIGH();
        return 1;
      } else if ((currByte == 0xD8) && (prevByte == 0xFF)) {
        Serial.println("Found header");

        is_header = true;
        myCAM.CS_HIGH();
        myCAM.CS_LOW();
        myCAM.set_fifo_burst();
        // buffer[i++] = prevByte;
        // buffer[i++] = currByte;
        i = add_to_buffer(buffer, i, prevByte);
        i = add_to_buffer(buffer, i, currByte);
      } else if (is_header) {
        myCAM.CS_HIGH();
        // buffer[i++] = currByte;
        i = add_to_buffer(buffer, i, currByte);
        myCAM.CS_LOW();
        myCAM.set_fifo_burst();
      }
    }
    return 0;
  }
}

void dump_buffer(byte buffer[], int index) {
  for (int i = 0; i < index; i++) {
    Serial.println(buffer[i], HEX);
  }
}

int add_to_buffer(byte buffer[], int index, byte elem) {
  if (index < BYTE_PACKET_SIZE) {
    buffer[index] = elem;
    return index + 1;
  } else {
    dump_buffer(buffer, BYTE_PACKET_SIZE);
    buffer[0] = elem;
    return 1;
  }
}
import serial
from binascii import unhexlify

arduino = serial.Serial(port='COM4', baudrate=921600)

doCapture = False

while not doCapture:
    doCapture = input("Start capture? ") == "A"

buffer = []
arduino.write(bytes("A", 'utf-8'))

prevByte = b""
currByte = b""

line = arduino.readline().strip()
while True:

    if (b"length" in line):
        print(line)

    if len(line) == 1:
        currByte = unhexlify(b'0' + line)
        if (prevByte == b"\xff" and currByte == b"\xd8"):
            buffer = [b"\xff", b"\xd8"]
            print("found a new start")
        else:
            buffer.append(currByte)

    if len(line) == 2:
        currByte = unhexlify(line)
        if (prevByte == b"\xff" and currByte == b"\xd8"):
            buffer = [b"\xff", b"\xd8"]
            print("found a new start")
        else:
            buffer.append(currByte)

    if line == b"End read" or (prevByte == b"\xff" and currByte == b"\xd9"):
        break

    line = arduino.readline().strip()
    prevByte = currByte


data = b"".join(buffer)
print(data)
with open("/path/to/image/test.jpg", "wb") as f:
    f.write(data)

arduino.close()

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.