2018-12-20 15:08:50 qq_41002345 阅读数 398

各位大哥,我最近在做51单片机的温湿度检测并显示报警,现在我想把这个系统和买的NB-IOT模块连接起来,把单片机采集到的数据传到NB-IOT模块中,请问用c51和NB-IOT分别什么接口,用什么通信方式,怎么编程流程和硬件连接,谢谢大佬解答!!!

2018-10-06 23:50:11 sadfdsfff 阅读数 646

单片机透传控制 SIM800C 模块

一、学习目标

  1. 通过串口调试助手,发送 AT 指令给单片机,单片机透传到 SIM800C 模块实现与远程服务器的数据透传。

二、开发环境

秉火指南者开发板+串口调试模块+SIM800C模块

三、学习过程

一、配置单片机串口2与串口3透传

  1. 由于实现过程比较繁琐,直接附上代码 -> 以后附上

二、按顺序发送以下指令给单片机(注意顺序):

  1. AT+CGDCONT=1,“IP”,“CMNET”
    定义PDP移动场景
  2. AT+CGATT=1
    激活PDP,获取IP地址
  3. AT+CIPCSGP=1,“CMNET”
    设置模块连接方式为GPRS链接方式,接入点为“CMNET”(对于移动和联通一样,上同)
  4. AT+CIPSTATUS
    一共十种状态,只有处于IP_INITIAL,IP_CLOSE,IP_STATUS三种状态下才能正确建立连接,否则返回错误。
  5. AT+CIPSTART=“TCP”,“140.143.85.71”,“80”
    建立GPRS连接,140.143.85.71是TCP服务器的IP(这里可以换成域名),80是服务器的端口号,有时会出现连接失败,多次重连即可。
  6. AT+CIPSEND
    发送数据,返回">"后输入要传输的数据,在发送CTRL+Z(或者以十六进制的方式发送0x1a),即可将所要发送的数据发送到指定IP或域名的服务器上。
  7. AT+CIPCLOSE
    关闭TCP连接
  8. AT+CIPSHUT
    关闭移动场景
2019-11-28 20:41:43 yaojiawan 阅读数 75

     

 Modular IoT 模块化物联网架构为物联网应用提供快速,简单的解决方案。让各种数字技术迅速融合到工业领域的各个地方。

Modular-2 IoT 的主要特点

       涵盖从传感器到云端的应用场景

modular-2

     模块化终端设备,将大量传感器,执行部件接入modularIoT平台,基于低成本corex-M 单片机实现,使用Arm 的Mbed OS 物联网操作系统。

  modular-2 实现了应用软件和物理设备的解耦。使用户在不需要了解过多硬件底层技术细节时,就可快速开发应用软件。

modular Edge

 modular  edge 是一个模块化边缘服务器,可以安装在各类工业现场,完成数据采集,控制,数据存储和分析。它基于linux OS,采用基于容器技术和微服务理念实现物联网应用软件的App化。

根据工业应用对计算能力的需要,modular-2 edge可以部署在低成本的Arm 处理器平台上,也可以部署在性能更强大的intel X86 计算机平台。使工业信息系统更加富有弹性。

modular cloud

   modular cloud 是modular edge 软件架构向云端的延申。实现原生云应用。可以接入运行商物联网接入网,也可以通过http,mqtt ,websocket 等多种方式接入。

应用软件App化

  modularIoT 架构的主要特点之一在边缘设备和云端应用软件实现App化,它采用了容器技术和微服务理念。

云端应用容器和微服务理念具有解构,便于运维,语言中性,多环境并存,快速迭代和部署等诸多优点,但是它主要还是大型云端应用的架构,大量的运维工具比较专业。需要有经验的运维人员才能够使用。modular IoT 提供了一整套软件和规范,使容器的运行和部署更加便捷,客户体验接近手机App。使工业现场维护人员就能够方便地完成App的安装,部署和维护。

通过 modular Iot 上的Appmanager 可以实现类似手机App 的用户体验。为此 modularIot 规范了网络协议,消息系统,webUI ,App 运行管理。用户可以更加便捷地开发各种物联网App,并且快速部署到边缘设备上,或者云端。

同时,modular Iot 也在不断地开发各种基础服务的微服务,为应用App 提供更强大的支持。比如 运营商物联(中国电信Wind和中国移动OneNet)网接入,时间序列数据库,数字化面板,AI等服务。使应用程序开发人员能够专注于他们的专业领域,迅速开发出各种应用软件。

开发语言中性化

可以使用各种程序设计语言来实现modular IoT 架构下的App,它们可以是C++ ,也可以是基于Node 的Javascript,用于数据分析的Python 。我们更推荐使用Go 语言来开发modularIoT App。modular IoT 在开发的初期,全部程序是采用C++来实现,最近,我们从C++转向了Go。应为使用Go来编写App更加快捷和高效。

 

modular IoT 使用的主要技术

docker 容器管理

modularIoT 的App 和支持微服务都实现容器化,docker 目前是最流行的容器管理技术。

RabbitMQ 消息系统

  modular IoT 内部App 之间的消息交换采用rabbitMQ 消息系统。RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现。

AMQP :Advanced Message Queue,高级消息队列协议。它是应用层协议的一个开放标准,为面向消息的中间件设计,基于此协议的客户端与消息中间件可传递消息,并不受产品、开发语言等条件的限制。

 

Go 程序设计语言

Go 是google 开发的新型程序设计语言,它的标准库支持大量的网络协议和程序设计的常用库。使用GO 编写物联网应用软件非常高效,快捷。我们推荐使用Go 语言编写modularIoT App程序。

数据库

modular IoT 使用两种数据库:

mongoDB 数据库

 modularIoT 使用mongoDB 实现App 管理。

influxDB 时间序列数据库

protocol Buffer

     Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。相比于XML 和json 而言,protocol Buffer 的处理速度更快,产生的序列化数据更短。这正是物联网应用所需要的。在modularIoT 架构中,rabbitMQ 的消息体采用了protocol buffer 格式

modular IoT 的体系架构

hub service

  所有外部设备和服务通过 Hub Service 接入modular IoT 。它们包括了modular-2 设备。人员,其它边缘设备和其它服务。比如电信部门的物联网接入平台。

App 管理服务

App 管理使用mongoDB 对App 的参数存储和管理。

 

App 管理

   在moddularIOT平台上,可以建立多个项目,每个项目可能有多个App运行。并且有多个用户使用这些App。

例如,在IOT 平台上,可以运行多个企业的IOT项目,而某个企业的项目中可同时了设备控制,状态检测和设备健康检测三个App。这些App将会有多个人员来使用。

建立项目

在modularIOT 上运行物联网项目,首先要建立一个项目。在modular-2 edge 上只有一个项目,而在云端,可以运行多个项目。

应用程序

每个项目上可能有多个应用程序(在本文档中简称为“App”)。

管理员

每个项目有一个管理员(在本文档中简称为“admin”),他负责App的建立,运行和运维管理。

用户

每个项目中有多个使用者,他们有项目管理员建立。

管理

在modularIOT 中,App 是一个Docker 化的容器,当一个App 在开发完成以后,需要将该App 的docker 映像上传到modularIOT 的私有仓库中(使用docker push)。同时要在modularIOT 的App manager 中注册。

App manager 是一个应用程序和用户管理的微服务,它使用 mongoDB 数据库对系统中的项目,App和用户实施管理。

注册

注册时,要提供下列信息:

  -name 名称

  -browsername 浏览器使用的名称

  -port 该App 暴露的端口

  -avatar  该App 的图标

  -imagefile  该App的docker image name

