by jamie allen Mar 2007

This code allows the transmission of 3 sensor inputs, as RAW value, averaged value and standard deviation, from the Arduino. The protocol is

A,B,C = raw #1, averaged #1, std dev #1

D,E,F = raw #2, averaged #2, std dev #2

G,H,I = raw #3, averaged #3, std dev #3

Note that the transmission format is character ASCII numbers - i.e.: not the most efficient (fast), but a somewhat more easily debugged format.


/*
  Sending three pieces of data - the original data, a weighted average and the standard deviation,
  deliminated by a header "A", "B", "C" at the beginning and a line break at the end

  We can also send "D", "E", "F" for a second sample
  and "G", "H", "I" for a third sample
  delineated similarly 

  based on stuff from Melvin Ochsmann and Tom Igoe. 
  reworked a bit for Sensor Workshop class by Jamie Allen, 2007

*/
//#include <math.h>  //required for our sqrt function!

long val[3] = {0,0,0};
long current[3] = {0,0,0};
long lastVal[3] = {0,0,0};
long sensorPin[6] = { 0, 1, 2, 3, 4, 5 };
long ledPin = 13;   // select the pin for the LED
long i; 

long stdVal[10];
long accVal;
long sampleDeviation = 0;  //an individual samples' 'deviation'
long sampleDeviation2[5];  //each individual samples' squared (deviation)
long sampleDeviationSum = 0;  //each individual samples' squared (deviation)
long avg;

long standardDeviation[3] = {0,0,0}; //the standard deviation result

void setup() {
  pinMode(ledPin, OUTPUT);  // declare the ledPin as an OUTPUT
  for (i=0; i<=6; i++)
  {
    pinMode(sensorPin[i], INPUT);  // declare the ledPin as an INTPUT
  }  
  Serial.begin(9600);	// opens serial port, sets data rate to 9600 bps
}


void loop() {

  digitalWrite(ledPin, HIGH);    // sets the LED on
  val[0] = analogRead(sensorPin[3]);    // read the value from the sensor
  val[1] = analogRead(sensorPin[4]);    // read the value from the sensor
  val[2] = analogRead(sensorPin[5]);    // read the value from the sensor

  current[0] = (1*val[0] + 9*lastVal[0])/10; //almost the same as the above but using integer math  
  current[1] = (1*val[1] + 9*lastVal[1])/10; //almost the same as the above but using integer math  
  current[2] = (1*val[2] + 9*lastVal[2])/10; //almost the same as the above but using integer math  

  lastVal[0] = current[0];
  lastVal[1] = current[1];
  lastVal[2] = current[2];

  //standardDeviation[1] = standardDeviator(sensorPin[1], 10);  //pin to do the standard deviation on, and number of sample to use to calculate it
  //standardDeviation[2] = standardDeviator(sensorPin[2], 10);  //pin to do the standard deviation on, and number of sample to use to calculate it
  //standardDeviation[3] = standardDeviator(sensorPin[3], 10);  //pin to do the standard deviation on, and number of sample to use to calculate it

  //Out protocol for data transmission is [AXXX BXXX CXXXX AXXXX BXX CXX ...]
  //which we then check for at the processing end

  Serial.print("A");  //header variable, so we know which sensor value is which
  Serial.print(val[1], DEC);  //send as a ascii encoded number - we'll turn it back into a number at the other end
  Serial.print(10, BYTE);  //terminating character
  //delay(10);

  Serial.print("B");  //header variable, so we know which sensor value is which
  Serial.print(current[1], DEC);  //send as a ascii encoded number - we'll turn it back into a number at the other end
  Serial.print(10, BYTE);  //terminating character
  //delay(10);

  //Serial.print("C");  //header variable, so we know which sensor value is which
  //Serial.print(standardDeviation[1], DEC);  //send as a ascii encoded number - we'll turn it back into a number at the other end
  //Serial.print(10, BYTE);  //terminating character
  //delay(10);

  Serial.print("D");  //header variable, so we know which sensor value is which
  Serial.print(val[2], DEC);  //send as a ascii encoded number - we'll turn it back into a number at the other end
  Serial.print(10, BYTE);  //terminating character
  //delay(10);

  Serial.print("E");  //header variable, so we know which sensor value is which
  Serial.print(current[2], DEC);  //send as a ascii encoded number - we'll turn it back into a number at the other end
  Serial.print(10, BYTE);  //terminating character
  //delay(10);

  //Serial.print("F");  //header variable, so we know which sensor value is which
  //Serial.print(standardDeviation[2], DEC);  //send as a ascii encoded number - we'll turn it back into a number at the other end
  //Serial.print(10, BYTE);  //terminating character
  //delay(10);

  Serial.print("G");  //header variable, so we know which sensor value is which
  Serial.print(val[3], DEC);  //send as a ascii encoded number - we'll turn it back into a number at the other end
  Serial.print(10, BYTE);  //terminating character
  //delay(10);

  Serial.print("H");  //header variable, so we know which sensor value is which
  Serial.print(current[3], DEC);  //send as a ascii encoded number - we'll turn it back into a number at the other end
  Serial.print(10, BYTE);  //terminating character
  //delay(10);

  //Serial.print("I");  //header variable, so we know which sensor value is which
  //Serial.print(standardDeviation[3], DEC);  //send as a ascii encoded number - we'll turn it back into a number at the other end
  //Serial.print(10, BYTE);  //terminating character
  //delay(10);
}


int standardDeviator(int pin, int howManyToAverage)
{
   accVal = 0;  // clear the accumulator

  for (i=0; i < howManyToAverage; i++)
  {
    stdVal[i] = analogRead(pin);    // read the value from the sensor

    //Serial.print("Raw Value: ");
    //Serial.println(val, DEC);  // print as an ASCII-encoded decimal

    accVal = accVal + stdVal[i];
    //Serial.print("Accumulator: ");
    //Serial.println(accVal, DEC);  // print as an ASCII-encoded decimal

    delay(10); 
  }

  avg = accVal/howManyToAverage;
  //Serial.print("Simple Average Value: ");
  //Serial.println(avg, DEC);  // print as an ASCII-encoded decimal

  for (i=0; i<howManyToAverage; i++)
  {
    sampleDeviation = abs(stdVal[i]-avg);
    sampleDeviation2[i] = sampleDeviation*sampleDeviation;        
  }

  sampleDeviationSum = 0;  
  for (i=0; i<howManyToAverage; i++)
  {
    sampleDeviationSum = sampleDeviationSum + sampleDeviation2[i]; 
  }


  // removed because the code was too big  
  //return sqrt(sampleDeviationSum/(howManyToAverage-1));

  return (sampleDeviationSum/(howManyToAverage-1));

 // Serial.print("Standard Deviation Value: ");
 // Serial.println(standardDeviation, DEC);  // print as an ASCII-encoded decimal  
}