I've created a nested loop and I want it to break that loop once 10 minutes has elapsed or after 10 loops!
I'm new to Arduino and would really appreciate some help on this.
Here is my code:
int temp; //A0 producing 4V
#define start_button 2 // #define any text saying start_button will be replaced with (port)2
#define LED1 3 // #define any text saying LED1 will be replaced with (port)3
#define heater_element 4 // #define any text saying heater_element will be replaced with (port)4
#define LED2 5 // #define any text saying LED2 will be replaced with (port)5
#define LED3 6 // #define any text saying LED3 will be replaced with (port)6
#define piezo_buzzer 7 // #define any text saying piezo_buzzer will be replaced with (port)7
void setup()
{
// initialize serial communication:
Serial.begin(9600);
// initialize pins:
pinMode(LED1,OUTPUT);
pinMode(heater_element,OUTPUT);
pinMode(LED2,OUTPUT);
pinMode(LED3,OUTPUT);
pinMode(piezo_buzzer,OUTPUT);
}
void loop()
{
if (digitalRead(start_button)==HIGH) //starting machine
{
digitalWrite (LED1,HIGH); //turning on 'started' LED
Serial.println("Started cooking process");
delay(5000); //delay for 5 seconds
}
if (analogRead(temp)<=4.5)
{
digitalWrite (heater_element,HIGH); //turing on heater
digitalWrite (LED2,HIGH); //turning on 'Boiling' LED
Serial.println("Started to boil");
delay(5000);
}
while (analogRead(temp)>4.5)
{
digitalWrite (heater_element,LOW); //turning off heating element
Serial.println("Water Boiled");
}
do
{
if (analogRead(temp)>4.5)
{
break;
}
else
{
digitalWrite (heater_element,HIGH);
delay(10000);
digitalWrite (heater_element,LOW);
delay(50000);
}
}
while(delay(600000));
}
You could rethink your code as a state machine and manage time and temperature as events to change state
If you were to describe in plain English what you want, how would it look like and what would be the state of the Heater element at each state
For example
state IDLE heater is off
State COOKING heater is on
Now define how you get from on state to the other
If state is IDLE and you press the button go to COOKING state (and thus set jester accordingly)
If state is COOKING and you press the button go to the IDLE state (and thus set jester accordingly)
If state is cooking and 10 minutes are up, go to the IDLE state (and thus set jester accordingly)
You might need other states to describe specifics. Like you have a BOILING state. What's the heater in that state?
The break operator leaves 1 nested level where it is.
while (delay... The while loop runs while the condition is true, but the delay function doesn't return value.
I can't see any nested loop in your sketch (not to mention you loops inside the loop function ).
What you need, IMHO, is to exit loop function if the time hasn't come yet and accumulate some time counter.
For example:
long _10m_delay=millis(); // get the start time moment
int _10timesy=0;
bool time_has_come=false;
loop() {
if ((millis - _10m_delay) > 1000*60*10) // 1000ms = 1 second
{
time_has_come=true;
_10m_delay=millis();
}
if ( _10times_delay > 9) {
_10times_delay = 0;
time_has_come=true;
}
if (time_has_come) {
time_has_come=false;
... do you want to do here ...
}
... if the time _10times_delay++;
}
BTW, to exit function immediately you need issue the return operator.
If you had nested loops - Sure you could use a goto... that's considered ugly practice in general unless it's really really needed and your code will soon become spaghetti code... hard to maintain... your call of course.
On the other hand, Understanding how to build a state machine will help you for many many other programs
As far as I understand the cooking process is 10 minutes long. After you press "Start" button you get the the start time, and then all you need is keep the temperature near 4.5 until 10 min has gone.
I've kept all minor things like LEDs in this code for your attention.
long ctime=0; // if ctime > 0 then cooking is started
const byte pinTEMP=A0; // don't forget to initialize variables or make constants
void loop()
{
if (digitalRead(start_button)==HIGH && ctime ==0) //starting machine
{
digitalWrite (LED1,HIGH); // turning on 'started' LED
Serial.println("Cooking...");
ctime=millis(); // get the cooking start time
}
if ((ctime>0) && (millis()-ctime) > 1000*60*10 )
{
ctime=0;
digitalWrite (heater_element,LOW);
Serial.println("Done!");
}
if (analogRead(pinTEMP)>4.5)
{
digitalWrite (heater_element,LOW); //turning off heating element
if(ctime > 0) Serial.println("Cooking... "); // erase "warming up"
}
// start warmin up if temperature is low and cooking in progress.
if (analogRead(pinTEMP)<=4.5 && (ctime>0))
{
digitalWrite (heater_element,HIGH); //turing on heater
digitalWrite (LED2,HIGH); //turning on 'Boiling' LED
Serial.println("Cooking... warming up");
}
}
@J-M-L:
I didn't want to introduce another bool to be cooking_in_progress flag, so ctime>0 condition is the flag. It becomes 0 only when device is powered on or the current task is done (10 minutes' gone).
So if button pressed when current cooking in progress then ctime>0 and condition
(digitalRead(start_button)==HIGH && ctime ==0)
returns false and nothing happens until task is finished and ctime accept value of 0.
My sketch is just an example to understand how it could be arranged.
P.S. we could add "Stop" button to set ctime=0 to interrupt current cooking or simple reset device. It depends on how smart the device's going to be.