1. 程式人生 > >【嵌入式】Arduino編程基礎到應用全解析

【嵌入式】Arduino編程基礎到應用全解析

接口 實現 關於 第一次 學習 wid 標誌位 解碼 post

Arduino

Author: Andrew.Du

基礎

基礎語法:

    setup()
    loop()
    pinMode(引腳,模式)
    
    pinMode(13,OUTPUT);設置13號引腳為輸出
    //在使用輸入或輸出功能前,你需要先通過pinMode() 函數配置引腳的模式為輸入模式或輸出模式。
        

---

    digitalWrite(引腳,HIGH/LOW) 把引腳電平拉高拉低
    digitalWrite() 讓其輸出高電平或者是低電平
        
    digitalRead() 函數讀取外部輸入的數字信號
    int value = digitalRead(pin);
            
    analogWrite函數 //analogWrite(引腳,0-255) 引腳電平,如控制led亮度,馬達轉速
    
    中斷:
        對中斷引腳進行初始化配置:
        setup(){
            attachInterrupt(interrupt,function,mode);
                    //              (引腳,函數,模式low/high/change);
                }
        //當觸發中斷引腳符合模式時,loop轉去執行中斷處理函數,執行完畢返回loop
        //比如,attachInterrupt(2,fun,change)
        //即:2號發生改變,fun執行
    串口通信:
        Serial.begin(9600);設置波特率
        Serial.println("hello world");在串口監視器中打印
        Serial.available() 返回當前緩沖區中接受到的字節數

練習使用

數字I/O的使用

流水燈:
        
        比如引腳2-7流水燈:
        void setup(){
            //初始化I/O口
            for(int i = 2;i<8;i++){
                pinMode(i,OUTPUT);
            }
        }
        void loop(){
            //從引腳2到引腳6,逐個點亮LED,在熄滅
            for(int i = 2;i<6;i++){
                digitalWrite(i,HIGH);
                delay(1000);
                digitalWrite(i,LOW);
                delay(1000);
            }
            //引腳7到3,逐個點亮,再熄滅
            for(int i = 7;i<=3;i--){
                digitalWrite(i,HIGH);
                delay(1000);
                digitalWrite(i,LOW);
                delay(1000);
            }
        }
    
    按鍵控制LED:
        
        按鍵2號,LED 13號;
        
        int buttonPin = 2;
        int ledPin = 13;
        int buttonState = 0;
        
        void setup(){
            pinMode(buttonPin,INPUT);
            pinMode(ledPin,OUTPUT);
        }
        void loop(){
            buttonState = digitalRead(buttonPin);
            //HIGH說明按鍵被按下
            if(buttonState == HIGH){
                digitalWrite(ledPin,HIGH);
            }else{
                digitalWrite(ledPin,LOW);
            }
        }
        進一步,按下按鈕,點亮LED,再按一下,熄滅LED
        
        boolean ledstate = false;
        boolean buttonState = true;
        
        void setup(){
            pinMode(buttonpin,INPUT_PULLUP);
            pinMode(ledpin,OUTPUT);
        }
        void loop(){
            while(digitalRead(buttonPin) == HIGH){
                if(ledState == ture){
                    digitalWrite(ledPin,LOW);
                    ledState = !ledState;
                }else{
                    digitalWrite(ledPin,HIGH);
                    ledState = !ledState;
                }
                delay(50);
            }
        }

模擬I/O的使用:

Arduino 有模擬0—模擬5 共計6 個模擬接口,
    這6 個接口也可以算作為接口功能復用,
    除模擬接口功能以外,這6 個接口可作為數字接口使用,編號為數字14—數字19
    analogRead()讀
    analogWrite()寫

傳感器控制的練習

//  模擬輸入analogRead()函數的返回值範圍是0 到1023,
//而模擬輸出analogWrite()函數的輸出值範圍是0 到255
//註意除以4
溫度傳感器
    int potpin = 0;//模擬接口0,連接溫度傳感器
        void setup(){
            Serial.begin(9600);
        
        }
        void loop(){
            int val;
            int det;
            val = analogRead(potpin);//讀取模擬值
            det = (125 * val) >>8; //將模擬值轉換為溫度
            Serial.print("TEP:");
            Serial.print(det);
            Serial.println("C");
            delay(500);
        }