通过App Manager 的程序管理界面,上传这些信息。上传到App Manager 之后,在App Manager 的程序管理页面中会显示出来,状态为“未安装”(uninstall)

安装

  App 安装意味着将该App 的image 建立docker 容器。安装以后,App 自动进入run 状态。

运行

 该App 处于运行状态。

停止,暂停

  App 可以设定为停止,或者暂停状态,这时App 的容器依然在docker 中保留,状态为“stop”

取消

  将该App 的容器移去。但是image 并没有从modularIOT 的私有仓库删除,App manager 中仍然保留该App 的信息。该App 处于未安装状态

删除

  完全将该App 在modularIOT 平台上去除。

未完待续

2019-01-03 12:23:51 IoT_Sharer 阅读数 2781

相关信息

设备接入方式:CoAP非加密方式

 

应用开发

串口助手AT命令对接平台

这部分内容是通过电脑串口调试软件,手动发AT指令,直接发给NB-IoT模块。NB模块返回的信息,直接到电脑串口调试软件。一步一步动手操作,实现连接OceanConnect平台。采用的通讯协议是CoAP协议。

Step 1 配置对接平台地址

指令:AT+NCDP=<ip_addr>[,<port>]

<ip_addr>:填写平台设备接入地址

<port>:填写接入方式的端口号

例:AT+NCDP= 139.159.140.34,5683

Step 2 软件重启模组

指令:AT+NRB    //配置完配置对接平台地址后需要重启模块才能生效

REBOOTING

0???

REBOOT_CAUSE_APPLICATION_AT

Neul

OK

Step 3 检查是否入网成功

指令:AT+CGATT?

+CGATT:1 //返回1表示入网成功,返回0入网失败,300s后依然为0,则重启模组

 

OK

Step 4 发送数据

指令:AT+NMGS=<length>,<data>

<length>:数据长度

<data>:数据(十六进制格式)

例:AT+NMGS=8,31322E3132332E34  //上报数据

OK

LiteOS API方式接入

这部分的通过单片机搭载华为LiteOS操作系统,并移植了可兼容所有AT指令型的AT框架程序,调用AT框架的API接口实现快速连接华为OceanConnect平台。并能实时接收平台下发的命令,实现对设备的控制,以下讲解调用API实现的方式。

Step 1 分析主程序

int main(void)
{
    UINT32 uwRet = LOS_OK;
	
    HardWare_Init();
    uwRet = LOS_KernelInit();
    if (uwRet != LOS_OK)
    {
        return LOS_NOK;
    }
			
    uwRet = creat_main_task();
    if (uwRet != LOS_OK)
    {
        return LOS_NOK;
    }


    LOS_Start();
}

 

主程序主要包括初始化硬件外设、初始化内核、创建传感器数据采集任务、创建数据上报任务,接下来讲详细讲解主要部分的实现方式。

Step 2初始化硬件

 

VOID HardWare_Init(VOID)
{
	HAL_Init();
	/* Configure the system clock */
	SystemClock_Config();

	/* Initialize all configured peripherals */
	dwt_delay_init(SystemCoreClock);
	MX_GPIO_Init();
	MX_USART1_UART_Init();
	printf("Welcome to IoT-Club, This is EVB-M1 Board.\r\n");

	
}

首先调用 HAL_Init() 初始化HAL库;SystemClock_Config(),用于系统时钟的配置;再调用MX_GPIO_Init()

初始化相应的GPIO;最后初始化单片机debug串口。

Step 3创建传感器采集任务

VOID data_collection_task(VOID)
{
	UINT32 uwRet = LOS_OK;
	
	DHT11_Init();									//初始化传感器

	while (1)
  {

		printf("This is data_collection_task !\r\n");
		
		    if(DHT11_Read_TempAndHumidity(&DHT11_Data)==SUCCESS)
    {
			printf("读取DHT11成功!-->湿度为%.1f %RH ,温度为 %.1f℃ \n",DHT11_Data.humidity,DHT11_Data.temperature);
    }
    else
    {
      printf("读取DHT11信息失败\n");
			DHT11_Init();      
    }
		sprintf(DHT11_send.temp, "%.1f", DHT11_Data.temperature);
		sprintf(DHT11_send.hum, "%.1f", DHT11_Data.humidity);

		uwRet=LOS_TaskDelay(2000);
		if(uwRet !=LOS_OK)
		return;
	
  }
}

