Newbie need help with simple sketch

Two momentary buttons will alternatively turn on its respective LED for a
specified period "fanPeriod". At the same time the pin 5 analog output will
go 50% and 100% respectively.
Nano: All works fine with the LEDs and even the analog output. But the
"analogWrite(ANALOG_PIN, 0);" line seems to be the problem. This line is simply
supposed to set the analog output to 0%. Without this line the analog output
goes between 50% and 100%, following the buttons (but does not reset to 0% of course).
Adding the problematic line makes it work with one press only with button 1.
Starting with pressing button 2 just makes short DC jump.
There is something about the basic concept I don´t understand.

unsigned long period1StartMillis; //start counting period1 time
unsigned long period2StartMillis; //start counting period2 time
unsigned long currentMillis;
unsigned long fanPeriod1 = 2000; //fan duration
unsigned long fanPeriod2 = 4000; //fan duration
const int BUTTON1_PIN = A1; // Arduino pin connected to button's pin
const int BUTTON2_PIN = A2; // Arduino pin connected to button's pin
const int LED1_PIN    = 2; // Arduino pin connected to LED's pin
const int LED2_PIN    = 3; // Arduino pin connected to LED's pin
const int ANALOG_PIN  = 5; // Arduino pin connected to analog output pin

// variables will change:
int led1State = 0;     // the current state of LED1
int led2State = 0;     // the current state of LED2
int lastButton1State;    // the previous state of button
int currentButton1State; // the current state of button
int lastButton2State;    // the previous state of button
int currentButton2State; // the current state of button

void setup() {
  pinMode(BUTTON1_PIN, INPUT_PULLUP); // set arduino pin to input pull-up mode
  pinMode(BUTTON2_PIN, INPUT_PULLUP); // set arduino pin to input pull-up mode
  pinMode(LED1_PIN, OUTPUT);          // set arduino pin to output mode
  pinMode(LED2_PIN, OUTPUT);          // set arduino pin to output mode
  digitalWrite(LED1_PIN, led1State);
  digitalWrite(LED2_PIN, led2State);
  
}

void loop()
{
currentMillis = millis();
lastButton1State    = currentButton1State;      // save the last state
lastButton2State    = currentButton2State;      // save the last state
  {
      //Period1 (duration1):
    
    currentButton1State = digitalRead(BUTTON1_PIN); // read new state Button #1
    if(lastButton1State == 1 && currentButton1State == 0)
    {
      digitalWrite(LED1_PIN, 1); // LED#1 turn on
      digitalWrite(LED2_PIN, 0);
      analogWrite(ANALOG_PIN, 128); // set analog to 50%
      period1StartMillis = currentMillis;  //save the time that the state change occured      
    }
    if (currentMillis - period1StartMillis >= fanPeriod1) // check if time has run out
    {
      digitalWrite(LED1_PIN, 0);
      analogWrite(ANALOG_PIN, 0); // set analog to 0%  This is the PROBLEM #1
    }

      //Period2 (duration2):
   
    currentButton2State = digitalRead(BUTTON2_PIN); // read new state Buttom #2
    if(lastButton2State == 1 && currentButton2State == 0)
    {
      digitalWrite(LED2_PIN, 1); //LED#2 turn on
      digitalWrite(LED1_PIN, 0);
      analogWrite(ANALOG_PIN, 255);
      period2StartMillis = currentMillis;  //save the time that the state change occured      
    }
    if (currentMillis - period2StartMillis >= fanPeriod2) // check if time has run out
    {
      digitalWrite(LED2_PIN, 0);
      analogWrite(ANALOG_PIN, 0); // set analog to 0%  This is the PROBLEM #2
    }
  } 
}

The problem is in this line (and the corresponding one for period2StartMillis):

The code is always checking this, regardless of whether or not the fan has been turned on.

What you need to do is something like this (and there are many other ways of accomplishing the same thing):

    if (period1StartMillis && currentMillis - period1StartMillis >= fanPeriod1) // check if time has run out
    {
      digitalWrite(LED1_PIN, 0);
      analogWrite(ANALOG_PIN, 0); // set analog to 0%  This is the PROBLEM #1
      period1StartMillis = 0;
    }

This way, you'll only turn things off if the timer is running (period1StartMillis being set to a non zero value in the previous if block). And once turned off, period1StartMillis is set to 0, so this code won't be run until the fan is turned back on again and period1StartMillis is set to a non-zero value.

Of course, make similar mods to the "turn it off" if block for the other switch and LED.

1 Like

Thanks a lot for your time and help! This is my first project and I feel like I´m really stumbling getting forward, so I really appreciate all help I can get.
I´ve implemented your suggestion and it works, but only if one of the sections (Period1&2) are active.
This is the same as with my own original version.

But to me there is more strange things going on:

  1. All runs actually smooth in my original version when only digitalWrites are implemented. Even with both sections active ("Period 1&2").

  2. Adding the two lines analogWrite(ANALOG_PIN, 128 / 255);.
    All is still fine except for the analog O/P not being reset, of course. Even with both sections active (Period 1&2).

  3. The problem starts when adding the analogWrite(ANALOG_PIN, 0) lines.
    Here, digitalWrites, and the digital O/P´s, are still ok but the analog O/P is not.
    To be more detailed:
    The first section with Button1, and its analog O/P, works fine but just for one button press (following press gives however short pulses each time on the O/P).
    Section/Button2 analog O/P, never (even here, a short pulse is however noticed for each following press).
    I can get Section/Button1 to work one time again by interrupting Period2 by pressing button 1.

I still can´t figure out – why are digitalWrites fine, but not analogWrites? What is the difference?

I did find out a workaround even though its not very elegant. Instead of the lines: analogWrite(ANALOG_PIN, 0); I simply added:

if(digitalRead(LED1_PIN) == 0 && digitalRead(LED2_PIN) == 0)
{
analogWrite(ANALOG_PIN, 0);
}

To be more confident for the future I really need to know the problem here. Even though I found a workaround it would be good to know more about the structure details of this specific issue as I´m planning to use analog O/P´s a lot.

BTW, my background is as a longtime electronics designer, mostly in the analog area.

You can't really have both periods active at the same time since when you detect a button press, you turn on the given LED and turn off the other LED. This implies that a button press cancels any current period in progress.

One way to determine if a period is underway to to always set your StartMillis back to 0 when the duration has expired. This allows the code to test for any non-zero value to mean "period is active". The following code does that

unsigned long period1StartMillis; //start counting period1 time
unsigned long period2StartMillis; //start counting period2 time
unsigned long currentMillis;
const unsigned long fanPeriod1 = 2000; //fan duration
const unsigned long fanPeriod2 = 4000; //fan duration
const int BUTTON1_PIN = A1; // Arduino pin connected to button's pin
const int BUTTON2_PIN = A2; // Arduino pin connected to button's pin
const int LED1_PIN    = 2; // Arduino pin connected to LED's pin
const int LED2_PIN    = 3; // Arduino pin connected to LED's pin
const int ANALOG_PIN  = 5; // Arduino pin connected to analog output pin

// variables will change:
int led1State = 0;     // the current state of LED1
int led2State = 0;     // the current state of LED2
int lastButton1State;    // the previous state of button
int currentButton1State; // the current state of button
int lastButton2State;    // the previous state of button
int currentButton2State; // the current state of button

void setup() {
  pinMode(BUTTON1_PIN, INPUT_PULLUP); // set arduino pin to input pull-up mode
  pinMode(BUTTON2_PIN, INPUT_PULLUP); // set arduino pin to input pull-up mode
  pinMode(LED1_PIN, OUTPUT);          // set arduino pin to output mode
  pinMode(LED2_PIN, OUTPUT);          // set arduino pin to output mode
  digitalWrite(LED1_PIN, led1State);
  digitalWrite(LED2_PIN, led2State);

}

void loop()
{
  currentMillis = millis();
  lastButton1State    = currentButton1State;      // save the last state
  lastButton2State    = currentButton2State;      // save the last state

  //Period1 (duration1):

  currentButton1State = digitalRead(BUTTON1_PIN); // read new state Button #1
  if (lastButton1State == 1 && currentButton1State == 0)
  {
    digitalWrite(LED1_PIN, 1); // LED#1 turn on
    digitalWrite(LED2_PIN, 0);
    analogWrite(ANALOG_PIN, 128); // set analog to 50%
    period1StartMillis = currentMillis;  //save the time that the state change occured
    period2StartMillis = 0;               // turn period 2 off
  }
  if (period1StartMillis && currentMillis - period1StartMillis >= fanPeriod1) // check if time has run out
  {
    digitalWrite(LED1_PIN, 0);
    analogWrite(ANALOG_PIN, 0); // set analog to 0%  This is the PROBLEM #1
    period1StartMillis = 0;
  }

  //Period2 (duration2):

  currentButton2State = digitalRead(BUTTON2_PIN); // read new state Buttom #2
  if (lastButton2State == 1 && currentButton2State == 0)
  {
    digitalWrite(LED2_PIN, 1); //LED#2 turn on
    digitalWrite(LED1_PIN, 0);
    analogWrite(ANALOG_PIN, 255);
    period2StartMillis = currentMillis;  //save the time that the state change occured
    period1StartMillis = 0;               // turn period 1 off
  }
  if (period2StartMillis && currentMillis - period2StartMillis >= fanPeriod2) // check if time has run out
  {
    digitalWrite(LED2_PIN, 0);
    analogWrite(ANALOG_PIN, 0); // set analog to 0%  This is the PROBLEM #2
    period2StartMillis = 0;
  }
}

You can also see the code in action on the Wokwi simulator: 2ButtonPMW - Wokwi ESP32, STM32, Arduino Simulator

If you look at the logic analyzer output, it will show D5 Off/ 128 PWM/On for the button presses

Once more, thanks a lot for your help. It really helped me to understand how to keep track of timers/counters and how to use multiple timers.
Also, I now understand the benefit of using libraries. To make my own libraries will be on my bucket list.
All together, the project now works perfect. To be honest I am surprised, I did not believe I would ever do programming! As a long time analog electronics designer I do not consider programming to be true engineering (: (: (:
The trickiest part was not to get the fan to run as expected, but to deal with the indication LEDs. To move from one mode to another, keep track of the timers and get the LEDs behave as expected – this was the most challenging.
I can imagine that an experienced programmer would have great fun reading my code! Nevertheless, this was big fun! And it works.
BTW, the Wokwi thing, I did not know about this. Great tool, will dive into this next time.

// This "fan" project have three countdown/timer buttons, one stop button and four speed buttons.
// All eight momentary buttons has its own status LED.
// Further, each button press shall give an audible click (buzzer). When entering stop status, a double click.
// When in off status, pressing any of the speed buttons also starts "timer" period #1.
// When first pressing any of the "timer" buttons, at the same time the fan always starts at speed #4.
// Pressing a speed button for >4 seconds shall run the fan for an 
// infinite time with a tripple audible click at start and then every 15 minutes as a reminder while
// also keep its respective timer button-LEDs blinking. Timing LEDs should be kept off.
// When running, any change of speed or timing shall not affect the other entity setting. Note though, 
// when changing period, a new period shall start.
// Further, a dry-contact output is provided as a "fan-is-running" signal to the in-house FTX system (external relay).
// Optionally, an input shall be provided to let inhibitate the continious run-function if the outdoor 
// temperature is below a certain level (not yet implemented). This is to not let large volumes of cold 
// air into the building by mistake.

#include <ezLED.h>      //  Provides LED-blinks and audible clicks
ezLED ClickPulse(4);    //  Pin 4: provides singel click-sound when button is pressed, dual clicks when stop is 
                        //  executed: Tripple clicks every 15 minutes when in continous running mode
                        //  (with help from "Universal Timer").
                        //  No further pin-setup is needed.
ezLED BlinkingLED4(8);  // Continuing blink is output to pin 8 at continous mode. No further setup needed.
ezLED BlinkingLED5(9);  // Continuing blink is output to pin 9 at continous mode. No further setup needed.
ezLED BlinkingLED6(10); // Continuing blink is output to pin 10 at continous mode. No further setup needed.
ezLED BlinkingLED7(11); // Continuing blink is output to pin 11 at continous mode. No further setup needed.

#include <UniversalTimer.h>
UniversalTimer every15minTimer(900000, true);   // Timer. Triggers tripple clicks when fan is running 
                                              // in continous mode (every 15 minute as a reminder).
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#include <Bugtton.h>  //Debouncer. Also acts as button-press-delay when activating fan for continous run.
                      // Bugtton also sets the respective pins as pulled-up input buttons. No further setup needed.
const uint8_t buttonCount = 8; //number of input pins. Mandatory.
const uint8_t buttonPins[buttonCount] = {13,2,19,18,17,16,15,14};  // default = internal pull up. Pin 13 has an external pull-up.
                                                                    // Listed in specific order, see below.
Bugtton buttons(buttonCount, buttonPins, 25); //debounce period (25ms)
// Button pins numbering used in code:
// 0 = (pin 13) STOP
// 1 = (pin 2)  FanPeriod1
// 2 = (pin 19) FanPeriod2
// 3 = (pin 18) FanPeriod3
// 4 = (pin 17) FANSpeed1
// 5 = (pin 16) FANSpeed2
// 6 = (pin 15) FANSpeed3
// 7 = (pin 14) FANSpeed4

unsigned long period1StartMillis;
unsigned long period2StartMillis;
unsigned long period3StartMillis;
unsigned long currentMillis;
unsigned long FanPeriod1 = 300000; // 5 min
unsigned long FanPeriod2 = 900000; // 15 min
unsigned long FanPeriod3 = 1800000; // 30 min
unsigned long heldTime = 4000; // Press time for activate continious mode
unsigned long ClickOnTime = 4; // Click sound  
unsigned long ClickOffTime = 200; // Click sound
unsigned long Click1Times = 1; // One click
unsigned long Click2Times = 2; // Two clicks
unsigned long Click3Times = 3; // Threee clicks
unsigned long BlinkOnTime = 100; // Continious mode LED signaling period
unsigned long BlinkOffTime = 100; // Continious mode LED signaling period
unsigned long FANspeed1 = 53;   //  ~2V/800RPM
unsigned long FANspeed2 = 104;   // ~3,77V/1500RPM
unsigned long FANspeed3 = 180;  //  ~6,5V/2500RPM
unsigned long FANspeed4 = 254;  //  ~10V/3200RPM
unsigned long FANspeedSTOP = 0;
const int ANALOG_OP   = 3; // Analog output to fan (1-10V controlled, external level shifter to accomplish this range)
const int BUTTONstop_LED = 12;

// variables will change:
int All_STOP_State;
int T15minTimerState;
int ContSpeedState;

void setup()
{
  analogWrite(ANALOG_OP, 0); //set initial status of fan
  //Register settings below sets in- or output function of pins.
  DDRD = B11111000; 	//Period3_  Period2_ Period1_ Click_  analogOP_ FTX_ n/a_ n/a_	  Register D (sets IN or OUTputs 7-1)
  DDRB = B11111;		  //STOP_   Speed4_   Speed3_  Speed2_  Speed1		                    Register B (sets IN or OUTputs 12-8)
  //Register settings below sets the initial status of output LEDs.
  PORTD = B00000000;	//STOP status at power on
  PORTB = B10000;		  //STOP status at power on

  T15minTimerState = 0;
  All_STOP_State = 1;
  period1StartMillis = 0;
  period2StartMillis = 0;
  period3StartMillis = 0;
  pinMode(1, OUTPUT); // Sets pin 1 to OP (Fan active signal to in-house FTX)
}

void loop()
{
  currentMillis   = millis(); //Reference when starting timers
  All_STOP_State  = digitalRead(BUTTONstop_LED);
  ClickPulse.loop();        //ezLED mandatory
  BlinkingLED4.loop();      //ezLED mandatory
  BlinkingLED5.loop();      //ezLED mandatory
  BlinkingLED6.loop();      //ezLED mandatory
  BlinkingLED7.loop();      //ezLED mandatory
  every15minTimer.start();  //UniversalTimer mandatory
  buttons.update();         // Buggton mandatory

//Period1BUTTON//////////////////////////////////////////////////////////////////////////
  // Pressed when in STOPstatus Period1BUTTON__________________________________________________
  if(buttons.fell(1) && All_STOP_State == 1) //Button pressed
  {     
    analogWrite(ANALOG_OP, FANspeed4); //Set fan speed
		PORTD = B00100000;	//Period1 Speed4. Set LEDs
		PORTB = B01000;		//Period1 Speed4. Set LEDs
    period1StartMillis = currentMillis; //Start timer
    period2StartMillis = 0; //Kill timer
    period3StartMillis = 0; //Kill timer
    T15minTimerState = 0; //Reset state
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click1Times);  //Makes one click      
  }
  if (period1StartMillis && currentMillis - period1StartMillis >= FanPeriod1) // Check counter for full time
  {
    period1StartMillis=0; //Kill timer
    analogWrite(ANALOG_OP, FANspeedSTOP); //Stop fan
		PORTD = B00000000;	//STOP. Set LEDs
		PORTB = B10000;		//STOP.  Set LEDs
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click2Times); //Makes two clicks
  }
  else
  // Pressed when in RUNstatus Period1BUTTON______________________________________________________
  if(buttons.fell(1) && All_STOP_State == 0) //Button pressed. Does not change speed!
  {
		PORTD = B00100000;	//Period1 
    period1StartMillis = currentMillis; // Starts timer
    period2StartMillis = 0; //Kill timer
    period3StartMillis = 0; //Kill timer
    T15minTimerState = 0;   //Reset state
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click1Times); //Makes one click        
  }
  // The four sections below only affects the LEDs. It kills blinking LEDs and set respective LED 
  // when button is pressed and when continous run is active.
  if(buttons.fell(1) && ContSpeedState == FANspeed1)
  {
    BlinkingLED4.cancel();
    BlinkingLED5.cancel();
    BlinkingLED6.cancel();
    BlinkingLED7.cancel();
    digitalWrite(8,1);
  }
  if(buttons.fell(1) && ContSpeedState == FANspeed2)
  {
    BlinkingLED4.cancel();
    BlinkingLED5.cancel();
    BlinkingLED6.cancel();
    BlinkingLED7.cancel();
    digitalWrite(9,1);
  }
  if(buttons.fell(1) && ContSpeedState == FANspeed3)
  {
    BlinkingLED4.cancel();
    BlinkingLED5.cancel();
    BlinkingLED6.cancel();
    BlinkingLED7.cancel();
    digitalWrite(10,1);
  }
  if(buttons.fell(1) && ContSpeedState == FANspeed4)
  {
    BlinkingLED4.cancel();
    BlinkingLED5.cancel();
    BlinkingLED6.cancel();
    BlinkingLED7.cancel();
    digitalWrite(11,1);
  }
  if (period1StartMillis && currentMillis - period1StartMillis >= FanPeriod1) //Checks timer for full time
  {
    period1StartMillis=0; //Kills timer
    analogWrite(ANALOG_OP, FANspeedSTOP); //Stops fan
		PORTD = B00000000;	//STOP  Set LEDs
		PORTB = B10000;		//STOP  Set LEDs
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click2Times); //Makes two clicks
  }