舵機控制
//  一種是通過Arduino 的普通數字傳感器接口產生占空比不同的方波,
//模擬擬產生PWM 信號進行舵機定位,
//第二種是直接利用Arduino 自帶的Servo 函數進行舵機的控制,
//這種控制方法的優點在於程序編寫,缺點是只能控制2 路舵機,
//因為Arduino 自帶函數只能利用數字9、10 接口
方法一:
    
            int servopin = 9; //數字接口9連接舵機信號線
            int myangle;
            int pulsewidth;
            int val;
            
            //脈沖函數
            void servopulse(int servopin,int myangle){
                pulsewidth = (myangle *11) +500; //角度0-180轉化為500 - 2480的脈沖
                digitalWrite(servopin,HIGH); //舵機電平升高
                delayMicroseconds(pulsewidth);//延時脈寬值的微妙數
                degitalWrite(servopin,LOW); //拉低電平
                delay(20-pulsewidth/1000);
            }
            
            void setup(){
                pinMode(servopin,OUTPUT);
                Serial.begin(9600);
                Serial.println("--");
            }
            void loop(){ //將0-9的數轉換為0-180的角度
                //讀取控制輸入,這裏做成接口,從客戶端傳進參數
                val = Serial.read();
                if(val>‘0‘&&val<=‘9‘){
                    val = val-‘0’;
                    val = val *(180/9); //數字轉角度
                    Serial.print("moving to");
                    Serial.print(val.DEC);//轉換為十進制
                    Serial.println();
                    for(int i = 0;i<=50;i++){
                        //給予舵機時間,讓他轉動
                        servopulse(servopin,val);
                    }
                }
            }
方法二:
首先:Servo函數學習:
            1.attach(接口):設定舵機的接口,只有數字串口9和10可以用
            2.write(角度); 用於設定舵機旋轉角度的語句,可以設定的角度是0-180
            3.read(角度);用於讀取舵機角度
            4.attached 判斷舵機參數是否到達已發送到舵機所在的接口
            5.detach() 使得舵機與接口分離,該接口可以繼續用作PWM接口
            
            
            #include <Servo.h> //要註意在#include 與<Servo.h>之間要有空格,否則編譯時會報錯
            
            Servo myservo;
            
            int getServoAngle(){
                //得到輸入
                int angle = ..
                return angle;
            }
            
            void setup(){
                myservo.attach(9); //連接接口
            }
            void loop(){
                int angle = getServoAngle();
                if(angle>0 && angle <=180){
                    myservo.write(angle);
                }
            }

小車控制練習

實現小車方向控制、舵機控制、巡線、超聲波避障模式等 ---

#include <Servo.h>
#include <EEPROM.h>

int ledpin = A0; //啟動指示燈,A0接內置指示燈
//四個馬達接口.2是右前,4是左前,1是左後,3是右後
/**
   與單片機相連分別控制四個輸出端,
   輸出端口連接電機,控制電機的正反轉
   HIGH/LOW
*/
int INPUT2 = 7; //左前
int INPUT1 = 8; //左後
int INPUT3 = 12; //右後
int INPUT4 = 13; //右後
int adjust = 1; //電機標誌位
int Left_Speed_Hold = 255; //左側速度
int Right_Speed_Hold = 255; //右側速度
/**
   使能端口連接單片機PWM端口
   可以通過調節PWM來調節使能端口的電壓,
   從而調節電機輸出端口的電壓,達到調速的目的
*/
int ENB = 6; //L298使能B
int ENA = 5; //L298使能A

int Echo = A5;                      // 定義超聲波信號接收腳位
int Trig = A4;                      // 定義超聲波信號發射腳位
int Input_Detect_LEFT = A3;         //定義小車左側紅外
int Input_Detect_RIGHT = A2;        //定義小車右側紅外
int Input_Detect = A1;              //定義小車前方紅外
int Carled = A0;                    //定義小車車燈接口
int Cruising_Flag = 0;              //模式切換標誌
int Pre_Cruising_Flag = 0 ;         //記錄上次模式


Servo servo1;                       // 創建舵機#1號
Servo servo2;                       // 創建舵機#2號
Servo servo3;                       // 創建舵機#3號
Servo servo4;                       // 創建舵機#4號
//Servo servo5;                      // 創建舵機#5號
//Servo servo6;                      // 創建舵機#6號
Servo servo7;                       // 創建舵機#7號
Servo servo8;                       // 創建舵機#8號

