KRITSADA icon

WiFi Robot

KRITSADA | PRO | 02/25/21 12:06:40 AM UTC | 0 ⭐ | 866 👁️ | Never ⏰ | []
Arduino |

16.52 KB

|

None

|

0 👍

/

0 👎

/*
* Copyright (c) 2015,小二极客科技有限公司
* All rights reserved.
* 
* 文件名称:wifi-robots
* 文件标识:
* 摘    要:wifi机器人智能小车控制
* 
* 当前版本:1.0
* 作    者:小R团队
* 完成日期:2015年4月1日
*/
#include <Servo.h>
//#include <MsTimer2.h>
#include <EEPROM.h> 
 
int ledpin = 13;//设置系统启动指示灯
int ENA = 5;//L298使能A
int ENB = 6;//L298使能B
int INPUT2 = 7;//电机接口1
int INPUT1 = 8;//电机接口2
int INPUT3 = 12;//电机接口3
int INPUT4 = 13;//电机接口4
int num;//定义电机标志位
 
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 ;
int Left_Speed_Hold = 200;//定义左侧速度变量
int Right_Speed_Hold = 200;//定义右侧速度变量
 
 
#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);}    //车体前进
 
 
void forward(int num)
{
    switch(num)
    {
        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 num)
{
        switch(num)
    {
        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 num)
{
        switch(num)
    {
        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 num)
{
        switch(num)
    {
        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;
    }
}
 
 
int Left_Speed[11]={90,106,122,138,154,170,186,203,218,234,255};//左侧速度档位值
int Right_Speed[11]={90,106,122,138,154,170,186,203,218,234,255};//右侧速度档位值
 
//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=60;//舵机#1初始值
//byte angle2=60;//舵机#2初始值
byte angle3=60;//舵机#3初始值
byte angle4=60;//舵机#4初始值
byte angle5=60;//舵机#5初始值
byte angle6=120;//舵机#6初始值
byte angle7=60;//舵机#7初始值
byte angle8=60;//舵机#8初始值
 
 
int buffer[3];  //串口接收数据缓存
int rec_flag;   //串口接收标志位
int serial_data;
int Uartcount;
int IR_R;
int IR_L;
int IR;
unsigned long Pretime;
unsigned long Nowtime;
unsigned long Costtime;
float Ldistance;
 
void Open_Light()//开大灯
    {      
      digitalWrite(Carled,HIGH);   //拉低电平,正极接电源,负极接Io口
      delay(1000);             
    }
void Close_Light()//关大灯
    {  
      digitalWrite(Carled, LOW);   //拉低电平,正极接电源,负极接Io口
      delay(1000);             
    }
    
void  Avoiding()//红外避障函数
    {  
      IR = digitalRead(Input_Detect);
       if((IR == HIGH))
       {
          forward(num);;//直行 
          return;            
       }
       if((IR == LOW))
       {
            MOTOR_GO_STOP;//停止
            return;
       }
    }
           
   
 
void FollowLine()   // 巡线模式
    {  
      IR_L = digitalRead(Input_Detect_LEFT);//读取左边传感器数值
      IR_R = digitalRead(Input_Detect_RIGHT);//读取右边传感器数值
      
      if((IR_L == LOW) && (IR_R == LOW))//两边同时探测到障碍物
      {
        forward(num);//直行 
        return;          
        
      }
      if((IR_L == LOW) && (IR_R == HIGH))//右侧遇到障碍  
      {
        left(num);//左转 
        return;
        
      }
      if((IR_L == HIGH) &&( IR_R == LOW))//左侧遇到障碍 
      {
        right(num);//右转 
        return;
        
      }
      if((IR_L == HIGH) && (IR_R == HIGH))//左右都检测到,就如视频中的那样遇到一道横的胶带
      {
        MOTOR_GO_STOP;//停止
        return;
       }
    }     
 
char Get_Distence()//测出距离
 {  
      digitalWrite(Trig, LOW);   // 让超声波发射低电压2μs  
      delayMicroseconds(2);  
      digitalWrite(Trig, HIGH);  // 让超声波发射高电压10μs,这里至少是10μs  
      delayMicroseconds(10);  
      digitalWrite(Trig, LOW);    // 维持超声波发射低电压  
      Ldistance = pulseIn(Echo, HIGH);  // 读差相差时间  
      Ldistance= Ldistance/5.8/10;      // 将时间转为距离距离(单位:公分)    
    //  Serial.println(Ldistance);      //显示距离  
      return Ldistance;
      
  }    
  
void Avoid_wave()//超声波避障函数
{
  Get_Distence();
  if(Ldistance < 15)
      {
          MOTOR_GO_STOP;
      }
      else
      {
           forward(num);
      }
}
 
void Avoid_wave_auto()
{
  Get_Distence();
  if(Ldistance < 15)
  {
    back(num);;
    delay(300);
    MOTOR_GO_STOP;
  }
}
 
void Send_Distance()//超声波距离PC端显示
{
  int dis= Get_Distence();
  Serial.write(0xff);
  Serial.write(0x03);
  Serial.write(0x00);
  Serial.write(dis);
  Serial.write(0xff);
  delay(1000);
}
/*
*********************************************************************************************************
** 函数名称 :Delayed()
** 函数功能 :延时程序
** 入口参数 :无
** 出口参数 :无
*********************************************************************************************************
*/
void  Delayed()    //延迟40秒等WIFI模块启动完毕
{
    int i;
    for(i=0;i<20;i++)
    {
        digitalWrite(ledpin,LOW);
        delay(1000);
        digitalWrite(ledpin,HIGH);
        delay(1000);
    }
}
 
/*
*********************************************************************************************************
** 函数名称 :setup().Init_Steer()
** 函数功能 :系统初始化(串口、电机、舵机、指示灯初始化)。
** 入口参数 :无
** 出口参数 :无
*********************************************************************************************************
*/
void Init_Steer()//舵机初始化(角度为上次保存数值)
{
   // angle1 = EEPROM.read(0x01);//读取寄存器0x01里面的值
   // angle2 = EEPROM.read(0x02);//读取寄存器0x02里面的值
    angle3 = EEPROM.read(0x03);//读取寄存器0x03里面的值
    angle4 = EEPROM.read(0x04);//读取寄存器0x04里面的值
    angle5 = EEPROM.read(0x05);//读取寄存器0x05里面的值
    angle6 = EEPROM.read(0x06);//读取寄存器0x06里面的值
    angle7 = EEPROM.read(0x07);//读取寄存器0x07里面的值
    angle8 = EEPROM.read(0x08);//读取寄存器0x08里面的值
    
    if(angle7 == 255 && angle8 == 255)
    {
       // EEPROM.write(0x01,60);//把初始角度存入地址0x01里面
       // EEPROM.write(0x02,60);//把初始角度存入地址0x02里面
        EEPROM.write(0x03,60);//把初始角度存入地址0x03里面
        EEPROM.write(0x04,60);//把初始角度存入地址0x04里面
        EEPROM.write(0x05,60);//把初始角度存入地址0x05里面
        EEPROM.write(0x06,120);//把初始角度存入地址0x06里面
        EEPROM.write(0x07,60);//把初始角度存入地址0x07里面
        EEPROM.write(0x08,60);//把初始角度存入地址0x08里面
        return;
    }
 
   // servo1.write(angle1);//把保存角度赋值给舵机1
   // servo2.write(angle2);//把保存角度赋值给舵机2
    servo3.write(angle3);//把保存角度赋值给舵机3
    servo4.write(angle4);//把保存角度赋值给舵机4
    servo5.write(angle5);//把保存角度赋值给舵机5
    servo6.write(angle6);//把保存角度赋值给舵机6
    servo7.write(angle7);//把保存角度赋值给舵机7
    servo8.write(angle8);//把保存角度赋值给舵机8
    num = EEPROM.read(0x10);//读取寄存器0x10里面的值
    if(num==0xff)EEPROM.write(0x10,1);
}
 
void setup()
{
    pinMode(ledpin,OUTPUT); 
    pinMode(ENA,OUTPUT); 
    pinMode(ENB,OUTPUT); 
    pinMode(INPUT1,OUTPUT); 
    pinMode(INPUT2,OUTPUT); 
    pinMode(INPUT3,OUTPUT); 
    pinMode(INPUT4,OUTPUT); 
    pinMode(Input_Detect_LEFT,INPUT);
    pinMode(Input_Detect_RIGHT,INPUT);
    pinMode(Carled, OUTPUT);
    pinMode(Input_Detect,INPUT);
    pinMode(Echo,INPUT);
    pinMode(Trig,OUTPUT);
 
    Delayed();//延迟40秒等WIFI模块启动完毕
    analogWrite(ENB,Left_Speed_Hold);//给L298使能端B赋值
    analogWrite(ENA,Right_Speed_Hold);//给L298使能端A赋值
    digitalWrite(ledpin,LOW);
    //servo1.attach(SDA);//定义舵机1控制口
    //servo2.attach(SCL);//定义舵机2控制口
    servo3.attach(3);//定义舵机3控制口
    servo4.attach(4);//定义舵机4控制口
    servo5.attach(2);//定义舵机5控制口
    servo6.attach(11);//定义舵机6控制口
    servo7.attach(9);//定义舵机7控制口
    servo8.attach(10);//定义舵机8控制口
    Serial.begin(9600);//串口波特率设置为9600 bps
    Init_Steer();
}
/*
*********************************************************************************************************
** 函数名称 :loop()
** 函数功能 :主函数
** 入口参数 :无
** 出口参数 :无
*********************************************************************************************************
*/
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:FollowLine(); return;//巡线模式
       case 3:Avoiding(); return;//避障模式
       case 4:Avoid_wave();return;//超声波避障模式
           case 5:Send_Distance();//超声波距离PC端显示
       default:return;
      }
             
}
 
void loop()
  {  
    while(1)
    {
        Get_uartdata();
        UartTimeoutCheck();
        Cruising_Mod();
     }  
  }
 
 
 
/*
*********************************************************************************************************
** 函数名称 :Communication_Decode()
** 函数功能 :串口命令解码
** 入口参数 :无
** 出口参数 :无
*********************************************************************************************************
*/
void Communication_Decode()
{   
    if(buffer[0]==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)//舵机命令
    {
        if(buffer[2]<1)return;
        switch(buffer[1])
        {
           // case 0x01:angle1 = buffer[2];servo1.write(angle1);return;
           // case 0x02:angle2 = buffer[2];servo2.write(angle2);return;
            case 0x01:if(buffer[2]>170)return;angle3 = buffer[2];servo3.write(angle3);return;
            case 0x02:if(buffer[2]>170)return;angle4 = buffer[2];servo4.write(angle4);return;
            case 0x03:if(buffer[2]>170)return;angle5 = buffer[2];servo5.write(angle5);return;
            case 0x04:if((buffer[2]<105)||(buffer[2]>178))return;angle6 = buffer[2];servo6.write(angle6);return;
            case 0x07:if(buffer[2]>170)return;angle7 = buffer[2];servo7.write(angle7);return;
            case 0x08:if(buffer[2]>170)return;angle8 = buffer[2];servo8.write(angle8);return;
            default:return;
        }
    }
    
   else if(buffer[0]==0x02)//调速
    {
                int i,j;
        if(buffer[2]>10)return;
             
        if(buffer[1]==0x01)//左侧调档
        {
                        i=buffer[2];
            Left_Speed_Hold=Left_Speed[i] ;
                        analogWrite(ENB,Left_Speed_Hold);
        }
                if(buffer[1]==0x02)//右侧调档
                {
                        j=buffer[2];
                        Right_Speed_Hold=Right_Speed[j] ;
                        analogWrite(ENA,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(0x05,angle5);
        EEPROM.write(0x06,angle6);
        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]==0x05)
    {
        switch(buffer[1])   //
        {
            case 0x00:Open_Light(); return;
        case 0x02:Close_Light(); return;
            default: return;
        }   
    }
        else if(buffer[0]==0x40)//存储电机标志
    {
       num=buffer[1];
       EEPROM.write(0x10,num);
    }
}
/*
*********************************************************************************************************
** 函数名称 :Get_uartdata()
** 函数功能 :读取串口命令
** 入口参数 :无
** 出口参数 :无
*********************************************************************************************************
*/
void Get_uartdata(void)
{
    static int i;
   
    if (Serial.available() > 0) //判断串口缓冲器是否有数据装入
    {
        serial_data = Serial.read();//读取串口
        if(rec_flag==0)
        {
            if(serial_data==0xff)
            {
                rec_flag = 1;
                i = 0;
               Costtime = 0; 
            }
        }
        else
        {
            if(serial_data==0xff)
            {
                rec_flag = 0;
                if(i==3)
                {
                    Communication_Decode();
                }
                i = 0;
            }
            else
            {
                buffer[i]=serial_data;
                i++;
            }
        }
    }
}
/*
*********************************************************************************************************
** 函数名称 :UartTimeoutCheck()
** 函数功能 :串口超时检测
** 入口参数 :无
** 出口参数 :无
*********************************************************************************************************
*/
void UartTimeoutCheck(void)
{
    if(rec_flag == 1)
    {
       Costtime++;  
      if(Costtime == 100000)
      {
           rec_flag = 0;
      }
    }
}

Comments