So, I have been looking for a tutorial that can help me with my build, but I just can't find anything.
What I'm trying to do is: When I push a button once, a loop where I'm measuring temperature every second should start working and continue to do so even after I release the button. If I click the button one more time, the code should stop working. I've tried to make it work for a week, but I can't get it. I tried by using a state machine but when I enter the loop I can't make it stop.
I'm pretty new to all of this so any help is appreciated. Thanks in advance.
Then just poll the button, toggle a flag if the button is pressed and loop your measurement code if the flag is set.
PushButton button = { 2 }; // Create a new PushButton object on pin 2
void setup() {
pinMode(LED_BUILTIN, OUTPUT); // Set the built-in LED (pin 13) to output mode
}
void loop() {
static bool measuring = false;
if (button.isPressed()) { // If the button is pressed
measuring = ! measuring; // Toggle the state of the flag
digitalWrite (LED_BUILTIN, measuring); // Light the LED to show if you are currently measuring or not
}
if (measuring)
measureTemperature();
}
void measureTemperature() {
// Your implementation
}
I'm not really familiar with the terms poll and flag. As I said i'm still a beginner. I know some C++ from school from a few years ago but I'm not that good.
Here is the code I'm using to measure temperature, turn on an LED when the temperature reaches 26 degrees Celsius and to turn it off when the temperature goes down to 24 degrees Celsius. Now I want to make this code run when I press a button.
I ordered an arduino ethernet shield. I want to make this completely wireless over WAN. I will be making an android application to control the arduino through it's ip address. Basically I'm making some home automation stuff. I want to turn on a few devices even if i'm out of the country. Check the temperature (let's say a water heater). I'm just testing with the physical button to see if everything works like planned or is it simpler to control it with the app with a virtual on/off switch?
Forget about the temperature reading for a moment, keep it simple.
Try to understand the example I posted.
Then remove the delay from your code, look up Blink Without Delay, and combine the two.
Polling the button just means that you keep on calling button.isPressed() in a fast loop to check if it is pressed.
If you want to combine the timer (every second) with the button code above:
PushButton button = { 2 }; // Create a new PushButton object on pin 2
const unsigned long interval = 1000; // 1 second
void setup() {
pinMode(LED_BUILTIN, OUTPUT); // Set the built-in LED (pin 13) to output mode
}
void loop() {
static bool measuring = false;
static unsigned long timer = millis();
if (button.isPressed()) { // If the button is pressed
measuring = ! measuring; // Toggle the state of the flag
digitalWrite (LED_BUILTIN, measuring); // Light the LED to show if you are currently measuring or not
timer = millis();
}
if (measuring && (millis() - timer >= interval)) {
measureTemperature();
timer += interval;
}
}
void measureTemperature() {
// Your implementation
}
I finally got home and tried the code you provided. In this case, the button isn't used as a toggle switch, it's used as a regular button. When you press it, the LED is off and immediately after releasing it, it turns on. I need the button to act as a switch. If you press it once, the LED should stay off even after releasing the button. If I press it again, it should stay on, again, even after releasing the button.
I'm sorry, I know it's pretty easy for you, but this is literally my second arduino project. I'm still a newbie.
Then modify the code to do so.
Use change in state detection.
Edit:
“I ordered an arduino ethernet shield. I want to make this completely wireless over WAN.l”
If this is your 2nd project, you need to stop and spend more time on the basics before trying advanced stuff, but you know this already.
I should have made it more clear that you had to use the class from the link in the first reply I posted, i.e.
class PushButton
{
public:
PushButton(uint8_t pin) // Constructor (executes when a PushButton object is created)
: pin(pin) { // remember the push button pin
pinMode(pin, INPUT_PULLUP); // enable the internal pull-up resistor
};
bool isPressed() // read the button state check if the button has been pressed, debounce the button as well
{
bool pressed = false;
bool state = digitalRead(pin); // read the button's state
int8_t stateChange = state - previousState; // calculate the state change since last time
if (stateChange == falling) { // If the button is pressed (went from high to low)
if (millis() - previousBounceTime > debounceTime) { // check if the time since the last bounce is higher than the threshold
pressed = true; // the button is pressed
}
}
if (stateChange == rising) { // if the button is released or bounces
previousBounceTime = millis(); // remember when this happened
}
previousState = state; // remember the current state
return pressed; // return true if the button was pressed and didn't bounce
};
private:
uint8_t pin;
bool previousState = HIGH;
unsigned long previousBounceTime = 0;
const static unsigned long debounceTime = 25;
const static int8_t rising = HIGH - LOW;
const static int8_t falling = LOW - HIGH;
};
PushButton button = { 2 }; // Create a new PushButton object on pin 2
const unsigned long interval = 1000; // 1 second
void setup() {
pinMode(LED_BUILTIN, OUTPUT); // Set the built-in LED (pin 13) to output mode
}
void loop() {
static bool measuring = false;
static unsigned long timer = millis();
if (button.isPressed()) { // If the button is pressed
measuring = ! measuring; // Toggle the state of the flag
digitalWrite (LED_BUILTIN, measuring); // Light the LED to show if you are currently measuring or not
timer = millis();
}
if (measuring && (millis() - timer >= interval)) {
measureTemperature();
timer += interval;
}
}
void measureTemperature() {
// Your implementation
}
Well... I had no idea that I was using two different timers. I don't know how to use millis(), but I copied some stuff and it works, I don't know how, but it works and that's good enough for me. If you know how to make it more efficient, do so. I tried like this and it suits my needs.
class PushButton
{
public:
PushButton(uint8_t pin) // Constructor (executes when a PushButton object is created)
: pin(pin) { // remember the push button pin
pinMode(pin, INPUT_PULLUP); // enable the internal pull-up resistor
};
bool isPressed() // read the button state check if the button has been pressed, debounce the button as well
{
bool pressed = false;
bool state = digitalRead(pin); // read the button's state
int8_t stateChange = state - previousState; // calculate the state change since last time
if (stateChange == falling) { // If the button is pressed (went from high to low)
if (millis() - previousBounceTime > debounceTime) { // check if the time since the last bounce is higher than the threshold
pressed = true; // the button is pressed
}
}
if (stateChange == rising) { // if the button is released or bounces
previousBounceTime = millis(); // remember when this happened
}
previousState = state; // remember the current state
return pressed; // return true if the button was pressed and didn't bounce
};
private:
uint8_t pin;
bool previousState = HIGH;
unsigned long previousBounceTime = 0;
const static unsigned long debounceTime = 25;
const static int8_t rising = HIGH - LOW;
const static int8_t falling = LOW - HIGH;
};
/* ----------------------------------------------------------------------------------------------------------------------- */
PushButton button = { 2 }; // Create a new PushButton object on pin 2
const unsigned long interval = 1000; // 1 second
const uint8_t ledPin = LED_BUILTIN;
const uint8_t sensorPin = A0;
const float highThreshold= 26;
const float lowThreshold = 24;
const float ADC_to_Celsius = 500/1023;
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT); // Set the built-in LED (pin 13) to output mode
}
void loop() {
static bool measuring = false;
static unsigned long timer = millis();
if (button.isPressed()) { // If the button is pressed
measuring = ! measuring; // Toggle the state of the flag
timer = millis();
}
if (measuring && (millis() - timer >= interval)) {
measureTemperature();
timer += interval;
}
}
void measureTemperature() {
float temp = analogRead(sensorPin) * ADC_to_Celsius;
Serial.print(temp);
Serial.println("°C");
static float threshold = highThreshold;
if (temp < threshold) {
threshold = highThreshold;
digitalWrite(ledPin, HIGH);
} else if (temp >= threshold) {
threshold = lowThreshold;
digitalWrite(ledPin, LOW);
}
}