Pages: [1]   Go Down
Author Topic: Start (Momentary) Button, safety  (Read 668 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Guys,
I ran my project last night and it worked great. I then went to bed and as my head hit the pillow i realized...

If my power goes out and comes back on my program will restart and destroy my distiller.

I found and have working some code that allows me to press a button to start my PWM but it seems the button code stops my loop from running (Unless i press it again)

Can someone show me how to handle this?

I would like to press the momentary button once and then program runs like without the button code.

Code:
#include "TimerOne.h"
#include <Button.h>
unsigned long time;
//unsigned long Cutout = 16800000;
unsigned long Cutout = 30000;
unsigned long Fan = 20000;
Button button = Button(12,PULLUP);
const int fanrelay =  13;
int duty = 614;



void setup()
{
  pinMode(9, OUTPUT);
  pinMode(fanrelay, OUTPUT);
  Timer1.initialize(500000);         // initialize timer1, and set a 1 second period
  //Serial.begin(9600);
}
 


void loop()
 {
  if(button.uniquePress()){//button.isPressed() will cause the code to execute as long as button is pressed}
   if (time >= Fan)
  digitalWrite(fanrelay, HIGH);
  time = millis();
  Timer1.pwm(9,duty);                // setup pwm on pin 9, 0-1024 max resolution /100*% to get a % duty eg; 614.4 is 60%
  if (time >= Cutout)
  //duty = 100;
  //Serial.print("time = ");
 // Serial.print(time);
 // Serial.print(" duty = ");
 // Serial.println(duty);
  //if (time >= Cutout2)
  shutdown();
  //delay (1000);
 }
 }
void shutdown()
{
  // add you emergency shutdown code here
  Timer1.disablePwm(9);
  while(1);  // endless loop
}

Logged

Offline Offline
Sr. Member
****
Karma: 9
Posts: 254
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You could just wait for the pin state to go low at the end of your setup() function, so it won't enter loop unless the button is pressed.
Or create a static or global variable that you set when the button is pressed.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You could just wait for the pin state to go low at the end of your setup() function, so it won't enter loop unless the button is pressed.
Or create a static or global variable that you set when the button is pressed.

I just tried this

Code:
void loop()
 {
  if(button.uniquePress()){//button.isPressed() will cause the code to execute as long as button is pressed}
  Button(12,PULLDOWN);
Am i correct in thinking after the button is momentary pressed the code runs and "Button(12,PULLDOWN);" holds the button down?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You could just wait for the pin state to go low at the end of your setup() function, so it won't enter loop unless the button is pressed.

I like this idea.. how would i do that?
Logged

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 98
Posts: 4807
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

At the end of setup (a bit of pseudocode here)

while (start_button_ not_ pressed());

I made it a function call so you can add debounce and be sure against falsing.
You -can- just have a digitalRead(pin) if you don't believe in Murphy.

Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

HAHAHAHAHAHA one thing always leads to another....and another......and another.... hahah

Thanks Guys;

off to google debounce!!

Do I understand about you making it a function call?

While: will wait for whatever code in the function it has called to change then go on to my loop?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

At the end of setup (a bit of pseudocode here)

while (start_button_ not_ pressed());

I made it a function call so you can add debounce and be sure against falsing.
You -can- just have a digitalRead(pin) if you don't believe in Murphy.



If i put a function inside "while" I get error on compile.
PWM_distiller_working_noLCD_v2.ino: In function 'void setup()':
PWM_distiller_working_noLCD_v2:25: error: could not convert 'buttonpress()' to 'bool'

The while line in my setup() is then highlighted.

Code:
#include "TimerOne.h"


unsigned long time;
//unsigned long Cutout = 16800000;
unsigned long Cutout = 30000;
unsigned long Fanon = 20000;
unsigned long Fanoff = 40000;

int fanrelay =  13;
int duty = 614;
int buttonPin = 12;
int buttonState = 0;





void setup()
{
  pinMode(9, OUTPUT);
  pinMode(fanrelay, OUTPUT);
  Timer1.initialize(500000);  // initialize timer1, and set a 1 second period
  pinMode(buttonPin, INPUT);
  while (buttonpress());
  }
 
void loop()
 {
  if (time >= Fanon)
  digitalWrite(fanrelay, HIGH);
  time = millis();
  Timer1.pwm(9,duty);                // setup pwm on pin 9, 0-1024 max resolution /100*% to get a % duty eg; 614.4 is 60%
  if (time >= Cutout)
  shutdown();
  }
 
void shutdown()
{
  Timer1.disablePwm(9);
  while(1);  // endless loop
}

void buttonpress()
{
 
}
Logged

Connecticut, USA
Offline Offline
Full Member
***
Karma: 8
Posts: 202
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If your power goes out and back on you want your program to be in the state it was previous to the power loss?
How about using an EEPROM check to start/stop the desired function at restart?
When your function starts it writes a 1 to EEPROM:
Code:
eeprom.write(1, 1);

Then in setup (or loop):
Code:
int PowerFaliureCheck = EEPROM.read(1); if(PowerFaliureCheck ==1){ star/stopt your function};
Write a zero to the EEPROM when your done so it starts normally.
Logged

It's all about the skills

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 98
Posts: 4807
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

At the end of setup (a bit of pseudocode here)

while (start_button_ not_ pressed());

I made it a function call so you can add debounce and be sure against falsing.
You -can- just have a digitalRead(pin) if you don't believe in Murphy.



If i put a function inside "while" I get error on compile.
PWM_distiller_working_noLCD_v2.ino: In function 'void setup()':
PWM_distiller_working_noLCD_v2:25: error: could not convert 'buttonpress()' to 'bool'

The while line in my setup() is then highlighted.

Code:
#include "TimerOne.h"


unsigned long time;
//unsigned long Cutout = 16800000;
unsigned long Cutout = 30000;
unsigned long Fanon = 20000;
unsigned long Fanoff = 40000;

int fanrelay =  13;
int duty = 614;
int buttonPin = 12;
int buttonState = 0;





void setup()
{
  pinMode(9, OUTPUT);
  pinMode(fanrelay, OUTPUT);
  Timer1.initialize(500000);  // initialize timer1, and set a 1 second period
  pinMode(buttonPin, INPUT);
  while (buttonpress());
  }
 
void loop()
 {
  if (time >= Fanon)
  digitalWrite(fanrelay, HIGH);
  time = millis();
  Timer1.pwm(9,duty);                // setup pwm on pin 9, 0-1024 max resolution /100*% to get a % duty eg; 614.4 is 60%
  if (time >= Cutout)
  shutdown();
  }
 
void shutdown()
{
  Timer1.disablePwm(9);
  while(1);  // endless loop
}

void buttonpress()
{
 
}

When I debounce a button/switch I watch for many reads in a row all the same for maybe 5 to 10 ms. There are others who do a more thorough job that works on switches mine might and not and some who check a button and if it's the same 20 to 100 ms later then that's good enough.
Debounce doesn't have to be a function, I just wasn't ready to trot out a lot of code and explanation.

For this, consider the pin to be INPUT HIGH and pressing the button grounds the pin to LOW.
Not tested, not compiled, it's just easier to write this than make tech sense in English.

Code:
byte buttonNotPressed() // returns the opposite of last debounced button state
{
  static unsigned long lastChangeMillis = 0UL;
  static lastPinState = HIGH;  // button not pressed, pullup not grounded

  int pinState = digitalRead( buttonPin ); // most of these int used should be byte, save RAM

  if ( pinState != lastPinState ) // pin state has changed, set debounce start time
  {
    lastChangeMillis = millis();
  }
  else // pin state has not changed, see if it has been so for 10 ms
  {
    if ( millis() - lastChangeMillis >= 10 ) // debounced at last!
    {
      buttonState = pinState;
    }                                       
  }
  lastPinState = pinState;

  return buttonState; // will be 1=TRUE for button NOT pressed
}


2 if's,  some variables and a digital read. not so hard?

Code:
  while ( buttonNotPressed() ); // this will wait for the button to be pressed and debounced

The function could fit into that while loop but as it is it could also be put into loop() as an if() that does not block other code from running in between checks on the button. This way the while() at the end of setup is the only blocking line, and you -want- it to block!




Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Offline Offline
Sr. Member
****
Karma: 9
Posts: 254
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

De-bouncing for this case is not necessary in my opinion. The reason to de-bounce is that when you press the button the electrical contacts will literally bounce due to mechanical vibration in the button, so if you wanted to detect a button press you may get what appears like a couple of very short button presses followed by the actual button press. If you were counting button presses de-bouncing ensures that these spikes are not counted as separate presses. In this case you are just checking if the button is pressed, so as soon as the pin goes HIGH (assuming you're using an active HIGH configuration) you can safely assume that the button has been pressed, and continue regardless of whether the button then bounces.

To do this you only need one line of code:
Code:
void setup(){
   // Everything you do in setup...

   while(!digitalRead(buttonPin));
}

void loop(){
   // no changes here
}
Logged

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 98
Posts: 4807
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I like debounce to ensure deliberate contact. It's a little extra code is all. Your mileage may vary.

Most of the time I don't get bounce anyway but sometimes I wonder if there's an app just waiting for that switch.

It would still be better to measure the water level in the pot directly.

Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Pages: [1]   Go Up
Jump to: