当前位置:   article > 正文

硬件篇:基于微信小程序的智能分类垃圾桶(详细介绍)_esb8266智能能垃圾桶

esb8266智能能垃圾桶

硬件选择

因为我们需要实现的主要功能是控制四个垃圾桶的开合,所以舵机是必不可少的,至于用什么来控制舵机,我直接就选择了51单片机(因为我只学了51),明确了主要的硬件,进一步细化目标,用微信小程序通过云平台发送请求,51这边接收返回数据进行处理后控制舵机。网络这里我直接选用了我稍微了解一点的esp8266wifi模块,云平台经过与写小程序的同学商量决定采用容易上手的乐联网,这样一来,整个作品硬件选用思路就明确了!

硬件清单及部分图片展示

黑体为主要元件,非黑体为供电元件,可自行更换选择!!
DIY专用小垃圾桶
51单片机最小系统板
SG90舵机9g180度四个
ESP8266-12F WiFi模块

面包板+面包板电源模块
聚合物锂电池+LM2596降压模块(用于给舵机单独供电)
DC头12V1.5A电源适配器
公对母、母对母、公对公杜绑线若干
在这里插入图片描述
在这里插入图片描述

硬件连接示意图

注意:根据ESP8266用户手册要求,该模块工作电压为3.3V,同时EN置高点平。
在这里插入图片描述

乐联网设置流程

乐联网注册登录问题就不在这里赘述了,CSDN也有很多优秀的博客可以参考。注册登录后你只需要知道你的Userkey和网关号即可,因为任务中我们是要通过乐联网实现对51单片机的反向控制,所以选用了乐联网的服务器发送数据串给客户端的通信方式,具体流程可以参考乐联网官网给的指南或者下面的截图,应乐联网的要求你必须每隔40s向服务器发送一次登录信息以保证与服务器的正常连接,小程序发出请求后乐联网会返回字符串给客户端,此时客户端需要解析数据选择指定的舵机控制其转动,具体解析方法见程序部分。

{"method": "update","gatewayNo": "你的网关号","userkey": "你的userkey"}&^!  //登录信息
{"method":"send","gatewayNo":"你的网关号","userkey":"你的userkey","f":"updateSensor","p1":"约定的控制参数"}&^! //服务器返回的数据
  • 1
  • 2

在这里插入图片描述

单片机程序编写

根据此次任务要求,我们需要通过ESP8266WiFi模块与51单片机串口通信控制四路舵机,因为使用51控制四路舵机转动并不难,程序源码中也加了相关注释,对此我不做过多解释。这里我主要介绍51与WiFi模块串口通信、51定时40秒发送登录信息和51解析收到的数据部分。
串口通信时受51串口打印的限制,我们需要自己写打印函数,否则无法使用printf()进行打印,类似的博客在CSDN也有很多可以参考,下面是我的代码:

