第四 实现基于RS485与LoRa的混合网络环境监控系统(lora)

/**

  ******************************************************************************

  * File Name          : main.c

  * Description        : Main program body

  ******************************************************************************

  */

#include

#include

#include "board.h"

#include "radio.h"

#include "NS_Radio.h"

#include "hal_temHum.h"

uint8_t Rcv_Temp=0,Rcv_Hum=0;

uint16_t Rcv_Light=0;

// *** 用户代码添加:LoRa节点定义开始

#define LORA_GATEWAY

//#define LORA_NODE_TEHU

//#define LORA_NODE_LIGHT

// *** 用户代码添加:LoRa节点定义结束

// *** 通信协议相关宏定义

#define START_HEAD 0x55

#define CMD_READ 0x01

#define ACK_OK 0x00

#define ACK_NONE 0x01

#define ACK_ERR 0x02

#define MY_NET_ID 0xc0c2

#ifdef LORA_NODE_TEHU

#define MY_ADDR 0x01

#endif

#ifdef LORA_NODE_LIGHT

#define MY_ADDR 0x02

#endif

#ifdef LORA_GATEWAY

#define ADDR_MIN 1

#define ADDR_MAX 2

#endif

// *** 传感器全局变量声明

#ifdef LORA_NODE_TEHU

int8_t temperature=25;

int8_t humidity=70;

#endif

#ifdef LORA_NODE_LIGHT

uint16_t LightLux=200;

#endif

uint8_t CheckSum(uint8_t *buf,uint8_t len);

uint8_t *ExtractCmdframe(uint8_t *buf,uint8_t len,uint8_t CmdStart);

uint16_t GetHexStr(uint8_t *input ,uint16_t len,uint8_t *output);

void LoRa_DataParse(uint8_t *LoRaRxBuf,uint16_t len);

void LoRa_GetSensorDataProcess(void);

void LoRa_SendRead(uint16_t NetId,uint8_t addr);

void LoRa_AutoCTL(uint8_t *LoRaRxBuf,uint16_t len);

void LoRa_GateWay_AutoCTL(uint8_t *DataBuf,uint16_t len)

{

uint8_t *DestData =NULL;

#define HEAD_DATA  *DestData

#define CMD_DATA *(DestData+1)

#define NETH_DATA *(DestData+2)

#define NETL_DATA *(DestData+3)

#define ADDR_DATA    *(DestData+4)

#define ACK_DATA    *(DestData+5)

#define LEN_DATA    *(DestData+6)

#define DATASTAR_DATA *(DestData+7)

DestData =ExtractCmdframe((uint8_t *)DataBuf ,len,START_HEAD );

if(DestData !=NULL )

{

if((DestData - DataBuf )>(len-6)) return;

if(CMD_DATA !=CMD_READ ) return;

if(CheckSum((uint8_t *)DestData ,6+DestData[6]) !=(*(DestData+6+(*(DestData+6))))) return;

if(((((uint16_t)NETH_DATA )<<8)+NETL_DATA ) !=MY_NET_ID ) return;

char OledBuf[32];

memset(OledBuf  ,' ',30 );

memcpy(OledBuf,&DATASTAR_DATA,(LEN_DATA-1)>30?30:(LEN_DATA-1));

OLED_ShowString(0,4,(uint8_t *)OledBuf);

USART1_SendStr((uint8_t *)DestData,LEN_DATA+7);

}

// *** 用户添加代码:LoRa网关数据解析与逻辑控制开始

  if(ADDR_DATA == 0x01)

{

Rcv_Temp =(*(DestData+11)-'0')*10+(*(DestData+12)-'0');

Rcv_Hum =(*(DestData+20)-'0')*10+(*(DestData+21)-'0');

}

if(ADDR_DATA == 0x02)

{

if(*(DestData+6)==12)

{

Rcv_Light  =(*(DestData+13)-'0')*10+(*(DestData+14)-'0');

}

else

    {

Rcv_Light  =(*(DestData+13)-'0')*100+(*(DestData+14)-'0')*10+(*(DestData+15)-'0');

}

}

if(Rcv_Temp > 25 || Rcv_Hum  >= 70 || Rcv_Light <  200)

{

GpioWrite (&Relay ,1);

}

else

{

GpioWrite (&Relay ,0);

}

// *** 用户代码添加:LoRa网关数据解析与逻辑控制结束

}

