Go Down

Topic: Serial Transfer JPEG to Processing [SOLVED] (Read 2 times) previous topic - next topic

Dread-Eye

Sep 23, 2012, 06:29 am Last Edit: Sep 24, 2012, 02:02 pm by Dread-Eye Reason: 1
I am trying to send a jpeg image from an SD card, over serial, to Processing.  So far, I have pieced together some code that makes use of Arduino's DumpFile and Processing's PrintWriter.  Unfortunately, what I'm receiving is not exactly the same as what I'm sending - similar, but not the same.  Just looking at the two files in a text editor, some of the characters seem to have been "simplified" in transit.  Any suggestions?

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

Arduino:
Code: [Select]
#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:
Code: [Select]
import processing.serial.*;

Serial myPort;
PrintWriter output;


void setup(){
 
 size(320, 240);

 //println( Serial.list() );
 myPort = new Serial( this, Serial.list()[0], 115200);
 myPort.clear();

 output = createWriter("pic02.jpg");
}


void draw(){

 while ( myPort.available () > 0 ) {
   output.write(myPort.readString());
 }
}


void keyPressed() {

 output.flush();
 output.close();
}

http://peace.dreadeye.com

Coding Badly


Coding Badly

Code: [Select]
    output.write(myPort.readString());

I suspect a method named "readString" probably cooks the data.  Is there a "read" or "readByte" or "readBinary"?

Dread-Eye

#3
Sep 23, 2012, 07:18 am Last Edit: Sep 23, 2012, 05:47 pm by Dread-Eye Reason: 1
My programming "skills" are mostly limited to cut and paste.  No idea why 'Serial.flush', it doesn't seem to matter if that line is left in or not.  Replacing 'readString' with 'read' gives a slightly different output, but the transferred file remains unreadable.  Thanks.
http://peace.dreadeye.com

Coding Badly

No idea why 'Serial.flush', it doesn't seem to matter if that line is left in or not.


Then leave it out.

Quote
Replacing 'readString' with 'read' gives a slightly different output, but the transferred file remains unreadable.


Different in what way?  Truncated file?

PaulS

Code: [Select]
    while(digitalRead(buttonPin) == LOW);
    if(digitalRead(buttonPin) == HIGH){
      delay(50);

      if(digitalRead(buttonPin) == HIGH){
        delay(200);

While the switch is not pressed, do nothing. Then, test to see if the switch is pressed. If so (and, by definition is must be), do nothing some more. Why?

If the switch is still pressed, do nothing some more. Why?

Quote
My programming "skills" are mostly limited cut and paste.

Then jumping in, cutting and pasting stuff you don't understand, is really not a good idea.

Code: [Select]
void draw(){

  while ( myPort.available () > 0 ) {
    output.write(myPort.readString());
  }
}

Serial I/O is supposed to be done in the serialEvent() method, NOT the draw() function. Unlike loop() in an Arduino sketch, which is called over and over as fast as possible, the draw() function is called over and over, some number of times per second. During that wait for the next call to draw, serial data can overflow the buffer.

The serialEvent() method is called whenever there is serial data to read, regardless of when draw() will be called again.

Dread-Eye

The Arduino sketch I posted began life as the demo code for a serial jpeg camera that I would like to operate remotely.  I have been steadily cutting and pasting to this sketch by searching out posts, on this forum and others, by folks with similar projects and problems to mine.  The 'serial.flush' and button debounce delays were left over after stripping my Frankenstein code in an attempt to ask for specific help. 

I agree that using code that I don't understand is not a good idea; but, I suspect that it's common practice for electronics and programming newcomers.  I apologize for any distracting code that I can't help explain.

The received file is not truncated.  In fact, it's larger.  Looking at the sent and received file side by side in a text editor, I see that most of the Greek letters and symbols have been converted into square root symbols and accented letters.  The difference between the 'read' and 'readString' output was simply a matter of which accented letters were used to replace the original symbols.

I have posted this same question to the Processing forum and an early reply also suggests that my problem is on the receiving end.

Quote
...readString() isn't the right way to read binary data: strings are special beasts, following the Unicode standard, where some binary combinations are just forbidden. So, I guess that some strings have incorrect Unicode characters in them, and they are "fixed" by Java.


I'll move my Processing serial commands to a 'serialEvent' method and see if that helps.  Thanks again.
http://peace.dreadeye.com

Dread-Eye

The problem was with Processing's 'PrintWriter', so I tried something called 'createOutput' and that seems to get the job done:

Code: [Select]
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();
 }
}
http://peace.dreadeye.com

Go Up