Hello,
I could use some help with two residual bugs in my current "side project"...
I've been working on an IR sensor activated light switch the last two weeks or so, and the project is nearly finished, except for migrating it from a breadboard to a perfboard and soldering everything together.
With this light switch circuit, I want to illuminate a compartment in my car's center console that has no lighting, but it would be practical to have one there. So I've made a circuit with three modes that are switched with an "on-off-on" rocker switch - one mode is "always-on", then there's an "always-off" mode, and finally, an IR sensor activated mode using a TCRT5000, which switches the light on for ten seconds when the IR sensor picks up movement and then fades it out again. The lights will be dimmed up and down using PWM. The brightness can be adjusted through a pot, which is read by the Attiny and then translated into a cycle duty value between 0 and 255 to set the brightness via analogWrite.
Here's my circuit:
And here's my code... please note that as far as pin definitions, I am developing the code on an Atmega328P-PU, because that kind of makes it easier to debug; the final version of it will indeed be ported to and run on an Attiny85-20PU.
// Pin definitions
#define ledPin1 5
#define ledPin2 6
#define IRpin A1
#define switchPin A0
#define brightnessPot A2
// Brightness variables
volatile boolean lightOn = false;
int brightness = 0;
float ledMaxBrightness;
int ledMaxBrightnessSet;
// Timer variables
volatile unsigned long timerStart;
volatile unsigned long timeDifference = 0;
volatile unsigned long timeNow = 0;
// Setting maximum brightness according to brightness pot value
int getMaxBrightness() {
ledMaxBrightness = (float) analogRead(brightnessPot) / 1023;
ledMaxBrightnessSet = (int) (ledMaxBrightness * 255);
if (ledMaxBrightnessSet < 5) ledMaxBrightnessSet = 5; // Eliminating electrical noise on the pin
return ledMaxBrightnessSet;
}
// Dimming up the lights...
void dimUp() {
int delayFactorUp = (int) (3000 / analogRead(brightnessPot)); // The higher max brightness, the faster the dim up...
for (brightness = 0; brightness < getMaxBrightness(); brightness++) { // Dimming up the lights
analogWrite(ledPin1, brightness);
analogWrite(ledPin2, brightness);
delay(delayFactorUp);
}
lightOn = true;
}
// Dimming down the lights...
void dimDown() {
int delayFactorDown = (int) (5000 / analogRead(brightnessPot)); // ...and the same for dimming down
for (brightness = getMaxBrightness(); brightness >= 0; brightness--) { // Dimming down the lights
analogWrite(ledPin1, brightness);
analogWrite(ledPin2, brightness);
delay(delayFactorDown);
}
lightOn = false;
}
void setup() {
Serial.begin(9600);
pinMode(IRpin, INPUT);
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(switchPin, INPUT);
pinMode(brightnessPot, INPUT);
}
void loop() {
// IR activated mode
if (analogRead(switchPin) > 800) {
if (!digitalRead(IRpin) && !lightOn) dimUp(); // The IR pin goes to LOW (!) when the sensor is tripped
if (digitalRead(IRpin) && lightOn) {
timerStart = millis();
timeDifference = 0;
while (timeDifference <= 10000) {
timeDifference = millis() - timerStart;
analogWrite(ledPin2, getMaxBrightness());
if (analogRead(switchPin) < 800 || !digitalRead(IRpin)) break;
}
if (timeDifference >= 10000) dimDown();
}
}
// always-on mode
if (analogRead(switchPin) < 800 && analogRead(switchPin) > 100) {
if (!lightOn) dimUp();
analogWrite(ledPin2, getMaxBrightness());
}
// always-off mode
if (analogRead(switchPin) < 100 && lightOn) dimDown();
}
Now, this code is nearly finished and runs reasonably well; but it still has two bugs that just drive me nuts.
One is this here, in the function getMaxBrightness():
if (ledMaxBrightnessSet < 5) ledMaxBrightnessSet = 5;
The brightness adjustment using the pot works very well, but whenever I turn the pot down so that the analog input reading does go below 5 and then switch to a different mode, the IC gets stuck and I cannot dial the brightness up again. And the LEDs can't be switched off anymore either using the switch, only a reset helps.
The second one is that in "IR activated mode", the LEDs are supposed to be off when I initially put the mode switch in that position. Only when the sensor is tripped should the LEDs dim up. But about every other time, when I switch to IR activated mode, the lights go on without the sensor being tripped:
if (!digitalRead(IRpin) && !lightOn) dimUp();
(as in the code above, IR pin on LOW means the sensor is activated!)
Strangely, when I print out the IR sensor's state via serial using Serial.println(digitalRead(IRpin), it always comes back as "1". So that should kind of rule out that the lights would dim up anyway. But that's not what is happening.
It'd be great if you could help me fix this.
Cheers,
carguy.