I am tying to get a 3 second, 350ms pulse set out after I press a button for a heat sealer. I'm not sure what I am missing, or if this is not quite structured right. I was thing this would allow the button to be pressed, start a 3 second timer, and the 350ms loop be activated. What i get is; press the button, the first part of the pulse starts, and it stays there.
Code
#define BUTTON_PIN 17
#define heat 39
int btnState;
int pinState;
int latch = LOW;
int heatState = LOW;
unsigned long interval1 = 350;
unsigned long previousMillis1 = 0;
unsigned long currentTime = 0;
unsigned long interval2 = 3000;
unsigned long previousMillis2 = 0;
void button1() {
pinState = btnState;
btnState = digitalRead(17);
if (pinState == HIGH && btnState == LOW); {
Serial.print("btn "); Serial.println(btnState);
Serial.print("pin "); Serial.println(pinState);
heater();
}
}
void heater() {
if (digitalRead(17) == LOW) {
if (currentTime - previousMillis2 >= interval2) {
heater2();
previousMillis2 += currentTime;
}
if (digitalRead(17) != LOW) {
digitalWrite(39, LOW);
}
}
}
void heater2() {
if (millis() - previousMillis1 >= interval1) {
if (heatState == HIGH) {
heatState = LOW; Serial.println("on");
} else {
heatState = HIGH; Serial.println("off");
}
digitalWrite(heat, heatState);
previousMillis1 += millis();
}
}
void setup() {
Serial.begin(115200);
pinMode(17, INPUT_PULLUP);
pinMode(39, OUTPUT);
digitalWrite(39, LOW);
}
void loop() {
heater();
currentTime = millis();
}
Ant help would be appriciated.
Start out simple. When the button is pressed, turn on your output, wait 350 msec, turn it off, wait another 2.65 sec and then repeat. No need to start out complicated. Just use delay().
Have a look at the State Change Detection example (File->examples->02.digital->State Change detection) and learn how to detect when your button is pressed, not if the button is pressed.
That does not match your initial post about wanting a 350ms pulse and some sort of 3 sec delay. Are you still working on this or have your needs been met?
My apologies, I should have stated what I have got to work for now. I have a potentiometer inserted to vary the pulse timing last night, and now would like to have a timing variable added. I'm just not sure how to insert a millis function inside another millis function.
Right now, I press the button, and the strip loop continues until I release the button.
I would like to press and release the button and the strip loop continues (350ms on/off) for 3 seconds
There are many ways to achieve your functionality.
They differ in style and the grade if they are easier or harder to understand.
One way to increase understandability is to add explaining comments and using of self-explaining variable-names
So this is my attempt to do so.
source-code as in WOKWI
// https://forum.arduino.cc/t/button-timing-and-loops/1223168
// https://wokwi.com/projects/390016797849980929
unsigned long my3SecondTimer = 0; // Timer-variables MUST be of type unsigned long
unsigned long my350mSecsTimer = 0; // Timer-variables MUST be of type unsigned long
const byte buttonPin = 17;
const byte heaterPin = 39;
byte buttonState;
boolean heatingStarted = false;
const byte released = HIGH;
const byte pressed = LOW;
void setup() {
Serial.begin(115200);
Serial.println("Setup-Start");
pinMode(buttonPin, INPUT_PULLUP);
digitalWrite (heaterPin, LOW);
pinMode(heaterPin, OUTPUT);
Serial.println("press button to start heater-cycle");
}
void loop() {
// if heating has not yet started read in the button
if (heatingStarted == false) {
buttonState = digitalRead(buttonPin);
if ( buttonState == pressed ) {
Serial.println("Start-Button pressed start heater cycle heater-pulsing");
heatingStarted = true; // indicate heating HAS started
my3SecondTimer = millis(); // store actual time
my350mSecsTimer = millis(); // store actual time
digitalWrite(heaterPin,HIGH);
}
}
else { // heating HAS started and is running
// check if 350 milliseconds have pased by since heating started
if ( TimePeriodIsOver(my350mSecsTimer, 350) ) {
// when 350 milliseconds REALLY HAVE passed by
// update timervariable with name "my350mSecsTimer" automatically
// for next interval
invertHeaterStateOnOff(); // say what it does
}
// check if 3000 milliseconds have passed by since heating started
if ( TimePeriodIsOver(my3SecondTimer, 3000) ) {
// when 3000 milliseconds REALLY HAVE passed by
// not reevant here: update timervariable with name "my3SecondTimer" automatically
Serial.println("3 seconds over heater switched OFF");
digitalWrite(heaterPin, LOW);
Serial.println("heating cycle finished press button for new heater-cycle");
Serial.println();
heatingStarted = false;
}
}
}
void invertHeaterStateOnOff() {
if ( digitalRead(heaterPin) == HIGH) {
digitalWrite(heaterPin, LOW);
Serial.println("Heater switched OFF");
}
else {
digitalWrite(heaterPin, HIGH);
Serial.println("Heater switched ON");
}
}
// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
unsigned long currentMillis = millis();
if ( currentMillis - startOfPeriod >= TimePeriod ) {
// more time than TimePeriod has elapsed since last time if-condition was true
startOfPeriod = currentMillis; // a new period starts right here so set new starttime
return true;
}
else return false; // actual TimePeriod is NOT yet over
}