Cannot get mute button to lock in

Built this temperature guage for the Celica , see attached schematic.
Wanted to have the alarm silenced after temperature rise by a push button.
Although the alarm sounds at high temperature and resets when it cools down again below the trip level, the mute button needs to be continuously held on.
As soon as the button is released the alarm starts again.
Tried several different ways to remember a "state" but missing something somewhere and seem to be going round and round in circles and not getting anywhere.
Fairly certain I need to set the state to remember the low but just cannot seem to get my head around how to go about it.

/*128x32 Oled temp guage with alarm flashing type LED.....Celica 9_November 2020
  7809 9V regulator feeding into RAW terminal Arduino ProMini
  A4 ...SDA
  A5 ...SCL
  Flashing 3mm LED on pin 3
  DS18B20 waterproof temperature sensor assy 5V, neg and 4k7 resistor from 5v to signal....
  Temperature signal into pin 2
  Setup switch to enable a 15 turn pot to adjust the trip level during setup
  mod 5/8/21 for buzz without delay
  mod 6/8/21 for mute switch
*/
#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
#define ONE_WIRE_BUS 2                   // Data wire is plugged into pin 2 on the Arduino
#include <DallasTemperature.h>

OneWire oneWire(ONE_WIRE_BUS);          // Setup a oneWire instance to communicate with any OneWire devices

DallasTemperature sensors (&oneWire);   // Pass our oneWire reference to Dallas Temperature.

U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0);

int tripPot = A0; //Adjust to required level after testing...possibly 200
int tripLevel = 0;  //analog level from 0 to 256
int tripVal = 0;
const int alarmLed = 3;  // flashing type LED
const int swPin = 4;     //set up trip level during setup
const int muteSw = 5;    //piezo mute switch
const int buzzPin = 6;   // piezo alarm
const long interval = 250; //interval to sound piezo
int buzzState = 0;
int lastBuzzState = 0;
int nowMuteState = 0;
int lastMuteState = 0;

unsigned long previousMillis = 0;


void setup() {
  u8g2.begin();
  sensors.begin();
  pinMode(alarmLed, OUTPUT); // on-board LED for test...pin 3 there-after
  pinMode(swPin, INPUT_PULLUP); //set up trip level switch
  pinMode(muteSw, INPUT_PULLUP);
  pinMode(buzzPin, OUTPUT);

  tripVal = analogRead(tripPot);
  delay(200);
  tripLevel = map(tripVal, 0, 1023, 0, 255);

}

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

  //setup trip level

  while (digitalRead(swPin) == LOW) {
    tripVal = analogRead(tripPot);
    delay(200);
    tripLevel = map(tripVal, 0, 1023, 0, 255);
    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_logisoso32_tf);
    u8g2.setCursor(0, 32);
    u8g2.print(tripLevel);
    u8g2.sendBuffer();
    delay(100);
  }



  //Read and display temperature

  sensors.requestTemperatures();
  u8g2.clearBuffer();                     // clear the internal memory
  u8g2.setFont(u8g2_font_logisoso32_tf);  // choose a suitable font .....NOTE:- changed suffix from tr to tf to get degree symbol to work
  u8g2.setCursor (0, 32);

  //comment out whichever of the following for degrees Celcuis or Fahrenheit
  //u8g2.print (sensors.getTempCByIndex(0),1);  //
  u8g2.print(sensors.getTempFByIndex(0), 1);

  // alarm output to flashing LED

  if (sensors.getTempFByIndex(0) >= tripLevel)
  {
    digitalWrite(alarmLed, HIGH);      // flashing LED turns on

    nowMuteState = digitalRead(muteSw); //see if the mute switch has changed state

    if (nowMuteState != lastMuteState) {
      lastMuteState = nowMuteState;
    }


    if ( nowMuteState == HIGH) {
      // now turn the Piezo alarm on and off
      unsigned long currentMillis = millis();
      if (currentMillis - previousMillis >= interval) {
        previousMillis = currentMillis;
        // if the piezo is off turn it on and vis-versa
        if (buzzState == LOW) {
          buzzState = HIGH;
        }
        else
        {
          buzzState = LOW;
        }
        digitalWrite(buzzPin, buzzState);
      }
    }



  }
  // now set up and display the screen

  u8g2.setCursor(100, 38);
  u8g2.print((char)176); //degrees symbol
  u8g2.setCursor(110, 32);
  u8g2.print("F");
  u8g2.sendBuffer();          // transfer internal memory to the display
  delay(200);
}

