visit
For those people who areย familiar with microcontroller programming, you may have asked yourself this question.
Can multiple processes be executed at the same time on Arduino?
Asynchronous, you said? What is that?
Well, a coroutine is a function that has the ability to pause and resume itself. This means that with coroutines, we can execute parts of a function instead of executing it completely as usual. To achieve this, we will use a design pattern calledย State Machines. This design pattern will allow us to split the function into states and then execute them individually. Take a look at the next example:
#include <cstdlib>
#include <cstdio>
int coroutine() {
static int state = 0;
switch( state ){
case 0: printf(":>A\n"); state++; return 1; break;
case 1: printf(":>B\n"); state++; return 1; break;
case 2: printf(":>C\n"); state++; return 1; break;
case 3: printf(":>D\n"); state++; return 1; break;
case 4: printf(":>E\n"); state++; return 1; break;
} return -1;
}
int main() {
while( coroutine()>0 ){}
}
#define _Yield(VALUE) do { _state_ = VALUE; return 1; case VALUE:; } while (0)
#define _Start static int _state_ = 0; { switch(_state_) { case 0:;
#define _Goto(VALUE) do { _state_ = VALUE; return 1; } while (0)
#define _Stop } _state_ = 0; return -1; }
#include <cstdlib>
#include <cstdio>
int coroutine() {
static int x = 10;
_Start
while( x-->0 ){
printf(":>%d\n",x); _Yield(1);
}
_Stop
}
int main() {
while( coroutine()>0 ){}
}
#define _Yield(VALUE) do { _state_ = VALUE; return 1; case VALUE:; } while (0)
#define _Start static int _state_ = 0; { switch(_state_) { case 0:;
#define _Goto(VALUE) do { _state_ = VALUE; return 1; } while (0)
#define _Stop } _state_ = 0; return -1; }
/*โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ*/
using ulong = unsigned long int;
int OUT[] = { 12, 11 };
/*โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ*/
template < class T >
int wrk1( const T& function, const ulong& time ){ //firts we create a worker
static ulong stamp = millis() + time; //then we define a time stamp as static
_Start //Begin of the coroutine
while( millis() < stamp ){ _Yield(1); } //Async waiting a period of time
stamp = millis() + time; //we redefine the time stamp
function(); //now we are able to execute the function
_Goto(0); //and then set the state machine as 0
_Stop //End of the coroutine
}
template < class T >
int wrk2( const T& function, const ulong& time ){
static ulong stamp = millis() + time;
_Start
while( millis() < stamp ){ _Yield(1); }
stamp = millis() + time;
function(); _Goto(0);
_Stop
}
/*โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ*/
void setup(){
for( auto x : OUT ) pinMode( x, OUTPUT ); //Setting up Output pins
}
void loop(){
wrk1([](){ //Worker 1
static bool b=0; b=!b; //Simple Boolean Oscilator
digitalWrite( 12, b ); //setting up Output based on oscilations
},1000); //NOTE: 1000 represent time in ms
wrk2([](){
static bool b=0; b=!b;
digitalWrite( 11, b );
},500);
}