current position:Home>In order to make his girlfriend move, the boy not only bought a bike, but also designed an intelligent anti-theft bike lock

In order to make his girlfriend move, the boy not only bought a bike, but also designed an intelligent anti-theft bike lock

2022-05-15 04:27:50Huawei cloud developer community

Abstract : In this paper, we propose a method based on STM32 Intelligent bicycle lock with single chip microcomputer ( Horseshoe lock ) The design method of , To improve the intelligence and security level of bicycle lock .

This article is shared from Huawei cloud community 《 be based on STM32+ Hua Wei Yun IOT Designed intelligent anti-theft bicycle lock 【 Play with Huawei cloud 】》, author : DS Little dragon brother .

One 、 Preface

In recent years, with the development of national economy , Traffic congestion and environmental pollution are becoming more and more prominent , Bicycles play an important role in improving traffic and the environment . China itself is a big country using bicycles , With the development of bicycles , The scientific and technological content of bicycles is getting higher and higher , However, the problem of bicycle security is prominent . At present, most bicycle locks on the market are traditional mechanical structure car locks , No intelligence , There is an urgent need to solve . In this paper, we propose a method based on STM32 Intelligent bicycle lock with single chip microcomputer ( Horseshoe lock ) The design method of , To improve the intelligence and security level of bicycle lock .

Description of hardware options : Single chip microcomputer adopts STM32F103RCT6,GSM Module adoption SIM800C, Complete network connection 、 Data upload ,GPS Latitude and longitude analysis , Text messaging , The Internet of things platform adopts Huawei cloud IOT, As the data storage side , Bluetooth module adopts punctual atom and low power consumption BLE bluetooth , Support Bluetooth unlocking , The state of the vehicle is used ADXL345 Triaxial acceleration sensor detection , The password keyboard adopts capacitance matrix keyboard .

Two 、 Summary of design ideas

Need to design a Android mobile phone APP, It can be unlocked remotely , mobile phone APP Connect with Huawei cloud Internet of things platform , Realize remote data interaction with bicycle lock , Give orders to . Smart lock and Huawei cloud IOT The communication protocol between servers adopts MQTT agreement , mobile phone APP And Huawei cloud IOT Between servers HTTP agreement . In addition to supporting remote unlocking and locking, intelligent lock , It also supports Bluetooth unlocking and entering password to start , The design of the APP Bluetooth enabled , You can connect Bluetooth on the smart lock to unlock and close the lock , If you don't have a cell phone , You can enter the password to complete unlocking .

The status detection of the vehicle passes ADXL345 Triaxial accelerometer detection , If the vehicle is locked , If the vehicle is found to be moved, the alarm will be triggered , The buzzer in the lock will keep ringing , also SIM800C Will send SMS to the specified mobile phone number , Prompt that the vehicle may be stolen , Upload at the same time GPS Longitude and latitude to cloud server , mobile phone APP You can get the information uploaded by the smart lock on GPS Longitude and latitude , Call Baidu map to display the position of the vehicle , Convenient car search .

3、 ... and 、 Hardware selection

(1) Accelerometer sensor

ADXL345 It's a small size 、 Thin type 、 low power consumption 、 Complete triaxial accelerometer , Provide signal conditioned voltage output .

explain :CS If connected to high level, select IIC signal communication , whereas SPI signal communication .SDO( Address pins ) Connected to high level , According to the manual of the device 7 position I2C The address is 0x1D, Followed by reading / Write in (R/W), Then the write register is 0x3A, The read register is 0x3B; Connect to low level , be 7 position I2C The address is 0x53, Empathy , After following the read-write flag bit, the write register is 0xA6, The read register is 0xA7;

(2) STM32 Development board

STM32F103RCT6 The core specification is 32 position , The velocity is 72MHz, The capacity of program memory is 256KB, The type of program memory is FLASH,RAM Capacity is 48K.

(3) BLE Low power Bluetooth module

(4) SIM800C

Module features :

1、 Support limit DC5V-18V Wide voltage input

2、 There is a power enable switch pin EN

3、 Support lithium battery power supply interface VBAT3.5-4.5V

4、 Mobile input card and China Unicom support Micro SIM card

5、 send 51/STM32/ARDUINO Driver routines

1、DC 5V-18V Power input , Recommended DC 9V

2、 The power start enable pin is enabled by default

3、 Power ground

4、GSM Modular TXD The pin is connected to... Of other modules RXD

5、GSM Modular RXD The pin is connected to... Of other modules TXD

6、 Data terminal ready