这部分为传感器数据采集部分,首先是通过DHT11_Init();函数初始化温湿度传感器DHT11所对应的单片机管脚及传感器。

/**
  * 函数功能: DHT11 初始化函数
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
void DHT11_Init ( void )
{
  DHT11_Dout_GPIO_CLK_ENABLE();
  
	DHT11_Mode_Out_PP();
	
	DHT11_Dout_HIGH();  // 拉高GPIO
}

通过 DHT11_Read_TempAndHumidity函数采集传感器数据

/**
  * 函数功能: 一次完整的数据传输为40bit,高位先出
  * 输入参数: DHT11_Data:DHT11数据类型
  * 返 回 值: ERROR:  读取出错
  *           SUCCESS:读取成功
  * 说    明:8bit 湿度整数 + 8bit 湿度小数 + 8bit 温度整数 + 8bit 温度小数 + 8bit 校验和 
  */
uint8_t DHT11_Read_TempAndHumidity(DHT11_Data_TypeDef *DHT11_Data)
{  
  uint8_t temp;
  uint16_t humi_temp;
  
	/*输出模式*/
	DHT11_Mode_Out_PP();
	/*主机拉低*/
	DHT11_Dout_LOW();
	/*延时18ms*/
	Delay_ms(18);	
	/*总线拉高 主机延时30us*/
	DHT11_Dout_HIGH(); 

	DHT11_Delay(30);   //延时30us

	/*主机设为输入 判断从机响应信号*/ 
	DHT11_Mode_IPU();

	/*判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行*/   
	if(DHT11_Data_IN()==GPIO_PIN_RESET)     
	{
    /*轮询直到从机发出 的80us 低电平 响应信号结束*/  
    while(DHT11_Data_IN()==GPIO_PIN_RESET);

    /*轮询直到从机发出的 80us 高电平 标置信号结束*/
    while(DHT11_Data_IN()==GPIO_PIN_SET);

    /*开始接收数据*/   
    DHT11_Data->humi_high8bit= DHT11_ReadByte();
    DHT11_Data->humi_low8bit = DHT11_ReadByte();
    DHT11_Data->temp_high8bit= DHT11_ReadByte();
    DHT11_Data->temp_low8bit = DHT11_ReadByte();
    DHT11_Data->check_sum    = DHT11_ReadByte();

    /*读取结束,引脚改为输出模式*/
    DHT11_Mode_Out_PP();
    /*主机拉高*/
    DHT11_Dout_HIGH();
    
    /* 对数据进行处理 */
    humi_temp=DHT11_Data->humi_high8bit*100+DHT11_Data->humi_low8bit;
    DHT11_Data->humidity =(float)humi_temp/100;
    
    humi_temp=DHT11_Data->temp_high8bit*100+DHT11_Data->temp_low8bit;
    DHT11_Data->temperature=(float)humi_temp/100;    
    
    /*检查读取的数据是否正确*/
    temp = DHT11_Data->humi_high8bit + DHT11_Data->humi_low8bit + 
           DHT11_Data->temp_high8bit+ DHT11_Data->temp_low8bit;
    if(DHT11_Data->check_sum==temp)
    { 
      return SUCCESS;
    }
    else 
      return ERROR;
	}	
	else
		return ERROR;
	
}

最后将传感器数据以字符串的形式存入到数组中,用于发送到平台上。

sprintf(DHT11_send.temp, "%.1f", DHT11_Data.temperature);
sprintf(DHT11_send.hum, "%.1f", DHT11_Data.humidity);

