Snail Aid - Technology for Development

Impresa Sociale 

Via Montallegro 5/3, 16145 Genova
Fiscal Code: 95112630108
VAT n.: 02119750996
Registred at the Chamber of Commerce with the n. GE-460458
 
Contacts:
snailaid AT gmail.com
+39 3331655089
 
Categories
    Archives

     

    In the development of several projects we had the need of an easy, versatile and low cost data acquisition system for monitoring important variables like pressure, temperature and other meters.

    For this reason we developed a very simple data acquisition system based on Arduino platform and Processing programming language, naming it liber 1.

    Liber 1 is based on opensource hardware and software, and was developed in an interpreted language for keeping it available for different platforms (linux, mac os and even windows).

    The two basic concepts are rather simple:

    • having a minimum control on the instantaneous values , which are written into a simple window, for immediate intervention
    • storing the data into a text file on a pc.

    The code is divided into 2 parts, one (the firmware) has to be uploaded on the arduino microcontroller and is responsible for the channels reading and averaging the data into a certain time period, while the other (the software) runs on a pc connected to the Arduino card and is responsible for the collection, conversion and storage of the data.

    Screenshot - click on the image for larger view

    A txt file gets created with the time and the data collected, that can be easily imported in your favourite data processing software (spreadseet:libreoffice, openoffice, excel. Matlab, Scilab, Octave or similar).

    Everything, including the font to be used by processing, is included in the downloadable file here.

    The code is also included in the following. In case this is going to be used (and not the link above), remember to create the font file (named "mono.vlw") with the processing tool menu.

    The firmware (to be uploaded on the Arduino board):

    /*
     Liber 1

     Liber 1 is an easy set up for the Arduino Mega board fro realizing
     a cheap Data Acquisition.
     The circuit:
     Attach all the sensor with Tension signals to the pins of the board.
     The ones that are not used would better be ground connected.

    */

    void setup() {
     // initialize the serial communication:
     Serial.begin(9600);
    }

    void loop() {
     Serial.println('P');

    int nMedie=10;  //numeri da mediare ogni lettura

    //Setting empty array for getting data
    int canale[15]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

    //starting average
    for (int j=0; j <= nMedie; j++){
      for (int i=0; i <= 15; i++){
        canale[i] = analogRead(i) + canale[i];
      }
    }

    for (int j=0; j <= nMedie; j++){
      canale[j]=canale[j]/nMedie;
      // send the value of analog input 0:
      Serial.println(canale[j]);
    }  
     
     // wait a bit for the analog-to-digital converter
     // to stabilize after the last reading:

     delay(1000);

    }

    The Software (to be executed in processing sw):

    //************************************************************************
    // Graphing sketch
    // This program takes ASCII-encoded strings
    // from the serial port at 9600 baud and graphs them. It expects values in the
    // range 0 to 1023, followed by a newline, or newline and carriage return

    // Calling the Processing serial library
    import processing.serial.*;

    /*****************************************Definitions***************************************/
    //************************************************
    //Here are the values that have to be set up by the user
    //************************************************
    int nSerial=0;         //Serial Port number
    int nCanali = 8;       //Number of channels
    float nPres=7;         //Pressure probe channel, if absent, set to 30
    float nFumi=6;         //Flow gases Temp probe, if absent, set to 30
    float rP=.215;         //Known Resistance on the Pressure channel
    float rNotaNTC=10000;  //Known resistance for the NTC circuit, in Ohm
    float rNotaPT100=99.5; //Known resistance for the Pt100 circuit, in Ohm
    float aliment=5;       //Voltage for feeding the Temp probe circuits
    //************************************************
    //End of the settings part
    //************************************************

    /*********Other Variables************/
    float rMis=0;          //Measured resistance at the channel
    float tensMis=0;       //Measured voltage
    Serial myPort;         // The serial port
    int xPos = 1;          // horizontal position of the graphics
    int count = 0;
    int scrivi = 0;
    float[] data = new float[nCanali];
    PrintWriter output;    //Output filename
    float dataOut;
    /*********End of Other Variables************/
    /**************************************End of Definitions************************************/

    /*********Setup function, happens only once*********/
    void setup () {
      // set the window size:
      size(300, nCanali*25+35);
      // List all the available serial ports
      println(Serial.list());
      // Open whatever port is the one you're using.
      myPort = new Serial(this, Serial.list()[nSerial], 9600);
      // don't generate a serialEvent() unless you get a newline character:
      myPort.bufferUntil('\n');
      // set inital background:
      background(255);
      //Output Filename
      output = createWriter("data.txt");
    }
    /*********End of Setup**********/

    void draw () {
      // everything happens in the serialEvent()
    }

    void serialEvent (Serial myPort) {
      // get the ASCII string:
      String inString = myPort.readStringUntil('\n');
     
      if (inString != null) {
        // trim off any whitespace:
        inString = trim(inString);
        if(inString.equals("P")){
          count=0;
          if (second()==10||second()==40)
            scrivi=1; //scrivi is a  flag activated at the tenth second of each minute for writing to the ouput file
          if (scrivi==1){
            output.println("");
            output.print(day()+""+TAB+""+hour()+""+TAB+""+minute()+""+TAB);
          }
          PFont font;
          font = loadFont("mono.vlw");
          textFont(font);
          fill(0);
          text("Push <b> to stop",20,nCanali*25+25);
          fill(255);
      }
      else {
        if(count<nCanali) {
          //Calibrazione canali
          /*Trovata curva di calibrazione per NTC con curveexpert
          Harris Model: y=1/(a+bx^c)
          Coefficient Data:
          a=      -6.25116347002E-003
          b=      7.44960639190E-003
          c=      2.75523042335E-002
          */
          tensMis=float(inString)*5/1024; //Tens rilevata dal canale
          if (count==nFumi) { //caratteristica del canale della pt100
            //rMis=tensMis*rNotaPT100/(aliment-float(inString)*5/1024);
            dataOut=263.05*tensMis-675.68;
          }
          else if (count==nPres) { //caratteristica del canale del sensore di pressione
            dataOut=-63.047+15.11*(tensMis/rP);
          }
          else { //si suppongono i rimanenti canali aventi caratteristica NTC
            rMis=tensMis*rNotaNTC/(aliment-float(inString)*5/1024);
            dataOut=1/(-6.25116347002E-003+7.44960639190E-003*pow(rMis,
            2.75523042335E-002))-273;
          }
          //inizitialize the font
          PFont font;
          font = loadFont("mono.vlw");
          textFont(font);
          //draw a rectangle and write the value
          rect(15, 25*count, 240,25 );
          fill(0);
          String s="Can "+(count+1)+" - "+dataOut;
          text(s, 20, 22+25*count);
          fill(255);
          count++;
          //data[count]=float(inString);
          if (scrivi==1){
            output.print(dataOut+""+TAB);
            if (count==nCanali)
            scrivi=0;
          }
        }
      }
      }
          
    }
    //************************************************************************

    //Function for terminating and storing the data
    void keyPressed() {
      if (key == 'b' || key == 'B') {
        //output.flush(); // Write the remaining data
          output.close(); // Finish the file
          exit(); // Stop the program
      }
    }