My timer is not working correctly

Hi guys,

Still working on my projector remote control project. Nearly complete but I have this odd behaviour and I simply just can’t figure it out.

When the power button is pressed the power led goes on and flashes for 30 sec. When I press it again, the led flashes for 120 sec. But this only works the first time around. Every following presses the power up flash and power down flash time is different.

The solution is probably simple, but since I’m a total newbie I can’t figure it out.

The code:

// Projektor model Acer H5380BD

#include <Bounce2.h>

#define pwrButton 8
#define pwrLED 9

#define picButton 5
#define picLED 6

int pwrLEDState = LOW;
int picLEDState = LOW;

boolean pwrOn = false;
boolean picOn = false;

boolean bootTime = false;

unsigned long previousUpMillis = 0;
unsigned long pwrUpInterval = 30000;

unsigned long previousDownMillis = 0;
unsigned long pwrDownInterval = 120000;

int pwrValue, picValue;

Bounce pwrDebouncer = Bounce();
Bounce picDebouncer = Bounce();

void setup() {
  Serial.begin(9600);

  // Setup the buttons with an internal pull-up
  pinMode(pwrButton, INPUT_PULLUP);
  pinMode(picButton, INPUT_PULLUP);

  // After setting up the buttons, setup the Bounce instances
  pwrDebouncer.attach(pwrButton);
  pwrDebouncer.interval(5);

  picDebouncer.attach(picButton);
  picDebouncer.interval(5);

  // Setup the LED :
  pinMode(pwrLED, OUTPUT);
  digitalWrite(pwrLED, pwrLEDState);

  pinMode(picLED, OUTPUT);
  digitalWrite(picLED, picLEDState);
}

void loop() {
  // Update the Bounce instances
  pwrDebouncer.update();
  picDebouncer.update();

  // Power projector on / off
  if (pwrDebouncer.fell()) {
    pwrOn = !pwrOn;
    pwrControl();
  }

  // Hide/show picture
  if (picDebouncer.fell()) {
    if (pwrOn) {
      Serial.write("* 0 IR 030\r\n");
      picOn = !picOn;
      if (picOn == true) {
        digitalWrite(picLED, HIGH);
      }
    }
  }

  // Pulse picture LED if picture off
  picLedPulse();

  // Pulse power LED on power up
  if (pwrOn == true && bootTime == true) {
    pwrUp();
  }

  // Pulse power LED on power down
  if (pwrOn == false && bootTime == true) {
    pwrDown();
  }
}

void pwrLedPulse() {
  if (bootTime == true) {
    unsigned long pwrTime = millis();
    pwrValue = 128 + 127 * cos(2 * PI / 2000 * pwrTime);
    analogWrite(pwrLED, pwrValue);
  }
}

void picLedPulse() {
  if (picOn == false && pwrOn == true) {
    unsigned long picTime = millis();
    picValue = 128 + 127 * cos(2 * PI / 2000 * picTime);
    analogWrite(picLED, picValue);
  }
}

void pwrControl() {
  picOn = pwrOn;
  if (pwrOn == true) {
    Serial.write("* 0 IR 001\r\n");
    digitalWrite(picLED, picOn);
    bootTime = true;
  }
  else {
    Serial.write("* 0 IR 002\r\n");
    digitalWrite(picLED, LOW);
    bootTime = true;
  }
}

void pwrUp() {
  pwrLedPulse();
  unsigned long currentMillis = millis();
  if (currentMillis - previousUpMillis >= pwrUpInterval) {
    previousUpMillis = currentMillis;
    bootTime = false;
    digitalWrite(pwrLED, HIGH);
  }
}

void pwrDown() {
  pwrLedPulse();
  unsigned long currentMillis = millis();
  if (currentMillis - previousDownMillis >= pwrDownInterval) {
    previousDownMillis = currentMillis;
    bootTime = false;
    digitalWrite(pwrLED, LOW);
  }
}

Hope you can help!

/Carl

previousDownMillis And previousUpMillis might work better with proper initialization before starting countdown?

Yes of course @J-M-L - you’re absolutely right. I changed the the pwrControl() function to reset the timers before running the blinking the led:

void pwrControl() {
  picOn = pwrOn;
  if (pwrOn == true) {
    Serial.write("* 0 IR 001\r\n");
    digitalWrite(picLED, picOn);
    previousUpMillis = millis();
    bootTime = true;
  }
  else {
    Serial.write("* 0 IR 002\r\n");
    digitalWrite(picLED, LOW);
    previousDownMillis = millis();
    bootTime = true;
  }
}

/Carl

:slight_smile: