基于ESP8266和51单片机的手机遥控小车

小车效果在这里插入图片描述

APP效果在这里插入图片描述

设计材料

  1. ESP8266-01s模块。
  2. 51单片机最小系统板。
  3. L293D芯片一个。
  4. Android系统手机。
  5. 面包板一块。
  6. 充电宝一个,当做电源。
  7. 杜邦线若干。

设计思路

说明:这是一个可远程遥控的小车,只要小车连接上WIFI,理论上无论你在多远的地方都能遥控小车,因为使用了onenet云平台;当然如果小车使用GSM模组就更好了,小车在哪都能受控。

  1. ESP8266通过MQTT协议连接onenet云服务器。
  2. ESP8266与51单片机之间使用串口通信。
  3. 51单片机通过L293D芯片驱动两个电机,一个负责方向,另一个负责前进和后退。
  4. ESP8266订阅手机端发布的主题,从而实现手机控制小车。
  5. 工作过程。在这里插入图片描述

ESP8266端开发

说明:这是基于ESP8266-SDK进行二次开发的,怎么通过MQTT协议连接onenet不在多说,详情请查看我的另一篇博客看ESP8266端开发部分,提供了源代码,当然你也可以去安信可官方平台下载sdk包;在这里主要完成将相应的消息通过串口发送出去。

  1. 首先,订阅手机发布的CAR主题。
void mqttConnectedCb(uint32_t *args)
{
    MQTT_Client* client = (MQTT_Client*)args;
    INFO("MQTT: Connected\r\n");
    MQTT_Subscribe(client, "CAR", 0);//完成订阅
}
  1. 先判断是不是CAR主题,然后将该主题下的消息通过串口发送出去,比如说收到1,那么就在新的一行打印1即可。
void mqttDataCb(uint32_t *args, const char* topic, uint32_t topic_len, const char *data, uint32_t data_len)
{
    char *topicBuf = (char*)os_zalloc(topic_len+1),
            *dataBuf = (char*)os_zalloc(data_len+1);
    MQTT_Client* client = (MQTT_Client*)args;
    os_memcpy(topicBuf, topic, topic_len);
    topicBuf[topic_len] = 0;
    os_memcpy(dataBuf, data, data_len);
    dataBuf[data_len] = 0;
  //  INFO("Receive topic: %s, data: %s \r\n", topicBuf, dataBuf);
   // INFO("Topic_len = %d, Data_len = %d\r\n", topic_len, data_len);//串口打印主题长度、有效载荷长度
    if( os_strcmp(topicBuf,"CAR") == 0 )//判断是哪一个主题
              {
              	if( os_strcmp(dataBuf,"0") == 0 )	//如果收到的是0就打印0
              	{
              		os_printf("0\n");

              	}

              	else if( os_strcmp(dataBuf,"1") == 0 )
              	{
              		os_printf("1\n");

              	}
              	//此处省略了2,3,4,5的打印代码,可以自行补充。
              }
    os_free(topicBuf);
    os_free(dataBuf);
}
  1. 串口调试助手,调试实例。在这里插入图片描述

51单片机端开发

  1. 说明:51单片机只需要读取到上述串口打印的消息,然后合理的解读到消息内容,同时做出相应的动作就可以了。 比如说,串口收到0,表示让小车左转;收到1让小车右转,收到2停止转向。手机按键是按下左键发送0,抬起左键发送2。这样马达就不会一直处于带电的状态。
  2. 晶振为11.0592M的, 初始化串口,波特率为9600,与ESP8266波特率保持一致即可。
  3. 源程序如下,可直接编译使用:
#include "reg52.h"	
#include "intrins.h"

typedef unsigned int u16;	  
typedef unsigned char u8;
sbit Led=P3^7;
sbit JDQ_S=P0^0;
sbit JDQ_C=P0^1;
sbit turn_left=P1^1;
sbit turn_right=P1^2;
sbit qianjin=P1^3;
sbit houtui=P1^4;
u8 receivearray[100];
//串口初始化函数,波特率设置为9600
void UsartInit()
{
	  SCON=0x50;                                           
      PCON=0x80;                 
      TMOD=0x21;                
      TH1=0xFA;          
      TL1=TH1;
      EA=1;                     
      ES=1;                      
      TR1=1;   
}
//串口发送函数,发送函数第一位为2,esp8266端才会发布消息
void Sent2Esp8266(u8 *p)				
{	
 	while(*p)
 	{
	 	SBUF=*p;
		while(!TI);
		TI=0;
		p++;
	}   
}

//主函数
void main()
{	
	UsartInit();  
	while(1)
	{
		
				
}
	}