//Period2BUTTON//////////////////////////////////////////////////////////////////////////
  // Pressed when in STOPstatus Period2BUTTON__________________________________________________
  if(buttons.fell(2) && All_STOP_State == 1) //Button pressed
  {     
    analogWrite(ANALOG_OP, FANspeed4);
		PORTD = B01000000;	//Period2 Speed4
		PORTB = B01000;		//Period2 Speed4
    period2StartMillis = currentMillis;
    period1StartMillis = 0;
    period3StartMillis = 0;
    T15minTimerState = 0; 
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click1Times);          
  }
  if (period2StartMillis && currentMillis - period2StartMillis >= FanPeriod2)
  {
    period2StartMillis=0;
    analogWrite(ANALOG_OP, FANspeedSTOP);
		PORTD = B00000000;	//STOP
		PORTB = B10000;		//STOP
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click2Times);
  }
  else
  // Pressed when in RUNstatus Period2BUTTON______________________________________________________
  if(buttons.fell(2) && All_STOP_State == 0) //Button pressed
  {
		PORTD = B01000000;	//Period2
    period2StartMillis = currentMillis;
    period1StartMillis = 0;
    period3StartMillis = 0;
    T15minTimerState = 0; 
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click1Times);         
  }
  if(buttons.fell(2) && ContSpeedState == FANspeed1)
  {
    BlinkingLED4.cancel();
    BlinkingLED5.cancel();
    BlinkingLED6.cancel();
    BlinkingLED7.cancel();
    digitalWrite(8,1);
  }
  if(buttons.fell(2) && ContSpeedState == FANspeed2)
  {
    BlinkingLED4.cancel();
    BlinkingLED5.cancel();
    BlinkingLED6.cancel();
    BlinkingLED7.cancel();
    digitalWrite(9,1);
  }
  if(buttons.fell(2) && ContSpeedState == FANspeed3)
  {
    BlinkingLED4.cancel();
    BlinkingLED5.cancel();
    BlinkingLED6.cancel();
    BlinkingLED7.cancel();
    digitalWrite(10,1);
  }
  if(buttons.fell(2) && ContSpeedState == FANspeed4)
  {
    BlinkingLED4.cancel();
    BlinkingLED5.cancel();
    BlinkingLED6.cancel();
    BlinkingLED7.cancel();
    digitalWrite(11,1);
  }
  if (period2StartMillis && currentMillis - period2StartMillis >= FanPeriod2)
  {
    period2StartMillis=0;
    analogWrite(ANALOG_OP, FANspeedSTOP);
		PORTD = B00000000;	//STOP
		PORTB = B10000;		//STOP
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click2Times);
  }