7、 Core audio output pin

8、 Core audio output pin

9、 Lithium battery input pin ,DC 3.5 - 4.5V

10、 Power ground

11、 Start pin and GND Short circuit can realize startup and self start

12、 Power ground

13、RTC External battery pin

14、 Kernel ring prompt pin

15、 Internal audio input pin

16、 Core audio input pin

Bold pins are generally used .

It is recommended to use V_IN Separate power supply DC5-18V Input ( Recommended 9V), perhaps VBAT Power supply lithium battery has two power supply modes, which are the most stable . If it's just a simple debugging , You can also use USB-TTL Or development board 5V Power the module directly . However, the power of general computers or development boards is limited , It could be unstable . Please choose the right power supply according to the specific situation .

Four . mobile phone APP software design

3.1 Communication description

The upper computer and the device support communication through BLE Low power serial port for Bluetooth communication , Support to connect Huawei ECS through network for communication , mobile phone APP Send out open_lock and close_lock Realize locking and unlocking .

3.2 Build development environment

The upper computer software adopts Qt framework design ,Qt It's a cross platform C++ GUI application framework .Qt It's a 1991 Year by year Qt Company Cross platform development C++ GUI application development framework . It can develop GUI Program , It can also be used to develop non GUI Program , For example, console tools and servers . Simply speaking ,QT It can easily help you make software with interface , It doesn't even require you to put a lot of energy .

QT Official website : https://www.qt.io/

 

QT Introduction to learning practical column : https://blog.csdn.net/xiaolong1126626497/category_11400392.html

QT5.12.6 Download address :
https://download.qt.io/archive/qt/5.12/5.12.6/

 

4、 Create cloud devices

4.1 Create products

Log in to the official website : https://www.huaweicloud.com/product/iothub.html

Search the Internet of things directly , Open the page .

4.2 Custom model

4.3 Register device

Device created successfully :

{    "device_id": "6274b1d62d5e854503d3a67e_lock",    "secret": "12345678"}

4.4 MQTT Device key

After creating the product 、 After the device , Then you need to know how to pass MQTT Log in to the Huawei ECS according to the protocol .

The official details are here :
https://support.huaweicloud.com/devg-iothub/iot_01_2127.html#ZH-CN_TOPIC_0240834853__zh-cn_topic_0251997880_li365284516112

Attribute reporting format :
https://support.huaweicloud.com/api-iothub/iot_06_v5_3010.html

 

MQTT Device login key generation address :

DeviceId  6274b1d62d5e854503d3a67e_lockDeviceSecret 12345678ClientId  6274b1d62d5e854503d3a67e_lock_0_0_2022050605Username  6274b1d62d5e854503d3a67e_lockPassword  334dd7c0c10e47280880e9dd004ae0d8c5abc24dbbc9daa735315722707fe13b

4.5 Use MQTT Client software login

All the parameters have been , Next, use MQTT The client logs in to Huawei cloud for testing .
The domain name of Huawei cloud Internet of things platform is : 161a58a78.iot-mqtts.cn-north-4.myhuaweicloud.com
Of Huawei's cloud Internet of things platform IP The address is :121.36.42.100
After the parameters are filled correctly in the software , You can see that the device has been successfully connected .
Next, open the device page , You can see that the device is online .

4.6 Data reporting test

// Subscribe to topics :  The platform sends a message to the device $oc/devices/6274b1d62d5e854503d3a67e_lock/sys/messages/down// Equipment report data $oc/devices/6274b1d62d5e854503d3a67e_lock/sys/properties/report// Reported attribute message  ( Multiple attributes can be reported at a time , stay json Just add it to the ){"services": [{"service_id": "lock","properties":{"lock":1}}]}

// Subscribe to topics :  The platform sends a message to the device $oc/devices/6274b1d62d5e854503d3a67e_lock/sys/messages/down// Equipment report data $oc/devices/6274b1d62d5e854503d3a67e_lock/sys/properties/report// Reported attribute message  ( Multiple attributes can be reported at a time , stay json Just add it to the ){"services": [{"service_id": "lock","properties":{"GPS Information ":"lat:12.345,lng:45.678"}}]}

4.7 Application side development

In order to display equipment data more conveniently , Interact with the device , We also need to develop a supporting host computer , The official provides the application side development API Interface 、SDK Interface , For convenience and versatility , I'm using API Interface to complete data interaction , The upper computer software adopts QT Development .

Help document address : https://support.huaweicloud.com/api-iothub/iot_06_v5_0034.html

The device attribute is the sensor status data information uploaded by the device , The application side provides API Interface , It can actively send request instructions to the device end ; After receiving the instruction, the device needs to report the data according to the agreed data format ; therefore , To realize the data interaction between the application layer and the device side , It needs the cooperation between the application layer and the device end to complete .

5. STM32 Development

5.1 ADXL345.c

#include "app.h"/* The functionality :  Various hard initialization relay modules --DAT--->PA4PB12----- Input pin , Check whether the module is connected or disconnected */void Hardware_Init(void){    RCC->APB2ENR|=1<<2;    GPIOA->CRL&=0xFFF0FFFF;    GPIOA->CRL|=0x00030000;        RCC->APB2ENR|=1<<3;    GPIOB->CRH&=0xFFF0FFFF;    GPIOB->CRH|=0x00080000;}//////////////////////////////////////////////////////////////////////////////////// initialization ADXL345.// Return value :0, Successful initialization ;1, initialization failed .u8 ADXL345_Init(void){				  	IIC_Init();							// initialization IIC Bus 		if(ADXL345_RD_Reg(DEVICE_ID)==0XE5)	// Reading device ID	{  		ADXL345_WR_Reg(DATA_FORMAT,0X2B);	// Low level interrupt output ,13 Bit full resolution , Right alignment of output data ,16g range  		ADXL345_WR_Reg(BW_RATE,0x0A);		// The data output speed is 100Hz		ADXL345_WR_Reg(POWER_CTL,0x28);	   	// Link enable , Measurement mode 		ADXL345_WR_Reg(INT_ENABLE,0x00);	// Do not use interrupt 		 	 	ADXL345_WR_Reg(OFSX,0x00);		ADXL345_WR_Reg(OFSY,0x00);		ADXL345_WR_Reg(OFSZ,0x00);			return 0;	}				return 1;	   								  }   // Write ADXL345 register //addr: Register address //val: Value to write // Return value : nothing void ADXL345_WR_Reg(u8 addr,u8 val) {	IIC_Start();  				 	IIC_Send_Byte(ADXL_WRITE);     	// Send write device instruction 	 	IIC_Wait_Ack();	       IIC_Send_Byte(addr);   			// Send register address 	IIC_Wait_Ack(); 	 										  		   	IIC_Send_Byte(val);     		// Send value 					   	IIC_Wait_Ack();  		    	       IIC_Stop();						// Create a stop condition  	   }// read ADXL345 register //addr: Register address // Return value : The value read u8 ADXL345_RD_Reg(u8 addr) 		{	u8 temp=0;		 	IIC_Start();  				 	IIC_Send_Byte(ADXL_WRITE);	// Send write device instruction 	 	temp=IIC_Wait_Ack();	       IIC_Send_Byte(addr);   		// Send register address 	temp=IIC_Wait_Ack(); 	 										  		   	IIC_Start();  	 	   		// Restart 	IIC_Send_Byte(ADXL_READ);	// Send read device instruction 	 	temp=IIC_Wait_Ack();	       temp=IIC_Read_Byte(0);		// Read a byte , No more reading , send out NAK 	    	       IIC_Stop();					// Create a stop condition  	    	return temp;				// Return the read value }  // Read ADXL Average value //x,y,z: Read 10 Take the average value after times void ADXL345_RD_Avval(short *x,short *y,short *z){	short tx=0,ty=0,tz=0;	   	u8 i;  	for(i=0;i<10;i++)	{		ADXL345_RD_XYZ(x,y,z);		delay_ms(10);		tx+=(short)*x;		ty+=(short)*y;		tz+=(short)*z;	   	}	*x=tx/10;	*y=ty/10;	*z=tz/10;} // Auto calibration //xval,yval,zval:x,y,z Calibration value of the shaft void ADXL345_AUTO_Adjust(char *xval,char *yval,char *zval){	short tx,ty,tz;	u8 i;	short offx=0,offy=0,offz=0;	ADXL345_WR_Reg(POWER_CTL,0x00);	   	// Enter sleep mode first .	delay_ms(100);	ADXL345_WR_Reg(DATA_FORMAT,0X2B);	// Low level interrupt output ,13 Bit full resolution , Right alignment of output data ,16g range  	ADXL345_WR_Reg(BW_RATE,0x0A);		// The data output speed is 100Hz	ADXL345_WR_Reg(POWER_CTL,0x28);	   	// Link enable , Measurement mode 	ADXL345_WR_Reg(INT_ENABLE,0x00);	// Do not use interrupt 		 	ADXL345_WR_Reg(OFSX,0x00);	ADXL345_WR_Reg(OFSY,0x00);	ADXL345_WR_Reg(OFSZ,0x00);	delay_ms(12);	for(i=0;i<10;i++)	{		ADXL345_RD_Avval(&tx,&ty,&tz);		offx+=tx;		offy+=ty;		offz+=tz;	}	 			offx/=10;	offy/=10;	offz/=10;	*xval=-offx/4;	*yval=-offy/4;	*zval=-(offz-256)/4;	   	ADXL345_WR_Reg(OFSX,*xval);	ADXL345_WR_Reg(OFSY,*yval);	ADXL345_WR_Reg(OFSZ,*zval);	} // Read 3 Data of two axes //x,y,z: Data read void ADXL345_RD_XYZ(short *x,short *y,short *z){	u8 buf[6];	u8 i;	IIC_Start();  				 	IIC_Send_Byte(ADXL_WRITE);	// Send write device instruction 	 	IIC_Wait_Ack();	       IIC_Send_Byte(0x32);   		// Send register address ( The starting address of the data cache is 0X32)	IIC_Wait_Ack(); 	 										  		     	IIC_Start();  	 	   		// Restart 	IIC_Send_Byte(ADXL_READ);	// Send read device instruction 	IIC_Wait_Ack();	for(i=0;i<6;i++)	{		if(i==5)buf[i]=IIC_Read_Byte(0);// Read a byte , No more reading , send out NACK  		else buf[i]=IIC_Read_Byte(1);	// Read a byte , Continue to read , send out ACK  	}	        	       IIC_Stop();					// Create a stop condition 	*x=(short)(((u16)buf[1]<<8)+buf[0]); 	    	*y=(short)(((u16)buf[3]<<8)+buf[2]); 	    	*z=(short)(((u16)buf[5]<<8)+buf[4]); 	   }// Read ADXL345 The data of times Time , Then take the average //x,y,z: Data read //times: How many times void ADXL345_Read_Average(short *x,short *y,short *z,u8 times){	u8 i;	short tx,ty,tz;	*x=0;	*y=0;	*z=0;	if(times)// The number of reads is not 0	{		for(i=0;i<times;i++)// Read continuously times Time 		{			ADXL345_RD_XYZ(&tx,&ty,&tz);			*x+=tx;			*y+=ty;			*z+=tz;			delay_ms(5);		}		*x/=times;		*y/=times;		*z/=times;	}}// Get the angle //x,y,z:x,y,z The component of gravitational acceleration in the direction ( There is no need for units , Direct numerical value is enough )//dir: The angle to get .0, And Z The angle of the axis ;1, And X The angle of the axis ;2, And Y The angle of the axis .// Return value : Angle value . Company 0.1°.short ADXL345_Get_Angle(float x,float y,float z,u8 dir){	float temp; 	float res=0;	switch(dir)	{		case 0:// And nature Z The angle of the axis  			temp=sqrt((x*x+y*y))/z; 			res=atan(temp); 			break;		case 1:// And nature X The angle of the axis  			temp=x/sqrt((y*y+z*z)); 			res=atan(temp); 			break; 		case 2:// And nature Y The angle of the axis  			temp=y/sqrt((x*x+z*z)); 			res=atan(temp); 			break; 	}	return res*1800/3.14;}// initialization IICvoid IIC_Init(void){					         RCC->APB2ENR|=1<<3;		  // Enable peripherals first IO PORTB The clock  							 	GPIOB->CRL&=0X00FFFFFF;	//6/7  Push pull output 	GPIOB->CRL|=0X33000000;	   	GPIOB->ODR|=3<<6;     	//6,7  High output }// produce IIC Start signal void IIC_Start(void){	SDA_OUT();     //sda Line out 	IIC_SDA=1;	  	  	IIC_SCL=1;	delay_us(4); 	IIC_SDA=0;//START:when CLK is high,DATA change form high to low 	delay_us(4);	IIC_SCL=0;// Hold on I2C Bus , Ready to send or receive data  }	  // produce IIC Stop signal void IIC_Stop(void){	SDA_OUT();//sda Line out 	IIC_SCL=0;	IIC_SDA=0;//STOP:when CLK is high DATA change form low to high 	delay_us(4);	IIC_SCL=1; 	IIC_SDA=1;// send out I2C Bus end signal 	delay_us(4);							   	}// Waiting for the answer signal to arrive // Return value :1, Failed to receive response //        0, Received response successfully u8 IIC_Wait_Ack(void){	u8 ucErrTime=0;	SDA_IN();      //SDA Set to input   	IIC_SDA=1;delay_us(1);	   	IIC_SCL=1;delay_us(1);	 	while(READ_SDA)	{		ucErrTime++;		if(ucErrTime>250)		{			IIC_Stop();			return 1;		}	}	IIC_SCL=0;// Clock output 0 	   	return 0;  } // produce ACK The reply void IIC_Ack(void){	IIC_SCL=0;	SDA_OUT();	IIC_SDA=0;	delay_us(2);	IIC_SCL=1;	delay_us(2);	IIC_SCL=0;}// Do not produce ACK The reply 		    void IIC_NAck(void){	IIC_SCL=0;	SDA_OUT();	IIC_SDA=1;	delay_us(2);	IIC_SCL=1;	delay_us(2);	IIC_SCL=0;}					 				     //IIC Send a byte // Return whether the slave has a response //1, There's a response //0, No response 			  void IIC_Send_Byte(u8 txd){                            u8 t;   	SDA_OUT(); 	        IIC_SCL=0;// Pull down the clock and start data transmission     for(t=0;t<8;t++)    {                      IIC_SDA=(txd&0x80)>>7;        txd<<=1; 	  		delay_us(2);   // Yes TEA5767 All three delays are necessary 		IIC_SCL=1;		delay_us(2); 		IIC_SCL=0;			delay_us(2);    }	 } 	    // read 1 Bytes ,ack=1 when , send out ACK,ack=0, send out nACK   u8 IIC_Read_Byte(unsigned char ack){	unsigned char i,receive=0;	SDA_IN();//SDA Set to input     for(i=0;i<8;i++ )	{        IIC_SCL=0;         delay_us(2);		IIC_SCL=1;        receive<<=1;        if(READ_SDA)receive++;   		delay_us(1);     }					     if (!ack)        IIC_NAck();// send out nACK    else        IIC_Ack(); // send out ACK       return receive;}

