//
// step response, phototransistor and LED input
//
// 57600 baud FTDI interface
//
// Blair Evans
//
// based on step response c code by
// Neil Gershenfeld
// 10/27/10
//
// (c) Massachusetts Institute of Technology 2010
// Permission granted for experimental and personal use;
// license for commercial sale available from MIT.
//
// also based on LED input algorithm from Mike Cook at http://www.thebox.myzen.co.uk/


const byte chargePin = A0;  // Drive pin for step response charging
const int analogInPin1 = A1; // Analog input pin step1
const int analogInPin2 = A2; // Analog input pin step2
const byte settle_delay = 100;
const int charge_delay[] = {1, 10, 100};
const byte photoPin = A5; // Phototransitor
const byte anodePin = A3; //LED i/o
const byte cathodePin = A4; // LED i/o
const int LEDIntegrationTime = 10; // time to integrate photonic induced drain
//const int LEDIntegrationTime = 40; // time to integrate photonic induced drain
                                   // of charge stored on reverse biased diode jununction

int sensorValueUp;
int sensorValueDown;
int photoValue;
int LEDValue=0;
byte state = LOW;

// step response data capture
void capture(int sample, int pin) {
      delayMicroseconds(settle_delay);
      digitalWrite(chargePin,1); // start up charge;
      delayMicroseconds(charge_delay[sample]); // undersample delay time;
      sensorValueUp = analogRead(pin);
       //
      // settle, discharge, and wait undersample delay time
      //
      delayMicroseconds(settle_delay);
      digitalWrite(chargePin,0); // start down charge
      delayMicroseconds(charge_delay[sample]); // undersample delay time;
      sensorValueDown = analogRead(pin);

}

//LED data capture & set illumination state
int LEDIO (int state) {
  int LEDValue;
  int LEDRef;
   // charge up LED cathode = HIGH, anode = LOW
   pinMode(cathodePin,OUTPUT);   // Enable cathode pins as output
   digitalWrite(cathodePin,HIGH); 
   digitalWrite(anodePin,LOW);    
   // change mode of cathode pin to analog input for measurement
   pinMode(cathodePin,INPUT);

   // Take a reading of the voltage level of the stored charge to get a referance level before discharge
   LEDRef = analogRead(cathodePin);  // Store the referance level
   
   delay(LEDIntegrationTime);  // LED discharge time or photon intergration time

   // Read the sensors after discharge to measure the incedent light
   LEDValue = LEDRef - analogRead(cathodePin);     // subtract current reading from the referance to give the drop
   pinMode(cathodePin,OUTPUT);   // Enable cathode pins as output
   digitalWrite(cathodePin,LOW); // Turn LED to given illumination state
   digitalWrite(anodePin,state);
   return LEDValue;
} 


void setup() {
  // initialize serial communications
//  Serial.begin(9600); 
  Serial.begin(57600); 
  pinMode(chargePin, OUTPUT);     
  digitalWrite(chargePin,0);
  LEDSetup();
  pinMode(13, OUTPUT);
}

void LEDSetup() { 
    _SFR_IO8(0x35) |= 0x10;   // global disable pull up resistors
    digitalWrite(anodePin,LOW); // ensure pins go low immediatly after initializing them to outputs
    pinMode(anodePin,OUTPUT);   // anode pin as output
    pinMode(cathodePin,INPUT); // cathode pin as input
}


void loop() {
       //
      // send framing
      //
//  Serial.write("1234");                       
      Serial.write(1);
      Serial.write(2);
      Serial.write(3);
      Serial.write(4);
 /*     put_char(&serial_port, serial_pin_out, 1);
      char_delay();
      put_char(&serial_port, serial_pin_out, 2);
      char_delay();
      put_char(&serial_port, serial_pin_out, 3);
      char_delay();
      put_char(&serial_port, serial_pin_out, 4);
*/
      // Step1
      //
      // charge and discharge 1
      //
      capture(0, analogInPin1);
      //
      // send result
      //
 /*
      Serial.print(sensorValueUp);      
      Serial.print(",");      
      Serial.print(sensorValueDown);      
      Serial.print(";");      
 */
      Serial.write(lowByte(sensorValueUp));
      Serial.write(highByte(sensorValueUp));
      Serial.write(lowByte(sensorValueDown));
      Serial.write(highByte(sensorValueDown));
      //
      // charge and discharge 2
      //
      capture(1, analogInPin1);
      //
      // send result
      //
 /*
      Serial.print(sensorValueUp);      
      Serial.print(",");      
      Serial.print(sensorValueDown);      
      Serial.print(";");      
 */
      Serial.write(lowByte(sensorValueUp));
      Serial.write(highByte(sensorValueUp));
      Serial.write(lowByte(sensorValueDown));
      Serial.write(highByte(sensorValueDown));
      //
      // charge and discharge 3
      //
      capture(2, analogInPin1);
      //
      // send result
      //
 /*
      Serial.print(sensorValueUp);      
      Serial.print(",");      
      Serial.print(sensorValueDown);      
      Serial.print(";");      
 */
      Serial.write(lowByte(sensorValueUp));
      Serial.write(highByte(sensorValueUp));
      Serial.write(lowByte(sensorValueDown));
      Serial.write(highByte(sensorValueDown));
//      Serial.println();
      // Step2
      //
      // charge and discharge 1
      //
      capture(0, analogInPin2);
      //
      // send result
      //
 /*
      Serial.print(sensorValueUp);      
      Serial.print(",");      
      Serial.print(sensorValueDown);      
      Serial.print(";");      
 */
      Serial.write(lowByte(sensorValueUp));
      Serial.write(highByte(sensorValueUp));
      Serial.write(lowByte(sensorValueDown));
      Serial.write(highByte(sensorValueDown));
      //
      // charge and discharge 2
      //
      capture(1, analogInPin2);
      //
      // send result
      //
 /*
      Serial.print(sensorValueUp);      
      Serial.print(",");      
      Serial.print(sensorValueDown);      
      Serial.print(";");      
 */
      Serial.write(lowByte(sensorValueUp));
      Serial.write(highByte(sensorValueUp));
      Serial.write(lowByte(sensorValueDown));
      Serial.write(highByte(sensorValueDown));
      //
      // charge and discharge 3
      //
      capture(2, analogInPin2);
      //
      // send result
      //
 /*
      Serial.print(sensorValueUp);      
      Serial.print(",");      
      Serial.print(sensorValueDown);      
      Serial.print(";");      
 */
      Serial.write(lowByte(sensorValueUp));
      Serial.write(highByte(sensorValueUp));
      Serial.write(lowByte(sensorValueDown));
      Serial.write(highByte(sensorValueDown));


      photoValue  = analogRead(photoPin);
      Serial.write(lowByte(photoValue));
      Serial.write(highByte(photoValue));

      LEDValue  = LEDIO(HIGH);
      Serial.write(lowByte(LEDValue));
      Serial.write(highByte(LEDValue));
/*
      Serial.write(lowByte(512));
      Serial.write(highByte(512));
*/
      if (state == LOW){
         state = HIGH;
       } else {
         state = LOW;
       }
       digitalWrite(13,state);

   }