今年的中央一号文件提出,“持续实施数字乡村发展行动,发展智慧农业”。近年来,物联网、大数据、人工智能等技术在农业领域深入应用,促进农业生产更便捷、管理更高效,智能农业监控系统。基于STM32H7S7智慧工农业控制台通过STM32H7S7嵌入式系统结合各种传感器、执行器和通信模块,实现对农田环境的实时监测、自动控制和数据传输。所需要的器件:
4G模块:移远EC800 WiFi:EWM3080
土壤传感器可以同时测量土壤温度、土壤体积含水量和土壤电导率三项参数,通过RS485 modbus 与STM32H7S7进行通信。
首先基于STM32H7S78-DK强大的GUI显示能力, 作为看板和控制台,实时监测农业各种参数,控规按键进行远程遥控。基于Freertos和touchGFX搭建物联网边缘控制台,通过4G或者WiFi读取传感器参数,实时显示。TouchGFX生态链工具支持全系列STM32 MCU,能够最大化发挥STM32H7RS内置的硬件图形优化器性能,并且通过“所见即所得”的开发界面,自动生成代码,让用户使用起来非常的简单且高效。TouchGFX Core提供了性能测量信号,通过与STM32CubeMX配置的GPIO同步,可以实现对渲染时间等指标的可视化。在生成器中,GPIO类的函数被用于响应这些信号。
STM32H7S78的LTDC+DMA2D性能,100Hz以上无压力,刷800*480图片和色块仅需2ms一张,实现了更多的动画效果以及性能优化,把CPU从图形任务中释放出来,低功耗,少存储,具有更高的GUI性能,可实现平滑而丰富的图形效果。
物接入(IoT Hub)是面向物联网领域开发者的全托管云服务,通过主流的物联网协议(如 MQTT)通讯,可以在智能设备与云端之间建立安全的双向连接,快速实现物联网项目。物接入分为设备型(原物管理)和数据型两种项目类型。设备型适用于基于设备的物联网场景;数据型适用于基于数据流的物联网场景。利用物接入来作为搭建物联网应用的第一步,支持亿级并发连接和消息数,支持海量设备与云端安全可靠的双向连接,无缝对接阿里云,华为云,或者百度天工平台和百度智能云。
框架:
物模型:物模型由一个或多个属性构成,可以用他来表示一类(或同一型号的一批)设备。基于物模型可以创建物影子。
MQTT(Message Queuing Telemetry Transport)是一个基于二进制消息的客户端服务端架构的发布/订阅(Publish/Subscribe)模式的消息传输协议,最早由
IBM 提出的,如今已经业界通行规范,更符合机器与机器的通信(M2M)以及物联网环境(IoT)。
MQTT 关键代码:
#include "mqtt.h"
#include "stdlib.h"
#include "string.h"
_MQTT_INFO mqtt_info;
/*******************************************************************************
* Function Name : Mqtt_Init
* Description : MQTT³õʼ»¯
* Input : keep_time ±£»îʱ¼ä
Data_Send ·¢Ëͻص÷
Data_Recv ½ÓÊջص÷
* Output : None
* Return : None
* Note : None
*******************************************************************************/
void Mqtt_Init(uint16_t keep_time,void (*Data_Send)(u8 *databuff, u16 len),void (*Data_Recv)(u8 *databuff, u16 len))
{
mqtt_info.keep_live_time = keep_time;
mqtt_info.mqtt_Data_Send = Data_Send;
mqtt_info.mqtt_Data_Recv = Data_Recv;
}
/*******************************************************************************
* Function Name : Mqtt_Connect
* Description : MQTTÁ¬½Ó±¨ÎÄ
* Input : client_id ¿Í»§¶ËID
usr_name ̞
passward ÃÜÂë
* Output : None
* Return : None
* Note : None
*******************************************************************************/
void Mqtt_Connect(char *client_id, char *usr_name, char *passward)
{
int temp,Remaining_len;
u16 Fixed_len,Variable_len,Payload_len;
u16 client_id_len,usr_name_len,passward_len;
uint8_t *buff;
//Êý¾Ý»º³åÇøÖ¸Õë
buff = mqtt_info.TX_Buff;
client_id_len = strlen(client_id);
usr_name_len = strlen(usr_name);
passward_len = strlen(passward);
Fixed_len = 1; //Á¬½Ó±¨ÎÄÖУ¬¹Ì¶¨±¨Í·³¤¶ÈÔÝʱÏÈ=1
Variable_len = 10; //Á¬½Ó±¨ÎÄÖУ¬¿É±ä±¨Í·³¤¶È=10
Payload_len = 2 + client_id_len + 2 + usr_name_len + 2 + passward_len; //Á¬½Ó±¨ÎÄÖУ¬¸ºÔس¤¶È
Remaining_len = Variable_len + Payload_len; //Ê£Ó೤¶È=¿É±ä±¨Í·³¤¶È+¸ºÔس¤¶È
*buff++ = MSG_MQTT_CONN; //¹Ì¶¨±¨Í·µÚ1¸ö×Ö½Ú £º¹Ì¶¨0x10
do{ //Ñ»·´¦Àí¹Ì¶¨±¨Í·ÖеÄÊ£Ó೤¶È×Ö½Ú£¬×Ö½ÚÁ¿¸ù¾ÝÊ£Óà×Ö½ÚµÄÕæʵ³¤¶È±ä»¯
temp = Remaining_len%128; //Ê£Ó೤¶ÈÈ¡Óà128
Remaining_len = Remaining_len/128; //Ê£Ó೤¶ÈÈ¡Õû128
if(Remaining_len>0)
temp |= 0x80; //°´ÐÒéÒªÇóλ7ÖÃλ
*buff++ = temp; //Ê£Ó೤¶È×ֽڼǼһ¸öÊý¾Ý
Fixed_len++; //¹Ì¶¨±¨Í·×ܳ¤¶È+1
}while(Remaining_len>0); //Èç¹ûRemaining_len>0µÄ»°£¬ÔٴνøÈëÑ»·
*buff++ = 0x00; //¿É±ä±¨Í·µÚ1¸ö×Ö½Ú £º¹Ì¶¨0x00
*buff++ = 0x04; //¿É±ä±¨Í·µÚ2¸ö×Ö½Ú £º¹Ì¶¨0x04
*buff++ = 0x4D; //¿É±ä±¨Í·µÚ3¸ö×Ö½Ú £º¹Ì¶¨0x4D--M
*buff++ = 0x51; //¿É±ä±¨Í·µÚ4¸ö×Ö½Ú £º¹Ì¶¨0x51--Q
*buff++ = 0x54; //¿É±ä±¨Í·µÚ5¸ö×Ö½Ú £º¹Ì¶¨0x54--T
*buff++ = 0x54; //¿É±ä±¨Í·µÚ6¸ö×Ö½Ú £º¹Ì¶¨0x54--T
*buff++ = 0x04; //¿É±ä±¨Í·µÚ7¸ö×Ö½Ú £º¹Ì¶¨0x04,ÐÒ鼶±ð
*buff++ = 0xC2; //¿É±ä±¨Í·µÚ8¸ö×Ö½Ú £ºÊ¹ÄÜÓû§ÃûºÍÃÜÂëУÑ飬²»Ê¹ÓÃÒÅÖö£¬²»±£Áô»á»°
*buff++ = mqtt_info.keep_live_time/256; //¿É±ä±¨Í·µÚ9¸ö×Ö½Ú £º±£»îʱ¼ä¸ß×Ö½Ú
*buff++ = mqtt_info.keep_live_time%256; //¿É±ä±¨Í·µÚ10¸ö×Ö½Ú£º±£»îʱ¼ä¸ß×Ö½Ú
//¿Í»§¶ËID
*buff++ = client_id_len/256; //¿Í»§¶ËID³¤¶È¸ß×Ö½Ú
*buff++ = client_id_len%256; //¿Í»§¶ËID³¤¶ÈµÍ×Ö½Ú
memcpy(buff,client_id,client_id_len); //¸´ÖÆ¿Í»§¶ËID
buff += client_id_len;
//̞
*buff++ = usr_name_len/256; //Óû§Ãû³¤¶È¸ß×Ö½Ú
*buff++ = usr_name_len%256; //Óû§Ãû³¤¶ÈµÍ×Ö½Ú
memcpy(buff,usr_name,usr_name_len); //¸´ÖÆÓû§Ãû
buff += usr_name_len;
//ÃÜÂë
*buff++ = passward_len/256; //ÃÜÂ볤¶È¸ß×Ö½Ú
*buff++ = passward_len%256; //ÃÜÂ볤¶ÈµÍ×Ö½Ú
memcpy(buff,passward,passward_len); //¸´ÖƹýÀ´ÃÜÂë×Ö´®
buff += passward_len;
//·¢ËÍÊý¾Ý
if(mqtt_info.mqtt_Data_Send != NULL)
mqtt_info.mqtt_Data_Send(mqtt_info.TX_Buff,Fixed_len + Variable_len + Payload_len);
}
/*******************************************************************************
* Function Name : Mqtt_DisConnect
* Description : MQTT¶Ï¿ªÁ¬½Ó
* Input : None
* Output : None
* Return : None
* Note : None
*******************************************************************************/
void Mqtt_DisConnect(void)
{
uint8_t *buff;
//Êý¾Ý»º³åÇøÖ¸Õë
buff = mqtt_info.TX_Buff;
*buff++ = MSG_MQTT_DISCONN; //¹¦ÄÜÂë
*buff++ = 0x00;
//·¢ËÍÊý¾Ý
if(mqtt_info.mqtt_Data_Send != NULL)
mqtt_info.mqtt_Data_Send(mqtt_info.TX_Buff,2);
}
/*******************************************************************************
* Function Name : Mqtt_Ping
* Description : MQTTÐÄÌø
* Input : None
* Output : None
* Return : None
* Note : None
*******************************************************************************/
void Mqtt_Ping(void)
{
uint8_t *buff;
//Êý¾Ý»º³åÇøÖ¸Õë
buff = mqtt_info.TX_Buff;
*buff++ = MSG_MQTT_PING; //¹¦ÄÜÂë
*buff++ = 0x00;
//·¢ËÍÊý¾Ý
if(mqtt_info.mqtt_Data_Send != NULL)
mqtt_info.mqtt_Data_Send(mqtt_info.TX_Buff,2);
}
/*******************************************************************************
* Function Name : Mqtt_PingAck
* Description : MQTTÐÄÌøÓ¦´ð,·þÎñ¶Ëµ÷ÓÃ
* Input : None
* Output : None
* Return : None
* Note : None
*******************************************************************************/
void Mqtt_PingAck(void)
{
uint8_t *buff;
//Êý¾Ý»º³åÇøÖ¸Õë
buff = mqtt_info.TX_Buff;
*buff++ = MSG_MQTT_PING_ACK; //¹¦ÄÜÂë
*buff++ = 0x00;
//·¢ËÍÊý¾Ý
if(mqtt_info.mqtt_Data_Send != NULL)
mqtt_info.mqtt_Data_Send(mqtt_info.TX_Buff,2);
}
/*******************************************************************************
* Function Name : Mqtt_Subscribe
* Description : SUBSCRIBE¶©ÔÄtopic±¨ÎÄ
* Input : topic_name£º¶©ÔÄtopic±¨ÎÄÃû³Æ PackID ±¨Îıêʶ·û(°üºÅ)
QoS£º¶©Ôĵȼ¶
* Output : None
* Return : None
* Note : None
*******************************************************************************/
void Mqtt_Subscribe(char *topic_name, uint16_t PackID, uint8_t QoS)
{
int temp,Remaining_len;
u16 topic_len,pack_len,Variable_len,Payload_len;
uint8_t *buff;
//Êý¾Ý»º³åÇøÖ¸Õë
buff = mqtt_info.TX_Buff;
//Ö÷Ìⳤ¶È
topic_len = strlen(topic_name);
Variable_len = 2; //SUBSCRIBE±¨ÎÄÖÐ,±¨Îıêʶ·û³¤¶È,¹Ì¶¨Îª2
Payload_len = 2 + strlen(topic_name) + 1; //¼ÆËãÓÐЧ¸ººÉ³¤¶È = 2×Ö½Ú(topic_name³¤¶È)+ topic_name×Ö·û´®µÄ³¤¶È + 1×Ö½Ú·þÎñµÈ¼¶
Remaining_len = Variable_len + Payload_len; //Ê£Ó೤¶È
*buff++ = MSG_MQTT_SUBSCRIBE; //µÚ1¸ö×Ö½Ú £º¹Ì¶¨0x82
do{ //Ñ»·´¦Àí¹Ì¶¨±¨Í·ÖеÄÊ£Ó೤¶È×Ö½Ú£¬×Ö½ÚÁ¿¸ù¾ÝÊ£Óà×Ö½ÚµÄÕæʵ³¤¶È±ä»¯
temp = Remaining_len%128; //Ê£Ó೤¶ÈÈ¡Óà128
Remaining_len = Remaining_len/128; //Ê£Ó೤¶ÈÈ¡Õû128
if(Remaining_len>0)
temp |= 0x80; //°´ÐÒéÒªÇóλ7ÖÃλ
*buff++ = temp; //Ê£Ó೤¶È×ֽڼǼһ¸öÊý¾Ý
}while(Remaining_len>0); //Èç¹ûRemaining_len>0µÄ»°£¬ÔٴνøÈëÑ»·
*buff++ = PackID/256; //±¨Îıêʶ·û¸ß×Ö½Ú,°üºÅ
*buff++ = PackID%256; //±¨Îıêʶ·ûµÍ×Ö½Ú,°üºÅ
*buff++ = topic_len/256; //topic_name³¤¶È¸ß×Ö½Ú
*buff++ = topic_len%256; //topic_name³¤¶ÈµÍ×Ö½Ú
memcpy(buff,topic_name,topic_len); //¸´ÖÆtopic_name
buff += topic_len;
*buff++ = QoS; //×îºó1¸ö×Ö½Ú£º¶©Ôĵȼ¶
pack_len = buff - mqtt_info.TX_Buff;
//·¢ËÍÊý¾Ý
if(mqtt_info.mqtt_Data_Send != NULL)
mqtt_info.mqtt_Data_Send(mqtt_info.TX_Buff,pack_len);
}
/*******************************************************************************
* Function Name : Mqtt_UnSubscribe
* Description : È¡Ïû¶©ÔÄtopic±¨ÎÄ
* Input : topic_name£º¶©ÔÄtopic±¨ÎÄÃû³Æ PackID ±¨Îıêʶ·û(°üºÅ)
* Output : None
* Return : None
* Note : None
*******************************************************************************/
void Mqtt_UnSubscribe(char *topic_name, uint16_t PackID)
{
int temp,Remaining_len;
u16 topic_len,pack_len,Variable_len,Payload_len;
uint8_t *buff;
//Êý¾Ý»º³åÇøÖ¸Õë
buff = mqtt_info.TX_Buff;
//Ö÷Ìⳤ¶È
topic_len = strlen(topic_name);
Variable_len = 2; //SUBSCRIBE±¨ÎÄÖÐ,±¨Îıêʶ·û³¤¶È,¹Ì¶¨Îª2
Payload_len = 2 + strlen(topic_name); //¼ÆËãÓÐЧ¸ººÉ³¤¶È = 2×Ö½Ú(topic_name³¤¶È)+ topic_name×Ö·û´®µÄ³¤¶È
Remaining_len = Variable_len + Payload_len; //Ê£Ó೤¶È
*buff++ = MSG_MQTT_UNSUBSCRIBE; //µÚ1¸ö×Ö½Ú £º¹Ì¶¨0xA2
do{ //Ñ»·´¦Àí¹Ì¶¨±¨Í·ÖеÄÊ£Ó೤¶È×Ö½Ú£¬×Ö½ÚÁ¿¸ù¾ÝÊ£Óà×Ö½ÚµÄÕæʵ³¤¶È±ä»¯
temp = Remaining_len%128; //Ê£Ó೤¶ÈÈ¡Óà128
Remaining_len = Remaining_len/128; //Ê£Ó೤¶ÈÈ¡Õû128
if(Remaining_len>0)
temp |= 0x80; //°´ÐÒéÒªÇóλ7ÖÃλ
*buff++ = temp; //Ê£Ó೤¶È×ֽڼǼһ¸öÊý¾Ý
}while(Remaining_len>0); //Èç¹ûRemaining_len>0µÄ»°£¬ÔٴνøÈëÑ»·
*buff++ = PackID/256; //±¨Îıêʶ·û¸ß×Ö½Ú,°üºÅ
*buff++ = PackID%256; //±¨Îıêʶ·ûµÍ×Ö½Ú,°üºÅ
*buff++ = topic_len/256; //topic_name³¤¶È¸ß×Ö½Ú
*buff++ = topic_len%256; //topic_name³¤¶ÈµÍ×Ö½Ú
memcpy(buff,topic_name,topic_len); //¸´ÖÆtopic_name
buff += topic_len;
pack_len = buff - mqtt_info.TX_Buff;
//·¢ËÍÊý¾Ý
if(mqtt_info.mqtt_Data_Send != NULL)
mqtt_info.mqtt_Data_Send(mqtt_info.TX_Buff,pack_len);
}
/*******************************************************************************
* Function Name : Mqtt_Publish
* Description : Ïòtopic·¢²¼±¨ÎÄ
* Input : topic_name£º¶©ÔÄtopic±¨ÎÄÃû³Æ PackID ±¨Îıêʶ·û(°üºÅ)
QoS£ºµÈ¼¶ data ÓÐЧÊý¾Ý data_len ÓÐЧÊý¾Ý³¤¶È
* Output : None
* Return : None
* Note : PackIDÖ»Óе±QoSΪ1»ò2ʱÓÐЧ
*******************************************************************************/
void Mqtt_Publish(char *topic_name, uint16_t PackID, uint8_t QoS, uint8_t *data, uint16_t data_len)
{
int temp,Remaining_len;
u16 topic_len,pack_len,Payload_len;
uint8_t *buff;
//Êý¾Ý»º³åÇøÖ¸Õë
buff = mqtt_info.TX_Buff;
//Ö÷Ìⳤ¶È
topic_len = strlen(topic_name);
Payload_len = 2 + strlen(topic_name) + data_len; //¼ÆËãÓÐЧ¸ººÉ³¤¶È = 2×Ö½Ú(topic_name³¤¶È)+ topic_name×Ö·û´®µÄ³¤¶È + Êý¾Ý³¤¶È
Remaining_len = Payload_len; //Ê£Ó೤¶È
if(QoS == 0)
{
*buff++ = MSG_MQTT_PUBLISH_QS0; //µÚ1¸ö×Ö½Ú £º¹Ì¶¨0x30
}
else if(QoS == 1)
{
Remaining_len += 2; //Ê£Ó೤¶È,2Ϊ±¨Îıêʶ·û³¤¶È
*buff++ = MSG_MQTT_PUBLISH_QS1; //µÚ1¸ö×Ö½Ú £º¹Ì¶¨0x32
}
else if(QoS == 2)
{
Remaining_len += 2; //Ê£Ó೤¶È,2Ϊ±¨Îıêʶ·û³¤¶È
*buff++ = MSG_MQTT_PUBLISH_QS2; //µÚ1¸ö×Ö½Ú £º¹Ì¶¨0x34
}
do{ //Ñ»·´¦Àí¹Ì¶¨±¨Í·ÖеÄÊ£Ó೤¶È×Ö½Ú£¬×Ö½ÚÁ¿¸ù¾ÝÊ£Óà×Ö½ÚµÄÕæʵ³¤¶È±ä»¯
temp = Remaining_len%128; //Ê£Ó೤¶ÈÈ¡Óà128
Remaining_len = Remaining_len/128; //Ê£Ó೤¶ÈÈ¡Õû128
if(Remaining_len>0)
temp |= 0x80; //°´ÐÒéÒªÇóλ7ÖÃλ
*buff++ = temp; //Ê£Ó೤¶È×ֽڼǼһ¸öÊý¾Ý
}while(Remaining_len>0); //Èç¹ûRemaining_len>0µÄ»°£¬ÔٴνøÈëÑ»·
*buff++ = topic_len/256; //topic_name³¤¶È¸ß×Ö½Ú
*buff++ = topic_len%256; //topic_name³¤¶ÈµÍ×Ö½Ú
memcpy(buff,topic_name,topic_len); //¸´ÖÆtopic_name
buff += topic_len;
if(QoS != 0)
{
*buff++ = PackID/256; //±¨Îıêʶ·û¸ß×Ö½Ú,°üºÅ
*buff++ = PackID%256; //±¨Îıêʶ·ûµÍ×Ö½Ú,°üºÅ
}
//¸´ÖÆÓû§Êý¾Ý
memcpy(buff,data,data_len);
buff += data_len;
pack_len = buff - mqtt_info.TX_Buff;
//·¢ËÍÊý¾Ý
if(mqtt_info.mqtt_Data_Send != NULL)
mqtt_info.mqtt_Data_Send(mqtt_info.TX_Buff,pack_len);
}
/*******************************************************************************
* Function Name : Mqtt_RecvHandle
* Description : MQTT½ÓÊÕÊý¾Ý½âÎö
* Input : buff Êý¾Ý»º³åÇø
* Output : None
* Return : None
* Note : 0 ³É¹¦,ÆäËü ʧ°Ü
*******************************************************************************/
uint8_t Mqtt_RecvHandle(uint8_t *buff)
{
uint8_t *p;
uint8_t encodeByte = 0;
uint32_t multiplier = 1, Remaining_len = 0;
uint8_t QS_level = 0;
p = buff;
//½âÎö½ÓÊÕÊý¾Ý
if((*p != 0x30)&&(*p != 0x32)&&(*p != 0x34)) //²»ÊÇ·¢²¼±¨ÎÄÍ·
return 1;
if(*p != 0x30) QS_level = 1; //±ê¼ÇqsµÈ¼¶²»Îª0
p++;
//ÌáÈ¡Ê£ÓàÊý¾Ý³¤¶È
do{
encodeByte = *p++;
Remaining_len += (encodeByte & 0x7F) * multiplier;
multiplier *= 128;
if(multiplier > 128*128*128) //³¬³öÊ£Ó೤¶È×î´ó4¸ö×Ö½ÚµÄÒªÇó,´íÎó
return 2;
}while((encodeByte & 0x80) != 0);
//ÌáÈ¡Ö÷ÌâÊý¾Ý³¤¶È
mqtt_info.rx_topic_len = *p++;
mqtt_info.rx_topic_len = mqtt_info.rx_topic_len * 256 + *p++;
//ÌáÈ¡Ö÷Ìâ
memcpy(mqtt_info.RX_Topic,p,mqtt_info.rx_topic_len);
p += mqtt_info.rx_topic_len;
if(QS_level != 0) //Ìø¹ý±¨Îıêʶ·û
p += 2;
//ÌáÈ¡Óû§ÄêÊý¾Ý
if(mqtt_info.mqtt_Data_Recv != NULL)
mqtt_info.mqtt_Data_Recv(p,Remaining_len - mqtt_info.rx_topic_len - 2);
return 0;
}
后台对接阿里云
|
|