1. With thread-like control with Schedule Table, the control loop and Design is shown as follows,
The pBWAC and cPWAC are defined as byte, range 0x00H to 0xFFH.
In this diagram, cPWAC stands for cycles in bits,
and pPWAC stands for control command to various home applicants like door-lock, lights. Corresponding to output pins,
with Input signals vsx assigned pins listed as well.
2. The program enter first Cycle for low frequency MIC ADC sampling, then triggers 2nd and 5rd cycles for whistle signals, then 3rd, 4th and 6th cycles for controlling.
The architecture of schedule table can be migrated to other platform easily and make debug process faster.
3. The code Architecture shall be listed below. With Block Diagram above, it is easy to understand.
#include "BWaC.h" #include <ScheduleTable.h> SchedTable<1> firstCycle_BW_IDLE(1,1000); SchedTable<1> secondCycle_BW_ACTIVE(1,1000); SchedTable<1> thirdCycle(1,1000); SchedTable<1> forthCycle(1,1000); SchedTable<1> fifthCycle_FFT(1,1000); SchedTable<1> sixCycle_PUBLISH(1,1000); // enum { RESERVED, DOORLOCK, CURTAIN_A,CURTAIN_B,LIGHT_A,LIGHT_B,LIGHT_C,LIGHT_D}; enum { BW_IDLE,BW_ACTIVE, BWAC_CTL, BWAC_CMD,FFT,PUBLISH, LPM0, LPM1,}; byte pBWAC=0x00; byte pState=0; byte cBWAC=0x00; byte cState; byte state; void init_ScheduleTable(){ firstCycle_BW_IDLE.at(0,firstDT); secondCycle_BW_ACTIVE.at(0,secondWS); thirdCycle.at(0,thirdCTL); forthCycle.at(0,forthCMD); fifthCycle_FFT.at(0,fifthFFT); sixCycle_PUBLISH.at(0,sixthPUB); } void stop_ScheduleTable(){ firstCycle_BW_IDLE.stop(); secondCycle_BW_ACTIVE.stop(); thirdCycle.stop(); forthCycle.stop(); fifthCycle_FFT.stop(); sixCycle_PUBLISH.stop(); } void firstDT() { //Serial.print("BW Detection.\n"); bool BW_Detected; //BW_Detected=BW_Detection(); BW_Detected= 1; if (BW_Detected){ cState=BW_ACTIVE;} else { cBWAC=bitClear(cBWAC, BW_ACTIVE); secondCycle_BW_ACTIVE.stop(); cState=BW_IDLE;} //Serial.println("firstCycle."); //Serial.print("cState="); Serial.println(cState); } void secondWS() { Serial.println(pBWAC); Serial.println("2ndCycle."); cState=FFT; // BITSET 5thCycle Serial.print("cState="); Serial.println(cState); } void thirdCTL() { Serial.println(pBWAC); Serial.println("3Cycle."); cBWAC=bitClear(cBWAC, BWAC_CTL); thirdCycle.stop(); cState=BWAC_CMD; // BITSET 4thCycle } void forthCMD() { Serial.println(pBWAC); Serial.println("4Cycle."); cBWAC=bitClear(cBWAC, BWAC_CMD); forthCycle.stop(); cState=PUBLISH; // BITSET 6thCycle } void fifthFFT(){ Serial.println(pBWAC); Serial.println("5Cycle."); cBWAC=bitClear(cBWAC, FFT); fifthCycle_FFT.stop(); cState=BWAC_CTL; // BITSET 3rdCycle Serial.print("cState="); Serial.println(cState); } void sixthPUB() { Serial.println(pBWAC); Serial.println("6Cycle."); cBWAC=bitClear(cBWAC, PUBLISH); sixCycle_PUBLISH.stop(); } void setup() { Serial.begin(9600); while (!Serial) {} // Wait for Serial to be Ready. init_ScheduleTable(); firstCycle_BW_IDLE.start(); } void loop() { state=cState; switch (state) { case BW_IDLE: cBWAC=bitSet(cBWAC, BW_IDLE); //firstCycle_BW_IDLE.start(); // Never stopped! cState=LPM0; break; case BW_ACTIVE: cBWAC=bitSet(cBWAC, BW_ACTIVE); secondCycle_BW_ACTIVE.start(); cState=LPM0; break; case BWAC_CTL: cBWAC=bitSet(cBWAC, BW_ACTIVE); thirdCycle.start(); //Serial.println("BWAC_CTL."); cState=LPM0; break; case BWAC_CMD: cBWAC=bitSet(cBWAC, BWAC_CMD); forthCycle.start(); cState=LPM0; break; case FFT: cBWAC=bitSet(cBWAC, FFT); fifthCycle_FFT.start(); cState=LPM0; break; case PUBLISH: cBWAC=bitSet(cBWAC, PUBLISH); sixCycle_PUBLISH.start(); cState=LPM0; break; } ScheduleTable::update(); /* update all the schedule tables at once */ }
While the output of the running sequence shall be like this.
4. Full code attached below.