5.2 sim800.c

#include "sim800c.h"/* The functionality : towards SIM800C Module sends instruction function parameters :				char *cmd   Orders sent 			  char *check_data  Detect the returned data and return value : 0 It means success  1 It means failure */u8 SIM800C_SendCmd(char *cmd,char *check_data){   u16 i,j;   for(i=0;i<5;i++) // Total number of tests    {      USART2_RX_FLAG=0;      USART2_RX_CNT=0;			memset(USART2_RX_BUFFER,0,sizeof(USART2_RX_BUFFER));			USARTx_StringSend(USART2,cmd); // Send instructions       for(j=0;j<500;j++) // Waiting time (ms Company )      {          if(USART2_RX_FLAG)          {              USART2_RX_BUFFER[USART2_RX_CNT]='\0';              if(strstr((char*)USART2_RX_BUFFER,check_data))              {                  return 0;              }              else break;          }          delay_ms(20); // One time       }   }   return 1;}/* function    function :GSM Module initialization detection function return value :1 Indicates that module detection failed ,0 It means success */u8 SIM800C_InitCheck(void){	  if(SIM800C_SendCmd("AT\r\n","OK"))return 1;	  else printf("SIM800 The module is OK !\r\n");	  		if(SIM800C_SendCmd("ATE0\r\n","OK"))return 2;	  else printf(" Setting module does not echo successfully !\r\n");			if(SIM800C_SendCmd("AT+CGMI\r\n","OK"))return 3;		else printf(" The name of the manufacturer was queried successfully !%s\r\n",USART2_RX_BUFFER);			if(SIM800C_SendCmd("AT+CGMM\r\n","OK"))return 4;		else printf(" The module model is queried successfully !%s\r\n",USART2_RX_BUFFER);			    DelayMs(1000);		DelayMs(1000);		if(SIM800C_SendCmd("AT+CNUM\r\n","+CNUM:"))return 5;		else printf(" Get local number successfully !%s\r\n",USART2_RX_BUFFER);	  /*  The return format is as follows :		+CNUM: "","+8613086989413",145,7,4		OK		*/		return 0;}/* function    function :GSM Module SMS mode setting function return value :0 Indicates that the module is set successfully */u8 SIM800C_SetNoteTextMode(void){		if(SIM800C_SendCmd("AT+CSCS=\"GSM\"\r\n","OK"))return 1;// "GSM" Character set 		else printf(" SMS GSM The character set is set successfully !\r\n");		  if(SIM800C_SendCmd("AT+CMGF=1\r\n","OK"))return 2; // Text mode 		else printf(" SMS text mode is set successfully !\r\n");		return 0;}/* The functionality : Send SMS function parameters :					num: Phone number 					text: The return value of the SMS content function :0 Means the delivery is successful. */u8 SIM800C_SendNote(u8 *num,u8 *text,u16 len){    char data[50];    char send_buf[2];    sprintf(data,"AT+CMGS=\"%s\"\r\n",num);    if(SIM800C_SendCmd(data,">"))return 1; // Set the mobile number to send     USARTx_DataSend(USART2,text,len);     // Send SMS content     send_buf[0] = 0x1a;    send_buf[1] = '\0';    if(SIM800C_SendCmd(send_buf,"+CMGS"))return 2; // Send end symbol     return 0;}