byte angle1 = 70;                    //舵機#1初始值
byte angle2 = 60;                    //舵機#2初始值
byte angle3 = 60;                    //舵機#3初始值
byte angle4 = 60;                    //舵機#4初始值
//byte angle5 = 60;                  //舵機#5初始值
//byte angle6 = 60;                  //舵機#6初始值
byte angle7 = 60;                    //舵機#7初始值
byte angle8 = 60;                    //舵機#8初始值

int buffer[3];                       //串口接收數據緩存
int rec_flag;                        //串口接收標誌位
int serial_data;                     //串口數據零時存儲
unsigned long Costtime;              //串口超時計數
int IR_R;                            //巡線右側紅外狀態標誌
int IR_L;                            //巡線左側紅外狀態標誌
int IR;                              //中間紅外狀態標誌

#define MOTOR_GO_FORWARD {digitalWrite(INPUT1,LOW);digitalWrite(INPUT2,HIGH);digitalWrite(INPUT3,LOW);digitalWrite(INPUT4,HIGH);}
#define MOTOR_GO_BACK      {digitalWrite(INPUT1,HIGH);digitalWrite(INPUT2,LOW);digitalWrite(INPUT3,HIGH);digitalWrite(INPUT4,LOW);}   //車體後退
#define MOTOR_GO_RIGHT    {digitalWrite(INPUT1,HIGH);digitalWrite(INPUT2,LOW);digitalWrite(INPUT3,LOW);digitalWrite(INPUT4,HIGH);}    //車體右轉
#define MOTOR_GO_LEFT     {digitalWrite(INPUT1,LOW);digitalWrite(INPUT2,HIGH);digitalWrite(INPUT3,HIGH);digitalWrite(INPUT4,LOW);}    //車體左轉
#define MOTOR_GO_STOP     {digitalWrite(INPUT1,LOW);digitalWrite(INPUT2,LOW);digitalWrite(INPUT3,LOW);digitalWrite(INPUT4,LOW);}      //車體停止


