Advertisement
lazyfai

小車程式

Jun 18th, 2017
245
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.33 KB | None | 0 0
  1. /*
  2.  
  3.   http://shop34791330.taobao.com/ //德飞莱旗舰店
  4.   http://qixingchong.tmall.com/   //七星虫旗舰店
  5.   http://www.doflye.net //德飞莱技术论坛
  6.   http://www.doflye.net/forum-98-1.html //德飞莱论坛arduino版块
  7.   http://www.langyidianzi.com //朗译科技
  8.   http://qixingchong.top  //七星虫商城
  9.  
  10. */
  11. #include <Servo.h>
  12. #define S_LIMIT_1 30 //距离判断参数预设值
  13. #define S_LIMIT_3 15 //距离判断参数预设值
  14. #define S_LIMIT_2 100
  15. long timer, runtime;
  16. const long TIME_OUT = 5000;
  17. Servo myservo;
  18. int ServoPin = 10;
  19. int pos = 0;    // 用于存储舵机位置的变量
  20.  
  21. #define MOTORADJUSTMENT
  22. int MotorAdjustmengPin = A1;
  23. //定义引脚
  24. const int trig = 4;    // 触发信号
  25. const int echo = 7;    // 反馈信号
  26.  
  27. const int DIR1_RIGHT = 12;  //2路直流电机方向控制引脚
  28. const int DIR2_RIGHT = 11;
  29. const int DIR1_LEFT = 8;
  30. const int DIR2_LEFT = 9;
  31.  
  32. const int PWM_LEFT = 6;  //2路电机调速引脚
  33. const int PWM_RIGHT = 5;
  34.  
  35. int Bit_Front, Bit_Left, Bit_Right;
  36.  
  37. //初始化端口
  38. void setup()
  39. {
  40.   pinMode(echo, INPUT);
  41.   pinMode(trig, OUTPUT);
  42.   //触发端口设置为输出,反馈端口设置为输入
  43.   //初始化led引脚为输出
  44.   pinMode(DIR1_RIGHT, OUTPUT);
  45.   pinMode(DIR2_RIGHT, OUTPUT);
  46.   pinMode(DIR1_LEFT, OUTPUT);
  47.   pinMode(DIR2_LEFT, OUTPUT);
  48.  
  49.   pinMode(PWM_LEFT, OUTPUT);
  50.   pinMode(PWM_RIGHT, OUTPUT);
  51.  
  52.   myservo.attach(ServoPin);  // 舵机控制信号引脚
  53.   Serial.begin(9600); //调试使用,可以去掉
  54.  
  55. }
  56. //电机控制子程序
  57. void motorsWrite(int speedLeft, int speedRight)
  58. {
  59.   float motorAdjustment = MotorAdjustment();
  60.   if (motorAdjustment < 0) {
  61.     speedRight *= (1 + motorAdjustment);
  62.   }
  63.   else {
  64.     speedLeft *= (1 - motorAdjustment);
  65.   }
  66.   if (speedRight > 0) //如果PWM数值小于0,表示运行方向变化
  67.   {
  68.     digitalWrite(DIR1_RIGHT, 0);
  69.     digitalWrite(DIR2_RIGHT, 1);
  70.   }
  71.   else
  72.   {
  73.     digitalWrite(DIR1_RIGHT, 1);
  74.     digitalWrite(DIR2_RIGHT, 0);
  75.   }
  76.   analogWrite(PWM_RIGHT, abs(speedRight));
  77.  
  78.   if (speedLeft > 0)
  79.   {
  80.     digitalWrite(DIR1_LEFT, 0);
  81.     digitalWrite(DIR2_LEFT, 1);
  82.   }
  83.   else
  84.   {
  85.     digitalWrite(DIR1_LEFT, 1);
  86.     digitalWrite(DIR2_LEFT, 0);
  87.   }
  88.   analogWrite(PWM_LEFT, abs(speedLeft));
  89. }
  90.  
  91. int ranging()
  92. {
  93.   long IntervalTime = 0; //定义一个时间变量
  94.   digitalWrite(trig, 1);//置高电平
  95.   delayMicroseconds(15);//延时15us
  96.   digitalWrite(trig, 0);//设为低电平
  97.   IntervalTime = pulseIn(echo, HIGH); //用自带的函数采样反馈的高电平的宽度,单位us
  98.   int S = IntervalTime / 58; //
  99.   return S;
  100. }
  101. //主循环
  102. void loop()
  103. {
  104.   int S, SL, SR;
  105.   int TimerFlag = 0;
  106.   myservo.write(90);//正前方位置
  107.   while (1)
  108.   {
  109.     if ((millis() - timer >= TIME_OUT)) //定时到更新标志位
  110.     {
  111.       TimerFlag = 1;
  112.     }
  113.     myservo.write(90);//正前方位置
  114.     delay(300);
  115.     S =  ranging();
  116.     Serial.println(S);//打印数据
  117.     if (S <= S_LIMIT_3)
  118.       back(400);
  119.     if (S <= S_LIMIT_1 || TimerFlag == 1) //测量距离小于预设距离或者定时到时
  120.     {
  121.       timer = millis(); //标志位清零,并准备重新计时
  122.       TimerFlag = 0; //清零标志位
  123.       stopMotor();   //停止小车
  124.       myservo.write(45); //超声波探头右转
  125.       delay(300);        //延时稳定后测量
  126.       int SR = ranging();//获取右边的障碍距离
  127.       myservo.write(145); //超声波探头左转
  128.       delay(300);      //延时
  129.       int SL = ranging();//获取左边的障碍距离
  130.       myservo.write(90); //探头返回中间位置
  131.       delay(300);      //延时
  132.       int SM  = ranging();//获取距离
  133.       if (SL > S_LIMIT_1 && SR > S_LIMIT_1 && SM < S_LIMIT_1) //前方障碍,左右无障碍,右转
  134.         turnRight(100);
  135.       else if (SL <= S_LIMIT_1 && SR > S_LIMIT_1) //左障碍,右转
  136.         turnRight(100);
  137.       else if (SL > S_LIMIT_1 && SR <= S_LIMIT_1) //右障碍,左转
  138.         turnLeft(100);
  139.       else if (SL <= S_LIMIT_1 && SR <= S_LIMIT_1) //左右都有障碍,转弯后退
  140.         back(300);
  141.     }
  142.     else
  143.       run(60); //前方无障碍,前行
  144.   }
  145. }
  146. //直行,输入0-100数字,表示百分比
  147. void run(int pct)
  148. {
  149.   motorsWritePct(pct, pct);
  150. }
  151. //右转,并带有时间参数,调整时间可以调节转弯角度
  152. void turnRight(int runtime)
  153. {
  154.   motorsWritePct(100, -50);
  155.   delay(runtime);
  156. }
  157. //左转,并带有时间参数,调整时间可以调节转弯角度
  158. void turnLeft(int runtime)
  159. {
  160.   motorsWritePct(-50, 100);
  161.   delay(runtime);
  162. }
  163. //后退,并带有时间参数,调整时间可以调节转弯角度,带转弯后退。
  164. void back(int runtime)
  165. {
  166.   motorsWritePct(-80, -50);
  167.   delay(runtime);
  168. }
  169. //停车
  170. void stopMotor()
  171. {
  172.   motorsWrite(0, 0);
  173. }
  174. //小车百分比输入
  175. void motorsWritePct(int speedLeftPct, int speedRightPct)
  176. {
  177.   int16_t speedLeft = 255 * speedLeftPct / 100.0;
  178.   int16_t speedRight = 255 * speedRightPct / 100.0;
  179.   motorsWrite(speedLeft, speedRight);
  180. }
  181.  
  182. //轮子校正程序,当2个电机在同等条件下转速不同时需要校正,使小车可以走直线,如果没有预定义校正功能,返回0,表示没有校正
  183. float  MotorAdjustment()
  184. {
  185. #ifdef MOTORADJUSTMENT
  186.   float motorAdjustment = map(analogRead(MotorAdjustmengPin), 0, 1023, -30, 30) / 100.0;
  187.   return motorAdjustment;
  188. #else
  189.   return 0;
  190. #endif
  191. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement