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

/**

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

  * File Name          : main.c

  * Description        : Main program body

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

  */

#include <string.h>

#include <stdio.h>

#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<len;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<len;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

    }

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,951评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,606评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,601评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,478评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,565评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,587评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,590评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,337评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,785评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,096评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,273评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,935评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,578评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,199评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,440评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,163评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,133评论 2 352

推荐阅读更多精彩内容