极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 14188|回复: 4

新手制作丑陋避障小车一枚

[复制链接]
发表于 2014-7-24 21:00:49 | 显示全部楼层 |阅读模式
  初学arduino,做了一台避障小车。其上安装了20格的码盘用于直行,安装了超声和红外探头用于避障。
整车就这模样
带码盘的齿轮箱
丑陋的排线
手工焊的红外对管模块
我是胶带党
码盘检测小车两轮的速度,然后用PI算法(没必要用D)控制小车走直线。
代码如下:
  1. const int TrigPin = 8;
  2. const int EchoPin = 7;//设置超声波端口
  3. const int Kleft = 3;
  4. const int Kright = 2;//设置码盘端口
  5. const int mlf=10;
  6. const int mlb=11;
  7. const int mrf=5;
  8. const int mrb=6;//设置电机接口
  9. const int IFleft=19;
  10. const int IFright=18;
  11. int count_left;
  12. int count_right;//定义码盘计数器
  13. long old_time;
  14. long time;//定义计时器
  15. int PID=0;
  16. int I=0;//PID控制用变量
  17. float cm; //超声测距结果
  18. void setup()
  19. {
  20.   pinMode(TrigPin, OUTPUT);
  21.   pinMode(EchoPin, INPUT);//设置超声波
  22.   pinMode(mlf,OUTPUT);
  23.   pinMode(mlb,OUTPUT);
  24.   pinMode(mrf,OUTPUT);
  25.   pinMode(mrb,OUTPUT);//设定电机
  26.   pinMode(Kleft,INPUT);
  27.   pinMode(Kright,INPUT);//码盘
  28.   attachInterrupt(0, Code_right, FALLING);
  29.   attachInterrupt(1, Code_left, FALLING);//中断设置
  30. }
  31. void advance(){
  32.   analogWrite(mlf,120+PID);
  33.   digitalWrite(mlb,LOW);
  34.   analogWrite(mrf,120);
  35.   digitalWrite(mrb,LOW);
  36. }//定义前进函数
  37. void back(){
  38.   analogWrite(mlb,120+PID);
  39.   digitalWrite(mlf,LOW);
  40.   analogWrite(mrb,120);
  41.   digitalWrite(mrf,LOW);
  42. }//定义后退函数
  43. void left(){
  44.   digitalWrite(mlf,LOW);
  45.   analogWrite(mlb,120);
  46.   analogWrite(mrf,120);
  47.   digitalWrite(mrb,LOW);
  48. }//定义左转函数
  49. void right(){
  50.   analogWrite(mlf,120);
  51.   digitalWrite(mlb,LOW);
  52.   digitalWrite(mrf,LOW);
  53.   analogWrite(mrb,120);
  54. }//定义右转函数
  55. void Stop(){
  56.   digitalWrite(mlf,LOW);
  57.   digitalWrite(mlb,LOW);
  58.   digitalWrite(mrf,LOW);
  59.   digitalWrite(mrb,LOW);
  60. }//定义停止函数
  61. void loop()
  62. {
  63.   old_time=millis();
  64.   while(millis()-old_time<500){
  65.   advance();
  66.   }//前进并计数
  67.   detachInterrupt(0); // 关闭外部中断0
  68.   detachInterrupt(1); // 关闭外部中断1
  69.   I+=count_right-count_left;
  70.   PID=(count_right-count_left)*4+I;//PI算法
  71.   if(count_right<10||count_right<10){
  72.     old_time=millis();
  73.    while(millis()-old_time<700){
  74.      back();
  75.    }
  76.    while(millis()-old_time<1100){
  77.      Stop();
  78.    }
  79.    while(millis()-old_time<1600){
  80.      left();
  81.    }
  82.   }//防卡死算法
  83.   count_left=0;
  84.   count_right=0;//码盘计数归零
  85.   //超声测距算法(需改进)
  86.   digitalWrite(TrigPin, LOW); //低高低电平发一个短时间脉冲去TrigPin
  87.   delayMicroseconds(2);
  88.   digitalWrite(TrigPin, HIGH);
  89.   delayMicroseconds(10);
  90.   digitalWrite(TrigPin, LOW);
  91.   cm = pulseIn(EchoPin, HIGH) / 58.0; //将回波时间换算成cm
  92.   cm = (int(cm * 100.0)) / 100.0; //保留两位小数
  93.   if(cm<30){
  94.    old_time=millis();
  95.    while(millis()-old_time<500){
  96.      right();
  97.    }
  98.   }//超声避障算法
  99.   if(analogRead(IFleft)<700){
  100.     old_time=millis();
  101.    while(millis()-old_time<500){
  102.      right();
  103.    }
  104.   }
  105.   if(analogRead(IFright)<700){
  106.    old_time=millis();
  107.    while(millis()-old_time<500){
  108.      left();
  109.    }
  110.   }//红外避障算法
  111.   attachInterrupt(0, Code_right,FALLING); // 重新开放外部中断0
  112.   attachInterrupt(1, Code_left,FALLING); // 重新开放外部中断1
  113. }
  114. //右侧电机码盘计数中断函数
  115. void Code_right()
  116. {  
  117.   count_right += 1; //右侧编码器码盘计数加一
  118. }
  119. //左侧电机码盘计数中断函数
  120. void Code_left()
  121. {
  122.   count_left += 1; // 编码器码盘计数加一   
  123. }
复制代码

这个算法问题还是很大的,一是红外避障部分没有排除环境红外光;二是使用了原始的超声测距算法;三是程序运行周期太长,反应迟钝。我想知道论坛里还有比我这更烂的小车么。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

 楼主| 发表于 2014-7-24 21:02:48 | 显示全部楼层
本帖最后由 迷你强 于 2014-7-27 14:36 编辑

注释怎么挂了
  1. const int TrigPin = 8;
  2. const int EchoPin = 7;//设置超声波端口
  3. const int Kleft = 3;
  4. const int Kright = 2;//设置码盘端口
  5. const int mlf=10;
  6. const int mlb=11;
  7. const int mrf=5;
  8. const int mrb=6;//设置电机接口
  9. const int IFleft=19;
  10. const int IFright=18;
  11. int count_left;
  12. int count_right;//定义码盘计数器
  13. long old_time;
  14. long time;//定义计时器
  15. int PID=0;
  16. int I=0;//PID控制用变量
  17. float cm; //超声测距结果
  18. void setup()
  19. {
  20.   pinMode(TrigPin, OUTPUT);
  21.   pinMode(EchoPin, INPUT);//设置超声波
  22.   pinMode(mlf,OUTPUT);
  23.   pinMode(mlb,OUTPUT);
  24.   pinMode(mrf,OUTPUT);
  25.   pinMode(mrb,OUTPUT);//设定电机
  26.   pinMode(Kleft,INPUT);
  27.   pinMode(Kright,INPUT);//码盘
  28.   attachInterrupt(0, Code_right, FALLING);
  29.   attachInterrupt(1, Code_left, FALLING);//中断设置
  30. }
  31. void advance(){
  32.   analogWrite(mlf,120+PID);
  33.   digitalWrite(mlb,LOW);
  34.   analogWrite(mrf,120);
  35.   digitalWrite(mrb,LOW);
  36. }//定义前进函数
  37. void back(){
  38.   analogWrite(mlb,120+PID);
  39.   digitalWrite(mlf,LOW);
  40.   analogWrite(mrb,120);
  41.   digitalWrite(mrf,LOW);
  42. }//定义后退函数
  43. void left(){
  44.   digitalWrite(mlf,LOW);
  45.   analogWrite(mlb,120);
  46.   analogWrite(mrf,120);
  47.   digitalWrite(mrb,LOW);
  48. }//定义左转函数
  49. void right(){
  50.   analogWrite(mlf,120);
  51.   digitalWrite(mlb,LOW);
  52.   digitalWrite(mrf,LOW);
  53.   analogWrite(mrb,120);
  54. }//定义右转函数
  55. void Stop(){
  56.   digitalWrite(mlf,LOW);
  57.   digitalWrite(mlb,LOW);
  58.   digitalWrite(mrf,LOW);
  59.   digitalWrite(mrb,LOW);
  60. }//定义停止函数
  61. void loop()
  62. {
  63.   old_time=millis();
  64.   while(millis()-old_time<500){
  65.   advance();
  66.   }//前进并计数
  67.   detachInterrupt(0); // 关闭外部中断0
  68.   detachInterrupt(1); // 关闭外部中断1
  69.   I+=count_right-count_left;
  70.   PID=(count_right-count_left)*4+I;//PI算法
  71.   if(count_right<10||count_right<10){
  72.     old_time=millis();
  73.    while(millis()-old_time<700){
  74.      back();
  75.    }
  76.    while(millis()-old_time<1100){
  77.      Stop();
  78.    }
  79.    while(millis()-old_time<1600){
  80.      left();
  81.    }
  82.   }//防卡死算法
  83.   count_left=0;
  84.   count_right=0;//码盘计数归零
  85.   //超声测距算法(需改进)
  86.   digitalWrite(TrigPin, LOW); //低高低电平发一个短时间脉冲去TrigPin
  87.   delayMicroseconds(2);
  88.   digitalWrite(TrigPin, HIGH);
  89.   delayMicroseconds(10);
  90.   digitalWrite(TrigPin, LOW);
  91.   cm = pulseIn(EchoPin, HIGH) / 58.0; //将回波时间换算成cm
  92.   cm = (int(cm * 100.0)) / 100.0; //保留两位小数
  93.   if(cm<30){
  94.    old_time=millis();
  95.    while(millis()-old_time<500){
  96.      right();
  97.    }
  98.   }//超声避障算法
  99.   if(analogRead(IFleft)<700){
  100.     old_time=millis();
  101.    while(millis()-old_time<500){
  102.      right();
  103.    }
  104.   }
  105.   if(analogRead(IFright)<700){
  106.    old_time=millis();
  107.    while(millis()-old_time<500){
  108.      left();
  109.    }
  110.   }//红外避障算法
  111.   attachInterrupt(0, Code_right,FALLING); // 重新开放外部中断0
  112.   attachInterrupt(1, Code_left,FALLING); // 重新开放外部中断1
  113. }
  114. //右侧电机码盘计数中断函数
  115. void Code_right()
  116. {  
  117.   count_right += 1; //右侧编码器码盘计数加一
  118. }
  119. //左侧电机码盘计数中断函数
  120. void Code_left()
  121. {
  122.   count_left += 1; // 编码器码盘计数加一   
  123. }
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-7-25 08:46:45 | 显示全部楼层
附上视频
回复 支持 反对

使用道具 举报

发表于 2014-7-26 23:35:39 | 显示全部楼层
真好,真好需要收藏备用!
回复 支持 反对

使用道具 举报

发表于 2014-7-27 15:38:36 | 显示全部楼层
朋友有硬件连接图吗?还有你是使用L298驱动还是直接驱动的?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-18 13:14 , Processed in 0.050624 second(s), 22 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表