/*
* ARDUINO STATE MACHINE 2022 07N
*
*/
#include <avr/sleep.h>.
#include <avr/wdt.h>
#define VERSION "ARDUINO STATE MACHINE 2022 01"
#define DEBUG 1
#if (DEBUG)
#define DEBUGP(x) Serial.print(x)
#define DEBUGN(x) Serial.println(x)
#else
#define DEBUGP(x)
#define DEBUGN(x)
#endif
//HZ Control
#define HZ_SETTING 20
int mainLoop_count;
unsigned long fast_loopTimer; // Time in miliseconds of main control loop
const int hzCount = (1000 / HZ_SETTING) - 1;
const int timeRemind = 1000 / HZ_SETTING;
void (*resetFunc)(void) = 0; //declare reset function @ address 0 call resetFunc(); if you want to reset
#define LED_PIN 13
#define LED_A 3
#define LED_B 4
#define LED_C 5
#define LED_D 6
#define LED_E 7
#define LED_F 8
unsigned long taskCounterA =0; // State A 裡面專用的計數器
unsigned long taskTimerA =0; // State A 裡面專用的計時器
unsigned long taskCounterB =0; // State B裡面專用的計數器
unsigned long taskTimerB =0; // State B 裡面專用的計時器
unsigned long taskCounterC =0; // State C 裡面專用的計數器
unsigned long taskTimerC =0; // State C 裡面專用的計時器
unsigned long taskCounterD =0; // State D 裡面專用的計數器
unsigned long taskTimerD =0; // State D 裡面專用的計時器
unsigned long taskCounterE =0; // State E 裡面專用的計數器
unsigned long taskTimerE =0; // State E 裡面專用的計時器
unsigned long taskCounterF =0; // State F 裡面專用的計數器
unsigned long taskTimerF =0; // State F 裡面專用的計時器
int secCount = 0;
void stateA(){
/// 下面這區只有進來的時候會作一次 -------------------------------
if(taskCounterA==0){
/// 顯示一下目前的狀態
Serial.println("Hello I am State A");
/// 把狀態裡面的變數清空
taskCounterA=1;
taskTimerA =0;
}
taskTimerA++;
// 狀態A 說要 每秒閃10 次,那就是每50ms 要變換一次燈號
// 目前這個系統跑在20 HZ ( 請參考一下LINE #27 的MACRO 設定 ),所以每1/20 會被呼叫一次
// 所以只要每次進來執行這個State 1次 就變換一下LED燈的狀態,就可跑到10HZ 的閃滅
digitalWrite(LED_A,!digitalRead(LED_A));
}
void stateB(){
/// 下面這區只有進來的時候會作一次 -------------------------------
if(taskCounterB==0){
/// 顯示一下目前的狀態
Serial.println("Hello I am State B");
/// 把狀態裡面的變數清空
taskCounterB=1;
taskTimerB =0;
}
taskTimerB++;
// 狀態B 說要 每秒閃5 次,那就是每100ms 要變換一次燈號
// 目前這個系統跑在20 HZ ( 請參考一下LINE #27 的MACRO 設定 ),所以每1/20 會被呼叫一次
// 所以只要每2次進來執行這個State 1次 就變換一下LED燈的狀態,就可跑到5HZ 的閃滅
if(taskTimerB%2 ==0){
digitalWrite(LED_B,!digitalRead(LED_B));
}
}
void stateC(){
/// 下面這區只有進來的時候會作一次 -------------------------------
if(taskCounterC==0){
/// 顯示一下目前的狀態
Serial.println("Hello I am State C");
/// 把狀態裡面的變數清空
taskCounterC=1;
taskTimerC =0;
}
taskTimerC++;
// 狀態C 說要 每秒閃1 次,那就是每500ms 要變換一次燈號
// 目前這個系統跑在20 HZ ( 請參考一下LINE #27 的MACRO 設定 ),所以每1/20 會被呼叫一次
// 所以只要每10次進來執行這個State 1次 就變換一下LED燈的狀態,就可跑到 1 HZ 的閃滅
if(taskTimerC%10 ==0){
digitalWrite(LED_C,!digitalRead(LED_C));
}
}
void stateD(){
/// 下面這區只有進來的時候會作一次 -------------------------------
if(taskCounterD==0){
/// 顯示一下目前的狀態
Serial.println("Hello I am State D");
/// 把狀態裡面的變數清空
taskCounterD=1;
taskTimerD =0;
}
taskTimerD++;
// 狀態D 說要 每5 秒閃1 次,那就是每2.5 秒 要變換一次燈號
// 目前這個系統跑在20 HZ ( 請參考一下LINE #27 的MACRO 設定 ),所以每1/20 會被呼叫一次
// 所以只要每50 次進來執行這個State 1次 就變換一下LED燈的狀態,就可跑到5 HZ 的閃滅
if(taskTimerD%50 ==0){
digitalWrite(LED_D,!digitalRead(LED_D));
}
}
void stateE(){
/// 下面這區只有進來的時候會作一次 -------------------------------
if(taskCounterE==0){
/// 顯示一下目前的狀態
Serial.println("Hello I am State E");
/// 把狀態裡面的變數清空
taskCounterE=1;
taskTimerE =0;
}
taskTimerE++;
// 狀態E 說要 每10 秒閃1 次,那就是每5秒 要變換一次燈號
// 目前這個系統跑在20 HZ ( 請參考一下LINE #27 的MACRO 設定 ),所以每1/20 會被呼叫一次
// 所以只要每100 次進來執行這個State 1次 就變換一下LED燈的狀態,就可跑到5 HZ 的閃滅
if(taskTimerE%100 ==0){
digitalWrite(LED_E,!digitalRead(LED_E));
}
}
void stateF(){
/// 下面這區只有進來的時候會作一次 -------------------------------
if(taskCounterF==0){
/// 顯示一下目前的狀態
Serial.println("Hello I am State F");
/// 把狀態裡面的變數清空
taskCounterF=1;
taskTimerF =0;
}
taskTimerF++;
// 狀態F 說要 每30 秒閃1 次,那就是每15秒 要變換一次燈號
// 目前這個系統跑在20 HZ ( 請參考一下LINE #27 的MACRO 設定 ),所以每1/20 會被呼叫一次
// 所以只要每300 次進來執行這個State 1次 就變換一下LED燈的狀態,就可跑到 每30 秒閃1 次的閃滅
if(taskTimerF%300 ==0){
digitalWrite(LED_F,!digitalRead(LED_F));
}
}
void doSM_A(){
stateA();
}
void doSM_B(){
stateB();
}
void doSM_C(){
stateC();
}
void doSM_D(){
stateD();
}
void doSM_E(){
stateE();
}
void doSM_F(){
stateF();
}
void hw_init()
{
pinMode(LED_PIN, OUTPUT);
pinMode(LED_A, OUTPUT);
pinMode(LED_B, OUTPUT);
pinMode(LED_C, OUTPUT);
pinMode(LED_D, OUTPUT);
pinMode(LED_E, OUTPUT);
pinMode(LED_F, OUTPUT);
}
void setup()
{
// put your setup code here, to run once:
Serial.begin(115200);
//Setup I/O
hw_init();
//setup WDT
wdt_enable(WDTO_4S);
}
void loop()
{
// system Loop HZ define in #define HZ_SETTING 5
if (millis() - fast_loopTimer > hzCount)
{
fast_loopTimer = millis();
mainLoop_count++;
wdt_reset(); // Reset WDT ...
/// do things
doSM_A();
doSM_B();
doSM_C();
doSM_D();
doSM_E();
doSM_F();
if (mainLoop_count % HZ_SETTING == 0)
{
secCount++;
digitalWrite(LED_PIN,!digitalRead(LED_PIN));
DEBUGP("Sec count : ");
DEBUGN(secCount);
}
// Time Remind for this Loop ---------------------------------------------------------------
DEBUGP("Time Remind ms :");
DEBUGN(timeRemind - (millis()-fast_loopTimer));
}
}