单片机交流
直播中

丁冬芹

7年用户 1304经验值
私信 关注
[问答]

怎样去设计一种基于ESP8266和51单片机的手机遥控小车

ESP8266与51单片机之间是如何进行串口通信的?
怎样去设计一种基于ESP8266和51单片机的手机遥控小车?

回帖(1)

朱利华

2021-8-20 15:06:49
  设计材料
  ESP8266-01s模块。
  51单片机最小系统板。
  L293D芯片一个。
  Android系统手机。
  面包板一块。
  充电宝一个,当做电源。
  杜邦线若干。
  设计思路
  说明:这是一个可远程遥控的小车,只要小车连接上WIFI,理论上无论你在多远的地方都能遥控小车,因为使用了onenet云平台;当然如果小车使用GSM模组就更好了,小车在哪都能受控。
  ESP8266通过MQTT协议连接onenet云服务器。
  ESP8266与51单片机之间使用串口通信。
  51单片机通过L293D芯片驱动两个电机,一个负责方向,另一个负责前进和后退。
  ESP8266订阅手机端发布的主题,从而实现手机控制小车。
  工作过程。
  ESP8266端开发
  说明:这是基于ESP8266-SDK进行二次开发的,怎么通过MQTT协议连接onenet不在多说,详情请查看我的另一篇博客看ESP8266端开发部分,提供了源代码,当然你也可以去安信可官方平台下载sdk包;在这里主要完成将相应的消息通过串口发送出去。
  首先,订阅手机发布的CAR主题。
  void mqttConnectedCb(uint32_t *args){ MQTT_Client* client = (MQTT_Client*)args; INFO(“MQTT: Connectedrn”); MQTT_Subscribe(client, “CAR”, 0);//完成订阅}
  先判断是不是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 rn”, topicBuf, dataBuf); // INFO(“Topic_len = %d, Data_len = %drn”, topic_len, data_len);//串口打印主题长度、有效载荷长度 if( os_strcmp(topicBuf,“CAR”) == 0 )//判断是哪一个主题 { if( os_strcmp(dataBuf,“0”) == 0 ) //如果收到的是0就打印0 { os_printf(“0n”); } else if( os_strcmp(dataBuf,“1”) == 0 ) { os_printf(“1n”); } //此处省略了2,3,4,5的打印代码,可以自行补充。 } os_free(topicBuf); os_free(dataBuf);}
  串口调试助手,调试实例。
  51单片机端开发
  说明:51单片机只需要读取到上述串口打印的消息,然后合理的解读到消息内容,同时做出相应的动作就可以了。 比如说,串口收到0,表示让小车左转;收到1让小车右转,收到2停止转向。手机按键是按下左键发送0,抬起左键发送2。这样马达就不会一直处于带电的状态。
  晶振为11.0592M的, 初始化串口,波特率为9600,与ESP8266波特率保持一致即可。
  源程序如下,可直接编译使用:
  #include “reg52.h” #include “intrins.h”typedef unsigned int u16; typedef unsigned char u8;***it Led=P3^7;***it JDQ_S=P0^0;***it JDQ_C=P0^1;***it turn_left=P1^1;***it turn_right=P1^2;***it qianjin=P1^3;***it houtui=P1^4;u8 receivearray[100];//串口初始化函数,波特率设置为9600void 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=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; }
  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端开发
  开发环境AndroidStudio3.6。
  这里只说明一些代码的作用,详情请查看我的另一篇博客看APP开发部分。
  手机端是不需要订阅消息的,只需要按键触发发布消息就可以了,下面是相关代码。
  你可以下载最下面的源码填写你的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; }
举报

更多回帖

发帖
×
20
完善资料,
赚取积分