void sendChar(u8 a) //单片机发送一个字节
{
        SBUF = a;
        while(TI==0);
        TI=0;        
}
void sendString(u8 *s)   //发送一个字符串
{
        while(*s!='\0')
        {
                sendChar(*s);
                s++;
        }        
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

这样一来sendString()就成了我新定义的打印函数用于串口打印字符串。
51定时40秒发送登录信息乐联网要求我们每隔40s发送一次登录信息,这里我用了51的T2定时器精确定时40秒,据我了解我的STC89C52RC是有三个定时器的,可能有一些只有两个,那就难受了啊。。为控制文章篇幅,这里的代码我会在文章末尾统一展示。
服务器返回的字符串的解析,我定义了一个全局变量的数组来存放,寄存器接收后放进数组,根据与小程序方面的约定,我们取!为一个字符串的结束标志,取下标为103的字符来控制舵机的选择。在中断里加了标志位,让舵机选择在主程序中完成以保证中断的正常运行,代码及部分注释:

void Usart() interrupt 4//串口通信中断函数
{
	if(RI==1) //接收完一帧数据
	{
		RI=0;//清除接收中断标记位
		dat=SBUF;      //出去接收到的数据   收到的数据放入receivedata[120]用于待解析
		receivedata[k]=dat;
		if(receivedata[k]=='!')  //收到标志位
		{
			k=0;
			X=receivedata[103];  //X为全局变量,将取得字符赋给他
			flag=1;  //接收完成标记位
		}else{
			k++;
		}
		}
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

主程序利用标志位减少在中断里的程序执行代码

void main(void)
{
	ConfigTimer0();//配置定时器0
	next=0;
	isSend=0;
	time2_init();
	UsartInit();	  //串口初始化
	while(1)
	{
		if(isSend==0){   //标志位
			led=0;
		}else{
			led=1;
			isSend=0;
			sendString("{\"method\":\"update\",\"gatewayNo\":\"02\",\"userkey\":\"30e217750d7e48008d8595105a14df2d\"}&^!");    //登录信息
		}
		
		if(flag==0) //标志位
		{
			led1=0;
		}else{
			led1=1;
			flag=0;
			sendString("{\"method\":\"response\",\"result\":{\"successful\":true,\"message\":\"Write serial successful 0\"}}&^!");
			dj_control();
			DJ_turn();
			X='4';
			receivedata[103]=0;
		}
		if( dj_select != 0)
			{
			dj_select = 0;	
			}
   }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

硬件安装及部分细节

因为材料原因,所有的硬件的连接我都只用了热熔胶固定,需要注意的一点是舵机的固定,我尝试了很多方法后采用的也是热熔胶固定,具体看图。两个LED是为了我能更直观确定数据的收发情况,可以以省略。
在这里插入图片描述

成品展示

更多成品展示参见我的上一篇博文:博文地址!!
在这里插入图片描述

总结反思

回想这次的制作过程可真是太难了,因为51是自学的,所以为了解决定时发送登录信息的问题吃饭都不香了!!数据解析实现控制也颇费了些力气,过程中请教了物联网学长很多问题,也得到了他的很多帮助,在这里还是想再说一句谢谢!最终经过近10天的时间成功实现了预期的效果,虽然没能在比赛中获奖,但这也是我的一次经历,一次提升我的过程。老师和同学的肯定是我继续学习硬件的动力之一。在这里我将我的经历一一记录下来,供小伙伴们参考,希望和你们一起进步。
工程文件自取地址:
链接:https://pan.baidu.com/s/1Hus4Ltfjs3GjgBsKvumlEA
提取码:7m0f
在这里插入图片描述

程序源码展示

#include <reg52.h>
#include <intrins.h>
#include <stdio.h>
#include <string.h>
 
typedef unsigned int u16;	      //数据类型声明
typedef unsigned char u8;
 
 sbit pwm1 = P0^0;
 sbit pwm2 = P0^1;
 sbit pwm3 = P0^2;
 sbit pwm4 = P0^3;
 sbit led=P2^0;
 sbit led1=P2^1;

 unsigned char count=0,dat;
unsigned char receivedata[120];     //变量数组存放数据
unsigned char  jd=20;
unsigned int i=0,k=0;  			
int dj_select=0;	//舵机选择(全局变量)
int next=0,isSend=0,flag=0;
char X='4';

void delay_ms(unsigned int z)//毫秒级延时
{
	unsigned int i,j;
	for(j=z;j>0;j--)
	for(i=112;i>0;i--);
}
void sendChar(u8 a) //单片机发送一个字节
{
        SBUF = a;
        while(TI==0);
        TI=0;        
}
void sendString(u8 *s)   //发送一个字符串
{
        while(*s!='\0')
        {
                sendChar(*s);
                s++;
        }        
}

void UsartInit(void)		//	串口初始化,定时器1
{
	SCON=0X50;			//设置为模式1
	PCON|=0X80;
	TMOD|=0X20;
	TH1=0XFA;				//计数器初始值设置
	TL1=0XFA;
	ES=1;						//打开接收中断,修改为0测试
	ET1 = 0;    //禁止定时器1中断
	EA=1;						//总中断
	TR1=1;					//打开计数器1
}

void ConfigTimer0()//配置并启动T0,0.1ms-T0定时时间 
{
  TMOD=0X01;//定时器
	TH0=(65536-100)/256;	  
	TL0=(65536-100)%256;
	ET0= 1;					
	TR0= 1;//打开计数器
	EA=1;
}

void time2_init() //配置定时器2
	{
	TH2=0x4C;   //50ms
  TL2=0x00;
	T2CON=0;
	T2MOD=0;
	EA=1;
	ET2=1;
	TR2=1;
} 


void pwm_Servomoto(void)//PWM信号产生控制舵机 
{  
		if(dj_select==1)//选择哪个舵机转动
		{
			if(count<=jd)
				pwm1=1;
			else 
					pwm1=0;
			if(count>=200)
			{
				count=0;
			}
		}
		else if(dj_select==2)
		{
			if(count<=jd)
				pwm2=1;
			else 
					pwm2=0;
			if(count>=200)
			{
				count=0;
			}
		}
		else if(dj_select==3)
		{
			if(count<=jd)
				pwm3=1;
			else 
					 pwm3=0;
			if(count>=200)
			{
				count=0;
			}
		}
		else if(dj_select==4)
		{
			if(count<=jd)
				pwm4=1;
			else 
					 pwm4=0;
			if(count>=200)
			{
				count=0;
			}
		}

}

void DJ_turn()     //舵机转动控制
{
	if(dj_select==1) 
	{
			jd=10;
			delay_ms(2500);
			jd=20;	
			delay_ms(1000);
	}
		if(dj_select==2) 
		{
			jd=10;
			delay_ms(2500);
			jd=20;	
			delay_ms(1000);
		}
   if(dj_select==3) 
			{
			jd=10;
			delay_ms(2500);
			jd=20;	
			delay_ms(1000);
		}
		if(dj_select==4) 
		{
			jd=10;
			delay_ms(2500);
			jd=20;	
			delay_ms(1000);
		}

}

void dj_control()   //根据解析函数的值判断
{
	if(X=='0')
	  {
		  dj_select = 1;
	  }
	if(X=='1')
		{
			dj_select = 2;
		}
	if(X=='2')
			{
			dj_select = 3;
			}
	if(X=='3')
		{
			dj_select = 4;
	}
}



void time1() interrupt 1   using 2//TIMER1中断服务子函数产生PWM信号
{	
   TH0=(65536-100)/256;	  //0.1ms
	 TL0=(65536-100)%256;		
	 count++;
	 pwm_Servomoto();
 }

 void time2() interrupt 5  //控制发送登录信息
	{
		TH2=0X4C;	  //初值为50ms
	  TL2=0X00;	
		next+=1;
		if(next>800){
			isSend=1;
			next=0;
		}
		TF2=0;
}

 

void Usart() interrupt 4//串口通信中断函数
{
	if(RI==1) //接收完一帧数据
	{
		RI=0;//清除接收中断标记位
		dat=SBUF;      //出去接收到的数据   收到的数据放入receivedata[120]用于待解析
		receivedata[k]=dat;
		if(receivedata[k]=='!')  //收到标志位
		{
			k=0;
			X=receivedata[103];
			flag=1;  //接收完成标记位
		}else{
			k++;
		}
		}
	}

void main(void)
{
	ConfigTimer0();//配置定时器0
	next=0;
	isSend=0;
	time2_init();
	UsartInit();	  //串口初始化
	while(1)
	{
		if(isSend==0){
			led=0;
		}else{
			led=1;
			isSend=0;
			sendString("{\"method\":\"update\",\"gatewayNo\":\"02\",\"userkey\":\"30e217750d7e48008d8595105a14df2d\"}&^!");    //登录信息
		}
		
		if(flag==0)
		{
			led1=0;
		}else{
			led1=1;
			flag=0;
			sendString("{\"method\":\"response\",\"result\":{\"successful\":true,\"message\":\"Write serial successful 0\"}}&^!");
			dj_control();
			DJ_turn();
			X='4';
			receivedata[103]=0;
		}
		if( dj_select != 0)
			{
			dj_select = 0;	
			}
   }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/560171
推荐阅读
相关标签
  

闽ICP备14008679号