当前位置:   article > 正文

【DIY】远程手机遥控车 androidbot_android 遥控车 方向微调器

android 遥控车 方向微调器
  androidbot机器人

              


一、设计初衷:

当过爸爸妈妈的都有类似感受:小孩慢慢长大,学说话,学走路,而自己平时上班太忙,陪小孩的时间自然就少了!为了弥补心中遗憾,很多我认识的朋友中会在自己家里安装WIFI IP camera方便自己随时查看小孩在家是否有哭闹或者做一些不安全的事,而也有很少一部分喜欢DIY的朋友选择了自己动手,我也是其中之一。

二、项目发展历程

尤其是当我女儿在2岁左右的时候,此时才刚好学会说话,走路,我是特别希望自己能多点时间陪伴她,于是这个项目在当时2015.8启动了。

这款安卓手机远程陪伴机器人项目经过了2年的反复改进,目前有三个版本,分别是2015/2016/2017三个版本, 虽然从外观,硬件和软件app上都有很大变动,但都是围绕主要功能来改进的:远程视频陪伴。


三、优势:

    设计之初不完全是为了DIY,我是希望能够做出一款实用便宜易用的产品,所以没有采用常用的DIY开源硬件方案例如arduino,而是选择了价格便宜,功耗极低的蓝牙BT4.0和MCU控制一体TI最新芯片CC2541来做控制方案。当然也相信大家能理解我为什么会选择android手机来做机器人大脑。

 

    项目过程中遇到最大难题是android手机兼容性问题,在APP的开发过程中,这个问题花最多时间和精力才做到今天这种程度,我个人感觉是非常有成就感的。

因为类似项目不止我一个人想做,但最后都因为这个问题而放弃,包括国外2012很火的romo机器人,国内也有不少这样的公司,他们最终都不得不选择苹果的手机或者平板来做。这里面主要是解决了app在没有root权限的情况下待机以后还会长时间不掉线,还可以随时被唤醒。

与WIFI IP camera对比:

1)可以到处跑,因为不需要插着电源线;2)省电,待机长,所以不用担心充电问题。3)监控温湿度声音情况。


四、功能:

 

1)远程视频(android手机+webrtc)

2)蓝牙遥控车(20天待机 BT4.0  CC2541)

3)百度语音识别和聊天(android手机编程)

4)温湿度传感器 (DHT11传感器模块)

5)声音传感器



五、硬件列表

下图是完整的实物零件图,基本上是从淘宝上面淘的(除了控制底板),

2)小车底盘(淘宝上面有非常多的小车底盘卖,自己任选),

3)马达:TT马达3元/个

4)轮子:2元/个

5)锂电池:2200mAH  7.4V   + 充电器  一起30元

1)控制板包括:

 蓝牙模块CC2541:11元

 电机模块:5元

 稳压模块:5元

温湿度传感器:5元

底板:自己设计的,自己也可以用面包板或者飞线来代替,只是可能会比较乱不好看。


自己算算很便宜吧!



六、应用介绍   
   

        CrabRobot是一款小孩陪伴机器人APP, 已经通过小米审核,可以在小米应用商店搜索CrabRobot 

1、两大功能:


1)、移动看家
2)、智能语音聊天

2、其他特点:

1)用手机替代网络摄像头,更智能,更省电;
2)自动应答;
3)查询环境温湿度信息;
4)支持蓝牙玩具遥控车; (移动功能和温湿度查询功能,需要配一款蓝牙玩具遥控车,可待机20天)。

3、使用方法:
1、注册账号,分别在两部手机上各自注册一个账号;
2、添加对方为好友;
3、把其中一部手机放到蓝牙遥控玩具车上;




组装后效果图,个人挺满意的 ^_^:


七、开放资源

https://github.com/luojin012/Android-phone-telepresence-robot

1、开源:控制电路板,结构,控制板软件;app免费使用

2、app接口免费使用,接口开放

这里列举下蓝牙命令接口,

例如通过蓝牙发送命令:


1)  b2;\n

小车以2的速度前行,如果是负数就倒车

2)  t3;\n

小车以3的速度转弯,负数的话就是反方向转弯


