手机通过ESP8266(WiFi)控制stm32f103c8t6的洒水小车

 一、大致结构

        手机(通过 TCP连接 这个APP)连接esp8266,esp8266通过串口与单片机(stm32f103c8t6)进行通信,单片机通过数据解析,从而进行控制电机与舵机。

洒水小车由两个个电机分别控制行进与洒水,两个舵机分别控制行进方向与洒水方向。

二、配置代码

        1 .sep8266配置

          ESP8266是一款超低功耗的UART-WiFi 透传模块,拥有业内极富竞争力的封装尺寸和超低能耗技术,专为移动设备和物联网应用设计,可将用户的物理设备连接到Wi-Fi 无线网络上,进行互联网或局域网通信,实现联网功能。

        硬件连接

         将esp8266模块的GND、VCC、TXD、RXD、CH-PD与单片机对应引脚连接,其中TXD与RXD要反接,模块在工作时CH-PD要处于高电平状态。

        软件配置

        第一步:设置WiFi模块的工作模式

        ESP8266模块支持STA/AP/STA+AP 三种工作模式。

        由于我是用手机连接WiFi,所以应该是WiFi作为热点,设置工作模式为AP模式                    指令为    “AT+CWMODE=<mode>”

<mode>    1 STA 模式:ESP8266模块通过路由器连接互联网,手机或电脑通过互联网实现对设                      备的远程控制。

                  2 AP 模式:ESP8266模块作为热点,实现手机或电脑直接与模块通信,实现局域网无                    线控制。

                  3 STA+AP 模式:两种模式的共存模式,即可以通过互联网控制可实现无缝切换,方                     便操作。

        第二步:设置 AP 模式下的参数

        设置热点的参数 指令为“ AT+ CWSAP=<ssid>,<pwd>,<chl>,<ecn>”

其中<ssid>字符串参数,热点名称,

        <pwd>字符串参数,密码最长 64 字节 ASCII,

        <chl>通道号,

        <ecn> 加密类型  0 OPEN

                                   2 WPA_PSK

                                   3 WPA2_PSK 

                                   4 WPA_WPA2_PSK

        第三步:启动多连接   

        设置热点的连接类型(单连接或者多连接)     

        指令为“AT+ CIPMUX=<mode>”

        <mode>        0 单路连接模式

                             1 多路连接模式

        第四步:配置为服务器

         开启 server 后自动建立 server 监听,当有 client 接入会自动按顺序占用一个连接 ,            AT+ CIPMUX=1 时才能开启服务器

指令为“AT+ CIPSERVER= <mode>,<port>”

<mode> 0 关闭 server 模式

              1 开启 server 模式

<port>    端口号,缺省值为 333

WiFi模块配置代码

void esp8266_start_trans(void)
{
	//设置工作模式 1:station模式   2:AP模式  3:兼容 AP+station模式
	esp8266_send_cmd("AT+CWMODE=2","OK",100);	
	esp8266_send_cmd("AT+CWSAP=\"yeyeye\",\"12345678\",1,3","OK",100);
	esp8266_send_cmd("AT+CIPMUX=1","OK",100);
	esp8266_send_cmd("AT+CIPSERVER=1,8080","OK",100);
}

        2.串口协议接收与解析

        通过手机发送一个长度为8个十六进制数的数据(包括指令头、地址、控制指令、校验码)到单片机,单片机通过串口接收,经过解析,完成对单片机控制。

//协议接收
void ESP8266_IntGenData(u16 rec_tem)
	{
		static unsigned char rec_count = 0;//--接收计数
		static unsigned char start_rec = 0;//--贞开始

	if(rec_tem == open_cpu||rec_tem == cpu_openstatse) //判断帧头
		{	
			rec_count = 0;
			start_rec = 1;
		}
		if(start_rec == 1) 
		{ 
			receive_dat[rec_count++] = rec_tem; //接收数据
			if(rec_count == command_length) //判断数据是否接收到八位
			{
				start_rec = 0;
				rec_flag = 1;			
			}
		}
	}

        串口接收到的数据传输到协议接收函数,先判断指令头是否正确,正确则接收标志位为1,把数据保存到数组中,当接收到数据为8个时,协议解析标志位为1,进行协议解析。

        3. 电机与舵机配置      

        电机配置

        分别使用定时器3的通道3与通道4控制前进与洒水的电机