//Period3BUTTON//////////////////////////////////////////////////////////////////////////
  // Pressed when in STOPstatus Period3BUTTON__________________________________________________
  if(buttons.fell(3) && All_STOP_State == 1) //Button pressed
  { 
    analogWrite(ANALOG_OP, FANspeed4);
		PORTD = B10000000;	//Period3 Speed4
		PORTB = B01000;		//Period3 Speed4 
    period3StartMillis = currentMillis;
    period1StartMillis = 0;
    period2StartMillis = 0;
    T15minTimerState = 0; 
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click1Times);          
  }
    if (period3StartMillis && currentMillis - period3StartMillis >= FanPeriod3)
  {
    period3StartMillis=0;
    analogWrite(ANALOG_OP, FANspeedSTOP);
		PORTD = B00000000;	//STOP
		PORTB = B10000;		//STOP
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click2Times);
  }
  else
  // Pressed when in RUNstatus Period3BUTTON______________________________________________________
  if(buttons.fell(3) && All_STOP_State == 0) //Button pressed
  {
		PORTD = B10000000;	//Period3 
    period3StartMillis = currentMillis;
    period1StartMillis = 0;
    period2StartMillis = 0;
    T15minTimerState = 0; 
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click1Times);          
  }
  if(buttons.fell(3) && All_STOP_State == 0 && ContSpeedState == FANspeed1)
  {
    BlinkingLED4.cancel();
    BlinkingLED5.cancel();
    BlinkingLED6.cancel();
    BlinkingLED7.cancel();
    digitalWrite(8,1);
  }
  if(buttons.fell(3) && All_STOP_State == 0 && ContSpeedState == FANspeed2)
  {
    BlinkingLED4.cancel();
    BlinkingLED5.cancel();
    BlinkingLED6.cancel();
    BlinkingLED7.cancel();
    digitalWrite(9,1);
  }
  if(buttons.fell(3) && All_STOP_State == 0 && ContSpeedState == FANspeed3)
  {
    BlinkingLED4.cancel();
    BlinkingLED5.cancel();
    BlinkingLED6.cancel();
    BlinkingLED7.cancel();
    digitalWrite(10,1);
  }
  if(buttons.fell(3) && All_STOP_State == 0 && ContSpeedState == FANspeed4)
  {
    BlinkingLED4.cancel();
    BlinkingLED5.cancel();
    BlinkingLED6.cancel();
    BlinkingLED7.cancel();
    digitalWrite(11,1);
  }
  if (period3StartMillis && currentMillis - period3StartMillis >= FanPeriod3)
  {
    period3StartMillis=0;
    analogWrite(ANALOG_OP, FANspeedSTOP);
		PORTD = B00000000;	//STOP
		PORTB = B10000;		//STOP
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click2Times);
  }

//*******************************************************************************************
//*******************************************************************************************
//Speed1BUTTON //////////////////////////////////////////////////////////////////////////
  //When pressed at STOPstatus Speed1BUTTON_____________________________________________
  if(buttons.fell(4) && All_STOP_State == 1 && T15minTimerState == 0) //Button pressed  
  {  
    analogWrite(ANALOG_OP, FANspeed1); // Sets fan speed
		PORTD = B00100000;	//Period1 Speed1.  Set LEDs
		PORTB = B00001;		//Period1 Speed1.  Set LEDs
    period1StartMillis = currentMillis; //Starts timer
    period2StartMillis = 0; //Kills timer
    period3StartMillis = 0; //Kills timer
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click1Times); //Makes one click
    All_STOP_State = 0;        
  }
  if (period1StartMillis && currentMillis - period1StartMillis >= FanPeriod1) //Checks timer
  {  
    period1StartMillis=0;    //Kills timer
    analogWrite(ANALOG_OP, FANspeedSTOP); //Sets fan speed
		PORTD = B00000000;	//STOP  Set LEDs
		PORTB = B10000;		//STOP   Set LEDs
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click2Times); //Makes two clicks
  }
  else
  //When pressed at RUNstatus Speed1BUTTON///////////////////////////////////////////////
  if(buttons.fell(4) && All_STOP_State == 0 && T15minTimerState == 0) //Button pressed
  {      
		analogWrite(ANALOG_OP, FANspeed1);
    PORTB = B00001;		//Speed1 Set LEDs
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click1Times); //Makes one click
    All_STOP_State = 0;
  }
  //When pressed at continous running state, first switch to 
  //new Period1/Speed1 state, (then wait for possible long press).
  if(buttons.fell(4) && T15minTimerState == 1)
  {
    BlinkingLED4.cancel();
    BlinkingLED5.cancel();
    BlinkingLED6.cancel();
    BlinkingLED7.cancel();
    analogWrite(ANALOG_OP, FANspeed1);
		PORTD = B00100000;	//Period1 Speed1 LED
		PORTB = B00001;		//Period1 Speed1 LED      
    period1StartMillis = currentMillis; //Start timer
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click1Times); //Makes one click
    All_STOP_State = 0;
    ContSpeedState = 0;
  }
  //If button pressed long (heldTime)
  if(buttons.heldUntil(4,heldTime)) //Button held
  {    
    analogWrite(ANALOG_OP, FANspeed1);
		PORTB = B00001;		//Speed1  Set LEDs
		PORTD = B00000000;	//NoPeriod  Set LEDs
    period1StartMillis=0; //Kills timer
    period2StartMillis=0; //Kills timer
    period3StartMillis=0; //Kills timer
    T15minTimerState = 1; //Enable 15min timer status
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click3Times); //Makes 3 clicks when continous run starts
    BlinkingLED4.blink(BlinkOnTime, BlinkOffTime); //Starts blinking LED
    every15minTimer.resetTimerValue(); // Restart 15min timer so that its first 3x clicks comes after 15min.
    All_STOP_State = 0;
    ContSpeedState = FANspeed1; //Sets fan speed  
  }
  //Speed2BUTTON////////////////////////////////////////////////////////////////////////// 
  //Pressed when in STOPstatus Speed2BUTTON__________________________________________________
  if(buttons.fell(5) && All_STOP_State == 1 && T15minTimerState == 0) //Button pressed  
  {      
    analogWrite(ANALOG_OP, FANspeed2);
    PORTD = B00100000;	//Period1 Speed2
		PORTB = B00010;		//Period1 Speed2       
    period1StartMillis = currentMillis;
    period2StartMillis = 0;
    period3StartMillis = 0;
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click1Times);
    All_STOP_State = 0;        
  }
  if (period1StartMillis && currentMillis - period1StartMillis >= FanPeriod1)
  {  
    period1StartMillis=0;    
    analogWrite(ANALOG_OP, FANspeedSTOP);
		PORTD = B00000000;	//STOP
		PORTB = B10000;		//STOP
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click2Times);
  }
  else
  //When pressed at RUNstatus Speed2BUTTON_________________________________________________
  if(buttons.fell(5) && All_STOP_State == 0 && T15minTimerState == 0) //Button pressed
  {      
		analogWrite(ANALOG_OP, FANspeed2);
    PORTB = B00010;		//Speed2
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click1Times);
    All_STOP_State = 0;        
  }
  //When pressed at continous running state, first switch to 
  //new Period1/Speed2 state, (then wait for possible long press).
  if(buttons.fell(5) && T15minTimerState == 1)
  {
    BlinkingLED4.cancel();
    BlinkingLED5.cancel();
    BlinkingLED6.cancel();
    BlinkingLED7.cancel();
    analogWrite(ANALOG_OP, FANspeed2);
    PORTD = B00100000;	//Period1 Speed2
		PORTB = B00010;		//Period1 Speed2       
    period1StartMillis = currentMillis;
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click1Times);
    All_STOP_State = 0;
    ContSpeedState = 0; 
  }
  //If button pressed long (heldTime)
  if(buttons.heldUntil(5,heldTime))
  {    
    analogWrite(ANALOG_OP, FANspeed2);
		PORTB = B00010;		//Speed2
		PORTD = B00000000;	//NoPeriod
    period1StartMillis=0;
    period2StartMillis=0;
    period3StartMillis=0;
    T15minTimerState = 1;
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click3Times);
    BlinkingLED5.blink(BlinkOnTime, BlinkOffTime);
    every15minTimer.resetTimerValue();
    All_STOP_State = 0;
    ContSpeedState = FANspeed2;
  }

  //Speed3BUTTON////////////////////////////////////////////////////////////////////////// 
  //Pressed when in STOPstatus Speed3BUTTON__________________________________________________
 if(buttons.fell(6) && All_STOP_State == 1 && T15minTimerState == 0) //Button pressed  
  {      
    analogWrite(ANALOG_OP, FANspeed3);
		PORTD = B00100000;	//Period1 Speed3
		PORTB = B00100;		//Period1 Speed3      
    period1StartMillis = currentMillis;
    period2StartMillis = 0;
    period3StartMillis = 0;
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click1Times);
    All_STOP_State = 0;        
  }
  if (period1StartMillis && currentMillis - period1StartMillis >= FanPeriod1)
  {  
    period1StartMillis=0;    
    analogWrite(ANALOG_OP, FANspeedSTOP);
		PORTD = B00000000;	//STOP
		PORTB = B10000;		//STOP
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click2Times); 
  }
  else
  //When pressed at RUNstatus Speed3BUTTON_________________________________________________
  if(buttons.fell(6) && All_STOP_State == 0 && T15minTimerState == 0) //Button pressed
  {      
		analogWrite(ANALOG_OP, FANspeed3);
		PORTB = B00100;		//Speed3
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click1Times);
    All_STOP_State = 0;        
  }
  //When pressed at continous running state, first switch to 
  //new Period1/Speed3 state, (then wait for possible long press).
  if(buttons.fell(6) && T15minTimerState == 1)
  {
    BlinkingLED4.cancel();
    BlinkingLED5.cancel();
    BlinkingLED6.cancel();
    BlinkingLED7.cancel();
    analogWrite(ANALOG_OP, FANspeed3);
		PORTD = B00100000;	//Period1 Speed3
		PORTB = B00100;		//Period1 Speed3        
    period1StartMillis = currentMillis;
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click1Times);
    All_STOP_State = 0;
    ContSpeedState = 0; 
  }
  //If button pressed long (heldTime)
  if(buttons.heldUntil(6,heldTime))
  {    
    analogWrite(ANALOG_OP, FANspeed3);
		PORTB = B00100;		//Speed3
		PORTD = B00000000;	//NoPeriod
    period1StartMillis=0;
    period2StartMillis=0;
    period3StartMillis=0;
    T15minTimerState = 1;
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click3Times);
    BlinkingLED6.blink(BlinkOnTime, BlinkOffTime);
    every15minTimer.resetTimerValue();
    All_STOP_State = 0;
    ContSpeedState = FANspeed3;  
  }

  //Speed4BUTTON////////////////////////////////////////////////////////////////////////// 
  //Pressed when in STOPstatus Speed4BUTTON__________________________________________________
  if(buttons.fell(7) && All_STOP_State == 1 && T15minTimerState == 0) //Button pressed  
  {      
    analogWrite(ANALOG_OP, FANspeed4);
		PORTD = B00100000;	//Period1 Speed4
		PORTB = B01000;		//Period1 Speed4    
    period1StartMillis = currentMillis;
    period2StartMillis = 0;
    period3StartMillis = 0;
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click1Times);
    All_STOP_State = 0;
  }
  if (period1StartMillis && currentMillis - period1StartMillis >= FanPeriod1)
  {  
    period1StartMillis=0;
    analogWrite(ANALOG_OP, FANspeedSTOP);
		PORTD = B00000000;	//STOP
		PORTB = B10000;		//STOP
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click2Times); 
  }
  else
  //When pressed at RUNstatus Speed4BUTTON_________________________________________________
  if(buttons.fell(7) && All_STOP_State == 0 && T15minTimerState == 0) //Button pressed
  {      
		analogWrite(ANALOG_OP, FANspeed4);
		PORTB = B01000;		//Speed4
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click1Times);
    All_STOP_State = 0;        
  }
  //When pressed at continous running state, first switch to 
  //new Period1/Speed4 state, (then wait for possible long press).
  if(buttons.fell(7) && T15minTimerState == 1)
  {
    BlinkingLED4.cancel();
    BlinkingLED5.cancel();
    BlinkingLED6.cancel();
    BlinkingLED7.cancel();
    analogWrite(ANALOG_OP, FANspeed4);
		PORTD = B00100000;	//Period1 Speed4
		PORTB = B01000;		//Period1 Speed4      
    period1StartMillis = currentMillis;
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click1Times);
    All_STOP_State = 0;
    ContSpeedState = 0;
  }
  //If button pressed long (heldTime)
  if(buttons.heldUntil(7,heldTime))
  {    
    analogWrite(ANALOG_OP, FANspeed4);
		PORTB = B01000;		//Speed4
		PORTD = B00000000;	//NoPeriod
    period1StartMillis=0;
    period2StartMillis=0;
    period3StartMillis=0;
    T15minTimerState = 1;
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click3Times);
    BlinkingLED7.blink(BlinkOnTime, BlinkOffTime);
    every15minTimer.resetTimerValue();
    All_STOP_State = 0;
    ContSpeedState = FANspeed4;    
  }

  // T15minTimer check & click//////////////////////////////////////////////////////////
  if (every15minTimer.check() && T15minTimerState == 1) // If so, it enables 3x clicks every 15min
  {    
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click3Times);
  }

  //StopBUTTON//////////////////////////////////////////////////////////////////////////
  // Take note:   All_STOP_State = digitalRead(BUTTONstop_LED); //  PORTB = B10000;		//STOP (stop led)
  if(buttons.fell(0)) // If STOP button is pressed
  {    
    PORTD = B00000000;	//STOP  Set LEDs
		PORTB = B10000;		//STOP  Set LEDs
    analogWrite(ANALOG_OP, 0); // Stops fan
    T15minTimerState = 0; // Restets timer state
    period1StartMillis = 0; // Kills timer
    period2StartMillis = 0; // Kills timer
    period3StartMillis = 0; // Kills timer
    ClickPulse.blinkNumberOfTimes(ClickOnTime, ClickOffTime, Click2Times); // Makes a 2x click
    BlinkingLED4.turnOFF();
    BlinkingLED5.turnOFF();
    BlinkingLED6.turnOFF();
    BlinkingLED7.turnOFF();
    ContSpeedState = 0; // Resets state
    
  }
  // Output signal on pin 3 to FTX (when fan is running)////////////////////////////////////////
  if(digitalRead(BUTTONstop_LED) == 0) // Fan is never running when BUTTONstop_LED == 0
  {
  digitalWrite(1,1);
  }
}

Thanks a lot for your help and time to nail this down, this really helped me getting forward!!!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.