极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 11357|回复: 4

我的多能智能小车

[复制链接]
发表于 2015-5-31 17:22:12 | 显示全部楼层 |阅读模式
本帖最后由 萧芸凤 于 2015-6-5 17:38 编辑

5月份开始做四驱小车,一开始就选定了是四轮驱动,Arduino 做主控,然后才是电机的选择,驱动的选择。
关于电机的驱动,现在用的最多的是L298和L293(特别是淘宝上这类模块扩展板很多)。使用过298的模块,不是很好用,5V的电机基本上需要7.2V的电压来驱动而且效率不是很高。查阅了资料才发现298的压降太厉害了,上下桥加起来2A时近5V,就是1A也有3V左右的压降,这样算下来几乎一半的电能都用在芯片上了。293没有用过,不过600mA的驱动电流很多的电机被排除了。

还有一个问题就是很多的驱动板都需要3个端口来控制,两个是电机的方向选择,一个是PWM控制转速。如此一来四个电机需要12个接口,Arduino没有这么多的资源来使用。然后很偶然的一个机会,在逛淘宝时发现了一个I2C的电机驱动板,而且还是扩展板的形式,连接比较方便。最巧的是居然是四电机的驱动板,使用东芝的TB6612FNG H桥电机驱动芯片。这个是MOSFET的结构,不是L298的晶体管,整体压降很少,每路1.2A的驱动能力,3.2A的峰值电流超过了293两倍。

驱动板确定了然后就是电机的选择。做小车最通常的是黄色的香蕉电机(130电机),这个在淘宝上一抓一大把。以前也是用过,不是很好减速比还行吧,好像是1:40,具体的忘记了,有一点就是驱动电流要求大,但是驱动力矩不够。还有一点体积比较大,何其配套的车轮一比较大。电机在运行时抖动比较厉害,之前做的小车只能全速运行,PWM使用时走起来一顿一顿的。
小型化电机时看到了N20,这个非常满足要求。自带减速机构,而且还是金属的齿轮减速系统。各项参数也很不错,驱动电压3-12V,转速3-1000rpm,驱动力矩7kgcm,外形12*10*25很少小巧,噪声也比香蕉电机小了很多。
这个电机其实以前使用过,公司的一个电动钟表螺丝批用的就是这个,噪声和震动控制的都很不错。还有在淘宝上发现了它的固定支架,DFROOBT,虽然他家的东西是出了名的贵,性价比严重的不好,可是也只有他们在买啊,而且质量倒是不错的,之前买过的开发板模块什么的就数他们家的做工精良。
选择了两对支架,逛店铺的时候发现了配套车轮,42mm直径,也很小巧。同时还带有12齿编码盘,虽然暂时不需要速度带闭环控制,但是车轮有这个也算是不错吧,以后也许可以用上。
如此一来一个小车基本上可以做了,驱动、电机、车轮、主控都好了。车架选择上没有采用现有的,主要是自己做车,如果买来现成车架还是自己做吗,那仅仅是组装了。在亚克力和PCB中选择了PCB,亚克力切割现在做不到。
电机点安装,驱动什么的都是很简单。既然要与众不同,那就要增加一些别人没有的,于是想到了灯光系统。
第一是方向灯,左右转向用,然后是刹车灯,还有前大灯。直接端口控制又要使用有限灯IO了,于是用595来扩展,使用4个接口其他灯四个也可以方便以后增加功能。
方向灯需要闪烁,如果用595来控制闪烁那就需要不停的写入数据,总觉得有些奇怪。既然这样闪光控制就需要独立出来来,RC电路虽然简单但是不好控制,555的暂稳态电路简单实用。
闪光频率选在在1秒左右,测试几种组合,还有是电容的体积,闪光效率等待,使用了现在的这个组合,R1,R2为20K,C1为22uF,周期924ms,占空比67%。
LED的控制使用与门,555的输出接一端,595的输出接另一个,然后与门输出接LED。74系列着了74HC08,很典型的四与门芯片。
四个闪光用了两个控制方向灯,另两个备用,595直接使用2两个控制前后灯,如此还有两个闪光和两个常态可以备用。
控制方面预留巡线,避障。巡线最少要三个输入,避障也需要两个。然后用了165扩展了8个输入,这样巡线避障等可以同时连接,需要什么功能可以自行选择。
为了体现PWM控制的特点需要实时的控制电机的加速与减速,这个就需要知道前方的距离了。在现有的模块中也只有超声波可以得到距离数值,红外什么的只能得到一个数值量,设定的数字。
连接线路,编写程序,一切都以为结束了。等到都准备好了才发现,电机一运行就会对灯光系统,对超声波系统产生干扰。一开始以为是辐射干扰,使用外置的595模块确实会好许多,然后对比发现了ST需要接下拉电阻。之后在测试还是不行。几经反复发现不只是辐射干扰,最主要的干扰来自马达的输入线路。
然后开始考虑如果来过滤这个干扰。首先确认干扰来源,这个网上讲的很是清楚了,换相时造成的电压波动。这个是周期性的,应该属于交流信号了吧,考虑各种滤波措施了。RC、LC、RL等各种手段都需要尝试。
在不了解各类滤波技术的时候只能先凭经验了。和电机串联的只能是电感和电阻,电容串联相当于断路,毕竟驱动是用的直流电源。电阻也不在选择之列,主要是会影响马达。
如此一来只有LC滤波了,串联了L,画出电路图一开居然是LC低频率波。
不知道该选择怎样的频率,把手头现有的电感和电容进行了组合,计算一下可能的组合,然后看一下各自的频率进行测试。
   
  
  220uH
  
  100uH
  
  68uH
  
  47uH
  
  33uH
  
  22uH
  
  10uH
  
  220uF
  
   
  
  1.07
  
   
  
   
  
   
  
   
  
   
  
  100uF
  
  1.07
  
  1.59
  
  1.93
  
  2.32
  
  2.77
  
  3.39
  
  5.03
  
  68uF
  
  1.3
  
  1.93
  
  2.34
  
  2.82
  
  3.36
  
  4.11
  
  6.1
  
  47uF
  
  1.57
  
  2.32
  
  2.82
  
  3.39
  
  4.04
  
  4.95
  
  7.34
  
  33uF
  
  1.87
  
  2.77
  
  3.36
  
  4.04
  
  4.82
  
  5.91
  
  8.76
  
  22uF
  
  2.29
  
  3.39
  
  4.11
  
  4.95
  
  5.91
  
  7.23
  
  10.73
  
  10uF
  
  3.39
  
  5.03
  
  6.1
  
  7.34
  
  8.76
  
  10.73
  
  15.92
  

