 /*
 Sketch for Arduino Uno included in the Open ISEmeter project (v.2)
 
 Authors J.D. Mozo and C. Salvador from the www.uhu.es/oswh group
 
 Released unther the Creative Commons Atribution-NonCommectial-ShareAlike 3.0 license (CC BY-NC-SA 3.0)
 
 Arduino Uno is supplied with a home-made shield to read the Open Circuit voltage from an Ion Selective Electrode
 or any chemical battery avoiding the consum of current by a high-impedande differential reading system
 It also includes a set of low-pass filters you can selected by code towards the USB port and
 a programable-gain differential amplifier to read de fem of cell.
 Arduino paces the adquisition by controlling time between readings and send data to PC by USB 
 */
 
 
 #include <SPI.h>                     // include library for SPI protocol (to set programmable resistor and controling Gain)
 
 // variable declaration
 int gain = 255;                      // set gain to x5
 boolean Flt = LOW;                   // set the analog channel for reading filtered volt 
 char serialData = 0;                 // stores data read from USB (one byte 0 to 255)
 unsigned long previousTime = 0;      // stores previous read time in microseconds
 unsigned long currentTime = 0;       // stores actual time in microseconds
 unsigned long interval = 333333;     // stores interval-between-reads in microseconds 
 boolean Adquire = LOW;               // stores if acquisition is enabled
 int volt = 0;                        // stores the voltage value from analog channel
 
 // pin assignation
 const int ss = 10;                   // Chip Select for programable resistor (arduino uno: 10; arduino mega: 53)
 const int flt = 4;                   // analog channel for reading filtered voltage

 
 /* USB command set
 gn     == Gain (n = 0 to 255)        gain setting for INA101
 r      == GO Run                     start analog adquisition
 s      == STOP run                   stop adquisition
 fn     == Filter (n = 0 to 1)        sets the analog channel for readings (n = 0: Active LP filter, n = 1: RC LP filter)
 vn,m   == Volt (n,m = 0 to 1024)     send the voltage value readed to USB (0 to 5 volts)(n unfiltered, m filtered)
 */
 
 
 void setup() {
   pinMode(ss,OUTPUT);

   // init SPI (variable resistor)
   SPI.begin();
   SPI.setBitOrder(MSBFIRST);
   // use SPI for change gain setting
   digitalWrite(ss,LOW);
   SPI.transfer(0x11); //to intialize
   SPI.transfer(gain); //send gain data by SPI port
   digitalWrite(ss,HIGH);
   
   // init serial port (USB)
   Serial.begin(9600);
 }
 void loop() {
   // first read the actual time 
   currentTime = micros();
   
   // check if data is waiting on serial port
   while (Serial.available() > 0) {
     serialData = Serial.read();
     switch (serialData) {
       case 'g':
         gain = Serial.parseInt();         // read numerical value for gain 
         gain = constrain(gain, 0, 255);
         Serial.print("Ok, g");            // handshaking "Ok, gn"
         Serial.println(gain,DEC);   
         // use SPI for change gain setting
         digitalWrite(ss,LOW);
         SPI.transfer(0x11); //to intialize
         SPI.transfer(gain);
         digitalWrite(ss,HIGH);
         break;
       case 'f':
         Flt = Serial.parseInt();          // read filter setting
         Flt = constrain(Flt, 0, 1);
         Serial.print("Ok, f");            // handshaking "Ok, fn"
         Serial.println(Flt,BIN);
         break;
       case 'r':
         Adquire = HIGH;
         Serial.print("Ok ,");
         Serial.println(serialData);
         break;
       case 's':
         Adquire = LOW;
         Serial.print("Ok ,");
         Serial.println(serialData);
         break;
     }
     int serialDataTmp = Serial.read();    // empty serial port (CR)
   }
   
   // check if reading time is ellapsed
   if (currentTime - previousTime >= interval && Adquire == HIGH) {
     previousTime = currentTime;           // stores actual time (RESET time)
     Serial.print("v");
     volt = analogRead(5);          // read not filtered volt
     Serial.print(volt,DEC);
     Serial.print(",");
     volt = analogRead(4-Flt);      // read volt regarding the Flt setting
     Serial.println(volt,DEC);
   }
 }
  





