📄 sensor.c
字号:
/**************************************************************************** * * MODULE: WSN - Router * * COMPONENT: $RCSfile: Sensor.c,v $ * * VERSION: $Name: HEAD $ * * REVISION: $Revision: 1.6 $ * * DATED: $Date: 2008/03/26 15:29:42 $ * * STATUS: $State: Exp $ * * AUTHOR: IDM * * DESCRIPTION: * * Implements a Wireless Sensor Network Router using the Jennic Jenie stack. * Reads temperature, humidity and battery voltage and transmits these to * network coordinator. Assumes code is running on a evaluation kit sensor * board. * * * Update history * $Log: Sensor.c,v $ * Revision 1.6 2008/03/26 15:29:42 mlook * Removed use of services, devices now send directly to coordinator. * * Revision 1.5 2008/01/15 15:42:41 mlook * Removed ZigBee reference. * * Revision 1.4 2007/11/21 16:11:28 mlook * JPI updates - completed * * Revision 1.3 2007/11/21 08:44:49 mlook * First stage of JPI update * * Revision 1.2 2007/11/20 16:21:42 mlook * Updated to recent Jenie template. * * Revision 1.1 2007/11/02 12:32:47 mlook * Adding new application notes * * Revision 1.7 2007/07/12 11:03:03 ndani * Add simple descriptor after network has started * * Revision 1.6 2007/07/12 10:03:34 ndani * * * LAST MODIFIED BY: $Author: mlook $ * $Modtime: $ * **************************************************************************** * * This software is owned by Jennic and/or its supplier and is protected * under applicable copyright laws. All rights are reserved. We grant You, * and any third parties, a license to use this software solely and * exclusively on Jennic products. You, and any third parties must reproduce * the copyright and warranty notice and any other legend of ownership on each * copy or partial copy of the software. * * THIS SOFTWARE IS PROVIDED "AS IS". JENNIC MAKES NO WARRANTIES, WHETHER * EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, * ACCURACY OR LACK OF NEGLIGENCE. JENNIC SHALL NOT, IN ANY CIRCUMSTANCES, * BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, SPECIAL, * INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON WHATSOEVER. * * Copyright Jennic Ltd 2005, 2006, 2007. All rights reserved * ****************************************************************************//****************************************************************************//*** Include files ***//****************************************************************************/#include <jendefs.h>#include <JPI.h>#include <ALSdriver.h>#include <HTSdriver.h>#include <Printf.h>#include <gdb.h>#include "Network.h"#include "Sensor.h"/****************************************************************************//*** Macro Definitions ***//****************************************************************************/#define SENSOR_IDLE 5 /* Sensor idle time between readings in 100ms intervals *//****************************************************************************//*** Type Definitions ***//****************************************************************************//* Battery reading state definitions */typedef enum{ E_STATE_READ_BATT_VOLT_IDLE, E_STATE_READ_BATT_VOLT_START, E_STATE_READ_BATT_VOLTS_ADC_CONVERTING, E_STATE_READ_BATT_VOLTS_COMPLETE, E_STATE_READ_BATT_VOLTS_READY}teStateReadBattVolt;/* Temperature/Humidity Sensor - reading state definitions */typedef enum{ E_STATE_READ_TEMP_HUMID_IDLE, E_STATE_READ_TEMP_HUMID_START, E_STATE_READ_HUMID_RUNNING, E_STATE_READ_TEMP_HUMID_COMPLETE, E_STATE_READ_TEMP_START, E_STATE_READ_TEMP_HUMID_RUNNING, E_STATE_READ_TEMP_COMPLETE, E_STATE_READ_TEMP_HUMID_READY}teStateReadTempHumidity;/* Sensor reading data */typedef struct{ uint16 u16Batt; uint16 u16Temp; uint16 u16Humid;} tsSensorReading;/****************************************************************************//*** Local Function Prototypes ***//****************************************************************************/PRIVATE void vSensor_Print(uint64, tsSensorReading *);PRIVATE void vSensor_ReadTempHumidity(void);PRIVATE void vSensor_ReadBatteryVoltage(void);PRIVATE void vSensor_Format(uint8 *, tsSensorReading *);PRIVATE void vSensor_Unformat(tsSensorReading *, uint8 *);/****************************************************************************//*** Local Variables ***//****************************************************************************/PRIVATE uint16 u16Idle = 0;PRIVATE teStateReadBattVolt eStateBatt;PRIVATE teStateReadTempHumidity eStateTempHumid;PRIVATE tsSensorReading sSensorReading;/****************************************************************************//*** Local Functions ***//****************************************************************************//**************************************************************************** * * NAME: vSensor_Init * * DESCRIPTION: * Initialise the temperature/humidity sensor and set the ADC to measure the * supply voltage. * ****************************************************************************/PUBLIC void vSensor_Init(void){ /* Initialise temp/humidity sensor interface and start reading */ vHTSreset(); eStateTempHumid = E_STATE_READ_TEMP_HUMID_START; /* Initialise ADC for internal battery voltage measurement and start reading */ eStateBatt = E_STATE_READ_BATT_VOLT_START; vJPI_AnalogueConfigure( E_JPI_AP_REGULATOR_ENABLE, E_JPI_AP_INT_DISABLE, E_JPI_AP_SAMPLE_2, E_JPI_AP_CLOCKDIV_2MHZ, E_JPI_AP_INTREF); /* Wait until the analogue peripheral regulator has come up before setting the ADC. */ while(!bJPI_APRegulatorEnabled()); vJPI_AnalogueEnable(E_JPI_ANALOGUE_ADC, E_JPI_AP_INPUT_RANGE_2, E_JPI_ADC_SINGLE_SHOT, E_JPI_ADC_SRC_VOLT, FALSE, 0); /* Zero idle timer */ u16Idle = 0;}/**************************************************************************** * * NAME: vSensor_Tick * * DESCRIPTION: * * Called by a BOS timer expiry. Reads sensor data and if complete prints and * transmits to coordinator. * ****************************************************************************/PUBLIC void vSensor_Tick(void){ /* Is our network up ? */ if (bNetwork_Up()) { /* Read sensor data */ vSensor_ReadTempHumidity(); vSensor_ReadBatteryVoltage(); /* If sensor reads are compete */ if ((eStateBatt == E_STATE_READ_BATT_VOLTS_READY) && (eStateTempHumid == E_STATE_READ_TEMP_HUMID_READY)) { /* Print the data locally - will only work if UART was opened */ vSensor_Print(0, &sSensorReading); /* Are we not the coordinator ? */ if (eNetwork_DeviceType() != E_JENIE_COORDINATOR) { /* Format sensor reading */ uint8 au8Data[6]; vSensor_Format(au8Data, &sSensorReading); /* Attempt to send data to coordinator */ (void) eNetwork_Tx(0ULL, 6, au8Data); } /* Go idle */ eStateBatt = E_STATE_READ_BATT_VOLT_IDLE; eStateTempHumid = E_STATE_READ_TEMP_HUMID_IDLE; /* Are we an end device ? */ if (eNetwork_DeviceType() == E_JENIE_END_DEVICE) { /* Set the sleep period (this is set in ms) */ (void) eNetwork_Sleep(SENSOR_IDLE * 1000, E_JENIE_SLEEP_OSCON_RAMON); } else { /* Start the idle timer (this is set in 100ms) */ u16Idle = SENSOR_IDLE * 10; } } /* Are we currently idle ? */ if (u16Idle > 0) { /* Decrement timer */ u16Idle--; /* Time to stop being idle ? */ if (u16Idle == 0) { /* Start the next reading */ eStateBatt = E_STATE_READ_BATT_VOLT_START; eStateTempHumid = E_STATE_READ_TEMP_HUMID_START; } } }}/**************************************************************************** * * NAME: vSensor_Remote * * DESCRIPTION: * * Unformat and print a reading from a remote sensor * ****************************************************************************/PUBLIC void vSensor_Remote(uint64 u64Address, uint16 u16Length, uint8 *pu8Data){ tsSensorReading sRemoteReading; /* Have we got 6 bytes of data ? */ if (u16Length == 6) { /* Unformat the data */ vSensor_Unformat(&sRemoteReading, pu8Data); /* Print the data - will only work if the UART was opened */ vSensor_Print(u64Address, &sRemoteReading); }}/**************************************************************************** * * NAME: vSensor_Print * * DESCRIPTION: * * Prints sensor address and data * ****************************************************************************/PRIVATE void vSensor_Print(uint64 u64Address, tsSensorReading *psSensorReading){ /* Has the network layer opened the UART for us ? */ if (bNetwork_UartUp()) { /* Local reading from this node ? */ if (u64Address == 0) { vPrintf("\n Address = Local\n"); } /* Reading from remote node */ else { vPrintf("\n Address = %x:%x\n", (uint32) (u64Address >> 32), (uint32) (u64Address & 0xFFFFFFFF)); } /* Output sensor readings */ vPrintf(" Voltage = %d\n", psSensorReading->u16Batt); vPrintf("Temperature = %d\n", psSensorReading->u16Temp); vPrintf(" Humidity = %d\n", psSensorReading->u16Humid); }}/**************************************************************************** * * NAME: vReadBatteryVoltage * * DESCRIPTION: * * Uses ADC to read supply voltage. Measurement is performed using a state * machine to ensure that it never blocks. * ****************************************************************************/PRIVATE void vSensor_ReadBatteryVoltage(void){ uint16 u16AdcReading; switch(eStateBatt) { case E_STATE_READ_BATT_VOLT_START: vJPI_AnalogueStartSample(); eStateBatt = E_STATE_READ_BATT_VOLTS_ADC_CONVERTING; break; case E_STATE_READ_BATT_VOLTS_ADC_CONVERTING: if (!bJPI_AdcPoll()) { eStateBatt = E_STATE_READ_BATT_VOLTS_COMPLETE; } break; case E_STATE_READ_BATT_VOLTS_COMPLETE: u16AdcReading = u16JPI_AnalogueAdcRead(); /* Input range is 0 to 2.4V. ADC has full scale range of 12 bits. Therefore a 1 bit change represents a voltage of approx 586uV */ sSensorReading.u16Batt = ((uint32)((uint32)(u16AdcReading * 586) + ((uint32)(u16AdcReading * 586) >> 1))) / 1000; eStateBatt = E_STATE_READ_BATT_VOLTS_READY; break; case E_STATE_READ_BATT_VOLTS_READY: break; default: break; }}/**************************************************************************** * * NAME: vReadTempHumidity * * DESCRIPTION: * * Read temperature/humidity sensor. Reading is performed using a state machine * to ensure that it never blocks. * ****************************************************************************/PRIVATE void vSensor_ReadTempHumidity(void){ switch(eStateTempHumid) { case E_STATE_READ_TEMP_HUMID_START: vHTSstartReadHumidity(); eStateTempHumid = E_STATE_READ_HUMID_RUNNING; break; case E_STATE_READ_HUMID_RUNNING: if ((u32JPI_DioReadInput() & HTS_DATA_DIO_BIT_MASK) == 0) { eStateTempHumid = E_STATE_READ_TEMP_HUMID_COMPLETE; } break; case E_STATE_READ_TEMP_HUMID_COMPLETE: sSensorReading.u16Humid = u16HTSreadHumidityResult(); eStateTempHumid = E_STATE_READ_TEMP_START; break; case E_STATE_READ_TEMP_START: vHTSstartReadTemp(); eStateTempHumid = E_STATE_READ_TEMP_HUMID_RUNNING; break; case E_STATE_READ_TEMP_HUMID_RUNNING: if ((u32JPI_DioReadInput() & HTS_DATA_DIO_BIT_MASK) == 0) { eStateTempHumid = E_STATE_READ_TEMP_COMPLETE; } break; case E_STATE_READ_TEMP_COMPLETE: sSensorReading.u16Temp = u16HTSreadTempResult(); eStateTempHumid = E_STATE_READ_TEMP_HUMID_READY; break; case E_STATE_READ_TEMP_HUMID_READY: break; default: break; }}/**************************************************************************** * * NAME: vSensor_Format * * DESCRIPTION: * * Format data from senor reading to uint8 array * ****************************************************************************/PRIVATE void vSensor_Format(uint8 *pu8Data, tsSensorReading *psSensorReading){ pu8Data[0] = (uint8)(psSensorReading->u16Batt >> 8); pu8Data[1] = (uint8)(psSensorReading->u16Batt & 0xFF); pu8Data[2] = (uint8)(psSensorReading->u16Temp >> 8); pu8Data[3] = (uint8)(psSensorReading->u16Temp & 0xFF); pu8Data[4] = (uint8)(psSensorReading->u16Humid >> 8); pu8Data[5] = (uint8)(psSensorReading->u16Humid & 0xFF);}/**************************************************************************** * * NAME: vSensor_Unformat * * DESCRIPTION: * * Unformat data from uint8 array to senor reading * ****************************************************************************/PRIVATE void vSensor_Unformat(tsSensorReading *psSensorReading, uint8 *pu8Data){ psSensorReading->u16Batt = ((uint16) pu8Data[0] << 8) | (uint16) pu8Data[1]; psSensorReading->u16Temp = ((uint16) pu8Data[2] << 8) | (uint16) pu8Data[3]; psSensorReading->u16Humid = ((uint16) pu8Data[4] << 8) | (uint16) pu8Data[5];}/****************************************************************************//*** END OF FILE ***//****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -