2020年5月22日 星期五

ROSA 2020 系統開發 1 ─ LED control

http://4rdp.blogspot.com/2020/05/rosa-2020-1-led-control.html

今年因為 COVID-19 的關係,把一些活動行程打亂,最近有空再重整 ROSA (Robot Operation System for Arduino) 程式碼,程式庫改以 C++ 物件導向設計,因此 ROSA 2020 跟 ROSA 2019 還是有許多差異,不過基本概念仍然相通。以下程式使用 Arduino Uno 控制 LED 為例,將程式寫得更結構化,以此 ROSA 再出發。


ROSA 主程式目錄檔案

ROSA 函式庫檔案

主程式為 ROSA_LED.ino,下面藍色部分,它讓 pin 13 的 LED 亮 250 ms,滅 250 ms 循環閃爍,因為這程式不需要處理日期時間,所以取消綠色部分的程式,可讓程式更小。關於 ROSA 系統參數設定,基本上標示作品名稱及日期版本,和重要 #define,ROSA 設計成函式庫型式,就是讓一般使用者專注寫自己的程式碼,而專業開發者提供精簡好用的功能, 這些 #define 和 #include 是介於兩者之間的橋樑,讓那些函式庫程式碼引入,個人覺得這些放在主程式比較醒目,提醒使用者他的設定。

// (C) 2019-2020, Bridan Wang, CC BY-NC-SA 3.0 TW
// This is a demo program applied Robot Operation System for Arduino (ROSA)
// http://4rdp.blogspot.tw/search/label/ROSA%20(Arduino)

//軟件許可協議
//
//研發養成所 Bridan Wang 提供此軟體供學校教育或個人單獨使用
//對外分享展示本軟體時,請說明來源來自研發養成所
//你可以架構在本軟體基礎上,設計新功能或修改
//本軟體屬於 Bridan 和或其它原始碼供應商,並受適用的法律版權保護
//此軟體按“原樣”提供,可能含有錯誤,不作任何明示,暗示或法律的保證
//本軟體僅限 Arduino 部分微控制器產品,適用於特定用途
// Bridan 在任何情況、環境以及特殊使用不負任何原因損害賠償責任
//
//這是 ROSA 韌體版本的一部分。
//
//建議使用 Arduino-1.8.8 以後版本編譯,因為有發現舊版本有錯誤情形


/***********************************************************
// System Condition DEFINE
************************************************************/
#define PRODUCT  "ROSA,LED "
#define VERSION  "v2020.5.11"

//#define TIME_2ms      // ROSA_TIME_2ms()
//#define TIME_10ms     // ROSA_TIME_10ms()
//#define TIME_50ms     // ROSA_TIME_50ms()
//#define TIME_100ms    // ROSA_TIME_100ms()
#define TIME_250ms    // ROSA_TIME_250ms()
//#define TIME_500ms    // ROSA_TIME_500ms()
//#define TIME_1sec     // ROSA_TIME_1sec()

//#define TIME_SYSTEM   // ROSA_TIME_SETUP()

/***********************************************************
// Include
************************************************************/
#include ".\ROSA\ROSA_BASE.cpp"

ROSA_PIN     led;

/***********************************************************
// Main Program
************************************************************/
void setup() {
  //ROSA_TIME_SETUP(20, 5, 9, 0, 0, 0) ;  // YEAR, MONTH, DAY, HOUR, MINUTE, SECOND
  led.SETUP(13, OUTPUT);                  // pin 13
}

void loop() 
{
  ROSA_TIME_RUNNING();     // 系統時間處理
}

/***********************************************************
// SYSTEM TIME
************************************************************/
void ROSA_TIME_250ms()
{
  led.OUT(CHANGE);     // 閃爍
}

所有 ROSA 程式必須包含 ROSA_BASE.cpp 函式庫,它是 ROSA 的基礎程式,先看一下程式碼,先說明跟時間相關部分,根據主程式 #define 設定,將需要的程式碼含入編譯。

#define  INTERVAL  2  // mili second, 改變此值,無法正常作動
unsigned long now = millis();   // Time start-up

#ifdef TIME_SYSTEM
  byte second;
  byte minute;
  byte hour;
  byte day;    // 1 ~ 31
  byte month;  // 1 ~ 12
  byte year;   // 2000 ~ 2255

  const byte MONTH_[13] PROGMEM = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

  void ROSA_TIME_SETUP(byte y, byte m, byte d, byte h, byte n, byte s)
  {
    year = y;   // YEAR;
    month = m;  // MONTH;
    day = d;    // DAY;
    hour = h;   // HOUR;
    minute = n; // MINUTE;
    second = s; // SECOND;
  }
#endif

void ROSA_TIME_2ms();
void ROSA_TIME_10ms();
void ROSA_TIME_50ms();
void ROSA_TIME_100ms();
void ROSA_TIME_250ms();
void ROSA_TIME_500ms();
void ROSA_TIME_1sec();

void ROSA_TIME_RUNNING()
{
  static byte tm_10ms = 0;

  // 每兩毫秒檢查一次-----------------------------------
  while (millis() - now >= INTERVAL) {
    now += INTERVAL;
    #ifdef TIME_2ms
      ROSA_TIME_2ms();
    #endif
    tm_10ms++;  //累加計數
  }

  // 如果超過 10 ms ---------------------------------
  if (tm_10ms >= 5) {  // 2 ms x 5
    tm_10ms -= 5;
    #ifdef TIME_10ms
      ROSA_TIME_10ms();
    #endif

    #ifdef TIME_50ms
      static byte tm_50ms = 0;
      tm_50ms++;
      // 如果超過 50 ms ---------------------------------
      if (tm_50ms >= 5) {    // 10 ms x 5
        tm_50ms -= 5;
        ROSA_TIME_50ms();
      }
    #endif

    #ifdef TIME_100ms
      static byte tm_100ms = 0;
      tm_100ms++;
      // 如果超過 100 ms ------------------------
      if (tm_100ms >= 10) {  // 10 ms x 10
        tm_100ms -= 10;
        ROSA_TIME_100ms();
      }
    #endif

    #ifdef TIME_250ms
      static byte tm_250ms = 0;
      tm_250ms++;
      // 如果超過 250 ms ------------------------
      if (tm_250ms >= 25) {  // 10 ms x 25
        tm_250ms -= 25;
        ROSA_TIME_250ms();
      }
    #endif

    #ifdef TIME_500ms
      static byte tm_500ms = 0;
      tm_500ms++;
      // 如果超過 500 ms ------------------------
      if (tm_500ms >= 50) {  // 10 ms x 50
        tm_500ms -= 50;
        ROSA_TIME_500ms();
      }
    #endif

    static byte tm_1sec = 0;
    tm_1sec++;
    // 如果超過一秒 ------------------------------------
    if (tm_1sec >= 100) {  // 10 ms x 100
      tm_1sec -= 100;
      #ifdef TIME_1sec
        ROSA_TIME_1sec();
      #endif

      #ifdef TIME_SYSTEM
        if (++second == 60) {
          second = 0;
          if (++minute == 60) {
            minute = 0;
            if (++hour == 24) {
              hour = 0;
              if ((++day) > pgm_read_byte(&MONTH_[month])) {
            if ((month == 2) && (day == 29) && (year % 100 != 0) && (year % 4 == 0)) return;
            day = 1;        // Arduino-1.8.5 之前版本有 bug,編譯後 換月份 day = 0
     
          if (++month == 13) {
          month = 1;    // Arduino-1.8.5 之前版本有 bug,編譯後 換年度 month & day = 0
          year++;
        }
            }
          }
        }
      }
      #endif
    }
  }
}

下面程式在 ROSA_BASE.cpp 中,用 C++ 寫法,也跟 pin 腳控制關聯,主程式設定 pin 13 為 LED 輸出

class ROSA_PIN
{
  private:
    byte pin;
    byte state = 0;                  

  public:
    void SETUP(byte p, byte mode);   // mode: OUTPUT, INPUT, INPUT_PULLUP
    void OUT(byte st);
    byte IN(void);
    byte count;
    #define CHANGE  2
};

void ROSA_PIN::SETUP(byte p, byte mode) {
  pin = p;
  pinMode(p, mode);
}

void ROSA_PIN::OUT(byte st) {  // 輸出設定   st: 0 LOW, 1 HIGH, 2 CHANGE
  if (st == 0 || st == 1)
    state = st;
  else
    state = 1 - state;
  digitalWrite(pin, state);    // 設定 pin 狀態
}

byte ROSA_PIN::IN(void) {      // 輸入
  return digitalRead(pin);

}

Version.txt 是 ROSA 程式開發的註記,希望未來 ROSA 深受大家喜愛。

沒有留言:

張貼留言