If, else if, and why wont this work,

Ok, newbie question time

I'm trying to get a feeling for how to program my Arduino.

What I'd like to have happen is depending on the value reported from the photoresister one of 3 LEDs are lit.

What I want is:
If the value from the resistor is >75 LED #2 comes on
If the value is between 50 and 75, LED #3 comes on
and if the value is less that 50, LED #4 comes on.
and the LEDs move back and forth depending on the value

What happens now is that LED#3 comes on and stays on only after I wave my hand over the resistor.

Here is the code:

int lightPin = 0; //define a pin for Photo resistor
#define LED2 2
#define LED3 3
#define LED4 4
int val=10;
int valu;
void setup()
{
Serial.begin(9600); //Begin serial communcation
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
pinMode(LED4, OUTPUT);
}

void loop()
{
Serial.println(analogRead(lightPin)); //Write the value of the photoresistor to the serial monitor.
valu = analogRead(lightPin);
if(valu >= 75)
{
analogWrite(LED2, valu/val);
}
else if(valu < 75 && valu >=50)
{
analogWrite(LED3, valu/val);

  }
  else if (valu <= 50)
  {
    analogWrite(LED4, valu/val);
  }

  delay(10); //short delay for faster response to light.

}

Let me see if I correctly understand what you're trying to do. You want the LEDs to fade on and off in sequence as the light over the photocell gets brighter and darker. Right?

The reason I ask about the fading is that you're using analogWrite which sets PWM outputs, not digital HIGHs and LOWs. PWM is useful for creating a dimming effect on LEDs. This function requires an argument between 0 (off) and 255 (full on). Since you're dividing your photocell values by 10, you're providing the analogWrite function with numbers between 0 and 7 (or so) which will cause an LED to just barely light.

BUT! I think your main problem is that you're using analogWrite on pins that don't support it. I don't know which Arduino you have, but for example the Duemilanove only supports analogWrite (PWM) on pins 3,5,6,9,10,11 and 13. You're trying to use pins 2,3 and 4, yet only pin 3 will work at all and even so, it will only light to a maximum brightness of about 3% due to the values you're passing it.

Finally, your IF structure will not properly update the PWM values if the incoming light changes quickly. For example if your LEDs are lit at 100%, 100%, and 50% respectively and the incoming light decreases quickly, the next execution of the IF block will cause LED4 to adjust since the sensor value is now in that range (assuming that a lower valu means dimmer light), but the other LEDs will remain at their previous PWM value. So in the previous example, you would now have your LEDs at something like 25%, 100%, 50%.

So what should you do?

  • Change your LED pins to PWM-capable pins. For example, on the Duemilanove 9,10,11.
  • Use the full range of the PWM output (0 to 255). You can use the map function to accomplist this. You could use map(valu,0,100,0,255). See the Arduino reference for details of how to use this function.
  • Consider why you're using the val variable to divide by 10. I don't know what your setup is, but I'm betting you don't need to do this (especially if you use the map function). Remember that analogRead() returns a value of 0 to 1023 which corresponds to the voltage measured relative to 5V (unless you've specified otherwise).
  • For each of the three segments of your IF block, add 2 digitalWrite commands that set the other LEDs to ensure they have the correct value. For example, (assuming that in the >75 block, you want the other two LEDs to be off), you would add digitalWrite(LED3, LOW); and digitalWrite(LED4,LOW);

Again, I'm making assumptions about what you're trying to do and how your circuits are set up, but these basic suggestions should help you solve your problem. Let us know how it goes. Good luck!

Thank you. Now it works perfectly. Since I didn't know much about the Arduino I was making some assumptions that were incorrect.

Using digital would have given me what I needed. I was just going off a tutorial and thought that I was doing it correctly.

Much learned tonight.
Thanks Again! :slight_smile:

Just a tip:

 if(valu >= 75)
 {
...
 }

[glow] else if(valu < 75 && valu >=50)[/glow] {
...
 }
 [glow]else if (valu <= 50)[/glow]
 {
...
 }

could be rewritten to:

 if(valu >= 75)
 {
...
 }
 else if(valu >=50)
{
...
 }
else 
 {
...
 }

The compiler probably optimizes the code out, but for code clarity you won't need to have all the logic that could later be confusing during debugging.

valu will never be >=75 in the second else if, and will never be <50 in the final else because they match the first and second 'if's respectively.