项目背景
随着中国城市的发展与建设,城市排水系统的压力越来越大。特别是遇到暴雨天气,不堪重负的排水系统往往很快就崩溃,其结果之一就是道路积水严重,很大程度上影响了城市的交通,造成混乱,尤其是地下车道、隧道,这些地势低的地方往往是重灾区。
原理结构
我们根据隧道的长度合理的布置多个CC2530结点,每个结点上有多种传感器。节点将采集的数据通过Zigbee协议无线传输到协调器中,由其进行加工数据,并通过GPRS远程通信到控制中心,或直接反馈到用户。
水位监测功能流程图
- 初始置位程序
void SET_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;//定义结构体变量
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1; //选择你要设置的IO口
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //设置推挽输出模式
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //设置传输速率
GPIO_Init(GPIOB,&GPIO_InitStructure); //初始化GPIO
GPIO_SetBits(GPIOB,GPIO_Pin_1);
}
void Reset_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;//定义结构体变量
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8; //选择你要设置的IO口
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //设置推挽输出模式
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //设置传输速率
GPIO_Init(GPIOC,&GPIO_InitStructure); //初始化GPIO
GPIO_ResetBits(GPIOC,GPIO_Pin_8);
}
- 状态唤醒程序
void node1(uint16_t *arr)//结点1
{
int x=arr[1];
switch(x)
{
case 0x31: //超声波
if(arr[3]==0x31){ //水位高
int i=0;
led1=0;
while(i<5000){
GPIO_SetBits(GPIOB,GPIO_Pin_1);
delay_ms(10);
i++;
}
}
else if(arr[3]==0x30){ //水位不高
led1=1;
GPIO_ResetBits(GPIOB,GPIO_Pin_1);
}
break;
case 0x30: //温湿度
if(arr[2]==0x31 && arr[3]==0x31) ;//高温高湿
else if(arr[2]==0x31 && arr[3]==0x30) ;//高温低湿 ;
else if(arr[2]==0x30 && arr[3]==0x31) ;//低温高湿
else if(arr[2]==0x30 && arr[3]==0x30) ;//低温低湿
break;
case 0x32: //烟雾
if(arr[3]==0x31){ //有烟雾
int i=0;
while(i<1000){
i++;
GPIO_SetBits(GPIOC,GPIO_Pin_8);
GPIO_SetBits(GPIOB,GPIO_Pin_5);
delay_ms(10);
}
GPIO_ResetBits(GPIOC,GPIO_Pin_8);
}
else if(arr[3]==0x30) ;//无烟雾
break;
default :
break;
}
}
- 协调器接收程序
void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{
uint16 flashTime;
//uint8 buff[30]={0};
//uint8 len=0;
switch ( pkt->clusterId )
{
//接收终端的距离数据
case SAMPLEAPP_chaoshengbo_CLUSTERID:
if(pkt->cmd.DataLength==4)//终端发的距离为5个字节
{
byte rf_buff[4]={0};
//取出数据
osal_memcpy(rf_buff, pkt->cmd.Data, pkt->cmd.DataLength);
//串口输出
HalUARTWrite(0, rf_buff, pkt->cmd.DataLength);
}
break;
case SAMPLEAPP_AIR_CLUSTERID:
{
HalUARTWrite(0, pkt->cmd.Data, pkt->cmd.DataLength); //输出接收到的数据
}
break;
case SAMPLEAPP_PERIODIC_CLUSTERID:
break;
case SAMPLEAPP_wenshidu_CLUSTERID:
HalUARTWrite(0, pkt->cmd.Data, pkt->cmd.DataLength); //输出接收到的数据
break;
case SAMPLEAPP_FLASH_CLUSTERID:
flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] );
HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) );
break;
}
}
- 节点程序
//1. 超声波
void SampleApp_Send_chaoshengbo_Message( void )
{
int us_count=0;
unsigned int distance_data=0;
unsigned char TxBuff0[5];
//触发引脚Trig产生一个20us的高电平
Trig=1;
Delay_20us();
Trig=0;
//等待Echo回波引脚变高电平
while(Echo==0);
while(Echo==1)//回波一直是高电平
{
//10us延时
Delay_10us();
us_count++;
}
distance_data=us_count*10;//计算时间
distance_data/=58;//计算距离,单位cm
if(distance_data>=1000)
{
//距离大于10米认为出错
//LCD_P8x16Str(44, 4, "error");
}
else
{
distance_data=16-distance_data;
if(distance_data>=3)
{
TxBuff[3]=1;
}
else
{
TxBuff[3]=0;
}
TxBuff[0]=0x30+b;
TxBuff[1]=0x30+1;
TxBuff[2]=0x30+0;
TxBuff[3]=0x30+TxBuff[3];
TxBuff0[0]=0x30+(distance_data%1000)/100;
TxBuff0[1]=0x30+((distance_data%1000)%100)/10;
TxBuff0[2]=0x30+((distance_data%1000)%100)%10;
TxBuff0[3]='c';
TxBuff0[4]='m';
//LCD显示
HalLcdWriteString("waterdepth", HAL_LCD_LINE_2 );
LCD_P8x16Str(82, 2, TxBuff0);
//发送到协调器
if ( AF_DataRequest( &SampleApp_P2P_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_chaoshengbo_CLUSTERID,
4,
TxBuff,
&SampleApp_TransID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
}
else
{
// Error occurred in request to send.
}
}
}
//2. 温湿度
void SampleApp_Send_wenshidu_Message( void )
{
byte i, temp[3], humidity[3], strTemp[4];
DHT11(); //获取温湿度
//将温湿度的转换成字符串,供LCD显示
temp[0] = wendu_shi+0x30;
temp[1] = wendu_ge+0x30;
temp[2] = '\0';
humidity[0] = shidu_shi+0x30;
humidity[1] = shidu_ge+0x30;
humidity[2] = '\0';
//数据采集速率控制
if(wendu_shi>=6)
{strTemp[2]=1;}
else
{strTemp[2]=0;}
if(shidu_shi>=3)
{a=2000;strTemp[3]=1;}
else
{a=10000;strTemp[3]=0;}
//strTemp[2]=0;自定义为DHT11识别代号——0
strTemp[0]=b+0x30;//结点代号
strTemp[1]=0+0x30;//DHT11识别代号——0
strTemp[2]=strTemp[2]+0x30;//高温代号
strTemp[3]=strTemp[3]+0x30;//高湿代号
//输出到LCD显示
for(i=0; i<3; i++)
{
if(i==0)
{
LCD_P16x16Ch(i*16,4,i*16);
LCD_P16x16Ch(i*16,6,(i+3)*16);
}
else
{
LCD_P16x16Ch(i*16,4,i*16);
LCD_P16x16Ch(i*16,6,i*16);
}
}
LCD_P8x16Str(44, 4, temp);
LCD_P8x16Str(44, 6, humidity);
if ( AF_DataRequest( &SampleApp_P2P_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_wenshidu_CLUSTERID,
4,
strTemp,
&SampleApp_TransID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
}
else
{
// Error occurred in request to send.
}
//3. 烟雾程序
void SampleApp_Send_AIR_Message( void )
{
byte TxBuff1[4];
if(DATA_PIN == 0)
{
TxBuff1[3]=0; //高电平时说明没有检测到气体。
//HalUARTWrite(0,"security\n", 9); //串口显示
HalLcdWriteString( "Air Security", HAL_LCD_LINE_1 ); //LCD显示
}
else
{
MicroWait (10000); // Wait 10ms
if(DATA_PIN == 1)
{
TxBuff1[3]=1; //当输出低电平时信号灯亮,检测到气体
//HalUARTWrite(0,"Got bad Air\n",12); //串口显示
HalLcdWriteString( "Bad Air", HAL_LCD_LINE_1 ); //LCD显示
}
}
TxBuff1[0]=b+0x30;
TxBuff1[1]=2+0x30;
TxBuff1[2]=0+0x30;
TxBuff1[3]=TxBuff1[3]+0x30;
if ( AF_DataRequest( &SampleApp_P2P_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_AIR_CLUSTERID,
4,
TxBuff1,
&SampleApp_TransID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
}
else
{
// Error occurred in request to send.
}
}
成果展示
链接:https://pan.baidu.com/s/1p6JslwTgG4v0C2Q1PkjHOw