Quantcast
Channel: Arduino - Processing 2.x and 3.x Forum
Viewing all articles
Browse latest Browse all 747

How to take pictures in continuous mode using ArduCAM and displaying them on Processing?

$
0
0

Hello, everyone. I am using an Arduino MEGA 2560 and ArduCAM OV2640 to take a JPEG picture and display it on my PC through a Processing sketch. The current Arduino and Processing sketches let me take single shots only. I am wondering how I can make it so the camera will take pictures continuously and display it on the PC, similar to a video stream. Here are the sketches, courtesy of Vernel. (https://github.com/Vernel/ArduCAM_OV562

Processing sketch:

import processing.serial.*;       // import the Processing serial library



Serial myPort;                    // The serial port



//NEW ADDITIONS

byte rawBytes[];

int sensorNum = 0;

PImage img;

long picNum = 0;



void setup() {

  size(640, 480);



  // List all the available serial ports

  // if using Processing 2.1 or later, use Serial.printArray()

  printArray(Serial.list());





  // Change the 0 to the appropriate number of the serial port

  // that your microcontroller is attached to.

  myPort = new Serial(this, Serial.list()[0], 250000);



  // read bytes into a buffer until you get a linefeed (ASCII 10):

  myPort.bufferUntil('\n');



  // draw with smooth edges:

  smooth();



  img = createImage(320, 240, RGB);

  img.loadPixels();

  //frameRate(600);

  myPort.write(0x10);
}





void draw() {



  background(255);

  image(img, 0, 0, width, height-100);

  fill(0);

  text("Help:", 20, height-80);

  text("- Press key 1-7 to change image resolution", 30, height-60);

  text("- Press key S to capture a still photo", 30, height-40);

  text("- Press key C to enable/disable StopMotion capture", 30, height-20);
}





// serialEvent  method is run automatically by the Processing applet

// whenever the buffer reaches the  byte value set in the bufferUntil()

// method in the setup():



void serialEvent(Serial myPort) {

  while (myPort.available() > 0) {



    String incoming[];

    String myString = myPort.readStringUntil('\n');



    myString = trim(myString);

    incoming = split(myString, ',');



    if (incoming.length > 1) {

      if (incoming[0].equals("FifoLength:")) {

        //initialize raw data byte array to the size of the picture

        rawBytes = new byte[int(incoming[1])];

        println("Picture Size: "+incoming[1]+" bytes");
      } else if (incoming[0].equals("Image:")) {

        int x = 0;

        for (int i = 1; i < incoming.length; i++) {

          try {

            //add raw jpeg incoming bytes to byte array

            rawBytes[x]= (byte)int(incoming[i]);

            x++;
          }

          catch(RuntimeException e) {

            println(e.getMessage());
          }
        }

        try {

          //Save raw data to file

          String fname = "capture#"+picNum+"_"+day()+month()+year()+".jpg";

          saveBytes("data/capture/"+fname, rawBytes);



          // Open saved picture for local display

          img = loadImage("/data/capture/"+fname);

          picNum++;
        }

        catch(RuntimeException e) {

          println(e.getMessage());
        }
      } else if (incoming[0].equals("Ready:")) {

        myPort.write(0x10);

        println("Starting Capture");
      }
    } else {

      println(myString);
    }
  }
}



void keyPressed() {

  switch(key) {

  case 's':

    myPort.write(0x10);

    println("Starting Capture");

    break;



  case 'c':

    myPort.write(7);

    break;



  case '1':

    myPort.write(0);

    println("Set Image Resolution: 320x240");

    break;



  case '2':

    myPort.write(1);

    println("Set Image Resolution: 640x480");

    break;



  case '3':

    myPort.write(2);

    println("Set Image Resolution: 1024x768");

    break;




  default:

    println("Unknown Command: "+key);

    break;
  }
}

Arduino Sketch:

#include <Wire.h>

#include <ArduCAM.h>

#include <SPI.h>

#include "memorysaver.h"



//This code can only work on OV5642_MINI_5MP_PLUS platform.

#if !(defined (OV2640_MINI_2MP))



#endif

#define   FRAMES_NUM    0x00



// set pin 4 as the slave select for SPI:

const int CS1 = 7;

bool CAM1_EXIST = false;

bool stopMotion = false;



ArduCAM myCAM1(OV2640, CS1);

long int streamStartTime;



void setup() {

  // put your setup code here, to run once:

  uint8_t vid, pid;

  uint8_t temp;

  Wire.begin();

  Serial.begin(250000); //921600

  Serial.println(F("ArduCAM Start!"));

  // set the CS output:

  pinMode(CS1, OUTPUT);



  // initialize SPI:

  SPI.begin();

  //Check if the 4 ArduCAM Mini 5MP PLus Cameras' SPI bus is OK

  while (1) {

    myCAM1.write_reg(ARDUCHIP_TEST1, 0x55);

    temp = myCAM1.read_reg(ARDUCHIP_TEST1);

    if (temp != 0x55)

    {

      Serial.println(F("SPI1 interface Error!"));

    } else {

      CAM1_EXIST = true;

      Serial.println(F("SPI1 interface OK."));

    }



    if (!(CAM1_EXIST)) {

      delay(1000); continue;

    } else

      break;

  }



  while (1) {

    //Check if the camera module type is OV5642


    myCAM1.rdSensorReg8_8(OV2640_CHIPID_HIGH, &vid);
    myCAM1.rdSensorReg8_8(OV2640_CHIPID_LOW, &pid);
    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;

    }

  }



  //Change to JPEG capture mode and initialize the OV2640 module

  myCAM1.set_format(JPEG);

  myCAM1.InitCAM();

  //myCAM1.write_reg(ARDUCHIP_TIM, VSYNC_LEVEL_MASK);   //VSYNC is active HIGH

  myCAM1.clear_fifo_flag();

  //myCAM1.write_reg(ARDUCHIP_FRAMES, FRAMES_NUM);



  //myCAM1.OV5642_set_JPEG_size(OV5642_640x480); delay(1000);

  myCAM1.OV2640_set_JPEG_size(OV2640_320x240); delay(1000);

  delay(1000);

  myCAM1.clear_fifo_flag();

  Serial.println("Ready:,1");

}



