2020年6月19日 星期五

ROSA 2020 系統開發 4 ─ 超音波距離偵測器

http://4rdp.blogspot.com/2020/06/rosa-2020-4.html

會開發這個程式是因為正好在重新設計 ROSA,文創造設計工作室的張宇文老師正在設計一個超音波感測讓垃圾桶蓋開閉的程式,因此就順手寫一個相同功能的程式。

主程式為 ROSA_Door.ino,Arduino pin 12, 11 分別連接超音波感測器 trig, echo,pin 9 接 servo ,並使用 USB 來幫忙除錯,所以 pin 1, 0 分別為 TX, RX,baud 115200 bps,程式碼如下:

// (C) 2019-2020, Bridan Wang, CC BY-NC-SA 3.0 TW
// This is a demo program applied Robot Operating 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,Door "
#define VERSION  "v2020.5.12"

//#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()

#define STRING_LENGTH 25
/*********************************************************** // Include ************************************************************/ #include ".\ROSA\ROSA_BASE.cpp" #include ".\ROSA\ROSA_LINK.cpp" #include ".\ROSA\ROSA_SENSOR.cpp" #include ".\ROSA\ROSA_SERVO.cpp" ROSA_LINK  link; ROSA_SONAR sonar; ROSA_SERVO servo; /*********************************************************** // Main Program ************************************************************/ void setup() {   link.USB_SETUP(115200);         // pin 1, 0  TX, RX USB, 115200 baud   sonar.SETUP(12, 11);            // pin trig, echo   servo.SETUP(9);                 // pin 9 } void loop()  {   ROSA_TIME_RUNNING();       // 系統時間處理 } /*********************************************************** // SYSTEM TIMER ************************************************************/ void ROSA_TIME_50ms() {   servo.PROCESS();           // 伺服馬達處理 } void ROSA_TIME_500ms() {   int cm = sonar.DETECT();   // 超音波偵測   link.PRINT(STRING("Distance : %d cm\n", cm)); // 印出以便偵錯      if (cm < 25) {             // 接近時開動     servo.setAngle = 180;     servo.hold = HOLDON;   } else if (cm > 100) {     // 遠離時關閉     servo.setAngle = 0;     servo.hold = 0;   } }

關於伺服馬達以及超音波模組的函式庫程式碼說明,再另篇補充,下面先針對 ROSA_LINK.cpp 說明。

enum{NONE, USB, BT};

class ROSA_LINK 
{
 private:
  byte cmd_from;
  byte cmd_index;
  char cmd0[64];    // USB or BT 讀入 buffer
  char cmd1[64];    // 可 parser buffer
  
 public:
  void PRINT(char* str);
  char COM_READ(void);
  void USB_SETUP(long baud);
  #ifdef DEVICE_BT
    void BT_SETUP(long baud);
  #endif
};

void ROSA_LINK::USB_SETUP(long baud) 
{
  Serial.begin(baud);
  Serial.print(PRODUCT VERSION "\n");
  //cmd_from = USB;
}

#ifdef DEVICE_BT
  void ROSA_LINK::BT_SETUP(long baud)
  {
   ROSA_BT.begin(baud);
   ROSA_BT.print(PRODUCT VERSION "\n");
    //cmd_from = BT;
  }
#endif

void ROSA_LINK::PRINT(char* str) {
 #ifdef DEVICE_BT
  if (cmd_from == BT)
    ROSA_BT.print(str);
   else
 #endif
   Serial.print(str);
}

char ROSA_LINK::COM_READ(void) {
  char a;

   if (cmd1[0] == NONE) {
   if (Serial.available() > 0) {     // USB
    cmd_from = USB;
    a = Serial.read();
    }
   #ifdef DEVIDE_BT
    else if (ROSA_BT.available() > 0) {    // BT
     cmd_from = BT;
     a = ROSA_BT.read();
    }
   #endif
    else
     return 0;

    if (a==0) return 0;   // 去除干擾
   if (a != '\r' && a != '\n') {
      #ifdef DEBUG_COMMAND_READ
        echo[echo_index++] = char(a);
      #endif
    cmd0[cmd_index++] = char(a);
    cmd0[cmd_index] = 0;
    return 0;
   }
   for (a = 0; a<64 a="" span="">
    if ((cmd1[a] = toUpperCase(cmd0[a])) == NONE) break;
   }
   #ifdef DEBUG_COMMAND_READ
    echo[echo_index] = 0;
      PRINT(echo);
      echo_index = 0;
   #endif
   cmd0[cmd_index = 0] = NONE;
  }
  return cmd1[0];
}


這個函數庫是 USB 和藍牙模組共用,基本上訊息從 USB 來,就會從 USB 回應,從藍牙來就從藍牙回,CMD_READ()會讀取一行完整的指令再處理。

沒有留言:

張貼留言