Help with logic in saving tables

Hi, I have a scriopt that receives data from an accelerometer through Arduino. I want to save these data in a csv file.

The system works as follows:

  • Processing generates a sequence of sine waves (stored in freqList[]), each of them for an amount of time (recTime)
  • Continuously record the incoming data from arduino (through serialEvent()).
  • Save a new table/file for each of the frequencies (fileNames[])

So far it works well except that I’m stuck with the logic in the saving the recordings in a differnet table for each frequency played. I don’t understand where to put the logic and how to write it (eg should I use a global variable to keep track of which frequency is playing and determine when this frequency has finished playing?)

What’s the best approach? Thank you!

/*
* This application plays a series of sine waves at different frequencies (see freqList[]) and record the correpondent incoming output of accelerometer.
* Setup: laptop out -> amp -> vibrotactile actuator -> accelerometer (arduino) -> serial to Processing -> csv
* Press ENTER to start application
* Press ESC to quit/exit application
*/

import processing.sound.*;
import processing.serial.*;
Serial myPort;
Table table;
String fileName;
SinOsc osc;
int[] freqList = {20, 40, 80, 100, 120, 160}; //frequencies to be played

//file names for tables
String[] fileNames = {"20_flat", "40_flat", "80_flat", "100_flat", "120_flat", "160_flat"};

Boolean runApp = false;
int startTime;
int recTime = 1000; //1 second play time for each frequency
int fileIndex = 0;

void setup()
{
  size(300,300);
  
  String portName = Serial.list()[0];  
  myPort = new Serial(this, portName, 9600);
  myPort.clear();
 
  osc = new SinOsc(this);
  osc.freq(0);
  osc.stop();
  
//define table columns
  table = new Table();
  table.addColumn("id");
  table.addColumn("time");
  table.addColumn("rawX");
  table.addColumn("X");
  table.addColumn("rawY");
  table.addColumn("Y");
  table.addColumn("rawZ");
  table.addColumn("Z"); 
}

// record a new table row every time data is received from arduino 
void serialEvent(Serial myPort){
  
  if(runApp){
    try{
      String val = myPort.readStringUntil('\n');
    
      if (val!= null) {
        val = trim(val);
        //println("VAL: " + val);
        float readings[] = float(split(val, ','));
        
        TableRow newRow = table.addRow();
        newRow.setInt("id", table.lastRowIndex());
        newRow.setFloat("time", readings[0]);
        newRow.setFloat("rawX", readings[1]);
        newRow.setFloat("X", readings[2]);
        newRow.setFloat("rawY", readings[3]);
        newRow.setFloat("Y", readings[4]);
        newRow.setFloat("rawZ", readings[5]);
        newRow.setFloat("Z", readings[6]);
        } 
      }catch(Exception e){
        println("caught error parsing data:");
        //e.printStackTrace();
    }
  }
}

void draw(){
  background(30);
  textSize(32);
  textAlign(CENTER, CENTER);
  
  if(runApp){
    text("Recording", width/2, height/2); 
    
    osc.amp(1);
    osc.play();

    int curTime = millis();
    int timeDiff = curTime - startTime;
   
//play each frequency in freqList in serie for the same amount of time
// HERE I need help. after each frequency has played a new table should be saved
    if(timeDiff < recTime){
      osc.freq(freqList[0]);
    }else if(timeDiff >= recTime && timeDiff < recTime*2){
      osc.freq(freqList[1]);
    }else if(timeDiff >= recTime && timeDiff < recTime*3){
      osc.freq(freqList[2]);
    }else if(timeDiff >= recTime && timeDiff < recTime*4){
      osc.freq(freqList[3]);
    }else if(timeDiff >= recTime && timeDiff < recTime*5){
      osc.freq(freqList[4]);
    }else if(timeDiff >= recTime && timeDiff < recTime*6){
      osc.freq(freqList[5]);
    }else{ 
//OLD code for saving table (this saves 1 table with all frequencies, not what I need)
      //println("WRITING FILE" + fileNames[fileIndex]);
      //fileName = fileNames[fileIndex] + ".csv";
      //saveTable(table, fileName);
      
      if(fileIndex < 5)
        fileIndex++;
      else{
        runApp = false;
        exit();
      }        
     startTime = millis();
     }
  }else
    text("Idle", width/2, height/2); 

}

// start/stop application
void keyPressed(){
  
  if(key == ENTER){
    startTime = millis();
    runApp = true;
  }
  if(key == ESC){
    runApp = false;
    exit();
  }
}
1 Like

Lots of questions.

First: the if’s are wrong imo because you need to multiply the >= part as well by 2,3,4,5…

new version:


if (timeDiff < recTime) {
  osc.freq(freqList[0]);
} else if (timeDiff >= recTime && timeDiff < recTime*2) {
  osc.freq(freqList[1]);
} else if (timeDiff >= recTime*2 && timeDiff < recTime*3) {
  osc.freq(freqList[2]);
} else if (timeDiff >= recTime*3 && timeDiff < recTime*4) {
  osc.freq(freqList[3]);
} else if (timeDiff >= recTime*4 && timeDiff < recTime*5) {
  osc.freq(freqList[4]);
} else if (timeDiff >= recTime*5 && timeDiff < recTime*6) {
  osc.freq(freqList[5]);
}

Second: The else is wrong. The else would only be executed after all if’s failed but you want to execute file save after each event. So no else needed.

Wrapping it up

Here is an idea for your filenames using indexForFileNames:


int indexForFileNames=-1;


if (timeDiff < recTime) {
  osc.freq(freqList[0]);
  indexForFileNames=0;
} else if (timeDiff >= recTime && timeDiff < recTime*2) {
  osc.freq(freqList[1]);
  indexForFileNames=1;
} else if (timeDiff >= recTime*2 && timeDiff < recTime*3) {
  osc.freq(freqList[2]);
  indexForFileNames=2;
} else if (timeDiff >= recTime*3 && timeDiff < recTime*4) {
  osc.freq(freqList[3]);
  indexForFileNames=3;
} else if (timeDiff >= recTime*4 && timeDiff < recTime*5) {
  osc.freq(freqList[4]);
  indexForFileNames=4;
} else if (timeDiff >= recTime*5 && timeDiff < recTime*6) {
  osc.freq(freqList[5]);
  indexForFileNames=5;
}

// save
if (indexForFileNames>-1) {
  // syntax: saveTable(table, filename)
  saveTable(table, fileNames[indexForFileNames];
}

Chrisir

1 Like

Thanks.
I was thinking of doing something like this…but this way it keeps saving the file for each run of the loop()…is it safe to do so?

Ah

In theory this is unnecessary

You could fill the current table and save it only when one time slot ends?

yes that was my plan…but how would I detect when time slots ends and save the table only once?

when you check this:

 if (indexForFileNames==0) {
    saveThis=true;
  }

it would be executed only once during the time span (because then we set indexForFileNames to 1)

full code section:


int indexForFileNames=-1;
boolean saveThis = false; // tells the sketch to save  

if (timeDiff < recTime) {
  osc.freq(freqList[0]);
  indexForFileNames=0;
} else if (timeDiff >= recTime && timeDiff < recTime*2) {
  if (indexForFileNames==0) {
    saveThis=true;
  }
  osc.freq(freqList[1]);
  indexForFileNames=1;
} else if (timeDiff >= recTime*2 && timeDiff < recTime*3) {
  if (indexForFileNames==1) {
    saveThis=true;
  }
  osc.freq(freqList[2]);
  indexForFileNames=2;
} else if (timeDiff >= recTime*3 && timeDiff < recTime*4) {
  if (indexForFileNames==2) {
    saveThis=true;
  }
  osc.freq(freqList[3]);
  indexForFileNames=3;
} else if (timeDiff >= recTime*4 && timeDiff < recTime*5) {
  if (indexForFileNames==3) {
    saveThis=true;
  }
  osc.freq(freqList[4]);
  indexForFileNames=4;
} else if (timeDiff >= recTime*5 && timeDiff < recTime*6) {
  if (indexForFileNames==4) {
    saveThis=true;
  }
  osc.freq(freqList[5]);
  indexForFileNames=5;
}


// save
if (saveThis && (indexForFileNames>0)) {
  // syntax: saveTable(table, filename)
  saveTable(table, fileNames[indexForFileNames - 1]; // using -1 here !!!!
  saveThis = false;
}

//

Chrisir

1 Like

mm there’s somethign wrong as it doesn’t save any table. This is the whole draw()

void draw(){
  background(30);
  textSize(32);
  textAlign(CENTER, CENTER);
  
  if(runApp){
    text("Recording", width/2, height/2); 
    
    osc.amp(1);
    osc.play();

    int curTime = millis();
    int timeDiff = curTime - startTime;

    int indexForFileNames=-1;
    boolean saveThis = false; // tells the sketch to save  
    
    if (timeDiff < recTime) {      
      osc.freq(freqList[0]);
      indexForFileNames=0;
    } else if (timeDiff >= recTime && timeDiff < recTime*2) {
      if (indexForFileNames==0) {
        saveThis=true;
      }
      osc.freq(freqList[1]);
      indexForFileNames=1;
    } else if (timeDiff >= recTime*2 && timeDiff < recTime*3) {
      if (indexForFileNames==1) {
        saveThis=true;
      }
      osc.freq(freqList[2]);
      indexForFileNames=2;
    } else if (timeDiff >= recTime*3 && timeDiff < recTime*4) {
      if (indexForFileNames==2) {
        saveThis=true;
      }
      osc.freq(freqList[3]);
      indexForFileNames=3;
    } else if (timeDiff >= recTime*4 && timeDiff < recTime*5) {
      if (indexForFileNames==3) {
        saveThis=true;
      }
      osc.freq(freqList[4]);
      indexForFileNames=4;
    } else if (timeDiff >= recTime*5 && timeDiff < recTime*6) {
      if (indexForFileNames==4) {
        saveThis=true;
      }
      osc.freq(freqList[5]);
      indexForFileNames=5;
    } else
      startTime = millis();
    
    
    // this is never run
    if (saveThis && (indexForFileNames>0)) {
      saveTable(table, fileNames[indexForFileNames - 1]); // using -1 here !!!!
      saveThis = false;
      
      if(indexForFileNames == 5){
        runApp = false;
        exit();
      }
        
    }
           
  }else
    text("Idle", width/2, height/2); 

}

ok I moved the initialization if indexForFileNames outside (as gobal variable)

but still something is missing cause I only have 5 tables (and 6 sounds). It doesn’t save the first sound because of the >0 in the save part. But if I change that it will break the whole thing because of the fileNames[indexForFileNames-1]

void draw(){
  background(30);
  textSize(32);
  textAlign(CENTER, CENTER);
      
  if(runApp){
    text("Recording", width/2, height/2); 
    
    osc.amp(1);
    osc.play();

    int curTime = millis();
    int timeDiff = curTime - startTime;

    boolean saveThis = false; // tells the sketch to save  
    
    if (timeDiff < recTime) {      
      osc.freq(freqList[0]);
      indexForFileNames=0;
    } else if (timeDiff >= recTime && timeDiff < recTime*2) {
      if (indexForFileNames==0) {
        saveThis=true;
      }
      osc.freq(freqList[1]);
      indexForFileNames=1;
    } else if (timeDiff >= recTime*2 && timeDiff < recTime*3) {
      if (indexForFileNames==1) {
        saveThis=true;
      }
      osc.freq(freqList[2]);
      indexForFileNames=2;
    } else if (timeDiff >= recTime*3 && timeDiff < recTime*4) {
      if (indexForFileNames==2) {
        saveThis=true;
      }
      osc.freq(freqList[3]);
      indexForFileNames=3;
    } else if (timeDiff >= recTime*4 && timeDiff < recTime*5) {
      if (indexForFileNames==3) {
        saveThis=true;
      }
      osc.freq(freqList[4]);
      indexForFileNames=4;
    } else if (timeDiff >= recTime*5 && timeDiff < recTime*6) {
      if (indexForFileNames==4) {
        saveThis=true;
      }
      osc.freq(freqList[5]);
      indexForFileNames=5;
    } else
      startTime = millis();
    
    
    // save
    //println("RUN");
    if (saveThis && (indexForFileNames>0)) {
      saveTable(table, fileNames[indexForFileNames-1] + ".csv"); // using -1 here !!!!
      saveThis = false;
      println(indexForFileNames);

//need to move the following somewhere else
      //if(indexForFileNames == 5){
      //  runApp = false;
      //  exit();
      //}
        
    }
           
  }else
    text("Idle", width/2, height/2); 

}

I think it does save the first but not the last?

Yes that’s true, I’ve just changed the last else like this

else{
      if (indexForFileNames==5) saveThis = true;

      indexForFileNames=6;
        startTime = millis();
    }

and it works

1 Like

so my last (and working) draw() is the following. Thank you @Chrisir !!

void draw(){
  background(30);
  textSize(32);
  textAlign(CENTER, CENTER);
      
  if(runApp){
    text("Recording", width/2, height/2); 
    
    osc.amp(1);
    osc.play();

    int curTime = millis();
    int timeDiff = curTime - startTime;

    boolean saveThis = false; // tells the sketch to save  
    
    if (timeDiff < recTime) {      
      osc.freq(freqList[0]);
      indexForFileNames = 0;
    } else if (timeDiff >= recTime && timeDiff < recTime*2) {
      if (indexForFileNames == 0) saveThis = true;
      osc.freq(freqList[1]);
      indexForFileNames = 1;
    } else if (timeDiff >= recTime*2 && timeDiff < recTime*3) {
      if (indexForFileNames==1) saveThis = true;
      osc.freq(freqList[2]);
      indexForFileNames = 2;
    } else if (timeDiff >= recTime*3 && timeDiff < recTime*4) {
      if (indexForFileNames==2) saveThis = true;
      osc.freq(freqList[3]);
      indexForFileNames = 3;
    } else if (timeDiff >= recTime*4 && timeDiff < recTime*5) {
      if (indexForFileNames == 3) saveThis = true;
      osc.freq(freqList[4]);
      indexForFileNames = 4;
    } else if (timeDiff >= recTime*5 && timeDiff < recTime*6) {
      if (indexForFileNames == 4) saveThis = true;
      osc.freq(freqList[5]);
      indexForFileNames = 5;
    } else{
      if (indexForFileNames == 5) saveThis = true;
      indexForFileNames = 6;
    }
    
    // save
    if (saveThis && (indexForFileNames > 0)) {
      saveTable(table, fileNames[indexForFileNames-1] + ".csv");
      saveThis = false;

      if(indexForFileNames == 6){
        runApp = false;
        exit();
      }
        
    }
           
  }else
    text("Idle", width/2, height/2); 

}
3 Likes