数码之家

 找回密码
 立即注册
搜索
查看: 3244|回复: 10

[手机] DIY远程手机遥控车 androidbot

[复制链接]
发表于 2020-4-4 17:03:47 来自手机浏览器 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

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

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

二、项目发展历程

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

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

wechat_upload15859914325e884f086c10d

三、优势:

    设计之初不完全是为了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元

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

wechat_upload15859914775e884f3593a2c

自己算算很便宜吧!






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

1、两大功能:



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

2、其他特点:

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

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



wechat_upload15859915125e884f58a472a



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

wechat_upload15859915685e884f90b4aec

七、开放资源

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核写的



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

//******************************************************************************               
    //name:             DHT11_Read_Humiture               
    //introduce:        DHT11的读温湿度函数              
    //parameter:        none         
    //return:           TRUE:读取正确,FALSE:读取错误              
    //author:           甜甜的大香瓜         
    //email:            897503845@qq.com      
    //changetime:       2016.04.11            
    //******************************************************************************   
     void DHT11_Read_Humiture(uint8 *pDHT11_data)     
    {  
        uint8 nHumidity_integer;  
        uint8 nHumidity_decimal;  
        uint8 nTemperature_integer;  
        uint8 nTemperature_decimal;   
        uint8 nChecksum;   
        uint8 nChecksum_count;  
        uint8 nFLAG;  
   //   EA = 0;
        //主机开始信号   
        SET_PIN_OUT;                                //IO口配置为输出  
         
        SET_DATA_PIN;                               //输出高电平  
           
     //  Delay_Us(100000);  
        CLR_DATA_PIN;                               //输出低电平  
            
        Delay_Us(4000);                            //延时至少18MS  
               
        SET_DATA_PIN;                               //输出高电平  
      
        Delay_Us(4);  
           
        //切换到DHT11端发数据  
        SET_PIN_IN;                                 //IO口配置为输入  
         
        Delay_Us(4);   
            
       if(DATA_PIN == 0)
        {  
            //DHT11响应                        
           nFLAG = 2;   
            EA = 0;
            while((DATA_PIN == 0) && (nFLAG++));  
              
            nFLAG = 2;  
              
            while((DATA_PIN == 1) && (nFLAG++));   
              
              
            //DHT11读值  
            nHumidity_integer = DHT11_Read_Char();          //湿度高位,整数  
              
            nHumidity_decimal = DHT11_Read_Char();          //湿度低位,小数  
              
            nTemperature_integer = DHT11_Read_Char();       //温度高位,整数  
              
            nTemperature_decimal = DHT11_Read_Char();       //温度低位,小数   
              
            nChecksum = DHT11_Read_Char();                  //校验和   
      
             EA = 1;
            //结束  
            SET_DATA_PIN;  
              
                  
            //计算校验和  
            nChecksum_count = nHumidity_integer + nHumidity_decimal + nTemperature_integer + nTemperature_decimal;  
              
            //验证数据正确性  
            if(nChecksum == nChecksum_count)  
            {            
                //正确,则将读出的值保存到全局变量  
                pDHT11_data[0] = nHumidity_integer;  
                  
                pDHT11_data[1] = nHumidity_decimal;  
                  
                pDHT11_data[2] = nTemperature_integer;  
                  
                pDHT11_data[3] = nTemperature_decimal;               
            }  
            else  
            {            
                 //错误,则值全为0  
                pDHT11_data[0] = 0;  
                  
                pDHT11_data[1] = 0;  
                  
                pDHT11_data[2] = 0;  
                  
                pDHT11_data[3] = 0;   
                 EA = 1;      
                return  ;  
            }   
        }  
        else                          
        {                                 
            //错误,则值全为0  
            pDHT11_data[0] = 0;  
                  
            pDHT11_data[1] = 0;  
                  
            pDHT11_data[2] = 0;  
                  
            pDHT11_data[3] = 0;   
             EA = 1;      
            return  ;        
        }  
          EA = 1;
        return  ;  
    }  
命令接受解析控制,可以看到和上面命令例子 是对应的。
void  car_stop()
{
        motor_Set(motor_A0, 0);
        motor_Set(motor_A1, 0);
        motor_Set(motor_B0, 0);
        motor_Set(motor_B1, 0);
        car.left=car.right=0;
        car.carn=0;
}


