Sunday, October 7, 2012

Arduino + Processing: JPEG Serial Transfer

I had a hard time figuring out how to send a jpeg file, over serial, from Arduino's SD card to Processing on my laptop. In the end, I found something called 'createOutput' in Processing and that seems to get the job done:

-Run the Processing sketch.
-Press the Arduino button to start sending jpeg.
-When transfer is complete (LED turns off), press any key in Processing sketch to finish saving file.

Arduino:
 #include <SD.h>   
  
 File photoFile;   
 const int buttonPin = 7;   
 const int ledPin = 5;   
   
   
 void setup(){   
   
  Serial.begin(115200);   
   
  pinMode(buttonPin,INPUT);   
  pinMode(ledPin,OUTPUT);   
   
  //Serial.println("initializing sd card");   
  pinMode(10,OUTPUT);     // CS pin of SD Card Shield   
   
  if (!SD.begin(10)) {   
   Serial.print("sd initialzation failed");   
   return;   
  }   
  //Serial.println("sd initialization done");   
 }   
   
   
 void loop(){   
   
  while(1){   
   // Serial.println("press the button to send picture");   
   Serial.flush();     
   
   while(digitalRead(buttonPin) == LOW);   
   if(digitalRead(buttonPin) == HIGH){   
    delay(50);   
   
    if(digitalRead(buttonPin) == HIGH){   
     delay(200);   
     File photoFile = SD.open("pic02.jpg");   
   
     if (photoFile) {   
      while (photoFile.position() < photoFile.size()) {   
   
       digitalWrite(ledPin,HIGH);              
       Serial.write(photoFile.read());   
      }   
   
      photoFile.close();   
      digitalWrite(ledPin,LOW);    
     }    
   
     else {   
      Serial.println("error sending photo");   
     }         
    }   
    //Serial.println("photo sent");    
   }   
  }   
 }     

Processing:
 import processing.serial.*;  
   
 Serial myPort;  
 OutputStream output;  
   
   
 void setup() {  
   
  size(320, 240);  
   
  //println( Serial.list() );  
  myPort = new Serial( this, Serial.list()[0], 115200);  
  myPort.clear();  
   
  output = createOutput("pic02.jpg");  
 }  
   
   
 void draw() {  
   
  try {   
   while ( myPort.available () > 0 ) {  
    output.write(myPort.read());  
   }  
  }   
  catch (IOException e) {  
   e.printStackTrace();  
  }  
 }  
   
   
 void keyPressed() {  
   
  try {   
   output.flush(); // Writes the remaining data to the file  
   output.close(); // Finishes the file  
  }   
   
  catch (IOException e) {  
   e.printStackTrace();  
  }  
 }    

7 comments:

  1. Hi, I know this is an old post now, but hopefully you will still be able to help.

    I'm making a pretty much identical program, with one key difference:
    I want to interpret serial commands in processing and then act accordingly.
    All that works fine, until eg:
    I receive the command to tell me data coming in is image data, I can then no longer interpret further commands to eg:
    end the image write.
    I've tried various ideas like sending the photo size across first, and looping until my byte array was the same, but with no luck.
    Unfortunately the same problem occurs when trying to send specific amounts of bytes.
    The only successful method I found, was waiting until the serial light stopped blinking, and manually flushing and closing the output.
    This is using code as above, but naturally I was hoping to automate it.

    Any help is hugely appreciated.

    Thanks, Joni

    ReplyDelete
  2. Hey, great post.
    I am actually trying to do the same but mm there's a problem with the processing code it seems.
    The arduino does send the data through the SPI but no picture appears at the other end.
    did i do something wrong. i basically copy pasted your code and still it does not work

    Thanks

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. Hello, this is my first arduino project: sending a file (jpeg, pdf, txt) from an arduino sd card module to android phone using arduino uno and bluetooth module HC-05

    have you any suggestion about the android app to receive the file ?
    thank you

    ReplyDelete
  5. Yeah! You must gîve trust on the fact that during sending time the device do send at a steady pace, lets say at l'est 8 bytes every 1/20 of a second on the Arduino side. So on the Processing side. If it's been a few 1/20 of a seconde, that no data is Avalable in the serial buffer, you Know the file is In.

    ReplyDelete
  6. Abhas Maskey if you Want to load jpeg to tft usinG MEGA526 OR Due. Try this libraire



    https://github.com/fredericplante/JPEGDecoder/blob/master/README.md

    ReplyDelete
  7. Otherwise, save the document as RTF (Rich Text Format) to maintain most, if not all, formatting.
    https://downloadshareitapp.com

    ReplyDelete