基于CC2530/CC2430 的温度采集系统--DS18B20
DS18B20是常用的温度传感器。CC2530 采集DS18B20 可以实现温度采集系统等等。
模块链接:https://item.taobao.com/item.htm?id=541308617329
代码使用Zstack 的sample 工程作为基本框架。
主要实现内容:一个节点采集DS18B20并发送到另一个节点,并在节点连接的LCD上显示温度信息。
节点数量:2个(可扩展)
数据传输: 终端节点到协调器节点
显示方式:LCD(可扩展串口显示)
A: 终端节点采集DS18B20 主要代码分析:
直接在应用层初始化函数中添加如下代码
- // Received whenever the device changes state in the network
- case ZDO_STATE_CHANGE:
- SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
- if ( (SampleApp_NwkState == DEV_ZB_COORD)
- || (SampleApp_NwkState == DEV_ROUTER)
- || (SampleApp_NwkState == DEV_END_DEVICE) )
- {
- initial_lcd();
- clear_screen();
- HalLcdWriteString( "DS18B20 Test ", HAL_LCD_LINE_1 );
- // full_display();
- // Start sending the periodic message in a regular interval.
- if(SampleApp_NwkState != DEV_ZB_COORD)
- {
- osal_start_timerEx( SampleApp_TaskID,
- SAMPLEAPP_SEND_PERIODIC_MSG_EVT,
- SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT );
- }
- }
- else
- {
- // Device is no longer in the network
- }
- break;
当设备启动成功后会初始化液晶,并在液晶上显示“DS18B20”,然后根据设备类型,当设备不是协调器(路由器和终端节点都可以采集数据)定时触发事件SAMPLEAPP_SEND_PERIODIC_MSG_EVT。
- // Send a message out - This event is generated by a timer
- // (setup in SampleApp_Init()).
- if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT )
- {
- // Send the periodic message
- SampleApp_SendPeriodicMessage();
- // Setup to send message again in normal period (+ a little jitter)
- osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT,
- (SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT + (osal_rand() & 0x00FF)) );
- // return unprocessed events
- return (events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT);
- }
SAMPLEAPP_SEND_PERIODIC_MSG_EVT 事件的处理函数,我们可以看到调用了函数SampleApp_SendPeriodicMessage(),这个函数主要是采集DS18B20,并将数据发送到协调器节点。 然后再次调用定时器触发SAMPLEAPP_SEND_PERIODIC_MSG_EVT 事件,形成周期性不停的采集发送-采集发送。
- /*********************************************************************
- * @fn SampleApp_SendPeriodicMessage
- *
- * @brief Send the periodic message.
- *
- * @param none
- *
- * @return none
- */
- void SampleApp_SendPeriodicMessage( void )
- {
- uint8 SensorBuf[2];
- SensorBuf[0]=Read_Temperature()/10+0x30;
- SensorBuf[1]=Read_Temperature()%10+0x30;
- HalLcdWriteString( SensorBuf, HAL_LCD_LINE_2 );
- //HalUARTWrite(0,&SensorBuf[1],i);
- // HalUARTWrite(SERIAL_APP_PORT,&SensorBuf[0],i);
- if ( AF_DataRequest( &SampleApp_Periodic_DstAddr,
- &SampleApp_epDesc,
- SAMPLEAPP_FLASH_CLUSTERID,
- 2,
- &SensorBuf[0],
- &SampleApp_TransID,
- AF_DISCV_ROUTE,
- AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
- {
- //Successfully requested to be sent
- }
- else
- {
- // Error occurred in request to send.
- }
- }
在这个函数中使用了Read_tempeature() 读取温度信息,具体DS18B20 处理函数和C51 的一样,主要要注意时序。 上面就是采集节点部分主要代码。
B 汇集节点,汇集远程节点数据
上面的代码分析到有终端节点发来的数据,我们回顾上面的代码
- if ( AF_DataRequest( &SampleApp_Periodic_DstAddr,
- &SampleApp_epDesc,
- SAMPLEAPP_FLASH_CLUSTERID,
- 2,
- &SensorBuf[0],
- &SampleApp_TransID,
- AF_DISCV_ROUTE,
- AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
- {
- //Successfully requested to be sent
- }
- else
- {
- // Error occurred in request to send.
- }
对应的cluster 是 SAMPLEAPP_FLASH_CLUSTERID,那么我们看协调器采集节点的处理函数
- /*********************************************************************
- * @fn SampleApp_MessageMSGCB
- *
- * @brief Data message processor callback. This function processes
- * any incoming data - probably from other devices. So, based
- * on cluster ID, perform the intended action.
- *
- * @param none
- *
- * @return none
- */
- void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
- {
- uint16 flashTime;
- uint8 buffer[2];
- switch ( pkt->clusterId )
- {
- case SAMPLEAPP_PERIODIC_CLUSTERID:
- break;
- case SAMPLEAPP_FLASH_CLUSTERID:
- flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] );
- HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) );
- buffer[0]=pkt->cmd.Data[0];
- buffer[1]=pkt->cmd.Data[1];
- HalLcdWriteString( buffer, HAL_LCD_LINE_2 );
- break;
- }
- }
由下面的代码在显示屏的第二行显示温度信息(第一行显示DS18B20 Test,初始化与终端节点使用相同的代码)
- buffer[0]=pkt->cmd.Data[0];
- buffer[1]=pkt->cmd.Data[1];
- HalLcdWriteString( buffer, HAL_LCD_LINE_2 );