//串口中断函数,用来读取串口读取到的数据
u8 i=0;
void Usart() interrupt 4
{
	u8 receiveData;
	receiveData=SBUF;
	receivearray[i]=receiveData;
	i++;
	if(receivearray[i-1]=='\n')i=0;	
	switch(receivearray[0])
		{
			case '0':
				turn_left=1;
				turn_right=0;
			    Led=1;
				//Sent2Esp8266("turn_left");
			break;
			case '1':
				turn_left=0;
				turn_right=1;
			    Led=0;
				//Sent2Esp8266("turn_right");
			break;
			case '2':
					turn_left=0;
				turn_right=0;
				//Sent2Esp8266("stop_turn");
			break;
			case '3':
				qianjin=1;
			    houtui=0;
				//Sent2Esp8266("qianjin");
			break;
			case '4':
				qianjin=0;
			    houtui=1;
				//Sent2Esp8266("houtui");
			break;
			case '5':
				qianjin=0;
			    houtui=0;
				//Sent2Esp8266("stop");
			break;
		}
	RI = 0;
	SBUF=receiveData;
	while(!TI);			 
	TI=0;						
}
  1. L293D的使用,只需要使用单片机的6个管脚就够了,两个控制前进后退,两个控制方向,两个使EN能端。比如说P1.0,P1.1来控制方方向,当高低电平不同时,电机旋转方向不同,将P1.0接1A,P1.1接2A;1Y、2Y接在电机上另一个电机也是一样,4、5、12、13管脚是联通的,将其中的一个接地即可,EN使能端高电平有效,可以给两个使能高电平,VCC1、2接电源正极在这里插入图片描述
    5、ESP8266与单片机连接
    在这里插入图片描述

APP端开发

  1. 开发环境AndroidStudio3.6。
  2. 这里只说明一些代码的作用,详情请查看我的另一篇博客看APP开发部分
  3. 手机端是不需要订阅消息的,只需要按键触发发布消息就可以了,下面是相关代码。
  4. 你可以下载最下面的源码填写你的OneNet相关ID直接使用。
@Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (v.getId()){
            case R.id.left:
                if(event.getAction()==MotionEvent.ACTION_DOWN){//如果按键是按下的状态
                    btn_left.setTextColor(Color.parseColor("#6200EE"));//更改按键颜色
                    byte[] left={'0'};//左转所要发布的消息
                    MqttPublish mqttPublish_left=new MqttPublish("CAR",left,QoS.AT_LEAST_ONCE);//这里一CAR主题名发布
                    MqttClient.getInstance().sendMsg(mqttPublish_left);//发布消息
                }else if(event.getAction()==MotionEvent.ACTION_UP){
                    btn_left.setTextColor(Color.parseColor("#c0c0c0"));
                    byte[] left={'2'};
                    MqttPublish mqttPublish_zt=new MqttPublish("CAR",left,QoS.AT_LEAST_ONCE);
                    MqttClient.getInstance().sendMsg(mqttPublish_zt);
                }
                break;
            case R.id.right:
                if(event.getAction()==MotionEvent.ACTION_DOWN){
                    btn_right.setTextColor(Color.parseColor("#6200EE"));
                    byte[] right={'1'};
                    MqttPublish mqttPublish_left=new MqttPublish("CAR",right,QoS.AT_LEAST_ONCE);
                    MqttClient.getInstance().sendMsg(mqttPublish_left);
                }else if(event.getAction()==MotionEvent.ACTION_UP){
                    btn_right.setTextColor(Color.parseColor("#c0c0c0"));
                    byte[] left={'2'};
                    MqttPublish mqttPublish_zt=new MqttPublish("CAR",left,QoS.AT_LEAST_ONCE);
                    MqttClient.getInstance().sendMsg(mqttPublish_zt);
                }
                break;
            case R.id.qj:
                if(event.getAction()==MotionEvent.ACTION_DOWN){
                    btn_qj.setTextColor(Color.parseColor("#6200EE"));
                    byte[] right={'4'};
                    MqttPublish mqttPublish_left=new MqttPublish("CAR",right,QoS.AT_LEAST_ONCE);
                    MqttClient.getInstance().sendMsg(mqttPublish_left);
                }else if(event.getAction()==MotionEvent.ACTION_UP){
                    btn_qj.setTextColor(Color.parseColor("#c0c0c0"));
                    byte[] left={'5'};
                    MqttPublish mqttPublish_zt=new MqttPublish("CAR",left,QoS.AT_LEAST_ONCE);
                    MqttClient.getInstance().sendMsg(mqttPublish_zt);
                }
                break;
            case R.id.ht:
                if(event.getAction()==MotionEvent.ACTION_DOWN){
                    btn_ht.setTextColor(Color.parseColor("#6200EE"));
                    byte[] right={'3'};
                    MqttPublish mqttPublish_left=new MqttPublish("CAR",right,QoS.AT_LEAST_ONCE);
                    MqttClient.getInstance().sendMsg(mqttPublish_left);
                }else if(event.getAction()==MotionEvent.ACTION_UP){
                    btn_ht.setTextColor(Color.parseColor("#c0c0c0"));
                    byte[] left={'5'};
                    MqttPublish mqttPublish_zt=new MqttPublish("CAR",left,QoS.AT_LEAST_ONCE);
                    MqttClient.getInstance().sendMsg(mqttPublish_zt);
                }
                break;
        }
        return true;
    }
  1. 点击下载源码
    到此就结束喽,有什么问题的话,还请大家指出。
  • 12
    点赞
  • 123
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小魏先森

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值