温湿度传感器命令:

如果小车控制板上有温湿度传感器,也可以按照下面格式发送数据到APP

DHT:60.2;28.5

60.2是湿度,28.5是温度。


控制板的代码是开源的基于CC251蓝牙模块C51核写的


读取温湿度代码,这里要感谢“甜甜的大香瓜”,在他的基础上修改来的,少走了弯路。

  1. //******************************************************************************
  2. //name: DHT11_Read_Humiture
  3. //introduce: DHT11的读温湿度函数
  4. //parameter: none
  5. //return: TRUE:读取正确,FALSE:读取错误
  6. //author: 甜甜的大香瓜
  7. //email: 897503845@qq.com
  8. //changetime: 2016.04.11
  9. //******************************************************************************
  10. void DHT11_Read_Humiture(uint8 *pDHT11_data)
  11. {
  12. uint8 nHumidity_integer;
  13. uint8 nHumidity_decimal;
  14. uint8 nTemperature_integer;
  15. uint8 nTemperature_decimal;
  16. uint8 nChecksum;
  17. uint8 nChecksum_count;
  18. uint8 nFLAG;
  19. // EA = 0;
  20. //主机开始信号
  21. SET_PIN_OUT; //IO口配置为输出
  22. SET_DATA_PIN; //输出高电平
  23. // Delay_Us(100000);
  24. CLR_DATA_PIN; //输出低电平
  25. Delay_Us(4000); //延时至少18MS
  26. SET_DATA_PIN; //输出高电平
  27. Delay_Us(4);
  28. //切换到DHT11端发数据
  29. SET_PIN_IN; //IO口配置为输入
  30. Delay_Us(4);
  31. if(DATA_PIN == 0)
  32. {
  33. //DHT11响应
  34. nFLAG = 2;
  35. EA = 0;
  36. while((DATA_PIN == 0) && (nFLAG++));
  37. nFLAG = 2;
  38. while((DATA_PIN == 1) && (nFLAG++));
  39. //DHT11读值
  40. nHumidity_integer = DHT11_Read_Char(); //湿度高位,整数
  41. nHumidity_decimal = DHT11_Read_Char(); //湿度低位,小数
  42. nTemperature_integer = DHT11_Read_Char(); //温度高位,整数
  43. nTemperature_decimal = DHT11_Read_Char(); //温度低位,小数
  44. nChecksum = DHT11_Read_Char(); //校验和
  45. EA = 1;
  46. //结束
  47. SET_DATA_PIN;
  48. //计算校验和
  49. nChecksum_count = nHumidity_integer + nHumidity_decimal + nTemperature_integer + nTemperature_decimal;
  50. //验证数据正确性
  51. if(nChecksum == nChecksum_count)
  52. {
  53. //正确,则将读出的值保存到全局变量
  54. pDHT11_data[0] = nHumidity_integer;
  55. pDHT11_data[1] = nHumidity_decimal;
  56. pDHT11_data[2] = nTemperature_integer;
  57. pDHT11_data[3] = nTemperature_decimal;
  58. }
  59. else
  60. {
  61. //错误,则值全为0
  62. pDHT11_data[0] = 0;
  63. pDHT11_data[1] = 0;
  64. pDHT11_data[2] = 0;
  65. pDHT11_data[3] = 0;
  66. EA = 1;
  67. return ;
  68. }
  69. }
  70. else
  71. {
  72. //错误,则值全为0
  73. pDHT11_data[0] = 0;
  74. pDHT11_data[1] = 0;
  75. pDHT11_data[2] = 0;
  76. pDHT11_data[3] = 0;
  77. EA = 1;
  78. return ;
  79. }
  80. EA = 1;
  81. return ;
  82. }