void LoRa_SendRead(uint16_t NetId,uint8_t addr)

{

uint8_t TxBuffer[BUFFER_SIZE];

TxBuffer[0]=START_HEAD;

TxBuffer[1]=CMD_READ;

TxBuffer[2]=(uint8_t)(NetId>>8);

TxBuffer[3]=(uint8_t)NetId;

TxBuffer[4]=addr;

TxBuffer[5]=CheckSum((uint8_t*)TxBuffer,5);

Radio.Send(TxBuffer,6);

}

// 网关:读取传感器数据处理

void LoRa_ReadSensorProcess(uint8_t AddrMin,uint8_t AddrMax)

{

static uint16_t time=1000;

static uint8_t addr=1;

if(User0Timer_MS >time )

{

User0Timer_MS =0;

time=randr(1000,4000);

#ifndef TRANSPARENCY

printf("读取网络ID为0x%04x,地址为%d的传感节点\r\n",MY_NET_ID,addr);

#endif

char StrBuf[32]={0};

memset(StrBuf ,'\0',32);

sprintf(StrBuf ,"ID:%04X,Addr:%d",MY_NET_ID,addr );

OLED_ShowString(0,2,(uint8_t *)StrBuf);

memset(StrBuf ,' ',32);

OLED_ShowString(0,4,(uint8_t *)StrBuf);

LoRa_SendRead(MY_NET_ID,addr++);

if(addr>AddrMax)

addr=AddrMin;

GpioToggle(&Led1 );

}

}

// 通信协议:校验和

uint8_t CheckSum(uint8_t *buf,uint8_t len)

{

uint8_t temp =0;

while(len--)

{

temp +=*buf;

buf++;

}

return (uint8_t )temp;

}

// 通信协议:通信帧头解析

uint8_t *ExtractCmdframe(uint8_t *buf,uint8_t len,uint8_t CmdStart)

{

uint8_t *point = NULL;

uint8_t i;

for(i=0;i

{

if(CmdStart ==*buf )

{

point = buf;

return point;

}

buf++;

}

return NULL;

}

// 通信协议:命令帧解析

void LoRa_DataParse(uint8_t *LoRaRxBuf,uint16_t len)

{

#if defined(LORA_GATEWAY)

LoRa_GateWay_AutoCTL(LoRaRxBuf,len);

#endif

#ifdef LORA_NODE_TEHU

uint8_t *DestData =NULL;

#define HEAD_DATA  *DestData

#define CMD_DATA *(DestData+1)

#define NETH_DATA *(DestData+2)

#define NETL_DATA *(DestData+3)

#define ADDR_DATA    *(DestData+4)

#define ACK_DATA    *(DestData+5)

#define LEN_DATA    *(DestData+6)

#define DATASTAR_DATA  *(DestData+7)

DestData =ExtractCmdframe((uint8_t *)LoRaRxBuf ,len,START_HEAD );

if(DestData !=NULL )

{

if((DestData - LoRaRxBuf )>(len-6)) return;

if(CMD_DATA !=CMD_READ ) return;

if(CheckSum((uint8_t *)DestData ,5) !=(*(DestData+5)) ) return;

if(((((uint16_t)NETH_DATA )<<8)+NETL_DATA ) !=MY_NET_ID ) return;

if(ADDR_DATA  !=MY_ADDR ) return;

uint8_t RspBuf[BUFFER_SIZE]={0};

memset(RspBuf ,'\0',BUFFER_SIZE );

RspBuf[0]=START_HEAD ;

RspBuf[1]=CMD_READ ;

RspBuf[2]=(uint8_t)(MY_NET_ID>>8) ;

RspBuf[3]=(uint8_t)MY_NET_ID ;

RspBuf[4]=MY_ADDR ;

RspBuf[5]=ACK_OK ;

sprintf((char *)(RspBuf +7),"tem:%dCe,hum:%d%%",temperature,humidity);

RspBuf[6]=strlen((const char *)(RspBuf +7))+1;

RspBuf[6+RspBuf[6]]=CheckSum((uint8_t *)RspBuf,6 +RspBuf[6]);

Radio.Send(RspBuf ,7 +RspBuf[6]);

GpioToggle(&Led1 );

}

#endif

#ifdef LORA_NODE_LIGHT

uint8_t *DestData =NULL;

#define HEAD_DATA  *DestData

#define CMD_DATA *(DestData+1)

#define NETH_DATA *(DestData+2)

#define NETL_DATA *(DestData+3)

#define ADDR_DATA    *(DestData+4)

#define ACK_DATA    *(DestData+5)

#define LEN_DATA    *(DestData+6)

#define DATASTAR_DATA  *(DestData+7)

DestData =ExtractCmdframe((uint8_t *)LoRaRxBuf ,len,START_HEAD );

if(DestData !=NULL )

{

if((DestData - LoRaRxBuf )>(len-6)) return;

if(CMD_DATA !=CMD_READ ) return;

if(CheckSum((uint8_t *)DestData ,5) !=(*(DestData+5)) ) return;

if(((((uint16_t)NETH_DATA )<<8)+NETL_DATA ) !=MY_NET_ID ) return;

if(ADDR_DATA  !=MY_ADDR ) return;

uint8_t RspBuf[BUFFER_SIZE]={0};

memset(RspBuf ,'\0',BUFFER_SIZE );

RspBuf[0]=START_HEAD ;

RspBuf[1]=CMD_READ ;

RspBuf[2]=(uint8_t)(MY_NET_ID>>8) ;

RspBuf[3]=(uint8_t)MY_NET_ID ;

RspBuf[4]=MY_ADDR ;

RspBuf[5]=ACK_OK ;

sprintf((char *)(RspBuf +7),"Light:%dLux",LightLux );

RspBuf[6]=strlen((const char *)(RspBuf +7))+1;

RspBuf[6+RspBuf[6]]=CheckSum((uint8_t *)RspBuf,6 +RspBuf[6]);

Radio.Send(RspBuf ,7 +RspBuf[6]);

GpioToggle(&Led1 );

}

#endif

}

// 格式转换

uint16_t GetHexStr(uint8_t *input ,uint16_t len,uint8_t *output)

{

for(uint16_t i=0;i

{

sprintf((char *)(output+i*3),"%02X ",*input );

input++;

}

return strlen((const char *)output);

}

// 读取传感器参数

void LoRa_GetSensorDataProcess(void)

{

#ifdef LORA_NODE_TEHU

const uint16_t time=1000;

if(User0Timer_MS >time )

{

User0Timer_MS =0;

uint16_t Temp,Rh;

call_sht11((uint16_t *)(&Temp),(uint16_t *)(&Rh));

temperature =(int8_t)Temp;

if(temperature<10)

temperature=10;

if(temperature>=100)

temperature=99;

humidity  =(int8_t)Rh;

if(humidity<10)

humidity=10;

char StrBuf[64]={0};

memset(StrBuf ,'\0',64);

sprintf(StrBuf ,"tem:%dCe,hum:%d%%",temperature,humidity);

OLED_ShowString(0,6,(uint8_t *)StrBuf);

}

#endif

#ifdef LORA_NODE_LIGHT

const uint16_t time=1000;

if(User0Timer_MS >time )

{

User0Timer_MS =0;

uint16_t AdcNum,voltage;

AdcNum =AdcReadChannel(&Adc,ADC_CHANNEL_0);

voltage=AdcNum*3300/(4096-1.0);

LightLux=5/2.0*(voltage/10.0);

if(LightLux>999)

LightLux=999;

if(LightLux<10)

LightLux=10;

char StrBuf[64]={0};

memset(StrBuf ,'\0',64);

sprintf(StrBuf ,"Light:%3dLux",LightLux );

OLED_ShowString(0,6,(uint8_t *)StrBuf);

}

#endif

}

// *** 用户添加部分结束

void LoRa_Send( uint8_t *TxBuffer, uint8_t len );

void MyRadioRxDoneProcess( void );

void OLED_InitView(void);

void PlatformInit(void);

/**********************************************************************************************

*函数:void LoRa_Send( uint8_t *TxBuffer, uint8_t len )

*功能:发送LoRa无线数据

*输入:

*      uint8_t *TxBuffer, 待发送数据

*      uint8_t len, 待发送数据长度

*输出:无

*返回:无

*特殊说明:无

**********************************************************************************************/

void LoRa_Send( uint8_t *TxBuffer, uint8_t len )

{

    Radio.Send( TxBuffer, len);

}

/**********************************************************************************************

*函数:void MyRadioRxDoneProcess( void )

*功能:无线模块数据接收完成处理进程函数

*输入:无

*输出:无

*返回:无

*特殊说明:接收到的无线数据保存在RxBuffer中,BufferSize为接收到的无线数据长度

**********************************************************************************************/

void MyRadioRxDoneProcess( void )

{

    uint16_t BufferSize = 0;

    uint8_t RxBuffer[BUFFER_SIZE];

    BufferSize = ReadRadioRxBuffer( (uint8_t *)RxBuffer );

    if(BufferSize>0)

    {

        //用户在此处添加接收数据处理功能的代码

        ;

GpioToggle(&Led2 );

LoRa_DataParse((uint8_t *)RxBuffer ,BufferSize );       


    }

}

/**********************************************************************************************

*函数:void OLED_InitView()

*功能:Lora液晶初始化

*输入:无

*输出:无

*特殊说明:无

**********************************************************************************************/

void OLED_InitView(void)

{

char StrBuf[32]={0};

memset(StrBuf ,'\0',32);

OLED_Clear();

#if defined(LORA_GATEWAY)

OLED_ShowString(0,0, (uint8_t *)"LoRa GateWay");

#else

OLED_ShowString(0,0,(uint8_t*)"Freq:");

OLED_ShowNum(5*8,0,(uint32_t)RF_PING_PONG_FREQUENCY,9,16);

sprintf(StrBuf ,"ID:%04X,Addr:%d",MY_NET_ID,MY_ADDR );

OLED_ShowString(0,2,(uint8_t *)StrBuf);

#endif

#if defined(LORA_NODE_TEHU)

OLED_ShowString(0,4, (uint8_t *)"Lora Temp/Hum");

#endif

#if defined(LORA_NODE_LIGHT)

OLED_ShowString(0,4, (uint8_t *)"Lora Light");

#endif

}

/**********************************************************************************************

*函数:void PlatformInit( void )

*功能:平台初始化

*输入:无

*输出:无

*特殊说明:无

**********************************************************************************************/

void PlatformInit(void)

{

    // 开发板平台初始化

    BoardInitMcu();

    BoardInitPeriph();

    // 开发板设备初始化

    OLED_Init();//液晶初始化

    USART1_Init(115200);//串口1初始化

    OLED_Clear();

    OLED_InitView();//OLED屏幕显示初始信息


    printf("新大陆教育 LoRa \r\n");

    //Lora模块初始化

    NS_RadioInit( (uint32_t) RF_PING_PONG_FREQUENCY, (int8_t) TX_OUTPUT_POWER, (uint32_t) TX_TIMEOUT_VALUE, (uint32_t) RX_TIMEOUT_VALUE );


    //请在下方添加用户初始化代码

#if defined(LORA_GATEWAY)

printf("Gateway\r\n");

#endif

#if defined(LORA_NODE_TEHU)

printf("LoRa TempRh\r\n");

hal_temHumInit();

#endif

#if defined(LORA_NODE_LIGHT)

printf("LoRa Light\r\n");

AdcInit(&Adc,ADC_0);

#endif

  connectionreset();

    Tim3McuInit(1);

    //IWDG_PrmInit(2048);//独立看门狗初始化,超时设置为2048ms

}

/**

* Main application entry point.

*/

int main( void )

{

    PlatformInit();

    while( 1 )

    {

        //IWDG_PrmRefresh( );//喂独立看门狗

        //请在下方添加用户功能代码

MyRadioRxDoneProcess();

#if defined(LORA_NODE_LIGHT)||defined(LORA_NODE_TEHU)

LoRa_GetSensorDataProcess();

#endif

#ifdef LORA_GATEWAY

LoRa_ReadSensorProcess(ADDR_MIN,ADDR_MAX);

#endif

    }

}

你可能感兴趣的:(第四 实现基于RS485与LoRa的混合网络环境监控系统(lora))