void loop() {



  if (CAM1_EXIST && stopMotion) {

    streamStartTime = millis();

    myCAMSendToSerial(myCAM1);

    double fps = ((millis() - streamStartTime) / 1000);

    Serial.println("fps: " + String(1 / fps ));

  }

}





void myCAMSendToSerial(ArduCAM myCAM) {

  char str[8];

  byte buf[5];



  static int i = 0;

  static int k = 0;

  uint8_t temp = 0, temp_last = 0;

  uint32_t length = 0;

  bool is_header = false;



  myCAM.flush_fifo(); //Flush the FIFO

  myCAM.clear_fifo_flag(); //Clear the capture done flag

  myCAM.start_capture();//Start capture



  while (!myCAM.get_bit(ARDUCHIP_TRIG , CAP_DONE_MASK));



  length = myCAM.read_fifo_length();

  Serial.print(F("FifoLength:,"));

  Serial.print(length, DEC);

  Serial.println(",");



  if (length >= MAX_FIFO_SIZE) //8M

  {

    Serial.println(F("Over size."));

    return ;

  }

  if (length == 0 ) //0 kb

  {

    Serial.println(F("Size is 0."));

    return ;

  }



  myCAM.CS_LOW();

  myCAM.set_fifo_burst();



  Serial.print("Image:,");



  while ( length-- )

  {

    temp_last = temp;

    temp =  SPI.transfer(0x00);

    //Read JPEG data from FIFO

    if ( (temp == 0xD9) && (temp_last == 0xFF) ) //If find the end ,break while,

    {

      buf[i++] = temp;  //save the last  0XD9

      //Write the remain bytes in the buffer

      myCAM.CS_HIGH();



      for (int i = 0; i < sizeof(buf); i++) {

        Serial.print(buf[i]); Serial.print(",");

      }



      Serial.println();

      Serial.println(F("Image transfer OK."));

      is_header = false;

      i = 0;

    }

    if (is_header == true)

    {

      //Write image data to buffer if not full

      if (i < 5) {

        buf[i++] = temp;

      } else

      {

        //Stream 5 bytes of raw image data to serial

        myCAM.CS_HIGH();



        for (int i = 0; i < sizeof(buf); i++) {

          Serial.print(buf[i]); Serial.print(",");

        }



        i = 0;

        buf[i++] = temp;

        myCAM.CS_LOW();

        myCAM.set_fifo_burst();



      }

    }

    else if ((temp == 0xD8) & (temp_last == 0xFF))

    {

      is_header = true;

      buf[i++] = temp_last;

      buf[i++] = temp;

    }



  }

}





void serialEvent() {

  if (Serial.available() > 0) {

    uint8_t temp = 0xff, temp_last = 0;

    uint8_t start_capture = 0;

    temp = Serial.read();

    switch (temp)

    {

      case 0:

        temp = 0xff;



        myCAM1.OV2640_set_JPEG_size(OV2640_320x240);

        Serial.println(F("OV2640_320x240")); delay(1000);

        myCAM1.clear_fifo_flag();

        break;

      case 1:

        temp = 0xff;



        myCAM1.OV2640_set_JPEG_size(OV2640_640x480);

        Serial.println(F("OV2640_640x480")); delay(1000);

        myCAM1.clear_fifo_flag();

        break;

      case 2:

        temp = 0xff;



        myCAM1.OV2640_set_JPEG_size(OV2640_1024x768);

        Serial.println(F("OV2640_1024x768")); delay(1000);

        myCAM1.clear_fifo_flag();

        break;




      case 3:

        {

          if (stopMotion)

            stopMotion = false;

          else

            stopMotion = true;

          Serial.println("Stop Motion Enabled: " + String(stopMotion));

        }

        break;



      case 0x10:

        if (CAM1_EXIST) {

          streamStartTime = millis();

          myCAMSendToSerial(myCAM1);

          double fps = ((millis() - streamStartTime) / 1000);

          Serial.println("Total Time: " + String(fps));

        }

        break;

      default:

        break;

    }

  }

}

Thanks in advance!


Viewing all articles
Browse latest Browse all 747

Latest Images

Trending Articles



Latest Images