Step 3创建数据上报任务

VOID data_report_task(VOID)

{

       UINT32 uwRet = LOS_OK;

      

       #define AT_DTLS 0

#if AT_DTLS

    sec_param_s sec;

    sec.pskid = "868744031131026";

    sec.psk = "d1e1be0c05ac5b8c78ce196412f0cdb0";

#endif

    printf("\r\n=====================================================");

    printf("\r\nSTEP1: Init NB Module( NB Init )");

    printf("\r\n=====================================================\r\n");

#if AT_DTLS

    los_nb_init((const int8_t*)"180.101.147.115",(const int8_t*)"5684",&sec);

#else

    los_nb_init((const int8_t*)"180.101.147.115",(const int8_t*)"5683",NULL);

#endif

    printf("\r\n=====================================================");

    printf("\r\nSTEP2: Register Command( NB Notify )");

    printf("\r\n=====================================================\r\n");

    los_nb_notify("+NNMI:",strlen("+NNMI:"),nb_cmd_data_ioctl,OC_cmd_match);

    LOS_TaskDelay(3000);

    printf("\r\n=====================================================");

    printf("\r\nSTEP3: Report Data to Server( NB Report )");

    printf("\r\n=====================================================\r\n");

              while(1)

       {

            if(los_nb_report((const char*)(&DHT11_send),sizeof(DHT11_send))>=0)        //发送数据到平台    
                printf("ocean_send_data OK!\n");                                                  //发生成功
        else                                                                                  //发送失败
            {
                printf("ocean_send_data Fail!\n"); 
            }



             uwRet=LOS_TaskDelay(1000);

              if(uwRet !=LOS_OK)

              return;

       }

}

这部分程序主要包括连接平台、注册下发命令的回调函数以及上报数据到平台,以下将讲解如何实现这三部分。

连接平台

连接平台的方式分为加密和非加密两种,通过#define AT_DTLS来实现连接方式的选择,定义为0时为非加密,此教程以非加密为例讲解,实现程序如下

#define AT_DTLS 0

#if AT_DTLS

    sec_param_s sec;

    sec.pskid = "868744031131026";

    sec.psk = "d1e1be0c05ac5b8c78ce196412f0cdb0";

#endif

    printf("\r\n=====================================================");

    printf("\r\nSTEP1: Init NB Module( NB Init )");

    printf("\r\n=====================================================\r\n");

#if AT_DTLS

    los_nb_init((const int8_t*)"139.159.140.34",(const int8_t*)"5684",&sec);

#else

    los_nb_init((const int8_t*)"139.159.140.34",(const int8_t*)"5683",NULL);

#endif

此部分通调用los_nb_init函数初始化模组,等待连接网络,设置平台对接地址实现对接平台。三个参数分别为设备对接IP、设备对接端口以及加密的PSK码。【注意】不同平台的设备对接地址不同,请以自己平台为准

int los_nb_init(const int8_t* host, const int8_t* port, sec_param_s* psk)

{

    int ret;

    int timecnt = 0;

    //if(port == NULL)

        //return -1;

    at.init();



    nb_reboot();

    LOS_TaskDelay(2000);

    if(psk != NULL)//encryption v1.9

    {

        if(psk->setpsk)

            nb_send_psk(psk->pskid, psk->psk);

        else

            nb_set_no_encrypt();

    }



    while(1)

    {

        ret = nb_hw_detect();

        printf("call nb_hw_detect,ret is %d\n",ret);

        if(ret == AT_OK)

            break;

        //LOS_TaskDelay(1000);

    }

    //nb_get_auto_connect();

    //nb_connect(NULL, NULL, NULL);



       while(timecnt < 120)

       {

              ret = nb_get_netstat();

              nb_check_csq();

              if(ret != AT_FAILED)

              {

                     ret = nb_query_ip();

                     break;

              }

              //LOS_TaskDelay(1000);

              timecnt++;

       }

       if(ret != AT_FAILED)

       {

              nb_query_ip();

       }

       ret = nb_set_cdpserver((char *)host, (char *)port);

    return ret;

}

 

