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);
}
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
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);
}
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.