Pages: [1]   Go Down
Author Topic: Serial Transfer JPEG to Processing [SOLVED]  (Read 1810 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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:
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();
}

« Last Edit: September 24, 2012, 07:02:24 am by Dread-Eye » Logged


Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 176
Posts: 12285
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
    Serial.flush();   

Why?
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 176
Posts: 12285
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
    output.write(myPort.readString());

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

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: September 23, 2012, 10:47:58 am by Dread-Eye » Logged


Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 176
Posts: 12285
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 547
Posts: 46000
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
    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:
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.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
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();
  }
}
Logged


Pages: [1]   Go Up
Jump to: