We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hi all, I am trying to record incoming data from a serial port as well as capturing video. Because of the speed (data is coming every millisecond) I had to trigger the video capture inside the serialEvent (built-in camera works at 30 fps max). I decided to capture a snapshot every 50ms. It takes too long to save the snapshot so I had to buffer it in an arrayList. I did the same with the serial data. Acquisition is triggered and stopped using keyPressed. Once it is finished, I come back to my arrayLists and save the pictures one by one (including the serial data in the name, it is just a short string). Here is the trouble: instead of reading the content of the Capture arrayList it reads whatever is coming from the camera.
I tried without success: -myPort.stop() -myVideo.stop() -noLoop() -using a PImage arrayList instead of Capture object arrayList -use different ways to trigger/stop acquisition.
It doesn't make any sense to me... why when I write mySnapshotAL.get(i) do I get the current camera view and not the content of the arrayList which is populated properly (I checked the size) ???
Many thanks!!!
import processing.video.*;
import processing.serial.*;
Capture myVideo; // declaring a Capture object
Serial myPort; // declaring a serial port
ArrayList<String> myDataAL; // declaring an ArrayList of String (serial data)
ArrayList<Capture> mySnapshotAL; // declaring an ArrayList of Capture objects
String myFileName;
String myDataString;
String myDate;
int startTime;
String myTime;
int i=0;
boolean saving=false;
void setup() {
frameRate(1000);
size(1000, 700);
background(0);
mySnapshotAL= new ArrayList<Capture>(); // initialising the ArrayList of Capture objets
myDataAL= new ArrayList<String>(); // initialising the ArrayList of String
myVideo = new Capture(this, 320, 240,30); // initialising the Capture object
myVideo.start();
myPort = new Serial(this, Serial.list()[1], 9600); // initialising the port dev/cu.usbmodem1411
myPort.bufferUntil(10); // char(10) = line feed
}
void serialEvent(Serial myPort) { // myPort receives data every ms
i++;
if (i==50){
myVideo.read(); // only acquire every 50 ms
i=0;
}
myDataString = trim(myPort.readString());
myTime=nf(millis()-startTime,6,1).substring(0,5);
myDataString=myTime + "," + myDataString;
if (saving){
mySnapshotAL.add(myVideo);
myDataAL.add(myDataString);
}
}
void draw() {
image(myVideo, 600, 40);
}
void keyPressed(){
if (!saving) {
saving=true;
startTime=millis();
}
else {
saving=false;
myDate= nf(hour(),2,1).substring(0,2) + "h" + nf(minute(),2,1).substring(0,2);
for (int i =0; i<mySnapshotAL.size(); i++){
myFileName="VideoFiles/Capture" + i + "@" +myDate+ "-" +myDataAL.get(i)+".png";
mySnapshotAL.get(i).save(myFileName);
if (i==300) break; // safety, until code is failproof
}
}
}
Answers
Line 38.... you are storing a reference to camera's PImage. Try this instead:
mySnapshotAL.add(myVideo.get());
Kf
Thanks for suggestion kfrajer but Processing didn't accept it: The function "add()" expects parameters like: "add(Capture)"
I found a workaround: I save pictures directly every 50 ms and I store data every 1 ms in a Table then I duplicate the missing pictures. Could be better but it serves the purpose...
That is because your array is of type Capture. You should define your array as PImage. capture extends PImage and PImage.get() ensures you are working with a copy of the data, not a reference to the data.
My approach is better than saving the pictures, if you are referring to either save() or saveFrame().
Kf