/**
   延遲50秒等待WIFI模塊啟動完畢
*/
void Delayed() {
  int i;
  for (i = 0; i < 20; i++) {
    digitalWrite(ledpin, LOW);
    delay(1000);
    digitalWrite(ledpin, HIGH);
    delay(1000);
  }
  //加快閃爍
  for (i = 0; i < 10; i++) {
    digitalWrite(ledpin, LOW);
    delay(500);
    digitalWrite(ledpin, HIGH);
    delay(500);
    digitalWrite(ledpin, HIGH);
  }
  //熄滅
  digitalWrite(ledpin, LOW);
  MOTOR_GO_STOP;
}
/**
   串口初始化函數
*/
void USART_init() {
  int BAUD = 9600;
  SREG = 0x80;                              //開啟總中斷
  //bitSet(UCSR0A,U2X0);
  bitSet(UCSR0B, RXCIE0);                   //允許接收完成中斷//
  bitSet(UCSR0B, RXEN0);                    //開啟接收功能//
  bitSet(UCSR0B, TXEN0);                    //開啟發送功能//
  bitSet(UCSR0C, UCSZ01);
  bitSet(UCSR0C, UCSZ00);                   //設置異步通信,無奇偶校驗,1個終止位,8位數據
  UBRR0 = (F_CPU / 16 / BAUD - 1);          //波特率9600
}
/***************************************************
   功能工具

 * ************************************************
*/
void Sendbyte(char c) {
  //檢查UCSROA的UDREO位是否置位 頭文件裏定義
  loop_until_bit_is_set(UCSR0A, UDRE0);
  UDR0 = c;
}
/**
   車燈控制
*/
void Open_Light()//開大燈
{
  digitalWrite(Carled, HIGH);  //拉低電平,正極接電源,負極接Io口
  delay(1000);
}
void Close_Light()//關大燈
{
  digitalWrite(Carled, LOW);   //拉低電平,正極接電源,負極接Io口
  delay(1000);
}
/**
   串口命令解碼
*/
void Communication_Decode() {
  if (buffer[0] == 0x00) { //0x00是控制電機命令
    switch (buffer[1]) { //電機命令
      case 0x01: MOTOR_GO_FORWARD; return;
      case 0x02: MOTOR_GO_BACK;  return;
      case 0x03: MOTOR_GO_LEFT; return;
      case 0x04: MOTOR_GO_RIGHT; return;
      case 0x00: MOTOR_GO_STOP; return;
      default: return;
    }
  }
  else if (buffer[0] == 0x01) { //0x01是舵機命令
    if (buffer[2] > 170) return;
    switch (buffer[1]) {
      case 0x01: angle1 = buffer[2]; servo1.write(angle1); return;
      case 0x02: angle2 = buffer[2]; servo2.write(angle2); return;
      case 0x03: angle3 = buffer[2]; servo3.write(angle3); return;
      case 0x04: angle4 = buffer[2]; servo4.write(angle4); return;
      case 0x07: angle7 = buffer[2]; servo7.write(angle7); return;
      case 0x08: angle8 = buffer[2]; servo8.write(angle8); return;
      default: return;
    }
  }
  else if (buffer[0] == 0x02) { //調速指令
    if (buffer[2] > 100) return;
    if (buffer[1] == 0x01) { //左側
      Left_Speed_Hold = buffer[2] * 2 + 55; //0-100轉換為PWM速度55-255;低於55電機不轉
      analogWrite(ENB, Left_Speed_Hold);
      EEPROM.write(0x09, Left_Speed_Hold); //記錄速度、持久化
    }
    else if (buffer[1] == 0x02 ) {
      Right_Speed_Hold = buffer[2] * 2 + 55; //速度檔位是0~100 換算成pwm 速度pwm低於55電機不轉
      analogWrite(ENA, Right_Speed_Hold);
      EEPROM.write(0x0A, Right_Speed_Hold); //存儲速度

    } else return;

  }
  else if (buffer[0] == 0x33) { //初始化舵機角度值命令
    Init_Steer();
    return;
  }
  else if (buffer[0] == 0x32) { //保存命令指令,鎖定舵機角度
    EEPROM.write(0x01, angle1);
    EEPROM.write(0x02, angle2);
    EEPROM.write(0x03, angle3);
    EEPROM.write(0x04, angle4);
    EEPROM.write(0x07, angle7);
    EEPROM.write(0x08, angle8);
    return;
  }
  else if (buffer[0] == 0x13) { //模式切換開關
    switch (buffer[1]) {
      case 0x02: Cruising_Flag = 2; return; //巡線模式
      case 0x03: Cruising_Flag = 3; return; //避障模式
      case 0x04: Cruising_Flag = 4; return;       //雷達避障
      case 0x05: Cruising_Flag = 5; return;       //超聲波距離PC端顯示
      case 0x00: Cruising_Flag = 0; return;       //正常模式
      default: Cruising_Flag = 0; return;         //正常模式
    }
  }
  else if (buffer[0] == 0x04) //開車燈指令為FF040000FF,關車燈指令為FF040100FF
  {
    switch (buffer[1])
    {
      case 0x00: Open_Light(); return; //開車燈
      case 0x01: Close_Light(); return; //關車燈
      default: return;
    }
  }
  else if (buffer[0] == 0x40) //存儲電機標誌
  {
    adjust = buffer[1];
    EEPROM.write(0x10, adjust);
  }
}
/**
   讀取串口命令
*/
void Get_uartdata(void)
{
  static int i;
  serial_data = UDR0;//讀取串口
  if (rec_flag == 0)
  {
    if (serial_data == 0xff)//第一次獲取到0xff(即包頭)
    {
      rec_flag = 1;
      i = 0;
      Costtime = 0;
    }
  }
  else
  {
    if (serial_data == 0xff)//第二次獲取到0xff(即包尾)
    {
      rec_flag = 0;
      if (i == 3)//獲取到中間數據為3個字節,說明此命令格式正確
      {
        Communication_Decode();//執行命令解析函數
      }
      i = 0;
    }
    else
    {
      buffer[i] = serial_data;//暫存數據
      i++;
    }
  }
}
ISR(USART_RX_vect)
{
  UCSR0B &= ~(1 << RXCIE0);         //關閉串口中斷
  Get_uartdata();
  UCSR0B |=  (1 << RXCIE0);         //打開串口中斷
}


/*****************************************************/