命令接受解析控制,可以看到和上面命令例子 是对应的。
  1. void car_stop()
  2. {
  3. motor_Set(motor_A0, 0);
  4. motor_Set(motor_A1, 0);
  5. motor_Set(motor_B0, 0);
  6. motor_Set(motor_B1, 0);
  7. car.left=car.right=0;
  8. car.carn=0;
  9. }
  10. /*void motor_Set( uint8 pin_d, uint8 mode )
  11. {
  12. //
  13. // cmd_st.key_timer=0;
  14. // PIN_setOutputValue(hKeyPins, pin_d, mode);
  15. pin_d=mode;
  16. }
  17. */
  18. void cmd_pase(char *data_c,int len)
  19. {
  20. int i;
  21. //char *data_c=Receive_CMD[0].receive_buf;
  22. //memset(RX2_Buffer,0,BUF_LENTH);
  23. for(i=0;i<len;i++)
  24. {
  25. if(data_c[i]=='t') // turn right or left
  26. {
  27. car.right=atoi(data_c+i+1);
  28. if(car.right>0)
  29. car.right+=2;
  30. else
  31. car.right-=2;
  32. car.left=-car.right;
  33. //motor_Set(duoji_A, 1);
  34. douji.x=0;
  35. car.carn=0;
  36. break;
  37. }
  38. else if(data_c[i]=='b') // both motor speed
  39. {
  40. car.right=car.left= atoi(data_c+i+1);
  41. //motor_Set(duoji_A, 1);
  42. douji.x=0;
  43. car.carn=0;
  44. //if(car.right==2)
  45. // car_led = ~car_led;
  46. break;
  47. }
  48. }
  49. }
  50. void receing_data(char datar)
  51. {
  52. if(datar==';')
  53. {
  54. Receive_CMD[0].receive_buf[Receive_CMD[0].receive_len++] = 0;
  55. Receive_CMD[0].receive_status=2;
  56. idle_buf++;
  57. /
  58. cmd_pase(Receive_CMD[0].receive_buf,Receive_CMD[0].receive_len);
  59. Receive_CMD[0].receive_status=0;
  60. Receive_CMD[0].receive_len=0;
  61. }
  62. else
  63. //else if(Receive_CMD[0].receive_status<2)
  64. {
  65. Receive_CMD[0].receive_buf[Receive_CMD[0].receive_len++] = datar;
  66. Receive_CMD[0].receive_status=1;
  67. if(Receive_CMD[0].receive_len>max_rebuf)
  68. Receive_CMD[0].receive_len=0;
  69. }
  70. }
  71. #if 1
  72. void car_control()
  73. {
  74. // car_led = (car.left||car.right);
  75. car.left_count++;
  76. if((car.left_count>=8))
  77. {
  78. car.left_count=1;
  79. if(car.left!=1)
  80. {
  81. motor_Set(motor_A0, 0);
  82. motor_Set(motor_A1, 0);
  83. }
  84. }
  85. if(car.left==0)
  86. { // stop
  87. motor_Set(motor_A0, 0);
  88. motor_Set(motor_A1, 0);
  89. }
  90. if(car.left==car.left_count)
  91. motor_Set(motor_A0, 1);
  92. //motor_A0=1;
  93. if(car.left==-car.left_count)
  94. motor_Set(motor_A1, 1);
  95. //motor_A1=1;
  96. */
  97. car.right_count++;
  98. if((car.right_count>=8))
  99. {
  100. car.right_count=1;
  101. if(car.right!=1)
  102. {
  103. // car.right=0;
  104. motor_Set( motor_B0, 0 );
  105. motor_Set( motor_B1, 0 );
  106. }
  107. }
  108. if(car.right==car.right_count)
  109. {
  110. motor_Set(motor_B0, 1);
  111. //car_led = 1;
  112. }
  113. // motor_B0=1;
  114. if(car.right==(-car.right_count))
  115. {
  116. motor_Set(motor_B1, 1);
  117. // car_led = 1;
  118. }
  119. if(car.right==0)
  120. { // stop
  121. motor_Set(motor_B0, 0);
  122. motor_Set(motor_B1, 0);
  123. }
  124. }

让我开心的是,隔壁家的男孩比我们家的女儿更喜欢玩;另外有次我把样品拿出去玩时,有个妈妈问有没有开始卖,她也需要一个来照看她家的老人和小孩。

https://item.taobao.com/item.htm?id=552635703115  想自己DIY的伙伴可以联系我,提供3D打印相关外壳及其它硬件!QQ:1074814960







声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号