​​​​​​​注册下发命令回调函数

注册下发命令回调函数可实现对平台下发命令的快速相应并处理

los_nb_notify("+NNMI:",strlen("+NNMI:"),nb_cmd_data_ioctl,OC_cmd_match);

第一个参数为要匹配数据字段,第二个参数为匹配字段的长度、第三个参数为命令回调的执行函数、第四个为注册字段的匹配函数。

int32_t nb_cmd_data_ioctl(void* arg, int8_t  * buf, int32_t len)

{

            int readlen = 0;

            char tmpbuf[1064] = {0};

    if (NULL == buf || len <= 0)

    {

        AT_LOG("param invailed!");

        return -1;

    }

                          sscanf((char *)buf,"\r\n+NNMI:%d,%s\r\n",&readlen,tmpbuf);

                          memset(bc95_net_data.net_nmgr, 0, 30);

    if (readlen > 0)

    { 

                          HexStrToStr(tmpbuf,  bc95_net_data.net_nmgr,readlen*2);

    }

                          AT_LOG("cmd is:%s\n",bc95_net_data.net_nmgr);

            if(strcmp(bc95_net_data.net_nmgr,"ON")==0)

                   {     

                                 HAL_GPIO_WritePin(Light_GPIO_Port,Light_Pin,GPIO_PIN_RESET);   

                   }

            if(strcmp(bc95_net_data.net_nmgr,"OFF")==0)

                   {     

                                 HAL_GPIO_WritePin(Light_GPIO_Port,Light_Pin,GPIO_PIN_SET); 

                   }

/*******************************END**********************************************/

            return 0;

}

命令回调处理函数主要实现命令的解析以及实现控制相应的设备,此处以控制LED灯为例

int32_t OC_cmd_match(const char *buf, char* featurestr,int len)

{



    if(strstr(buf,featurestr) != NULL)

        return 0;

    else

        return -1;

}

注册字段匹配函数用于验证数据是否与注册字段匹配/

​​​​​​​上报数据

            while(1)

     {



        if(los_nb_report((const char*)(&DHT11_send),sizeof(DHT11_send))>=0)		//发送数据到平台	
				printf("ocean_send_data OK!\n");                                                  //发生成功
		else                                                                                  //发送失败
			{
				printf("ocean_send_data Fail!\n"); 
			}



       uwRet=LOS_TaskDelay(1000);

            if(uwRet !=LOS_OK)

            return;

     }

上报数据调用的API为los_nb_report填入的参数为数据与数据长度,这个函数里封装了发送coap消息的AT指令以及查询发送的消息量的AT指令

int32_t nb_send_payload(const char* buf, int len)

{

    char *cmd1 = "AT+NMGS=";

    char *cmd2 = "AT+NQMGS\r";

    int ret;

    char* str = NULL;

    int curcnt = 0;

    int rbuflen;

    static int sndcnt = 0;

    if(buf == NULL || len > AT_MAX_PAYLOADLEN)

    {

        AT_LOG("payload too long");

        return -1;

    }

    memset(tmpbuf, 0, AT_DATA_LEN);

    memset(wbuf, 0, AT_DATA_LEN);

    str_to_hex(buf, len, tmpbuf);

    memset(rbuf, 0, AT_DATA_LEN);

    snprintf(wbuf, AT_DATA_LEN,"%s%d,%s%c",cmd1,(int)len,tmpbuf,'\r');

    ret = at.cmd((int8_t*)wbuf, strlen(wbuf), "OK", NULL,NULL);

    if(ret < 0)

        return -1;

    ret = at.cmd((int8_t*)cmd2, strlen(cmd2), "SENT=", rbuf,&rbuflen);

    if(ret < 0)

        return -1;

    str = strstr(rbuf,"SENT=");

    if(str == NULL)

        return -1;

    sscanf(str,"SENT=%d,%s",&curcnt,wbuf);

    if(curcnt == sndcnt)

        return -1;

    sndcnt = curcnt;

    return ret;

}

 