void TIM3_PWM_Init(u16 arr,u16 psc)
{      
	GPIO_InitTypeDef 			GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  	TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  			TIM_OCInitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);  //使能GPIO外设时钟使能
	                                                                     	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; //
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	 80K
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  不分频
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
	
	TIM_OC3Init(TIM3, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
	TIM_OC4Init(TIM3, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx


	TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);  //CH1预装载使能	 
	TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);  //CH2预装载使能	  

	TIM_ARRPreloadConfig(TIM3, ENABLE); //使能TIMx在ARR上的预装载寄存器
	
	TIM_Cmd(TIM3, ENABLE);  //使能TIM3


}

舵机配置

定时器2的通道1与通道2分别控制行进的舵机与洒水的舵机

void MG996_SG90_pwm_init(void)
{

	GPIO_InitTypeDef GPIO_InitStructure;   //声明一个结构体变量,用来初始化GPIO

	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//声明一个结构体变量,用来初始化定时器

	TIM_OCInitTypeDef TIM_OCInitStructure;//根据TIM_OCInitStruct中指定的参数初始化外设TIMx

	/* 开启时钟 */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);

	/*  配置GPIO的模式和IO口 */
	GPIO_InitStructure.GPIO_Pin= GPIO_Pin_0|GPIO_Pin_1;// PA0|PA1
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	//TIM3定时器初始化
	TIM_TimeBaseInitStructure.TIM_Period = 199; //PWM 频率=72000/(199+1)=36Khz//设置自动重装载寄存器周期的值
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7199;//设置用来作为TIMx时钟频率预分频值
	TIM_TimeBaseInitStructure.TIM_ClockDivision = 0;//设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;	//TIM向上计数模式
	TIM_TimeBaseInit(TIM2, & TIM_TimeBaseInitStructure);


	//PWM初始化	  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
	TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//PWM输出使能
	TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;
	TIM_OC1Init(TIM2, &TIM_OCInitStructure);
	TIM_OC2Init(TIM2,&TIM_OCInitStructure);
	//注意此处初始化时TIM_OC1Init而不是TIM_OCInit,否则会出错。因为固件库的版本不一样。
	TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);
	TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);//使能或者失能TIMx在CCR1上的预装载寄存器
	TIM_ARRPreloadConfig(TIM2,ENABLE);
	TIM_Cmd(TIM2,ENABLE);//使能或者失能TIMx外设
}

        4.红外避障

        在车头前方安装了3个红外避障模块,车子有自动行进洒水功能

//获取红外避障模块状态
char GetVoidStatus(void)
{
	char left=0,right=0,zhong=0;
	char count;
	if(bizhang_left == BARRIER_N) //左边检测到有障碍物
	{
			left = 1;
	}
	else left=0;
	
	if(bizhang_right == BARRIER_N) //右边检测到有障碍物
	{
			right = 2;
	}
	else right = 0;
	
		if(bizhang_zhong == BARRIER_N) //前方检测到有障碍物
	{
			zhong = 4;	
	}
		else zhong = 0;
	
	return left + right+zhong;
}

//红外避障处理
//处理方式:左边检测到  右转
//				 右边检测到  左转
//				 前方检测到  停止 后退 右转
//				 两边检测到  停止 后退 右转
//         没检测到    直行
void VoidRun(void)
{
	char status=7;	

				
		if(model==12)
			{
				status = GetVoidStatus();	 
			}		
	switch(status)
	{
		case VOID_1: ;
	 CarLeft(); delay_ms(1000);Cargo();
			break;
		case VOID_2:
	CarRight(); 	delay_ms(1000); Cargo();
			break;
		case VOID_3:
	CarStop();
			break;
		case VOID_4:
	CarStop();delay_ms(500);CarBack(); delay_ms(1500);CarRight();  delay_ms(1000);Cargo();
			break;
		case VOID_5:
	CarStop();delay_ms(500);CarBack(); delay_ms(1500);CarRight();  delay_ms(1000);Cargo();
			break;
		case VOID_6:
	CarStop();delay_ms(500);CarBack(); delay_ms(1500);CarRight();  delay_ms(1000);Cargo();
			break;		
		case VOID_NONE:
			Cargo();
			break;
		default: break;
	}
}

三、成品展示

 

ESP8266遥控洒水小车.zip-嵌入式文档类资源-CSDN下载

内附完整代码

  • 9
    点赞
  • 152
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 13
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

黑猫很可恶

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

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

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

打赏作者

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

抵扣说明:

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

余额充值