/**
   舵機初始化,速度初始化
*/
void Init_Steer() {
  //angle1 = EEPROM.read(ox01);
  angle7 = EEPROM.read(0x07);//讀取寄存器0x07裏面的值
  angle8 = EEPROM.read(0x08);//讀取寄存器0x08裏面的值
  if (angle7 == 255 && angle8 == 255)
  {
    EEPROM.write(0x01, 90); //把初始角度存入地址0x01裏面
    EEPROM.write(0x02, 90); //把初始角度存入地址0x02裏面
    EEPROM.write(0x03, 90); //把初始角度存入地址0x03裏面
    EEPROM.write(0x04, 90); //把初始角度存入地址0x04裏面
    //EEPROM.write(0x05,60);//把初始角度存入地址0x05裏面
    //EEPROM.write(0x06,120);//把初始角度存入地址0x06裏面
    EEPROM.write(0x07, 90); //把初始角度存入地址0x07裏面
    EEPROM.write(0x08, 90); //把初始角度存入地址0x08裏面
    return;
  }
  servo7.write(angle7);//把保存角度賦值給舵機7
  servo8.write(angle8);//把保存角度賦值給舵機8
  adjust = EEPROM.read(0x10);//電機標誌位放在0x10的位置
  if (adjust == 255) { //從未寫入時,是255
    EEPROM.write(0x10, 1);
  }
  Left_Speed_Hold = EEPROM.read(0x09); //oxo9是左側速度
  Right_Speed_Hold = EEPROM.read(0x0A); //0x0A是右側速度
  if ((Left_Speed_Hold < 55) | ( Right_Speed_Hold < 55)) {
    Left_Speed_Hold = 255;
    Right_Speed_Hold = 255;
  }
  /**
     調節使能端口的PWM輸入,能夠控制電機轉速
  */
  analogWrite(ENB, Left_Speed_Hold); //給L298使能端B賦值
  analogWrite(ENA, Right_Speed_Hold); //給L298使能端A賦值
  MOTOR_GO_STOP;
}

/**
   串口超時檢測
*/
void UartTimeoutCheck(void) {
  if (rec_flag == 1) {
    Costtime++;
    if (Costtime == 100000) {
      rec_flag = 0;
    }
  }
}
/*
  通過校準值校準小車方向
*/
void forward(int adjust)
{
  //adjust是電機標誌位
  switch (adjust)
  {
    case 1: MOTOR_GO_FORWARD; return;
    case 2: MOTOR_GO_FORWARD; return;
    case 3: MOTOR_GO_BACK; return;
    case 4: MOTOR_GO_BACK; return;
    case 5: MOTOR_GO_LEFT; return;
    case 6: MOTOR_GO_LEFT; return;
    case 7: MOTOR_GO_RIGHT; return;
    case 8: MOTOR_GO_RIGHT; return;
    default: return;
  }
}
/*
  通過校準值校準小車方向
*/
void back(int adjust)
{
  switch (adjust)
  {
    case 1: MOTOR_GO_BACK; return;
    case 2: MOTOR_GO_BACK; return;
    case 3: MOTOR_GO_FORWARD; return;
    case 4: MOTOR_GO_FORWARD; return;
    case 5: MOTOR_GO_RIGHT; return;
    case 6: MOTOR_GO_RIGHT; return;
    case 7: MOTOR_GO_LEFT; return;
    case 8: MOTOR_GO_LEFT; return;
    default: return;
  }
}
/*
  通過校準值校準小車方向
*/
void left(int adjust)
{
  switch (adjust)
  {
    case 1: MOTOR_GO_LEFT; return;
    case 2: MOTOR_GO_RIGHT; return;
    case 3: MOTOR_GO_LEFT; return;
    case 4: MOTOR_GO_RIGHT; return;
    case 5: MOTOR_GO_FORWARD; return;
    case 6: MOTOR_GO_BACK; return;
    case 7: MOTOR_GO_FORWARD; return;
    case 8: MOTOR_GO_BACK; return;
    default: return;
  }
}
/*
  通過校準值校準小車方向
*/
void right(int adjust)
{
  switch (adjust)
  {
    case 1: MOTOR_GO_RIGHT; return;
    case 2: MOTOR_GO_LEFT; return;
    case 3: MOTOR_GO_RIGHT; return;
    case 4: MOTOR_GO_LEFT; return;
    case 5: MOTOR_GO_BACK; return;
    case 6: MOTOR_GO_FORWARD; return;
    case 7: MOTOR_GO_BACK; return;
    case 8: MOTOR_GO_FORWARD; return;
    default: return;
  }
}

