title: Saving serial data in Processing
body: <p>Hello all for the second time,</p>
  
  <p>Initially I was looking for a broad answer, but this thread got blocked for being "too broad"... so I've got no choice, but to go into detail. My apologies if asking the question again is against the forum guidelines, I'm new to stackoverflow so please be kind.</p>
  
  <p>I’ve got data coming into a serial port at 250Hz and I’d like to save it all to a .csv file. Of course draw() is not going to be able to keep up with that rate of data...</p>
  
  <p>At the moment I am using the serialEvent(port) to collect and parse the data. Once parsed out, I'm calling a function in draw to add the data to a new line in a table and then saving that table every 5 seconds... </p>
  
  <p>Yes, I see the obvious flaw that if I'm saving the current data in draw then of course it's not going to be able to save all the data coming in, but rather just the data that happens to be present when the data saving function is called... but I'm not sure of the best way to solve that. A buffer scheme? Or can I have a separate thread that just adds ALL data coming in to a table?</p>
  
  <p>which lead to my initial (broad) question...
  Is there a way to save all incoming data to a file without polling? </p>
  
  <p>Thanks to all in advance.. code below:
  Twain</p>
  
  <pre><code>import processing.serial.*;
  import static javax.swing.JOptionPane.*;
  
  Table table;
  String Path = "PathProvidedHere.csv";
  String message;
  
  //Some time keeping variables
  int hours, minutes, seconds, milliseconds;
  float SaveTime;
  
  //Serial port selection
  Serial myPort;
  String COMx, COMlist = "";
  final boolean debug = true;
  String portName;
  
  // Data variables
  float yaw = 0.0; float pitch = 0.0; float roll = 0.0;
  float A1, A2, A3, A4;
  float E1, E2, E3, E4;
  
  void setup()
  {
      //Set up GIU box
      size(1024, 768, P3D);
      frameRate(250);  
      smooth();
  
      //Some other setups  like fonts, graphs, etc.
  
      //Set up the logging table
      table = new Table();  
      table.addColumn("A1"); table.addColumn("A2"); table.addColumn("A3"); table.addColumn("A4");
      table.addColumn(""); table.addColumn("E1"); table.addColumn("E3"); table.addColumn("E4");  
      table.addColumn(" "); table.addColumn("min"); table.addColumn("sec"); table.addColumn("milli");
  
      portName = chooseCOM();
  
      delay(1000); 
  }
  
  
  void draw()
  {  
      SavetoCSV();
  
      //serialEvent(myPort);  // read and parse incoming serial message
  
      ACouple();
      Unrelated();
      FunctionsHere();
  
      if(millis() - SaveTime &gt; 5000)
      {
          saveTable(table, Path);
          SaveTime=millis();
      }
  }
  
  
  String chooseCOM()
  {
      setupP2 = true;
  
      try 
      {
          if (debug) printArray(Serial.list());
  
          int i = Serial.list().length;
  
          if (i != 0) 
          {
              if (i &gt;= 2) 
              {
                  // need to check which port the inst uses -
                  // for now we'll just let the user decide
                  for (int j = 0; j &lt; i; ) 
                  {
                      COMlist += char(j+'a') + " = " + Serial.list()[j];
                      if (++j &lt; i) COMlist += ",  ";
                  }
  
                  COMx = showInputDialog("Which COM port is correct? (a,b,..):\n"+COMlist);
  
                  if (COMx == null) exit();
  
                  if (COMx.isEmpty()) exit();
  
                  i = int(COMx.toLowerCase().charAt(0) - 'a') + 1;
              }
  
              String portName = Serial.list()[i-1];
  
              if (debug) //println(portName + " Selected");
  
              myPort = new Serial(this, portName, 115200); // change baud rate to your liking
              myPort.bufferUntil(13); // buffer until CR/LF appears, but not required..
  
              return portName;
          } 
          else 
          {
              showMessageDialog(frame, "Device is not connected to the PC");
              exit();
          }
      }
      catch (Exception e)
      { //Print the type of error
          showMessageDialog(frame, "COM port is not available (may\nbe in use by another program)");
          //println("Error:", e);
          exit();
      }
  
      return "noPort";
  }
  
  
  void serialEvent(Serial myPort)
  {
      int newLine = 13; // new line character in ASCII
  
      do
      {
          message = myPort.readStringUntil(newLine); // read from port until new line
  
          if (message != null) 
          {
              String[] list = split(trim(message), " ");
  
              if (list.length == 4 &amp;&amp; list[0].equals("i")) 
              {
                  yaw =  float(list[1]); // convert to float yaw
                  pitch = float(list[2]); // convert to float pitch
                  roll = float(list[3]); // convert to float roll
              } 
              else if (list.length == 5 &amp;&amp; list[0].equals("s")) 
              {  
                  A1 = float(list[1]);
                  A2 = float(list[2]);
                  A3 = float(list[3]);
                  A4 = float(list[4]);
              } 
              else if (list.length &gt;=2 &amp;&amp; list[0].equals("b")) 
              {  
                  Battery = int(list[1]);
              } 
              else if (list.length &gt;= 2 &amp;&amp; list[0].equals("m")) 
              {  
                  MACid = int(list[1]);
              } 
              else 
              {
                  //print anything extra to console
                  //println(message);
              }
          }
      } while (message != null);
  }
  
  void SavetoCSV() 
  {
      if (A1 != 0) 
      {
          TableRow newRow = table.addRow();
          newRow.setFloat("A1", (A1));
          newRow.setFloat("A2", (A2));
          newRow.setFloat("A3", (A3));
          newRow.setFloat("A4", (A4));
  
          //saveTable(table, Path);
      }
  }
  </code></pre>
  
  <p>Additional info:
   - Processing P3
   - For the record, with the rest of my script I can get draw up to 80hz or so
   - I'd be okay with saving all the data and parsing it later</p>