Guage Circuit

    nowMuteState = digitalRead(muteSw); //see if the mute switch has changed state
    if (nowMuteState != lastMuteState)
    {
      lastMuteState = nowMuteState;
    }
    if ( nowMuteState == HIGH)
    {
      // now turn the Piezo alarm on and off

You have the code controlling the piezo outside of the test for whether the button state has changed, so it sounds when the input is HIGH which it will be when the button is released

Sorry, but cannot follow what you mean.
Below is what I wanted to do in the code.

mute

Your code needs to test whether the state has changed and is now HIGH.

Currently it tests whether the state has changed and if so it saves the current state, whatever it is. But then the code goes on to sound the alarm if the state is HIGH whether or not it has changed

You could set a boolean to true if the state changes and is now HIGH and set it to false if is now LOW. Then in loop(), if the boolean is true then sound the alarm

Ok...I did that, or at least I think I did but obviously not correct as the alarm sounds again after I release the button.

Might be out of place here but as I see it, if I read the button in the loop every time, it will read as high whenever I release it and make the variable true anyhow.

/*128x32 Oled temp guage with alarm flashing type LED.....Celica 9_November 2020
  7809 9V regulator feeding into RAW terminal Arduino ProMini
  A4 ...SDA
  A5 ...SCL
  Flashing 3mm LED on pin 3
  DS18B20 waterproof temperature sensor assy 5V, neg and 4k7 resistor from 5v to signal....
  Temperature signal into pin 2
  Setup switch to enable a 15 turn pot to adjust the trip level during setup
  mod 5/8/21 for buzz without delay
  mod 6/8/21 for mute switch
*/
#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
#define ONE_WIRE_BUS 2                   // Data wire is plugged into pin 2 on the Arduino
#include <DallasTemperature.h>

OneWire oneWire(ONE_WIRE_BUS);          // Setup a oneWire instance to communicate with any OneWire devices

DallasTemperature sensors (&oneWire);   // Pass our oneWire reference to Dallas Temperature.

U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0);

int tripPot = A0; //Adjust to required level after testing...possibly 200
int tripLevel = 0;  //analog level from 0 to 256
int tripVal = 0;
const int alarmLed = 3;  // flashing type LED
const int swPin = 4;     //set up trip level during setup
const int muteSw = 5;    //piezo mute switch
const int buzzPin = 6;   // piezo alarm
const long interval = 250; //interval to sound piezo
int buzzState = 0;
int lastBuzzState = 0;

boolean nowMuteOnOff = false;

unsigned long previousMillis = 0;