/*void motor_Set( uint8 pin_d, uint8 mode )
{
//
   // cmd_st.key_timer=0;
  //  PIN_setOutputValue(hKeyPins, pin_d, mode);
         pin_d=mode;
}
*/
void cmd_pase(char *data_c,int len)
{
         int i;
         
        //char *data_c=Receive_CMD[0].receive_buf;

        //memset(RX2_Buffer,0,BUF_LENTH);

                        

        for(i=0;i<len;i++)
        {
                if(data_c=='t')                   // turn right or left  
                {
                        
                        car.right=atoi(data_c+i+1);
                        if(car.right>0)
                          car.right+=2;
                        else
                          car.right-=2;
                        car.left=-car.right;
                        //motor_Set(duoji_A, 1);
                        douji.x=0;
                        car.carn=0;
                        break;
                }
               
                else if(data_c=='b')           // both motor speed
                {
                         car.right=car.left=  atoi(data_c+i+1);
                        //motor_Set(duoji_A, 1);
                        douji.x=0;
                        car.carn=0;
                        //if(car.right==2)
                        //        car_led = ~car_led;  

                        break;
                }
               

                        
        }
}

void receing_data(char datar)
{

        if(datar==';')
        {
                Receive_CMD[0].receive_buf[Receive_CMD[0].receive_len++] = 0;        
                Receive_CMD[0].receive_status=2;
                idle_buf++;
                /////
               
                cmd_pase(Receive_CMD[0].receive_buf,Receive_CMD[0].receive_len);
                Receive_CMD[0].receive_status=0;
                Receive_CMD[0].receive_len=0;
               
               
        }
        else
        //else  if(Receive_CMD[0].receive_status<2)
        
        {
                Receive_CMD[0].receive_buf[Receive_CMD[0].receive_len++] = datar;        
                Receive_CMD[0].receive_status=1;
                if(Receive_CMD[0].receive_len>max_rebuf)
                        Receive_CMD[0].receive_len=0;

        }

        
}

#if 1


void car_control()
{

// car_led = (car.left||car.right);  
        car.left_count++;
        if((car.left_count>=8))
        {
                car.left_count=1;
        if(car.left!=1)
        {
          motor_Set(motor_A0, 0);
          motor_Set(motor_A1, 0);
        }
        }

        if(car.left==0)
        { // stop
                motor_Set(motor_A0, 0);
                motor_Set(motor_A1, 0);
        }         

          if(car.left==car.left_count)
                motor_Set(motor_A0, 1);
                 //motor_A0=1;        

          if(car.left==-car.left_count)
                motor_Set(motor_A1, 1);
                 //motor_A1=1;               



////////////*/

    car.right_count++;        
    if((car.right_count>=8))
        {
                car.right_count=1;
                if(car.right!=1)
                {
                 // car.right=0;
                  motor_Set( motor_B0, 0 );
                  motor_Set( motor_B1, 0 );
                     
                }

        }


        if(car.right==car.right_count)
        {
                motor_Set(motor_B0, 1);
        //car_led = 1;         
        }
         //        motor_B0=1;               

          if(car.right==(-car.right_count))
        {
                motor_Set(motor_B1, 1);
              // car_led = 1;   
        }

          if(car.right==0)
        { // stop
                motor_Set(motor_B0, 0);
                motor_Set(motor_B1, 0);
                    
        }         

        
        

         



}

原文链接:https://blog.csdn.net/xpp012/article/details/77964192

打赏

参与人数 4家元 +102 收起 理由
lihefeng0528 + 3 優秀文章
aladdincp + 40 原創內容
ztrdiy + 50 優秀文章
ppyuyi + 9

查看全部打赏

发表于 2020-4-4 22:21:30 来自手机浏览器 | 显示全部楼层
辛苦了,备用学习
回复 支持 反对

使用道具 举报

发表于 2020-4-4 22:36:55 | 显示全部楼层
很好的制作,这么好的文章,申精的节奏!
回复 支持 反对

使用道具 举报

发表于 2020-4-5 09:15:38 来自手机浏览器 | 显示全部楼层
记录一下,备用
回复 支持 反对

使用道具 举报

发表于 2020-4-5 23:55:15 | 显示全部楼层
真的太棒了,我等小白只有望洋兴叹的份啊
回复 支持 反对

使用道具 举报

发表于 2020-4-10 11:16:48 | 显示全部楼层
楼主厉害 谢谢 是个好东西!
回复 支持 反对

使用道具 举报

发表于 2020-4-12 20:21:23 | 显示全部楼层
怎么找不到APP
回复 支持 反对

使用道具 举报

发表于 2020-4-14 18:51:39 | 显示全部楼层
这转发的是什么时候的,,,还能找到代码么
回复 支持 反对

使用道具 举报

发表于 2020-4-15 18:36:05 | 显示全部楼层
顶一个,厉害。
回复 支持 反对

使用道具 举报

发表于 2020-4-16 09:47:13 | 显示全部楼层
Never。 发表于 2020-4-14 18:51
这转发的是什么时候的,,,还能找到代码么

最后一版是17,怕是有几年了,看来找代码难了
回复 支持 反对

使用道具 举报

发表于 2020-4-17 12:38:15 | 显示全部楼层
感谢分享,备用
回复 支持 反对

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2024-4-24 02:12 , Processed in 0.109200 second(s), 14 queries , Redis On.

Powered by Discuz!

© 2006-2023 smzj.net

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