Asynchronous function inside main loop

I come from a PHP background, so excuse any noob thought or questions.....I am writing a laser trip alarm, using an Arduino Pro Micro(5v) and an ESP8266 (to update a value on Thingspeak when the alarm goes off), and also a speaker and some RGB lights.
I have the sketch uploaded here: Laser Trap using a Photocell and KY-008, Thingspeak Alert with ESP8266 by sandbird

In general, the main algorithm is this:

  • Ard. connects via ESP to my router
  • It then initializes the laser and goes into the main loop
  • If something triggers the alarm, it will:
  • Connect to Thingspeak to update a value.
  • When done, start the alarm loop which blinks the RGB light and produce sound through the speaker.

And here is my problem...I have to wait for the esp to update Thingspeak first, before the alarm goes off.

I want the alarm to sound, and while it is doing that, to also update Thingspeak.
The problem is that the alarm event is a loop...I have to somehow execute that function async, so i can continue to the ESP function.

Part of the main loop where the problem is:

    boolean triggered = false;  // Alarm trigger
    .....
    if(triggered == true){
     alarm();
    }
    else{
      delay(2);// Wait 2ms between check
      value = analogRead(RESISTOR);
      if (abs(value-maxval)>=DROPVAL){
        triggered = true;
         digitalWrite (LASER, LOW); // laser off so that the intruder wont see it
	     // Wifi notification
	     DebugSerial.println("thingspeak connect");
	     updateThingSpeakHTTPApp();
	     Serial.println("closing connection");
      }
   }

I need something like this instead:

    boolean triggered = false;  // Alarm trigger
    .....
    if(triggered == true){
     alarm();
     // Wifi notification
     DebugSerial.println("thingspeak connect");
     updateThingSpeakHTTPApp();
     Serial.println("closing connection");
    }
    else{
      delay(2);// Wait 2ms between check
      value = analogRead(RESISTOR);
      if (abs(value-maxval)>=DROPVAL){
        triggered = true;
        digitalWrite (LASER, LOW); // laser off so that the intruder wont see it
      }
   }

where alarm() function is the looping sound/lights that runs asynchronously.

-Thanks

I want the alarm to sound, and while it is doing that, to also update Thingspeak.
The problem is that the alarm event is a loop...I have to somehow execute that function async, so i can continue to the ESP function.

It sounds like you need the BlinkWithoutDelay principle applied to your program.

Save the millis() value at the time that the start action happens. Then, each time through loop(), check whether the required wait period has elapsed by subtracting the start time from the millis() value now. If the period has elapsed then act accordingly and maybe save the start time for the next activity. If not, then go round loop() again, perhaps taking other actions and/or reading inputs, but don't block the free running of loop().

Thanks for the answer,
I took a look at that sample code. It kinda looks like what i want yes...Can i apply this code inside the alarm() function though? I cant seem to grasp this type of coding. Since the alarm will run inside a loop continuously how is going to 'escape' to continue with the Thingspeak function ?
Unless you mean i have to embed the alarm() and updateThingspeak() function inside the main loop and not have them in separate functions....Then somehow with the milis trick to keep looping the alarm....But what will happen to the Thingspeak connect then ? It will loop that as well...sending values every time the loops starts again :confused:

The alarm() function should check whether the required period has elapsed and if so act on it then exit whether or not the period has elapsed rather than staying in the function.

Once the Thinkspeak connect has been initiated set a flag variable to true to indicate that it has happened. Only do the connect when the variable is false. Reset the flag to false when appropriate to do another connect.

All of this is moot if the Thinkspeak connect blocks whilst it happens rather than initiating a connection and returning.

The demo Several Things at a Time is an extended example of BWoD.

Also look at how the program is structured.

Sandbird:
Since the alarm will run inside a loop continuously how is going to 'escape' to continue with the Thingspeak function ?

Both the alarm code and the Thingspeak code should be in functions that are called from loop() and none of the functions should take more than a few millisecs to complete so that loop() can repeat as often as possible.

...R

Thanks guys for clearing things out. Unfortunately the Thingspeak connect is taking more than a few seconds to do its thing...so i guess there is no way around this.
I understand what you mean now though. I'll try and implement something like that and see how it goes.
Worst case scenario i let the thief in, report to Thingspeak then scare the hell out of him, ahahaha

Sandbird:
Unfortunately the Thingspeak connect is taking more than a few seconds to do its thing...so i guess there is no way around this.

Maybe you can break it down into different parts. For example start a connection and then, in between doing other things, repeatedly check whether the connection has been made.

...R

Robin2:
Maybe you can break it down into different parts. For example start a connection and then, in between doing other things, repeatedly check whether the connection has been made.

...R

I am doing the connect to the router before the setup...its the part inside the loop that posts data to thingspeak that takes longer. I guess it depends on the traffic at that moment on their API page.

There is another solution.....i could do the internet part in the ESP8266. Have the connect to thingspeak there. So if the alarm triggers i just send a command to esp8266 with the values and move on to the alarm loop. The ESP will take care of the rest....I think thats the best solution....

The ESP will take care of the rest....I think thats the best solution....

Sounds like a plan to me.