void setup() {
  u8g2.begin();
  sensors.begin();
  pinMode(alarmLed, OUTPUT); // on-board LED for test...pin 3 there-after
  pinMode(swPin, INPUT_PULLUP); //set up trip level switch
  pinMode(muteSw, INPUT_PULLUP);
  pinMode(buzzPin, OUTPUT);

  tripVal = analogRead(tripPot);
  delay(200);
  tripLevel = map(tripVal, 0, 1023, 0, 255);

}

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

  //setup trip level

  while (digitalRead(swPin) == LOW) {
    tripVal = analogRead(tripPot);
    delay(200);
    tripLevel = map(tripVal, 0, 1023, 0, 255);
    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_logisoso32_tf);
    u8g2.setCursor(0, 32);
    u8g2.print(tripLevel);
    u8g2.sendBuffer();
    delay(100);
  }

  nowMuteOnOff = digitalRead(muteSw); //see if the mute switch has changed state
  delay(100);

  //Read and display temperature

  sensors.requestTemperatures();
  u8g2.clearBuffer();                     // clear the internal memory
  u8g2.setFont(u8g2_font_logisoso32_tf);  // choose a suitable font .....NOTE:- changed suffix from tr to tf to get degree symbol to work
  u8g2.setCursor (0, 32);

  //comment out whichever of the following for degrees Celcuis or Fahrenheit
  //u8g2.print (sensors.getTempCByIndex(0),1);  //
  u8g2.print(sensors.getTempFByIndex(0), 1);

  // alarm output to flashing LED
  digitalWrite(alarmLed, LOW);
  Serial.print("nowMuteOnOff-1 = ");
  Serial.println(nowMuteOnOff);

  if (sensors.getTempFByIndex(0) >= tripLevel)
  {
    digitalWrite(alarmLed, HIGH);      // flashing LED turns on

    Serial.print("nowMuteOnOff-2 = ");
    Serial.println(nowMuteOnOff);



    if ( nowMuteOnOff == true) {
      // now turn the Piezo alarm on and off
      unsigned long currentMillis = millis();
      if (currentMillis - previousMillis >= interval) {
        previousMillis = currentMillis;
        // if the piezo is off turn it on and vis-versa
        if (buzzState == LOW) {
          buzzState = HIGH;
        }
        else
        {
          buzzState = LOW;
        }
        digitalWrite(buzzPin, buzzState);
      }
    }
    


  }
  if(nowMuteOnOff == false){
    digitalWrite(buzzPin,LOW);
    }
  // now set up and display the screen

  u8g2.setCursor(100, 38);
  u8g2.print((char)176); //degrees symbol
  u8g2.setCursor(110, 32);
  u8g2.print("F");
  u8g2.sendBuffer();          // transfer internal memory to the display
  delay(200);
}

UKHeliBob,
Thanks for your help as I managed to follow your points and things finally sunk in and it now works as I needed.
Might not be pretty and I'm sure there are better ways to go about it so any further suggestion appreciated also.

Cheers Jorgo

/*128x32 Oled temp guage with alarm flashing type LED.....Celica 9_November 2020
  7809 9V regulator feeding into RAW terminal Arduino ProMini
  A4 ...SDA
  A5 ...SCL
  Flashing 3mm LED on pin 3
  DS18B20 waterproof temperature sensor assy 5V, neg and 4k7 resistor from 5v to signal....
  Temperature signal into pin 2
  Setup switch to enable a 15 turn pot to adjust the trip level during setup
  mod 5/8/21 for buzz without delay
  mod 7/8/21 for mute switch
*/
#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
#define ONE_WIRE_BUS 2                   // Data wire is plugged into pin 2 on the Arduino
#include <DallasTemperature.h>

OneWire oneWire(ONE_WIRE_BUS);          // Setup a oneWire instance to communicate with any OneWire devices

DallasTemperature sensors (&oneWire);   // Pass our oneWire reference to Dallas Temperature.

U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0);

int tripPot = A0; //Adjust to required level after testing...possibly 200
int tripLevel = 0;  //analog level from 0 to 256
int tripVal = 0;
const int alarmLed = 3;  // flashing type LED
const int swPin = 4;     //set up trip level during setup
const int muteSw = 5;    //piezo mute switch
const int buzzPin = 6;   // piezo alarm
const long interval = 250; //interval to sound piezo
int buzzState = 0;
int lastBuzzState = 0;
int buttonState = 0;
int lastButtonState = 0;
boolean muteOn = false;
unsigned long previousMillis = 0;


void setup() {
  u8g2.begin();
  sensors.begin();
  pinMode(alarmLed, OUTPUT); // on-board LED for test...pin 3 there-after
  pinMode(swPin, INPUT_PULLUP); //set up trip level switch
  pinMode(muteSw, INPUT_PULLUP);
  pinMode(buzzPin, OUTPUT);

  tripVal = analogRead(tripPot);
  delay(200);
  tripLevel = map(tripVal, 0, 1023, 0, 255);

}

void loop() {
  //Serial.begin(9600);
  //*************************************************************************************
  //setup trip level by pressing the button on pin 4 and adjusting the trim pot (15 turn)

  while (digitalRead(swPin) == LOW) {
    tripVal = analogRead(tripPot);
    delay(200);
    tripLevel = map(tripVal, 0, 1023, 0, 255);
    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_logisoso32_tf);
    u8g2.setCursor(0, 32);
    u8g2.print(tripLevel);
    u8g2.sendBuffer();
    delay(100);
  }
  //*************************************************************************************

  digitalWrite (alarmLed, LOW);
  digitalWrite (buzzPin, LOW);

  //*************************************************************************************
  //Read and display temperature

  sensors.requestTemperatures();
  u8g2.clearBuffer();                     // clear the internal memory
  u8g2.setFont(u8g2_font_logisoso32_tf);  // choose a suitable font .....NOTE:- changed suffix from tr to tf to get degree symbol to work
  u8g2.setCursor (0, 32);

  //comment out whichever of the following for degrees Celcuis or Fahrenheit
  //u8g2.print (sensors.getTempCByIndex(0),1);  //
  u8g2.print(sensors.getTempFByIndex(0), 1);
  //***********************************************************************************
  
  
  // check if alarm temperature is below trip level and reset the mute variable
  
  if (sensors.getTempFByIndex(0) < tripLevel) {
    muteOn = false;
  }


  //*************************************************************************************
  // check if alarm temperature is equal to or above trip level and turn on alarms
  // also reset the piezo to "silence" if required
 
  if (sensors.getTempFByIndex(0) > tripLevel)
  {
    digitalWrite(alarmLed, HIGH);      // flashing LED turns on

    buttonState = digitalRead(muteSw); // when temperature is equal to or above trip level,
    delay(50);                         // check to see if mute button has been pushed to silence the Piezo
    // Serial.print("button state is : ");
    //Serial.println(digitalRead(muteSw));

    if (buttonState != lastButtonState) {
      //if the state has changed
      // Serial.print ("button change has occured");
      if (buttonState == LOW) {
        muteOn = true;                 // boolean to hold the mute button
      }
    }
    //Serial.print ("muteOn = ");
    //Serial.println(muteOn);

    //********************************************************************************
    // now pulse the Piezo alarm on and off at "interval" rate by blink without delay
    //********************************************************************************

    if ( muteOn == false) {             // if the mute button has NOT been pressed
      unsigned long currentMillis = millis();
      if (currentMillis - previousMillis >= interval) {
        previousMillis = currentMillis;
        // if the piezo is off turn it on and vis-versa
        if (buzzState == LOW) {
          buzzState = HIGH;
        }
        else
        {
          buzzState = LOW;
        }
        digitalWrite(buzzPin, buzzState);
      }
    }
  }
  lastButtonState = buttonState;


  //***********************************************************************************
  // now set up and display the screen
  //***********************************************************************************
  u8g2.setCursor(100, 38);
  u8g2.print((char)176); //degrees symbol
  u8g2.setCursor(110, 32);
  u8g2.print("F");
  u8g2.sendBuffer();          // transfer internal memory to the display
  delay(200);
}

I am glad you got it working

The most obvious thing that I would change is to declare many of the variables, such as pin numbers, as byte rather than int as their value is less than 255. This will not affect the running of the sketch but is good practice.

I notice that buzzState is declared as an int and given an initial value of zero. Later its value is tested to see whether it is LOW, it is set HIGH or LOW and is used in digitalWrite(). For consistency I would set its initial value to LOW, along with lastBuzzState. The same applies to buttonState and lastButtonState. There is nothing wrong with how these variables are valued and used but it grates when I read the code !

Going further, I would be inclined to put the buzzer sounding code in a function with a suitable name and call it when needed, and the same with the code that handles the display. If nothing else, using meaningful names makes the code easier to read and understand because you can have something like this

if ( muteOn == false)               // if the mute button has NOT been pressed
    {
      soundAlarm();
    }

which makes what is going on more obvious in my opinion

Thankyou for your comments.
I have read and saved them to file with the code and the diagrams I made etc.
Tend to have to read things a couple of times these days to help it sink in but I imagine as with many other aspects, practice is best.
Thanks again, appreciated.

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