SparkFun Forums 

Where electronics enthusiasts find answers.

Your source for all things Atmel.
By keithg
#84557
LED's will change state when analog input is five or six numbers from the threshold, making accurate transitions impossible. Is there some better way to resolve this problem?
Code: Select all
unsigned long starTime;
int flashRed = 20000;
 
 const int numReadings = 3;
 int readings[numReadings];      // the readings from the analog input
 int index = 0;                  // the index of the current reading
 int total = 0;                  // the running total
 int average = 0;

#define blueLED 11
#define redLED 12
#define greenLED 13
#define AnIn 1
#define redThresh 670
#define blueThresh 660
#define greenThresh 0

int val;


void setup()
{
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
  readings[thisReading] = 0; 

  starTime = millis();  //timer
   
  pinMode(redLED,OUTPUT); 
  pinMode(blueLED,OUTPUT); 
  pinMode(greenLED,OUTPUT);
 

Serial.begin(9600);
}
void loop()
{
  // subtract the last reading:
   total= total - readings[index];         
   // read from the sensor:  
   readings[index] = analogRead(AnIn); 
   // add the reading to the total:
   total= total + readings[index];       
   // advance to the next position in the array:  
   index = index + 1;                    
   // if we're at the end of the array...
   if (index >= numReadings)              
     // ...wrap around to the beginning: 
     index = 0;                           
   // calculate the average:
   average = total / numReadings;
  
    starTime = millis();  //timer

  //val = analogRead(AnIn);
 // val = val/2;
if(average >= redThresh){
 digitalWrite(redLED,HIGH);
 digitalWrite(blueLED,LOW);
 digitalWrite(greenLED,LOW);
 delay(1000);
}
else {
  digitalWrite(redLED,LOW);

if((average>= blueThresh) && (average <= redThresh))
{
 digitalWrite(blueLED,HIGH);
 digitalWrite(redLED,LOW);
 digitalWrite(greenLED,LOW);
 delay(1000);
}
else {
  digitalWrite(blueLED,LOW);
  
  if((average>= greenThresh) && (average <= blueThresh))
  {
 digitalWrite(greenLED,HIGH);
 digitalWrite(blueLED,LOW);
 digitalWrite(redLED,LOW);
 delay(1000);
  }
else {
  digitalWrite(greenLED,LOW);
}
} 
Serial.println(average);
}

}



  

By Liencouer
#84614
The biggest thing I can see is that your thresholds are very close. 10 adc counts on a 10bit adc is only about 1% variation of input, or about 50mV difference on a 5V system. What is the input to the ADC? I would suggest looking at that portion of the system first.

Also, you don't need the second conditional in the average threshold comparisons - this should work:
Code: Select all
// if redThresh > blueThresh > greenThresh, the following is valid:
if(average >= redThresh)
{
 // do red thing
}
else if( average >= blueThresh) // we know its less than red, 'cause we wouldn't get here otherwise
{
// do blue thing
}
else if( average >= greenThresh) // we know its less than blue and reg, 'cause we couldn't get here otherwise
{
// do green thing
}
else
{
// none of the above
}
 
By Liencouer
#84699
Increasing the gain of the op-amp should help increase the output range, if you're not already clipping. What is the purpose of the mash of diodes (D1, D2, D3, D5 on the right side of the schematic)? I think you need to take a look at the portion of the circuit between the output of the op amp OUT1 and make sure it does what you intend it to do.
By Liencouer
#84962
I dont think you need the diodes. The rectifier bridge doesn't make any sense - you don't have a positive and negative going signal to need rectifying. In your circuit, it should be obvious that D1, D2 and D3 will never turn on. I think that D5 doesn't help you either.

I'd also mention sparkfun has a breakout board for something like this. I'd recommend taking a peek at http://www.sparkfun.com/commerce/produc ... ts_id=8669