Problem "turning off" or toggling my code from pushbutton

So I have this code to adjust the speed of a fan based off the temperature of the room and it works fine in it’s own. Even better I added a pushbutton so I can just turn it on/off instead of having it run continuously. it turns on fine, it just won’t turn off now when I re-click the pushbutton. I looked around for other solutions to this problem and I believe I’m close, I just need one last tweak probably.

Any help would be great! Below is the code I have that can turn on the fan and adjust based off the temperature:

const int motorPin = 11;
int fanSpeed = 0;
int temp;
int tempR;
int tempV;
const int tempPin = A1;
int tempMin = 65;
int tempMax = 80;
const int buttonPin = 7;
int buttonState;
int lastButtonState = LOW;

long lastDebounceTime = 0;
long debounceDelay = 50;

void setup()
{
pinMode(buttonPin,INPUT);
pinMode(motorPin,OUTPUT);
pinMode(tempPin,INPUT);
Serial.begin(9600);
}
void loop()
{
int reading = digitalRead(buttonPin);
if (reading != lastButtonState)
{
lastDebounceTime = millis();
if(buttonState == HIGH)
{
float tempR = analogRead(tempPin);
float tempV = tempR*5/1024;
float temp = (((tempV-0.5)*100)*1.8)+32;
Serial.print("Temp Reading = “);
Serial.print(tempR,1);
Serial.print(” Temp Voltage = “);
Serial.print(tempV,5);
Serial.print(” Temp = ");
Serial.println(temp,2);
delay(1000);
if(temp < tempMin)
{
fanSpeed = 0;
digitalWrite(motorPin, LOW);
}
if((temp >= tempMin)&&(temp <= tempMax))
{
fanSpeed = map(temp,tempMin,tempMax,32,255);
analogWrite(motorPin, fanSpeed);
}
}
}
if ((millis() - lastDebounceTime) > debounceDelay)
{
buttonState = reading;
}
lastButtonState = reading;
}

Thanks

Frank

Please use the code button “</>” for your code.

I think you should put the line

   lastDebounceTime = millis();

after the line

if ((millis() - lastDebounceTime) > debounceDelay)
  {

otherwise it keeps being updated and never has a chance to expire.

See several things at a time

…R

Sorry about the code, wasn’t sure how that worked, hope this one is better.

So that doesn’t have any effect on the fan. It still does the same thing before, also I forgot to mention it won’t run the temperature loop on it’s own, I have to click the button to get a new temperature each time. Where as if I run the temperature loop on it’s own it’s fully functioning as I want it to.

const int motorPin = 11;
int fanSpeed = 0;
int temp;
int tempR;
int tempV;
const int tempPin = A1;
int tempMin = 65;
int tempMax = 80;
const int buttonPin = 7;
int buttonState;
int lastButtonState = LOW;

long lastDebounceTime = 0;
long debounceDelay = 50;

void setup()
{
  pinMode(buttonPin,INPUT);
  pinMode(motorPin,OUTPUT);
  pinMode(tempPin,INPUT);
  Serial.begin(9600);
}
void loop()
{
  int reading = digitalRead(buttonPin);
  if (reading != lastButtonState)
  {
    if(buttonState == HIGH)
    {
      float tempR = analogRead(tempPin);
      float tempV = tempR*5/1024;
      float temp = (((tempV-0.5)*100)*1.8)+32;
      Serial.print("Temp Reading = ");
      Serial.print(tempR,1);
      Serial.print("     Temp Voltage = ");
      Serial.print(tempV,5);
      Serial.print("     Temp = ");
      Serial.println(temp,2);
      delay(10);
      if(temp < tempMin)
      {
        fanSpeed = 0;
        digitalWrite(motorPin, LOW);
      }
      if((temp >= tempMin)&&(temp <= tempMax))
      {
        fanSpeed = map(temp,tempMin,tempMax,32,255);
        analogWrite(motorPin, fanSpeed);
      }
      //delay(10);
    }
  }
  if ((millis() - lastDebounceTime) > debounceDelay)
  {
    lastDebounceTime = millis();
    buttonState = reading;
  }
  lastButtonState = reading;
}

Thanks

Read your code slowly. Start at the top of loop():

  int reading = digitalRead(buttonPin);
  if (reading != lastButtonState)

OK, so far, so good. We got a reading and compared it to the last button state. Let's say this is the first time through the loop and the button is LOW. So the true part of the if() statement isn't executed and there's no else.

After that if(), we get to:

  if ((millis() - lastDebounceTime) > debounceDelay)
  {
    lastDebounceTime = millis();
    buttonState = reading;
  }
  lastButtonState = reading;

Assume for this analysis that the code has been running for more than 50ms, so this if() is true and it updates the lastDebounceTime. But we haven't pressed the switch yet! Why is it debouncing a switch that wasn't pressed?

Thinking this through logically like a computer is the key to making the Arduino understand what you intended to happen.

So with my code it's really saying run this temperature sequence only after I press the button? Cause that would make sense about why it doesn't continually update as opposed to if it was on it's own.

So how do I go about changing that? That's where I'm struggling. In a sense I want to push the button, turn on the sequence and have it adjust my fan speed (which it does on it's own before I added the button), and then turn the sequence off when I push the button again. Why won't it run my sequence continuously like it has before without pushing the button over and over and then once that is fixed why won't it turn back off?

You have to forgive me, this is my first project outside of tutorials as I'm trying to relate logic to coding.

Load the example debounce code in a new window. (It's under 02. Digital.) Look at the order of operations - when does it look at the reading, when does it update the debounce timer...

frankr2108:
So how do I go about changing that? That’s where I’m struggling.

Have a look at planning and implementing a program.

The key is writing down the steps you want to happen expressed in plain language (not code).

…R

frankr2108: if(buttonState == HIGH)

This is your issue. You are having this be the condition for your fan running or not, yet you dont have the arduino change its value until after this condition. move

frankr2108: buttonState = reading;

to above

frankr2108: if(buttonState == HIGH)