////////////// polytask.h ////////////
//--------- some elements of 'basic'---------//
#define ext_up_to 1
#define ext_dn_to -1
#define For(var,from,dir,to)\
for(var=from;var!=to+ext_##dir; var+=ext_##dir)
#define Func
#define end_func
#define Proc
#define end_proc
#define end_(rem)
#define Loop while(1)
#define Next
// poly_var(5,int x,y;) use x,y in poly __
#define poly_var(mem,...) /*- - - - - - */\
const int max_poly=mem-1; \
typedef struct \
{void *PC; uint16_t cs; int para;\
__VA_ARGS__;}p_var; \
static p_var p_A[mem]; \
static uint8_t p_cur; \
static uint8_t p_tmp; \
static bool init_done
// poly_intit{ autostarts} ____________________
#define poly_init /*- - - - - - - - - - - - */\
for (;!init_done;init_done=!init_done)
/* ________ variable 'frame' */
#define sP_(s,var) p_A[s]. var
#define P_(var) sP_(p_cur,var)
// poly_schedule[polys} _______________
#define poly_schedule \
For(p_cur,0,up_to,max_poly) \
{ if (P_(PC)!=NULL) goto *(P_(PC)); \
next_poly:; } \
if(!init_done)
// polyPoly(0,..) 0:free;p_tmp=id _______
#define startPoly(slot,name,_para) \
if(slot<=max_poly) \
{ if(slot!=0){p_tmp=slot;} \
else For(p_tmp,max_poly,dn_to,0) \
if(sP_(p_tmp,PC)==NULL) break;\
if(p_tmp>=0) \
{ sP_(p_tmp,PC) =p_adr(name); \
sP_(p_tmp,para)=_para; } }
// stopPoly(3) _________________________
#define stopPoly(slot) sP_(slot,PC)=NULL
// stopPolys(-1) __________________
#define stopPolys(mod ) \
For(p_tmp,0,up_to,max_poly mod) \
sP_(p_tmp,PC)=NULL
/* _________ poly 'frame' ______________ */
#define POLY(name) p_conc(name): while(1)
#define poly_end P_(PC)=NULL;goto next_poly;
#define poly_rep p_yield;
#define poly_to(name)P_(PC)=p_adr(name);goto next_poly;
/* ________ time sharing ___*/
// p_yield save PC; return __
#define p_yield /* - - - - */\
{P_(PC)=p_adr(__LINE__); \
goto next_poly; \
p_label(__LINE__); }
#define P_Wait(cond) while(not(cond)) p_yield;
#define P_Wait_cs(_cs) P_(cs)=centis+_cs; P_Wait(centis==P_(cs))
/* __________ name'helper'______*/
#define p_conc(name) poly_ ##name
#define p_label(name) p_conc(name):
#define p_adr(name) &&p_conc(name)
//maybe 'simplified' language
#define P_For(var,from,dir,to) For(P_(var),from,dir,to)
#define P_Until(cond) p_yield;if(cond) break;
#define P_Switch_to(name) {poly_to(name)}
//////////////////////////////////////////////
//////////////////////////////////////////////
#define ana1 A1
//---------- some led ----------//
//Project by MOHD SOHAIL// (Board)
// 15+18 lost in Kutupalong 2021(Aug)
#define pinsCount 12
int pins_a[] = {2,3,4,5,6,7,8,9,10,11,12,13};
uint8_t pins_cur[pinsCount];
uint8_t pins_des[pinsCount];
Proc void w_pin(uint8_t num,uint8_t val,int8_t sw){
switch(sw){
case -1: pins_des[num-1]=000; pins_cur[num-1]=val;break;
case 0: pins_des[num-1]=val; break;
case 1: pins_des[num-1]=val; pins_cur[num-1]=val;break;
}
end_proc;}
Func void pin_update(){int i;
For(i,0,up_to,pinsCount-1)
{ if(pins_cur[i]!=pins_des[i])
if(pins_cur[i]>pins_des[i]) pins_cur[i]--;
else pins_cur[i]++;
if(pins_cur[i]==0)
digitalWrite(pins_a[i], LOW);
else digitalWrite(pins_a[i], HIGH);
// analogWrite(pins_a[i],pins_cur[i]*16);
}
end_func;}
// macro test:num:poly_var
#define P_test_pin(num,duration) \
{w_pin(P_(num),2,-1); P_Wait_cs(duration); };
//---------- some buttons ----------//
#define btn1 A2
#define btn2 A0
enum { btn_press=1*256,btn_repeat=4*256,
btn_short=2*256,btn_long =3*256};
uint8_t btn_scan;
Func int button(){
static uint8_t time;
uint8_t scan;
int tmp_return;
scan=1*(digitalRead(btn1)==LOW)+
2*(digitalRead(btn2)==LOW);
if(scan!=btn_scan)
{ if(time<20) tmp_return=btn_scan+btn_short;
else tmp_return=btn_scan+btn_long;
btn_scan=scan; time=0; }
else switch(time++) {
case 1:tmp_return=scan + btn_press;break;
case 30:tmp_return=scan + btn_repeat;break;
case 50:time=29;
default:tmp_return=0; }
return tmp_return;
end_(button);}
/////////////////////////////////////
Proc void do_Poly(uint16_t centis) {
poly_var(8,int A,B,C);
poly_init{
startPoly(0,btn,NULL);
startPoly(0,blink,25);
startPoly(1,on,20);
/*end init/autostart*/}
poly_schedule{
// ---
POLY(blink){
w_pin(12,3,-1);
P_Wait_cs(P_(para));
poly_rep;}
// ---
POLY(on){
P_For(A,1,up_to,pinsCount-1){
w_pin(P_(A),55,-1);
P_Wait_cs(3);
Next;}
poly_to(p_max);}
// ---
POLY(p_max){
P_For(A,1,up_to,pinsCount-1)
P_test_pin(A,P_(para));
poly_rep;}
// ---
POLY(p_1_8){
P_For(A,1,up_to,8) P_test_pin(A,P_(para));
poly_to(p_7_2);}
// ---
POLY(p_7_2){
P_For(A,7,dn_to,2) P_test_pin(A,P_(para));
poly_to(p_1_8);}
// ---
POLY(prg_1){ poly_rep;}
// ---
POLY(prg_2){ poly_end;}
//---
POLY(flash){// poly_prg_1
P_For(A,1,up_to,5) w_pin(P_(A),5,-1);
P_Wait_cs(5);
P_For(A,5,up_to,9) w_pin(P_(A),5,-1);
poly_end;}
//---
POLY(btn){
switch (button()){
case 1+btn_press :Serial.println("1-Press stop 1");
stopPoly(1);break;
case 1+btn_repeat:Serial.println("1-Repeat flash 1 ");
startPoly(1,flash,40);break;
case 1+btn_short :Serial.println("1-short kn slow");
startPoly(1,p_1_8,10);break;
case 1+btn_long :Serial.println("1-long kn fast");
startPoly(1,p_7_2,5);break;
case 2+btn_press :Serial.println("2-Press ");
break;
case 2+btn_repeat:Serial.println("2-Repeat ");
break;
case 2+btn_short :Serial.println("2-short add max ");
startPoly(0,p_max,5);break;
case 2+btn_long :Serial.println("2-long stop polys ");
stopPolys(-2);break;
end_(switch)} P_Wait_cs(1);
poly_rep;}
/*end of polys*/}
int ana_val;static int ana_val_;
ana_val = analogRead(ana1)/16+1;
if(ana_val!=ana_val_)
{ sP_(1,para)=ana_val;
Serial.print("slide:"); Serial.println(ana_val);
ana_val_=ana_val;}
end_(do_poly);}
Proc void setup() {int i;
for (i=0; i<pinsCount; i=i+1) pinMode(pins_a[i], OUTPUT);
pinMode(btn1, INPUT_PULLUP); pinMode(btn2, INPUT_PULLUP);
pinMode(ana1, INPUT);
Serial.begin(38400);
end_proc;}
Func void loop() {
static long millis_upd;
if(millis()>=millis_upd)
{ millis_upd=millis()+20; pin_update();}
uint16_t centis;//intended use:'slow' poly
static long millis_cent;
if(millis()>=millis_cent)
{ millis_cent=millis()+10; centis++;}
do_Poly(centis);
end_proc;}