5.3 MQTT Information

// Equipment information of Huawei Internet of things server #define MQTT_ClientID "62381267575fb713ee164ad2_xl_1_0_0_2022032106"#define MQTT_UserName "62381267575fb713ee164ad2_xl_1"#define MQTT_PassWord "124344feff3e3d96ff6af13cf36af36766619ff1eeee40e99cbae9b7b9739fe4"// Topics subscribed and published #define SET_TOPIC  "$oc/devices/62381267575fb713ee164ad2_xl_1/sys/messages/down"  // subscribe #define POST_TOPIC "$oc/devices/62381267575fb713ee164ad2_xl_1/sys/properties/report"  // Release // Set the connected router information #define CONNECT_WIFI  "abc"   // The name of the router to be connected  -- Do not appear in Chinese 、 Special characters such as spaces #define CONNECT_PASS "1234567890"       // The password of the router to be connected #define CONNECT_SERVER_IP "a161a58a78.iot-mqtts.cn-north-4.myhuaweicloud.com"   // The server IP Address #define CONNECT_SERVER_PORT 1883            // Server port number u8 *mqtt_rxbuf;u8 *mqtt_txbuf;u16 mqtt_rxlen;u16 mqtt_txlen;u8 _mqtt_txbuf[256];// Send data buffer u8 _mqtt_rxbuf[256];// Receive data buffer typedef enum{	// name  	     value  			 Message flow direction  	 describe 	M_RESERVED1	=0	,	//	 prohibit 	 Retain 	M_CONNECT		,	//	 Client to server 	 The client requests to connect to the server 	M_CONNACK		,	//	 Service end to client 	 Connection message confirmation 	M_PUBLISH		,	//	 Both directions allow 	 Release the news 	M_PUBACK		,	//	 Both directions allow 	QoS 1 Message release received confirmation 	M_PUBREC		,	//	 Both directions allow 	 Release received ( The first step in ensuring delivery )	M_PUBREL		,	//	 Both directions allow 	 Release ( Guaranteed delivery step two )	M_PUBCOMP		,	//	 Both directions allow 	QoS 2 Message release complete ( The third step in ensuring interaction )	M_SUBSCRIBE		,	//	 Client to server 	 Client subscription request 	M_SUBACK		,	//	 Service end to client 	 Subscription request message confirmation 	M_UNSUBSCRIBE	,	//	 Client to server 	 Client unsubscribe request 	M_UNSUBACK		,	//	 Service end to client 	 Unsubscribe message confirmation 	M_PINGREQ		,	//	 Client to server 	 Heartbeat request 	M_PINGRESP		,	//	 Service end to client 	 Heartbeat response 	M_DISCONNECT	,	//	 Client to server 	 Client disconnected 	M_RESERVED2		,	//	 prohibit 	 Retain }_typdef_mqtt_message;// The connection was successful and the server responded  20 02 00 00// The client actively disconnects  e0 00const u8 parket_connetAck[] = {0x20,0x02,0x00,0x00};const u8 parket_disconnet[] = {0xe0,0x00};const u8 parket_heart[] = {0xc0,0x00};const u8 parket_heart_reply[] = {0xc0,0x00};const u8 parket_subAck[] = {0x90,0x03};void MQTT_Init(void){    // Buffer assignment 	mqtt_rxbuf = _mqtt_rxbuf;    mqtt_rxlen = sizeof(_mqtt_rxbuf);	mqtt_txbuf = _mqtt_txbuf;    mqtt_txlen = sizeof(_mqtt_txbuf);	memset(mqtt_rxbuf,0,mqtt_rxlen);	memset(mqtt_txbuf,0,mqtt_txlen);		// Unconditional active disconnection first 	MQTT_Disconnect();    delay_ms(100);	MQTT_Disconnect();    delay_ms(100);}/* The functionality :  The return value of the login server function : 0 It means success  1 It means failure */u8 MQTT_Connect(char *ClientID,char *Username,char *Password){    u8 i,j;    int ClientIDLen = strlen(ClientID);    int UsernameLen = strlen(Username);    int PasswordLen = strlen(Password);    int DataLen;	mqtt_txlen=0;	// Variable header +Payload   Each field contains a length identifier of two bytes     DataLen = 10 + (ClientIDLen+2) + (UsernameLen+2) + (PasswordLen+2);		// Fixed header 	// Control message type     mqtt_txbuf[mqtt_txlen++] = 0x10;		//MQTT Message Type CONNECT	// Residual length ( Not including fixed head )	do	{		u8 encodedByte = DataLen % 128;		DataLen = DataLen / 128;		// if there are more data to encode, set the top bit of this byte		if ( DataLen > 0 )			encodedByte = encodedByte | 128;		mqtt_txbuf[mqtt_txlen++] = encodedByte;	}while ( DataLen > 0 );    		// Variable header 	// The name of the agreement     mqtt_txbuf[mqtt_txlen++] = 0;        	// Protocol Name Length MSB        mqtt_txbuf[mqtt_txlen++] = 4;           // Protocol Name Length LSB        mqtt_txbuf[mqtt_txlen++] = 'M';        	// ASCII Code for M        mqtt_txbuf[mqtt_txlen++] = 'Q';        	// ASCII Code for Q        mqtt_txbuf[mqtt_txlen++] = 'T';        	// ASCII Code for T        mqtt_txbuf[mqtt_txlen++] = 'T';        	// ASCII Code for T    	// Agreement level     mqtt_txbuf[mqtt_txlen++] = 4;        		// MQTT Protocol version = 4    about  3.1.1  Version of the agreement , The value of the protocol level field is  4(0x04)   	// Connection sign     mqtt_txbuf[mqtt_txlen++] = 0xc2;        	// conn flags     mqtt_txbuf[mqtt_txlen++] = 0;        		// Keep-alive Time Length MSB        mqtt_txbuf[mqtt_txlen++] = 100;        	// Keep-alive Time Length LSB  100S Heartbeat bag      Time to live 	    mqtt_txbuf[mqtt_txlen++] = BYTE1(ClientIDLen);// Client ID length MSB        mqtt_txbuf[mqtt_txlen++] = BYTE0(ClientIDLen);// Client ID length LSB  		memcpy(&mqtt_txbuf[mqtt_txlen],ClientID,ClientIDLen);    mqtt_txlen += ClientIDLen;        if(UsernameLen > 0)    {           mqtt_txbuf[mqtt_txlen++] = BYTE1(UsernameLen);		//username length MSB            mqtt_txbuf[mqtt_txlen++] = BYTE0(UsernameLen);    	//username length LSB    		memcpy(&mqtt_txbuf[mqtt_txlen],Username,UsernameLen);        mqtt_txlen += UsernameLen;    }        if(PasswordLen > 0)    {            mqtt_txbuf[mqtt_txlen++] = BYTE1(PasswordLen);		//password length MSB            mqtt_txbuf[mqtt_txlen++] = BYTE0(PasswordLen);    	//password length LSB  		memcpy(&mqtt_txbuf[mqtt_txlen],Password,PasswordLen);        mqtt_txlen += PasswordLen;     }    memset(mqtt_rxbuf,0,mqtt_rxlen);    MQTT_SendBuf(mqtt_txbuf,mqtt_txlen);    for(j=0;j<10;j++)    {        delay_ms(50);        if(USART2_RX_FLAG)        {            memcpy((char *)mqtt_rxbuf,USART2_RX_BUFFER,USART2_RX_CNT);                        //memcpy                        for(i=0;i<USART2_RX_CNT;i++)printf("%#x ",USART2_RX_BUFFER[i]);                        USART2_RX_FLAG=0;            USART2_RX_CNT=0;        }        //CONNECT        if(mqtt_rxbuf[0]==parket_connetAck[0] && mqtt_rxbuf[1]==parket_connetAck[1]) // Successful connection 			           {            return 0;// Successful connection         }    }    	return 1;}/* The functionality : MQTT subscribe / Unsubscribe data packaging function parameters :    topic        The theme        qos          Message level  0: Distribute at most once   1:  Distribute at least once   2:  Distribute only once     whether      subscribe / Unsubscribe request package  (1 To subscribe to ,0 Means unsubscribe ) Return value : 0 It means success  1 It means failure */u8 MQTT_SubscribeTopic(char *topic,u8 qos,u8 whether){        u8 i,j;	mqtt_txlen=0;    int topiclen = strlen(topic);		int DataLen = 2 + (topiclen+2) + (whether?1:0);// Variable header length (2 byte ) Plus the length of the payload 	// Fixed header 	// Control message type     if(whether)mqtt_txbuf[mqtt_txlen++] = 0x82; // Message type and flag subscription     else	mqtt_txbuf[mqtt_txlen++] = 0xA2;    // Unsubscribe 	// Residual length 	do	{		u8 encodedByte = DataLen % 128;		DataLen = DataLen / 128;		// if there are more data to encode, set the top bit of this byte		if ( DataLen > 0 )			encodedByte = encodedByte | 128;		mqtt_txbuf[mqtt_txlen++] = encodedByte;	}while ( DataLen > 0 );			// Variable header     mqtt_txbuf[mqtt_txlen++] = 0;			// Message identifier  MSB    mqtt_txbuf[mqtt_txlen++] = 0x0A;        // Message identifier  LSB	// Payload     mqtt_txbuf[mqtt_txlen++] = BYTE1(topiclen);// Theme length  MSB    mqtt_txbuf[mqtt_txlen++] = BYTE0(topiclen);// Theme length  LSB   	memcpy(&mqtt_txbuf[mqtt_txlen],topic,topiclen);    mqtt_txlen += topiclen;        if(whether)    {       mqtt_txbuf[mqtt_txlen++] = qos;//QoS Level     }        for(i=0;i<10;i++)    {        memset(mqtt_rxbuf,0,mqtt_rxlen);		MQTT_SendBuf(mqtt_txbuf,mqtt_txlen);        for(j=0;j<10;j++)        {            delay_ms(50);            if(USART2_RX_FLAG)			{                memcpy((char *)mqtt_rxbuf,(char*)USART2_RX_BUFFER,USART2_RX_CNT);				USART2_RX_FLAG=0;				USART2_RX_CNT=0;			}						if(mqtt_rxbuf[0]==parket_subAck[0] && mqtt_rxbuf[1]==parket_subAck[1]) // Subscription succeeded 			   			{				return 0;// Subscription succeeded 			}        }    }	return 1; // Failure }//MQTT Publish data packaging functions //topic    The theme  //message  news //qos      Message level  u8 MQTT_PublishData(char *topic, char *message, u8 qos){      int topicLength = strlen(topic);        int messageLength = strlen(message);         static u16 id=0;	int DataLen;	mqtt_txlen=0;	// The length of the payload is calculated like this : Subtract the length of the variable header from the value of the remaining length field in the fixed header 	//QOS by 0 There is no identifier 	// Data length               topic name     Message identifier     Payload     if(qos)	DataLen = (2+topicLength) + 2 + messageLength;           else	DataLen = (2+topicLength) + messageLength;       // Fixed header 	// Control message type     mqtt_txbuf[mqtt_txlen++] = 0x30;    // MQTT Message Type PUBLISH  	// Residual length 	do	{		u8 encodedByte = DataLen % 128;		DataLen = DataLen / 128;		// if there are more data to encode, set the top bit of this byte		if ( DataLen > 0 )			encodedByte = encodedByte | 128;		mqtt_txbuf[mqtt_txlen++] = encodedByte;	}while ( DataLen > 0 );		    mqtt_txbuf[mqtt_txlen++] = BYTE1(topicLength);// Theme length MSB    mqtt_txbuf[mqtt_txlen++] = BYTE0(topicLength);// Theme length LSB 	memcpy(&mqtt_txbuf[mqtt_txlen],topic,topicLength);// Copy the theme     mqtt_txlen += topicLength;        	// Message identifier     if(qos)    {        mqtt_txbuf[mqtt_txlen++] = BYTE1(id);        mqtt_txbuf[mqtt_txlen++] = BYTE0(id);        id++;    }	memcpy(&mqtt_txbuf[mqtt_txlen],message,messageLength);    mqtt_txlen += messageLength;        	MQTT_SendBuf(mqtt_txbuf,mqtt_txlen);    return mqtt_txlen;}

More learning , Please pay attention to IoT Internet of things community , Add Huawei cloud IoT Little assistant micro signal (hwc-iot), reply “ read ” Get more information

 

Click to follow , The first time to learn about Huawei's new cloud technology ~

copyright notice
author[Huawei cloud developer community],Please bring the original link to reprint, thank you.
https://caren.inotgo.com/2022/131/202205111423153061.html

Random recommended