2020-02-18 19:24:06 Fresh_Air666 阅读数 51

51单片机和NBIOT模块

一、NBIOT模块

1.基本功能

NB75-BA用于实现MCU与NB-IoT网络间的数据双向透传功能。

2.工作模式

NB75-BA支持CoAP、UDP、TCP透传,由于受到运营商限制,我使用的电信物联网卡仅支持CoAP透传模式,不过移动联通用户支持CoAP、UDP、TCP透传。
在这里插入图片描述

3.模块调试

我使用的模块为针插式并配有一根天线和一个物联网卡。特别注意一下就是,调试模块的时候不需要连接单片机,否则会产生错误信息,调试完成后的模块,再连接单片机进行数据的发送和接收。
1)打开设置软件,打开串口(出厂串口参数9600/8/N/1)进入配置状态(若是出厂状态下cmd模式,无需进入配置状态),一键联网检测一下模块是否OK。
在这里插入图片描述
2)读取当前参数,然后设置工作模式为coap透传模式,coap服务器地址和端口保持默认的117.60.157.137:5683.然后点击设置所有参数,模块会自动保存参数并重启,等待重启完成之后,设备联网Ok之后会打印connected,此时可以测试数据通信。
在这里插入图片描述
启用心跳包功能的作用是它间隔一定的时间不停的向云端发送数据以保持唤醒模块。

4.注意

51单片机VCC=5V,可以为模块提供给电源,但是使用模块的串口引脚需要3V,所以一定要转换电平,否则会造成模块功耗过大,甚至烧毁芯片。

二、透传云使用

1.透传云的功能

通过透传云可以实现温湿度报警和在云端发送数据无线控制单片机。

2.在透传云平台实现报警配置

1)添加设备
在这里插入图片描述
2)添加数据模板
在这里插入图片描述
3)添加报警联系人
在这里插入图片描述
4)添加触发器
在这里插入图片描述

3.在透传云实现远程控制单片机配置

1)添加设备
在这里插入图片描述
2)数据调试
通过你发送的数据来实现无线控制单片机做出应答。

在这里插入图片描述

三、Modbus RTU通信协议

在实现报警的过程中,需要采用Modbus RTU通信协议,这样云端才可以采集到有效信息。

1.MODBUS 数据模型

1)MODBUS 以一系列具有不同特征表格上的数据模型为基础。四个基本表格为:
在这里插入图片描述
对于基本表格中任何一项,协议都允许单个地选择 65536 个数据项,而且设计那些项的读写操 作可以越过多个连续数据项直到数据大小规格限制,这个数据大小规格限制与事务处理功能码有关。
2)协议描述
在这里插入图片描述
启动 MODBUS 事务处理的客户机创建 MODBUS 应用数据单元。功能码向服务器指示将执行哪 种操作。MODBUS 协议建立了客户机启动的请求格式。用一个字节编码 MODBUS 数据单元的功能码域。有效的码字范围是十进制 1-255(128-255 为 异常响应保留)。当从客户机向服务器设备发送报文时,功能码域通知服务器执行哪种操作。
我在实现报警机制中只使用了保持寄存器 利用modbus通信协议向云端发送的数据。如下图:
在这里插入图片描述
当单片机发送一个数据至云端,云端会自行计算数据通过crc校验查看发送的数据是否出现错误。

四、实现报警功能