有不少的组合是重复的,虽然不知道相同的频率不同的电感和电容组合会有什么影响,但是现在就需要测试一下。
电机的PWM频率是1-1.6KHz的,就在这个附近开始测试。选择了220uH/47uF、100uH/100uF这两个组合。

220uH/47uF灯光还是会受到干扰,100uH/100uF干扰小了许多,有时候没有有时候又有了,但是电机速度受影响比较大,速度下降明显。

继续测试另一个组合,这次选择小于1.6KHz的,由于手头没有68uF的电容,只能先测试220uH/100uF、100uH/220uF这两个组合。
结果不是很好,干扰现不是是否接触,电机基本上是动了。分析原因可能是低通滤波将1K以上的过滤了,而PWM是用的1.6KHz的。
知道了原因就测试另一个组合,高于1.6的,先测试100uH/47uF、100uH/33uF、68uH/47uF、68uH/33uF四个组合。
100uH/47uF干扰基本解除了,但是马达速度还是受到了影响;100uH/33uF马达速度倒是还好,干扰不是滤除的很好,灯光可以不受干扰,但是超声波还是受到了干扰;68uH/47uF干扰滤除的还可以,偶尔能看到灯光到闪烁;68uH/33uF灯光不受干扰,超神波的影响也没有那么大,但是总觉得没有之前的那些好。
分析一下,68uH/33uF的频率是3.36KHz的,效果没有前面的好可能的原因是频率高了,一些低于这个频率的信号还是进入了系统。100uH/47uF的最好,100uH/33uF还是会受到影响说明了干扰频率来源在2.32KHz附近。所以其他的两个组合滤除的是高于2.8KHz附近的,一些干扰还是存在的。
本来还应该测试一下220uH/33uF、68uH/100uF的,这个是低于2K的组合,但是手头的100uF电容和33uF电容数量不足,没办法满足4个电机所需要的8个要求所以没在做测试。虽然100uH/47uF这个组合会影响一下马达速度,但是实际测试发现马达的加速和减速效果最好。之前的加速和减速是突然进行的,现在明显的有个过程,显然是在滤波的时候也同时影响到了马达对PWM的响应。这个是什么原理,为什么这样怎样来避免这个不是很清楚,好在这不是个问题,反而是个意外的惊喜。所以说这一次就只是记录了下来,以后如果遇到了在继续研究。
遥控方面,通常来说是蓝牙、APC220、24L01几个,Xbee太贵了。蓝牙比较简单,串口透传,安卓有很多的免费软件,就是距离短;APC220号称可以传输1000米,没测试过,仅仅试过几米的,超过5米的时候就经常受到错误的数据,而且控制端要不是电脑要不是另一个控制板;24L01的速度是最快的,现在的库也能保证数据接收,但是要占用4个端口,距离也不咋地,同样需要电脑或另一个控制器。
闲逛的时候看到了DTMF模块(双频多音),电话拨号时用的数据传输方法,看了一下也挺简单的。芯片MT8870,四个输出Q1~Q4组合成16个数据,STD用来判断是否有数据到达,其他的端口可以默认不需要控制。这样一来只需要一个接口接STD来判断数据是否到达,Q接口接165的输入端,音频口直接接手机,如此可以远程控制了,理论上讲距离时无限的,只要电话能够接通。
现在所有的接口(除了01串口)都用上了,2、3、4用来控制595;5、6、12用来控制165;7用来控制LCD背光;8、9、10、11、13用来控制LCD;A0接五维按键;15、16(A1、A2)连接超声波;17(A3)接STD;A4、A5是I2C接口。至于串口,以后有时间加个蓝牙吧,可能会内存不足,现在已经占用了76%的内存(1516字节),程序大小19546字节(占用60%)。


  1. #include <Wire.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <limits.h>
  5. #include "U8glib.h"
  6. #include <Adafruit_MotorShield.h>
  7. #include "utility/Adafruit_PWMServoDriver.h"
  8. //
  9. #define remotepin 17
  10. //超声波模块 端口
  11. #define trpin        16                
  12. #define ecpin        15
  13. //74HC165 端口
  14. #define q7pin        12               
  15. #define plpin        6
  16. #define cppin        5
  17. //74HC595 端口
  18. #define dspin        4               
  19. #define stpin        3
  20. #define shpin        2
  21. //前置巡线数据-> 74HC165 数据位
  22. #define IRL                7                
  23. #define IRR                6
  24. #define IRM                4
  25. //前置避障数据-> 74HC165 数据位
  26. #define BZL                4                
  27. #define BZR         5
  28. //motor number 马达编号
  29. #define LF                 1                
  30. #define RF                 4
  31. #define LB                 2
  32. #define RB                 3

  33. //RGB PWM编号
  34. #define GPIN        0                
  35. #define RPIN         1                
  36. #define GPIN        14
  37. #define BPIN        15

  38. #define LEFT        0x40        // 2 -> D6 -> 0x40
  39. #define RIGHT        0x02        // 4 -> D1 -> 0x02
  40. #define BRIGHT        0x10         //      D4 -> 0x10
  41. #define BRAKEL        0x01        //      D0 -> 0x01
  42. #define STOP        0x00        //
  43. #define WARNING        0x43        //2+4 -> D6+D1+D0 -> 0x43
  44. #define DEBUG        0x53        //2+4 -> D6+D1+D0+D4 -> 0x53
  45. #define NORMAL  0x00

  46. #define KEYIN                A0         //5-key 五维导航按键读取

  47. #define KEY_NONE        0
  48. #define KEY_PREV         1
  49. #define KEY_NEXT         2
  50. #define KEY_SELECT         3
  51. #define KEY_BACK         4

  52. //
  53. Adafruit_MotorShield Motor = Adafruit_MotorShield();
  54. Adafruit_DCMotor *Motor_LF = Motor.getMotor(LF);
  55. Adafruit_DCMotor *Motor_RF = Motor.getMotor(RF);
  56. Adafruit_DCMotor *Motor_LB = Motor.getMotor(LB);
  57. Adafruit_DCMotor *Motor_RB = Motor.getMotor(RB);

  58. /////////////////////////////////////////////////////////////////////////////////////////////////////
  59. U8GLIB_NHD_C12864 u8g(13, 11, 10, 9, 8);        // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, RST = 8

  60. static  char *menu_strings[5] =         //模式选择菜单[避障模式、巡线模式、遥控模式、系统测试、设置]
  61. {
  62.         "Avoida mode", "Patrol mode", "Remote mode", "System Mode" ,"Setup Mode"
  63. };

  64. static  char *linght_testing[7] =                         //灯光测试显示字符串
  65. {
  66.         "Front light testing","Brake light testing","Left light testing",
  67.         "Right light testing","Waring signal testing","Debug signal testing ",
  68.         "   Normal Status"
  69. };
  70. static  char *motor_testing[7] =                        //马达测试显示字符串
  71. {
  72.         "Forward testing","Backward testing",
  73.         " Left testing","  Right testing",
  74.         "Turn Left testing ","Turn Right testing ",
  75.         "   Stop ! "
  76. };
  77. static  char *GRB_testing[7] =                                // RGB测试显示字符串
  78. {
  79.         "Red testing","Green testing","Blue testing",
  80.         "Yellow testing"," Pink testing","Cyan testing",
  81.         "Whihe testing"
  82. };
  83. static  char *runstauts[9] =                                //小车运行状态显示字符串
  84. {
  85.         "  Forward  "," Backward ",
  86.         "   Left   ","   Right  ",
  87.         " Turn Left ","Turn Right",
  88.         "   Stop   ","  Accel  ",
  89.         "  Brake   "
  90. };

  91. static  char light[7] = {'F','B','L','R','W','D','N'};
  92. static  char motor[7] = {'F','B','L','R','l','r','S'};
  93. static  int  rgb[7][3] =                                        //RGB 测试时的显示序列,红绿蓝黄粉青白
  94. {
  95.         {4096,0,0},{0,4096,0},{0,0,4096},
  96.         {4096,4096,0},{4096,0,4096},
  97.         {0,4096,4096},{4096,4096,4096}
  98. };

  99. uint8_t uiKeyCodeFirst = KEY_NONE;                        //按键控制
  100. uint8_t uiKeyCodeSecond = KEY_NONE;
  101. uint8_t uiKeyCode = KEY_NONE;

  102. uint8_t menu_current = 0;
  103. uint8_t menu_redraw_required = 0;
  104. uint8_t last_key_code = KEY_NONE;

  105. int keyvalue ;
  106. int key = -1 ;
  107. int oldkey = -1;
  108. /////////////////////////////////////////////////////////////////////////////////////////
  109. int ms = 5 ;                                                                 //
  110. int distance,motorspeed;
  111. int current_speed;
  112. char dir_flag,ctrl;
  113. int runstaut;
  114. byte dd;

  115. void setup()
  116. {
  117.         u8g.setRot180();                          // 屏幕旋转180度

  118.         uiStep();  
  119.         menu_redraw_required = 2 ;

  120.         init_595();                                        //初始化
  121.         init_ultra();
  122.         Motor.begin();                                //马达初始化
  123.         motorspeed = 0;
  124.         speedCtrl( 100 );
  125.         motorCtrl('S');

  126.         sysInitialize();

  127.         distance = distanceRead();
  128.         current_speed = 0;

  129.         randomSeed(analogRead(A2)*analogRead(A1));

  130.         Serial.begin(9600);

  131. }
  132. void loop()
  133. {
  134.         //GRBTest();
  135.         sysStar();

  136.         if(uiKeyCodeFirst == KEY_SELECT)
  137.         {
  138.                 switch (menu_current)
  139.                 {
  140.                         case 0 : avoidanceMode();break;
  141.                         case 1 : patrolMode();break;
  142.                         case 2 : remoteMode();break;
  143.                         case 3 : systemMode();break;
  144.                         case 4 : setupMode();break;
  145.                 }
  146.         }
  147. }
  148. ///////////////////////////////////////////////////////////////////////////////
  149. void sysStar()                                                                         //模式菜单显示
  150. {
  151.         uiStep();                                   // 按键检查
  152.         if (  menu_redraw_required != 0 )
  153.         {
  154.                 u8g.firstPage();
  155.                 do  
  156.                         {
  157.                                 drawMenu();
  158.                     }
  159.             while( u8g.nextPage() );
  160.                 menu_redraw_required = 0;
  161.         }
  162.         updateMenu();                            // 更新菜单
  163. }

  164. int keyGetvalue( int value)                                 //按键值
  165. {
  166.         if(value < 100 )       return 0 ;                //左键
  167.         else if (value < 300 ) return 1 ;                //中键
  168.         else if (value < 500 ) return 2 ;                //下键
  169.         else if (value < 700 ) return 3 ;                //右键
  170.         else if (value < 900 ) return 4 ;                //上键
  171.         else return -1 ;
  172. }
  173. void uiStep(void)                                                          //按键设置
  174. {
  175.         keyvalue = analogRead(KEYIN);
  176.         key = keyGetvalue(keyvalue);
  177.         if (key != oldkey)
  178.         {
  179.                 delay(10);
  180.                 keyvalue = analogRead(KEYIN);
  181.                 key = keyGetvalue(keyvalue);
  182.                
  183.                 if(key != oldkey)
  184.                 {
  185.                         oldkey = key;
  186.                         switch (key)
  187.                         {
  188.                             case 0 :  uiKeyCodeFirst = KEY_BACK;   break ;
  189.                             case 1 :  uiKeyCodeFirst = KEY_SELECT; break ;
  190.                             case 2 :  uiKeyCodeFirst = KEY_NEXT;   break ;
  191.                             case 3 :  uiKeyCodeFirst = KEY_NONE;   break ;
  192.                             case 4 :  uiKeyCodeFirst = KEY_PREV;   break ;   
  193.                             default : uiKeyCode = uiKeyCodeFirst;  break ;      
  194.                         }
  195.                 }
  196.         }
  197.         delay(20);
  198. }

  199. void drawMenu(void)                                          //绘制菜单
  200. {
  201.         uint8_t i, h;
  202.         u8g_uint_t w, d;

  203.         u8g.setFont(u8g_font_6x13);
  204.         u8g.setFontRefHeightText();
  205.         u8g.setFontPosTop();
  206.   
  207.         h = u8g.getFontAscent()-u8g.getFontDescent();
  208.         w = u8g.getWidth();
  209.         for( i = 0; i < 5; i++ )
  210.         {
  211.                 d = (w-u8g.getStrWidth(menu_strings[i]))/2;
  212.                 u8g.setDefaultForegroundColor();
  213.             if ( i == menu_current )
  214.             {
  215.                         u8g.drawBox(0, i*h+1, w, h);
  216.                         u8g.setDefaultBackgroundColor();
  217.                 }
  218.                 u8g.drawStr(d, i*h, menu_strings[i]);
  219.         }
  220. }

  221. void updateMenu(void)                                  //更新菜单显示
  222. {
  223.         switch ( uiKeyCode )
  224.         {
  225.                 case KEY_NEXT :
  226.                                         menu_current++;
  227.                                       if ( menu_current >= 5 )
  228.                                         menu_current = 0;
  229.                                       menu_redraw_required = 1;
  230.                                       break;
  231.                 case KEY_PREV :
  232.                                         if ( menu_current == 0 )
  233.                                                 menu_current = 5;
  234.                                         menu_current--;
  235.                                         menu_redraw_required = 1;
  236.                                         break;
  237.         }
  238.         uiKeyCode = KEY_NONE ;
  239. }
  240. void menuLight()                                                 //选择条高亮(加黑)
  241. {
  242.         uint8_t i, h;
  243.         u8g_uint_t w, d;

  244.         u8g.setFont(u8g_font_6x13);
  245.         u8g.setFontRefHeightText();
  246.         u8g.setFontPosTop();
  247.   
  248.         h = u8g.getFontAscent()-u8g.getFontDescent();
  249.         w = u8g.getWidth();
  250.         for( i = 0; i < 5; i++ )
  251.         {
  252.                 d = (w-u8g.getStrWidth(menu_strings[i]))/2;
  253.                 u8g.setDefaultForegroundColor();
  254.             if ( i == menu_current )
  255.             {
  256.                         u8g.drawBox(0, i*h+1, w, h);
  257.                         u8g.setDefaultBackgroundColor();
  258.                 }
  259.                 u8g.drawStr(d, i*h, menu_strings[i]);
  260.         }
  261. }
  262. void screenSet()                                         //屏幕模式获取
  263. {
  264.         if ( u8g.getMode() == U8G_MODE_R3G3B2 )
  265.         {
  266.                 u8g.setColorIndex(255);     // white
  267.         }
  268.         else if ( u8g.getMode() == U8G_MODE_GRAY2BIT )
  269.         {
  270.                 u8g.setColorIndex(3);         // max intensity
  271.         }
  272.         else if ( u8g.getMode() == U8G_MODE_BW )
  273.         {
  274.                 u8g.setColorIndex(1);         // pixel on
  275.         }
  276.         else if ( u8g.getMode() == U8G_MODE_HICOLOR )
  277.         {
  278.                 u8g.setHiColorByRGB(255,255,255);
  279.         }
  280. }
  281. ////////////////////////////////////////////////////////////////////////////

  282. void avoidanceMode()                                 //避障模式
  283. {
  284.         distance = distanceRead();
  285.         speedCtrl(motorspeed);
  286.         car_speed_dirCtrl(distance);
  287.         ///////////////////////////////////////////////////////////
  288.         screenSet();
  289.         u8g.firstPage();
  290.         do
  291.         {
  292.                 u8g.setFont(u8g_font_6x13);
  293.                 u8g.drawStr( 10, 15, "*** Run Stauts ***");
  294.                 u8g.drawStr( 35, 35, runstauts[runstaut]);
  295.                 u8g.drawStr( 10, 60, "*******************");
  296.        
  297.         } while(u8g.nextPage());
  298.         //////////////////////////////////////////////////////////
  299. }
  300. void patrolMode()                                                //巡线模式
  301. {
  302.         car_dirCtrl();
  303.         //////////////////////////////////////////////////////////
  304.         screenSet();
  305.         u8g.firstPage();
  306.         do
  307.         {
  308.                 u8g.setFont(u8g_font_6x13);
  309.                 u8g.drawStr( 10, 15, "*** Run Stauts ***");
  310.                 u8g.drawStr( 35, 35, runstauts[runstaut]);
  311.                 u8g.drawStr( 10, 60, "*******************");
  312.        
  313.         } while(u8g.nextPage());
  314.         ///////////////////////////////////////////////////////////
  315. }
  316. void remoteMode()                                         //遥控模式
  317. {
  318.         byte value;
  319.        
  320.         if ( digitalRead(remotepin) )
  321.         {
  322.                 value = read_165();
  323.                 value = value & 0x0f;
  324.                 switch (value)
  325.                 {
  326.             
  327.                          case 1 : ctrl = 'l'; runstaut = 4; break;                                // 1
  328.                     case 2 : ctrl = 'F'; runstaut = 0; break;
  329.                     case 3 : ctrl = 'r'; runstaut = 5; break;
  330.                     case 4 : ctrl = 'L'; runstaut = 2; break;
  331.                     case 5 : ctrl = 'S'; runstaut = 6; break;
  332.                     case 6 : ctrl = 'R'; runstaut = 3; break;
  333.                     //case 7 : ctrl = 'F'; runstaut = 4; break;
  334.                     case 8 : ctrl = 'B'; runstaut = 4; break;
  335.                            //case 9 : ctrl = 'F'; runstaut = 4; break;
  336.                     //case 10 : ctrl = 'F' runstaut = 4; ;break;                         // 0
  337.                     //case 11 : ctrl = 'F'; runstaut = 4; break;                        // *
  338.                          //case 12 : ctrl = 'F'; runstaut = 4; break;                        // #
  339.                     //case 13 : ctrl = 'F'; runstaut = 4; break;                        // A
  340.                          //case 14 : ctrl = 'F'; runstaut = 4; break;                        // B
  341.                     //case 15 : ctrl = 'F'; runstaut = 4; break;                        // C
  342.                     //case 0 : ctrl = 'D'; runstaut = 4; break;                                // D

  343.                 }

  344.         }

  345.         screenSet();
  346.         u8g.firstPage();
  347.         do
  348.         {
  349.                 u8g.setFont(u8g_font_6x13);
  350.                 u8g.drawStr( 10, 15, "*** Run Stauts ***");
  351.                 u8g.drawStr( 35, 35, runstauts[runstaut]);
  352.                 u8g.drawStr( 10, 60, "*******************");
  353.        
  354.         } while(u8g.nextPage());

  355.         lightCtrl(ctrl);
  356.         motorCtrl(ctrl);
  357.         Serial.println(value,HEX);
  358. }
  359. void systemMode()
  360. {


  361. }
  362. void setupMode()
  363. {
  364.        
  365. }
  366. //////////////////////////////////////////////////////////////////////////////////////

  367. void sysInitialize()                                                         //系统初始化显示信息,包括功能测试
  368. {
  369.         screenSet();
  370.         u8g.setFont(u8g_font_6x13);

  371.         u8g.firstPage();
  372.         do
  373.         {
  374.                 u8g.drawStr( 0, 35, "System is initializing ...");
  375.                 delay(100);
  376.         } while(u8g.nextPage());

  377.         u8g.firstPage();
  378.         do
  379.         {
  380.                 u8g.drawStr( 0, 35, "Light system testing");
  381.                 delay(200);
  382.         } while(u8g.nextPage());
  383.         for ( int  i = 0 ; i < 7; i ++)
  384.         {
  385.                 u8g.firstPage();
  386.                 do
  387.                 {
  388.                         u8g.drawStr( 5, 35, linght_testing[i]);
  389.                         delay(10);

  390.                 } while(u8g.nextPage());       
  391.                 lightCtrl(light[i]);
  392.                 delay(3000);       
  393.         }

  394.         u8g.firstPage();
  395.         do
  396.         {
  397.                 u8g.drawStr( 0, 35, "Motor system testing");
  398.                 delay(200);
  399.         } while(u8g.nextPage());
  400.         for ( int i = 0 ; i < 7; i ++)
  401.         {
  402.                 u8g.firstPage();
  403.                 do
  404.                 {
  405.                         u8g.drawStr( 20, 35, motor_testing[i]);
  406.                         delay(10);
  407.                        
  408.                 } while(u8g.nextPage());
  409.                 motorCtrl(motor[i]);
  410.                 delay(1000);               
  411.         }
  412.        
  413.         u8g.firstPage();
  414.         do
  415.         {
  416.                 u8g.drawStr( 10, 35, "RGB LED testing");
  417.                 delay(100);
  418.         } while(u8g.nextPage());
  419.         for ( int i = 0 ; i < 7; i ++)
  420.         {
  421.                 u8g.firstPage();
  422.                 do
  423.                 {
  424.                         u8g.drawStr( 20, 35, GRB_testing[i]);
  425.                         delay(10);
  426.                        
  427.                 } while(u8g.nextPage());
  428.                 RGBctrl(rgb[i][0],rgb[i][1],rgb[i][2]);
  429.                 delay(1000);               
  430.         }
  431.         RGBctrl(0,0,0);
  432.         u8g.firstPage();
  433.         do
  434.         {
  435.                 u8g.drawStr( 0, 35, "Initializtion Finished");
  436.                 delay(1000);
  437.         } while(u8g.nextPage());

  438. }

  439. ////////////////////
  440. void RGBctrl(int r,int g,int b)                         ///
  441. {
  442.         Motor.setPWM(RPIN,r);
  443.         Motor.setPWM(GPIN,g);
  444.         Motor.setPWM(BPIN,b);
  445. }
  446. void GRBTest()
  447. {
  448.         int i ;
  449.         i = random();
  450.         if ( !(i % 17) ) RGBctrl(random(1024, 4095),0,0 );
  451.         if ( !(i % 37) ) RGBctrl(0,random(1024, 4095),0 );
  452.         if ( !(i % 47) ) RGBctrl(0,0,random(1024, 4095) );
  453.         if ( !(i % 57) ) RGBctrl(0,random(1024, 4095),random(1024, 4095) );
  454.         if ( !(i % 67) ) RGBctrl(random(1024, 4095),random(1024, 4095),0 );
  455.         if ( !(i % 87) ) RGBctrl(random(1024, 4095),0,random(1024, 4095) );
  456.         if ( !(i % 97) ) RGBctrl(random(1024, 4095),random(1024, 4095),random(1024, 4095) );
  457. }
  458. void lightTest()
  459. {       
  460.         int value;
  461.         value = analogRead(KEYIN);
  462.         if(value < 100 )       lightCtrl('L') ;
  463.         else if (value < 300 ) lightCtrl('W') ;
  464.         else if (value < 500 ) lightCtrl('B') ;
  465.         else if (value < 700 ) lightCtrl('R') ;
  466.         else if (value < 900 ) lightCtrl('F') ;
  467. }
  468. void MotorTest()
  469. {
  470.         int value;
  471.         value = analogRead(KEYIN);
  472.         if(value < 100 )       motorCtrl('L') ;
  473.         else if (value < 300 ) motorCtrl('S') ;
  474.         else if (value < 500 ) motorCtrl('B') ;
  475.         else if (value < 700 ) motorCtrl('R') ;
  476.         else if (value < 900 ) motorCtrl('F') ;
  477. }
  478. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  479. void speedCtrl(byte speed)
  480. {
  481.         Motor_LF->setSpeed(speed);
  482.         Motor_RF->setSpeed(speed);
  483.         Motor_LB->setSpeed(speed);
  484.         Motor_RB->setSpeed(speed);
  485. }

  486. //
  487. void motorCtrl(byte status)
  488. {
  489.         switch(status)
  490.         {
  491.                 case 'F' :
  492.                                 Motor_LF->run(FORWARD);
  493.                                 Motor_RF->run(FORWARD);
  494.                                 Motor_LB->run(FORWARD);
  495.                                 Motor_RB->run(FORWARD);
  496.                                 break;
  497.                 case 'B' :
  498.                                 Motor_LF->run(BACKWARD);
  499.                                 Motor_RF->run(BACKWARD);
  500.                                 Motor_LB->run(BACKWARD);
  501.                                 Motor_RB->run(BACKWARD);
  502.                                 break;
  503.                 case 'L' :
  504.                                 Motor_LF->run(RELEASE);
  505.                                 Motor_RF->run(FORWARD);
  506.                                 Motor_LB->run(RELEASE);
  507.                                 Motor_RB->run(FORWARD);
  508.                                 break;
  509.                 case 'R' :
  510.                                 Motor_LF->run(FORWARD);
  511.                                 Motor_RF->run(RELEASE);
  512.                                 Motor_LB->run(FORWARD);
  513.                                 Motor_RB->run(RELEASE);
  514.                                 break;
  515.                 case 'S' :                               
  516.                                 Motor_LF->run(RELEASE);
  517.                                 Motor_RF->run(RELEASE);
  518.                                 Motor_LB->run(RELEASE);
  519.                                 Motor_RB->run(RELEASE);
  520.                                 break;
  521.                 case 'l' :
  522.                                 Motor_LF->run(BACKWARD);
  523.                                 Motor_RF->run(FORWARD);
  524.                                 Motor_LB->run(BACKWARD);
  525.                                 Motor_RB->run(FORWARD);
  526.                                 break;
  527.                 case 'r' :
  528.                                 Motor_LF->run(FORWARD);
  529.                                 Motor_RF->run(BACKWARD);
  530.                                 Motor_LB->run(FORWARD);
  531.                                 Motor_RB->run(BACKWARD);
  532.                                 break;
  533.         }
  534. }
  535. void init_ultra()
  536. {
  537.         pinMode(trpin,OUTPUT);
  538.         pinMode(ecpin,INPUT);
  539. }
  540. int distanceRead()
  541. {
  542.         float distance;
  543.         digitalWrite(trpin, LOW);                   // 发射低电压2μs
  544.         delayMicroseconds(2);
  545.         digitalWrite(trpin, HIGH);                // 发射高电压并维持10μs
  546.         delayMicroseconds(10);
  547.         digitalWrite(trpin, LOW);                 // 恢复低压发射
  548.         distance = pulseIn(ecpin, HIGH);        // 读取返回时间差
  549.         distance = distance/5.8/10;   
  550.           
  551.         return (int) distance;
  552. }
  553. char dirSet(char mode)                                         //方向确定,a为避障模式,红外避障传感器作用,p为巡线模式,3个巡线传感器作用
  554. {
  555.         char flag;
  556.         byte d = read_165();
  557.         if ( mode == 'a' ) /////需要确认有效电平是高还是低
  558.         {
  559.                

  560.                 if ( !(bitRead(d,BZR)) &&  (bitRead(d,BZR)) ) flag = 'L' ;
  561.                 if (  (bitRead(d,BZR)) && !(bitRead(d,BZL)) ) flag = 'R' ;
  562.                 if ( !(bitRead(d,BZR)) && !(bitRead(d,BZR)) ) flag = 'S' ;
  563.                 //if ( !(bitRead(d,BZR)) && !(bitRead(d,BZL ) ) flag = 'B' ;
  564.         }
  565.         if (mode == 'p') /////需要确认有效电平是高还是低
  566.         {
  567.                

  568.                 if ( !(bitRead(d,IRL)) && !(bitRead(d,IRM)) && !(bitRead(d,IRR)) ) flag = 'F' ;
  569.                 if (  (bitRead(d,IRL)) && !(bitRead(d,IRM)) && !(bitRead(d,IRR)) ) flag = 'R' ;
  570.                 if ( !(bitRead(d,IRL)) && !(bitRead(d,IRM)) &&  (bitRead(d,IRR)) ) flag = 'L' ;
  571.                 if (  (bitRead(d,IRL)) &&  (bitRead(d,IRM)) &&  (bitRead(d,IRR)) ) flag = 'S' ;
  572.         }
  573.        
  574.         return flag;
  575. }
  576. void car_speed_dirCtrl(int distance)                         //避障模式方向与速度控制,需要根据前方距离确定运行状态
  577. {
  578.        
  579.         if (distance >= 1000)
  580.         {
  581.                 if(current_speed < 255 )
  582.                 {
  583.                         motorspeed += 30 ;
  584.                         if (motorspeed > 255 ) motorspeed = 255;
  585.                         current_speed = motorspeed;
  586.                 }
  587.             lightCtrl('F');
  588.             motorCtrl('F');
  589.             runstaut = 7 ;
  590.             
  591.         }
  592.         else if (distance < 1000 && distance >= 500)
  593.         {
  594.             if(current_speed > 200)
  595.             {
  596.                     current_speed = motorspeed;
  597.             }
  598.             else if (current_speed < 50 )
  599.             {
  600.                     motorspeed += 30 ;
  601.                         if (motorspeed > 200 ) motorspeed = 200;
  602.                         current_speed = motorspeed;

  603.             }
  604.             else
  605.             {
  606.                     motorspeed += 20 ;
  607.                         if (motorspeed > 200 ) motorspeed = 200;
  608.                         current_speed = motorspeed;

  609.             }
  610.             lightCtrl('F');
  611.             motorCtrl('F');
  612.             runstaut = 7 ;
  613.                
  614.         }
  615.         else if (distance < 500  && distance >= 100)
  616.         {
  617.             if(current_speed > 180)
  618.             {
  619.                     current_speed = motorspeed;
  620.             }
  621.             else if (current_speed < 50 )
  622.             {
  623.                     motorspeed += 20 ;
  624.                         if (motorspeed > 180 ) motorspeed = 180;
  625.                         current_speed = motorspeed;

  626.             }
  627.             else
  628.             {
  629.                     motorspeed += 5 ;
  630.                         if (motorspeed > 180 ) motorspeed = 180;
  631.                         current_speed = motorspeed;

  632.             }
  633.             lightCtrl('F');
  634.             motorCtrl('F');
  635.             runstaut = 7 ;
  636.             
  637.         }
  638.         else if (distance < 100  && distance >= 80)  
  639.         {
  640.             if(current_speed > 200)
  641.             {
  642.                     motorspeed -= 20 ;
  643.                         if (motorspeed < 100 ) motorspeed = 100;
  644.                         current_speed = motorspeed;

  645.             }
  646.             lightCtrl('B');
  647.             motorCtrl('F');
  648.             runstaut = 8 ;

  649.         }
  650.         else if (distance < 80   && distance >= 50)
  651.         {
  652.                 if(current_speed > 200)
  653.             {
  654.                     motorspeed -= 20 ;
  655.                         if (motorspeed < 80 ) motorspeed = 80;
  656.                         current_speed = motorspeed;

  657.             }
  658.             else if (current_speed > 150)
  659.             {
  660.                     motorspeed -= 10 ;
  661.                         if (motorspeed < 80 ) motorspeed = 80;
  662.                         current_speed = motorspeed;

  663.             }

  664.                 motorCtrl('F');
  665.             lightCtrl('B');
  666.             runstaut = 8 ;

  667.         }
  668.         else if (distance < 50   && distance >= 30)
  669.         {
  670.             if(current_speed > 200)
  671.             {
  672.                     motorspeed -= 50 ;
  673.                         if (motorspeed < 50 ) motorspeed = 50;
  674.                         current_speed = motorspeed;

  675.             }
  676.             else if (current_speed > 150)
  677.             {
  678.                     motorspeed -= 40 ;
  679.                         if (motorspeed < 50 ) motorspeed = 50;
  680.                         current_speed = motorspeed;

  681.             }
  682.             else if (current_speed > 100)
  683.             {
  684.                     motorspeed -= 40 ;
  685.                         if (motorspeed < 10 ) motorspeed = 10;
  686.                         current_speed = motorspeed;

  687.             }
  688.             dir_flag = dirSet('a');
  689.             if (dir_flag == 'L') runstaut = 4 ;
  690.             if (dir_flag == 'R') runstaut = 5 ;
  691.             if (dir_flag == 'S') runstaut = 6 ;
  692.             if (dir_flag == 'B') runstaut = 1 ;

  693.             lightCtrl('B');
  694.             lightCtrl(dir_flag);
  695.             motorCtrl(dir_flag);

  696.         }
  697.         else if (distance < 30   && distance >= 15)
  698.         {
  699.                 if(current_speed > 200)
  700.             {
  701.                     motorspeed -= 80 ;
  702.                         if (motorspeed < 0 ) motorspeed = 0;
  703.                         current_speed = motorspeed;

  704.             }
  705.             else if (current_speed > 150)
  706.             {
  707.                     motorspeed -= 60 ;
  708.                         if (motorspeed < 0 ) motorspeed = 0;
  709.                         current_speed = motorspeed;

  710.             }
  711.             else if (current_speed > 100)
  712.             {
  713.                     motorspeed -= 40 ;
  714.                         if (motorspeed < 0 ) motorspeed = 0;
  715.                         current_speed = motorspeed;

  716.             }
  717.             
  718.             lightCtrl('B');
  719.             dir_flag = dirSet('a');
  720.             if (dir_flag == 'L') runstaut = 4 ;
  721.             if (dir_flag == 'R') runstaut = 5 ;
  722.             if (dir_flag == 'S') runstaut = 6 ;
  723.             if (dir_flag == 'B') runstaut = 1 ;
  724.                 dir_flag += 32;
  725.             lightCtrl(dir_flag);
  726.             motorCtrl(dir_flag);
  727.         }
  728.         else if (distance < 15 && distance > 10)
  729.         {
  730.                 motorspeed = 0 ;
  731.                 motorCtrl('S');
  732.                 lightCtrl('W');
  733.                 motorspeed = 0 ;
  734.                 runstaut = 6 ;
  735.         }
  736. }
  737. void car_dirCtrl()                                         // 巡线模式方向控制,小车速度恒定,方向确认
  738. {
  739.         dir_flag = dirSet('p');
  740.         if (dir_flag == 'F') runstaut = 0 ;
  741.         if (dir_flag == 'L') runstaut = 2 ;
  742.         if (dir_flag == 'R') runstaut = 3 ;
  743.         if (dir_flag == 'S') runstaut = 6 ;
  744.         lightCtrl(dir_flag);
  745.         motorCtrl(dir_flag);

  746. }
  747. //////////////////////////////////////////////////////////////////////////////////
  748. void init_595()
  749. {
  750.         pinMode(stpin,OUTPUT);
  751.         pinMode(shpin,OUTPUT);
  752.         pinMode(dspin,OUTPUT);

  753. }
  754. void write_595(byte data)
  755. {
  756.     digitalWrite(stpin,LOW); //将ST_CP口上面加低电平让芯片准备好接收数据
  757.     shiftOut(dspin,shpin,MSBFIRST,data);
  758.     digitalWrite(stpin,HIGH); //将ST_CP这个针脚恢复到高电平
  759. }
  760. void lightCtrl(byte status)
  761. {
  762.         switch (status)
  763.         {
  764.             case 'L' :        write_595(LEFT   ); break;
  765.             case 'R' :        write_595(RIGHT  ); break;
  766.             case 'F' :        write_595(BRIGHT ); break;
  767.             case 'B' :        write_595(BRAKEL ); break;
  768.             case 'S' :        write_595(STOP   ); break;
  769.             case 'W' :        write_595(WARNING); break;
  770.             case 'D' :        write_595(DEBUG  ); break;
  771.             default  :        write_595(NORMAL ); break;   
  772.         }
  773. }
  774. ////////////////////////////////////////////////////////////////////////////
  775. void init_165()
  776. {
  777.         pinMode(cppin,OUTPUT);
  778.         pinMode(plpin,OUTPUT);
  779.         pinMode(q7pin,INPUT);
  780. }
  781. byte read_165()
  782. {
  783.         byte temp,data;

  784.         digitalWrite(plpin, LOW);
  785.         delayMicroseconds(ms);
  786.         digitalWrite(plpin, HIGH);
  787.         delayMicroseconds(ms);

  788.         data = 0 ;

  789.         for(int i = 0 ; i < 8 ; i++)
  790.         {
  791.                 data = data << 1;
  792.                 digitalWrite(cppin, LOW);
  793.                 delayMicroseconds(ms);
  794.                 temp = digitalRead(q7pin);
  795.                 data |= temp;
  796.                 digitalWrite(cppin, HIGH);
  797.                 delayMicroseconds(ms);
  798.         }

  799.         return data ;
  800. }
复制代码

回复

使用道具 举报

发表于 2015-5-31 19:50:28 | 显示全部楼层
放个照片吧~
回复 支持 反对

使用道具 举报

发表于 2015-5-31 19:51:50 | 显示全部楼层
不错,赞一个
回复 支持 反对

使用道具 举报

发表于 2015-5-31 21:39:20 | 显示全部楼层
看着程序够牛,赞个{:soso_e179:}
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-6-5 17:39:20 | 显示全部楼层
zoologist 发表于 2015-5-31 19:50
放个照片吧~

不知道为什么,没办法上传图片,JPEG 320K也不行
回复 支持 反对

使用道具 举报

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

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-24 03:21 , Processed in 0.055867 second(s), 20 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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