Saving Arduino data with Processing

xluxlu
edited November 2013 in Arduino

Hi,

I have read the other posts but I still have a hard time putting together the codes for Processing.

The goal here is to save the instantaneous voltage reading by Arduino with Processing (one column for time and the other for voltage reading).

Here is my Arduino code (for now, every second it reads one voltage, print all 30 readings in CSV form, and stop completely) :

void setup(){
  Serial.begin(9600);  //open the serial port at 9600 bps
  unsigned long time;
  time = millis();
  while(millis() - time < 30UL * 1000UL){
  int sensorValue = analogRead(A0); //read the analog input on pin 0
  float voltage = sensorValue * (5.00/1023.00);
  Serial.print(voltage,DEC);
  Serial.println(",");
  delay(1000);
}
}

void loop(){
  //everything already happened//
}

For Processing, I just used the codes from a previous post seen in this forum. Right now, the createWrite() will generate an empty file with the proper date and time. I tried the read() example from the Processing site and Arduino is indeed senting some data because the Processing monitor printed some numbers. So I think the problem is the Processing code below is not completely customized for the purpose.

import processing.serial.*;
import java.text.*;
import java.util.*;

PrintWriter output;
DateFormat fnameFormat = new SimpleDateFormat("yyMMdd_HHmm");
DateFormat timeFormat = new SimpleDateFormat("hh:mm:ss:SSS");

String fileName;

Serial myPort;        // Create object from Serial class
short portIndex = 3;  // select the com port, 0 is the first port
char HEADER = 'H';

void setup()
{
  // Open whatever serial port is connected to Arduino.
  println(Serial.list());
  myPort = new Serial(this, Serial.list()[0], 9600);
  Date now = new Date();
  fileName = fnameFormat.format(now);
  output = createWriter(fileName + ".csv"); // save the file in the sketch folder
}

void draw()
{
  int val;
  String time;

  if ( myPort.available() >= 15)  // wait for the entire message to arrive
  {
    if( myPort.read() == HEADER) // is this the header
    {
      String timeString = timeFormat.format(new Date());
      println(timeString);
      val = myPort.read();
      output.println(timeString);
      // header found
      // get the integer containing the bit values
       val = myPort.read();
      // print the analog value
      for(int i=0; i < 1; i ++){
        val = myPort.read();
        println(val);
        output.println(val);
      }
    }
  }
}

void keyPressed() {
  output.flush(); // Writes the remaining data to the file
  output.close(); // Finishes the file
  exit(); // Stops the program
}

Please give me some insights on how I may save the instantaneous voltage reading by Arduino with Processing (one column for time and the other for voltage reading).

Thank you!

Answers

  • Answer ✓

    http://processing.org/reference/Table.html Table readings;

    readings = loadTable(<table file>); // add this line to setup() if you have a table file already (so you can update the file)
    readings = new Table(); // add this line to setup() if you don't have a table file already
    readings.addColumn("Time", Table.STRING); // add this line to setup() if you don't have a table file already
    readings.addColumn("Value", Table.INT); // add this line to setup() if you don't have a table file already
    
    void addEntry(String time, int reading) {
        readings.addRow();
        readings.setString((readings.getRowCount()-1), "Time", time);
        readings.setInt((readings.getRowCount()-1), "Value", reading);
    }
    
    void saveReadings() {
        saveTable(readings, <filename>);
    }
    

    Using the methoods above, you can just store your readings inside of a table and then save the table, use it later, do anything you want with these readings.

  • Thank you. I found a simpler way to do this.

  • xluxlu
    edited November 2013

    It might not appear to be simpler. But the following is just modifying the codes SLIGHTLY from the examples online so the beginners like me can follow better.

    Important: The reason why I am not using the original Arduino code posted earlier is that although it is nice to have the actual numbers (float) for the voltage reading, it is more efficient to work with binary numbers.

    For the Arduino, I just copied and pasted the voltage reading example. (http://arduino.cc/en/Tutorial/ReadAnalogVoltage)

    int voltPin = 1; //voltmeter connected to analog pin 0
    int analogValue = 1; //variable to hold the analog values
    
    void setup(){
      Serial.begin(9600); //open the serial port at 9600 bps
      pinMode(voltPin, INPUT);
    }
    
    void loop(){
      int analogValue = analogRead(voltPin); //read the analog input on pin 0
      Serial.println(analogValue, DEC); //print the voltmeter reading
      delay(1000); //delay 1 second before the next reading
    }
    

    (Btw, I modified voltPin = 1 instead of 0 because my copper wire is broken and stuck in the A0 pin. I can't get it out! So frustrating! Anyway, I put the wire in the A1 pin for now. Suggestion on how to get the broken wire out will be very much appreciated!)

  • xluxlu
    edited November 2013

    Here is the Processing Code. I kind of modified the codes also from the same Arduino voltage reading example (same site).

    In short, it prints a cycle of one line of voltage reading and one line of time (and plus graphing which is included from the example code). When a key on the keyboard is pressed, the program stops and a Excel file is created automatically with the data. Then I open the Excel file and use the OFFSET function to separate the one column of combined time and voltage into two columns (one for time and the other column for voltage).

    (I am still looking for a way for Processing to put them into two columns. Hopefully, it would not require a major overhaul like using the Table functions because I am tired of this 4-weeks of intermittent trial and error. I am ready to collect some data and write my thesis! I am a civil engineering student doing a thesis project on solar panel efficiency so I am quite ignorant of Arduino and Processing, unlike most electrical engineering students.)

    Ok, back on track. The file name is the exact time of when data is being taken. This little feature is copied directly from a discussion thread in this Processing/Arduino forum.

    import processing.serial.*;
    import java.text.*;
    import java.util.*;
    
    PrintWriter output;
    DateFormat fnameFormat = new SimpleDateFormat("MMddyy_HHmm");
    DateFormat timeFormat = new SimpleDateFormat("hh:mm:ss:SSS");
    
    String fileName;
    
    Serial myPort; // Create object from the serial port
    short portIndex = 3; //Select the com port, 0 is the first port
    char HEADER = 'H'; 
    int xPos = 1; // horizontal position of the graph
    
    int savedTime;
    
    void setup () {
      size(400, 300); // set the window size:
      println(Serial.list()); // List all the available serial ports
      //If Arduino is in the first port in the serial list, open Serial.list()[0].
      myPort = new Serial(this, Serial.list()[0], 9600);
      // don't generate a serialEvent() unless you get a newline character
      myPort.bufferUntil('\n');
      background(0); // set inital background
      savedTime = millis();
      Date now = new Date();
      fileName = fnameFormat.format(now);
      output = createWriter(fileName + ".csv");
    }
    
    void draw () {
      savedTime = millis();
    }
    
    void serialEvent (Serial myPort) {
      String inString = myPort.readStringUntil('\n'); // get the ASCII string
      if (inString != null) {
         inString = trim(inString); // trim off any whitespace
         float inByte = float(inString); // convert to an int and map to the screen height
         output.println(inByte);
         output.println(savedTime/1000);
         println(inByte);
         println(savedTime/1000);
         inByte = map(inByte, 0, 1023, 0, height);
         stroke(127,34,255); // draw the line
         line(xPos, height, xPos, height - inByte);
    
         // at the edge of the screen, go back to the beginning:
         if (xPos >= width) {
         xPos = 0;
         background(0); 
         } 
      else {
         xPos++; // increment the horizontal position:
      }
     }
    }
    
    void keyPressed() {
      output.flush();  // Writes the remaining data to the file
      output.close();  // Finishes the file
      exit();  // Stops the program
    }
    
  • I got this error message "The function readStringUntil(char) does not exist". Please help me to solve this issue.

  • In place of lines 43 and 44 try

    output.println(inByte + "," + savedTime/1000);
    

    to put in the comma for csv format.

Sign In or Register to comment.