单片机发送数据给模块,模块再上传云端,数据通过与透传云触发器设置的报警阈值进行比对,查看是否满足报警。透传云可通过微信,手机号,邮箱向用户发出报警信息,如下图的微信报警图:
在这里插入图片描述
完成数据发送,与云端可主动采集数据,需要编写串口通信函数,和crc校验函数,注意的是利用modbus通信协议只能实现上传数据,所以把串口中断开关设置为0防止出现乱码,采用适合通信的11.0592晶振,波特率设置为9600 不用波特率加倍,当只发送一次数据时可能在数据调试窗口看不到发送的数据,那是因为数据发送的太开,在你打开数据调试窗口之前它已经将数据发送完毕,所以可以在main函数当中加一个延时,延时它发送数据,给我们留出打开数据调试窗口的时间。函数如下:

#include<reg52.h>
#include<intrins.h>
typedef unsigned char u8;
typedef unsigned int u16;
u16 dat[7];         
void crc() 
{
 u16 cc=0xffff;
 u16 i=0,j=0;
 dat[0]=0x01 ;dat[1]=0x03;dat[2]=0x02 ; dat[3]=0x00; dat[4]=0x11;
  for(i=0; i<5;i++)
 {   
        cc = (cc^dat[i]);     
        for(j=0;j<8; j++)
  {
            if((cc & 0x01) == 1)   
   {
                cc = ((cc >> 1) ^0xa001);   
            }
   else
   {
                cc = (cc >> 1);
            }
        }
 }
 dat[5]=cc%256;      
    dat[6]=cc/256;       
}
void Delay500ms()       
{
 unsigned char i, j, k;
 _nop_();
 _nop_();
 i = 22;
 j = 3;
 k = 227;
do
 {
  do
  {
   while (--k);
  } while (--j);
 } while (--i);
}
void UsartInit()        //串口初始化
{ 
 SCON=0X50;
 TMOD=0x20;
 TH1=0XFD;        //9600比特率
 TL1=0xFD;
 TR1=1;
 ES=0;
 EA=1;
}
void main()
{
 u8 a;
 Delay500ms()crc(); 
 UsartInit();
 for(a=0;a<7;a++)
 {
  SBUF=dat[a];
  while(!TI);
  TI=0;
 }
 while(1);

五、实现远程控制单片机功能

实现此功能采用的是数据透传协议,此功能只用到了串口通信,没有报警那么繁琐。我利用数据透传控制单片机上的数码管显示,如下图:在这里插入图片描述自行焊接数码管和单片机的原理图
在这里插入图片描述
相关代码如下:

#include <reg52.h>    
sbit s0=P2^0; //定义数码管
sbit s1=P2^1; //定义数码管
sbit s2=P2^2; //定义数码管
sbit s3=P2^3; //定义数码管
typedef unsigned int u16;   
typedef unsigned char u8;
u8 a[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0X76};
u8 dat;
u16 xianshi[3];
void UsartInit()
{
 SCON=0X50;   
 TMOD=0X20;      
 TH1=0XFD;    
 TL1=0XFD;
 ES=1;      
 EA=1;      
 TR1=1;     
}
void delay(u16 v)
{
 while(v--);
}
void display()
{  u16 i;
 for(i=0;i<3;i++)
 { 
  switch(i)
  { 
   case(0):
    s3=0;delay(500);s3=1; break;
   case(1): 
    s1=0;delay(500);s1=1; break; 
   case(2):
    s2=0;delay(500); s2=1;break;  
  }
  
  P0=xianshi[i];
 }
}
void main()
{ 
 delay();
 UsartInit();  
 while(1)
 { 
  s0=1;
  if(0xff||dat)
  {
      xianshi[0]=a[dat/16];
   xianshi[1]=a[dat%16];
   xianshi[2]=a[16];
  }
   display(); 
 }  
}
void Usart() interrupt 4
{
 dat=SBUF;
 RI = 0;
 SBUF=dat;
 while(!TI);    
 TI=0;      
}
没有更多推荐了,返回首页