/**
   巡線模式
*/
void TrackLine() {
  IR_L = digitalRead(Input_Detect_LEFT); //讀取左邊傳感器數值
  IR_R = digitalRead(Input_Detect_RIGHT);//右邊紅外傳感器數值,巡線為LOW
  if ((IR_L == LOW) && (IR_R == LOW)) //兩邊同時探測到路線
  {
    forward(adjust); //前進
    return;
  }
  if ((IR_L == LOW) && (IR_R == HIGH)) {
    left(adjust); //左轉
    return;
  }
  if ((IR_L == HIGH) && (IR_R == LOW)) {
    right(adjust); //右轉
    return;
  }
  if ((IR_L == HIGH) && (IR_R == HIGH)) {
    MOTOR_GO_STOP; //停止
    return;

  }

}

/**
   紅外線避障
*/
void Avoiding() {
  //IR是中間紅外狀態標誌、Input_Detect定義紅外接口
  IR = digitalRead(Input_Detect);//如果有障礙物,就返回LOW,否則HIGH(1)
  if ((IR == LOW)) {
    MOTOR_GO_STOP;
  }
}
/**
   得到距離
   Trig是超聲波發射位
   Echo是超聲波接收位
*/
char Get_Distance() {
  digitalWrite(Trig, LOW); //超聲波發射低電壓 2us
  delayMicroseconds(2);
  digitalWrite(Trig, HIGH); //超聲波發射高電壓10us 註意至少10us
  delayMicroseconds(10);
  digitalWrite(Trig, LOW); //維持超聲波發射低電壓
  float Ldistance = pulseIn(Echo, HIGH, 5000); //讀取相差時間,超聲波發射到接收的時間
  Ldistance = Ldistance / 58; //時間轉換為cm
  return Ldistance;
}
/**
   Send_Distance
   向上位機發送超聲波數據,超聲波距離PC端顯示
   數據格式:0xFF,0x03,角度(默認0x00),距離(dis),0xFF
*/
void Send_Distance() {
  int dis = Get_Distance();
  Sendbyte(0xff);
  Sendbyte(0x03);
  Sendbyte(0x00);
  Sendbyte(dis);
  Sendbyte(0xff);
  delay(1000);
}
/**
   超聲波避障,當超聲波檢測距離小於distance厘米時,停止。
*/
void AvoidByRadar(int distance) {
  int leng = Get_Distance();
  if (distance < 10) distance = 10; //限定,最小避障距離10cm
  if ((leng > 1 ) && (leng < distance)) {
    while ((Get_Distance() > 1) && (Get_Distance() < distance)) {
      back(adjust);
    }
    MOTOR_GO_STOP;
  }
}



/**
   模式功能切換函數
*/
void Cruising_Mod() {
  if (Pre_Cruising_Flag != Cruising_Flag) {
    if (Pre_Cruising_Flag != 0) {
      MOTOR_GO_STOP;
    }
    Pre_Cruising_Flag = Cruising_Flag;
  }
  switch (Cruising_Flag) {
    case 2: TrackLine(); return; //2是巡線模式
    case 3: Avoiding(); return;//紅外線避障模式
    case 4: AvoidByRadar(15); return; //超聲波避障模式
    case 5: Send_Distance(); return; //超聲波距離 PC端顯示
    default: return;
  }
}

void setup() {
  // put your setup code here, to run once:
  pinMode(ledpin, OUTPUT);
  pinMode(INPUT1, OUTPUT);
  pinMode(INPUT2, OUTPUT);
  pinMode(INPUT3, OUTPUT);
  pinMode(INPUT4, OUTPUT);
  pinMode(Trig, OUTPUT);
  pinMode(Echo, INPUT);
  Delayed();
  servo7.attach(9);         //定義舵機7控制口,上下控制
  servo8.attach(10);        //定義舵機8控制口,左右控制
  USART_init(); //串口初始化、開啟中斷等
  Init_Steer(); //舵機角度、電機速度的初始化
}

void loop() {
  // put your main code here, to run repeatedly:
  while (1) {
    UartTimeoutCheck();
    Cruising_Mod();
  }
}

關於控制Arduino小車這個項目,我會給出具體的實現方案以及全部源程序。以上。

【嵌入式】Arduino編程基礎到應用全解析