• 【嵌入式】Arduino编程基础到应用全解析


    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小车这个项目,我会给出具体的实现方案以及全部源程序。以上。

  • 相关阅读:
    只能输入数字
    js 添加、获取、删除 cookie
    获取一个对象的属性/属性值,以及动态给属性赋值
    自定义注解
    C#快捷方式
    前端乱码
    句法错误#{}, 也会导致的异常 org.apache.ibatis.builder.BuilderException java.lang.StringIndexOutOfBoundsException
    [mybatis重复mapper] Error parsing SQL Mapper Configuration
    [aop报错] Cannot resolve reference to bean 'txPointCut' while setting bean property 'pointcut'
    Java工具安装配置(JDK、MySql、Tomcat、Maven、Idea)
  • 原文地址:https://www.cnblogs.com/duye/p/8641072.html
Copyright © 2020-2023  润新知