Wireless Gas Meter Reading System Meter Reader Module Code
Diff: main.cpp
- Revision:
- 0:fb08b3e9f2f4
- Child:
- 1:3830cdfa2c1b
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Apr 17 15:54:41 2012 +0000 @@ -0,0 +1,354 @@ + +#include "mbed.h" +#include "Serial.h" + +//PC Serial for DEBUG Messages +Serial pc(USBTX, USBRX); + +//Sensor Input +InterruptIn SensorIn(p21);//Sensor Sensed Needle and sends voltaga (minimum > 2V) +Timer SensorIn_Filter; +//mbed Pin Wake +//InterruptIn wake(p22); + + +//Battery Voltage +AnalogIn supplyin(p15);//Connection From XBEE Power Supply + +//Gas Consumption Variable +unsigned GasCounter = 0; +//unsigned GasCounter = 1;//Increment at ev reset/////////.......DEBUG + +//Meter Reader Data Storage +LocalFileSystem fs("fs");//mbed internal flash storage +//FILE *previous;// Pointer for previous_readings.txt (Gas consumption data not yet transmitted ) +//unsigned previous_consumption = 0;//Variable for storing previous consumption (unsigned => only positive value) + +//Indicators +DigitalOut SafeShutdown(LED1);//User can now power off +DigitalOut BoilerOn(LED2);//Indicate to turn on boiler +DigitalOut XbeeOff(LED3);//XBEE can not get power +DigitalOut EndDeviceOff(LED3);//Flash LED2 when End Device is not accessable +DigitalOut PreviousData(LED4);//Previous shutdown was not safe or coordinator was not present +DigitalOut CounterIncrement(LED4);//Indicates Counter Increment +BusOut BatteryLow(LED1, LED2, LED3, LED4);// Battery is Low (Flash from LED1 to LED4) + +//XBEE Connection +Serial xbee(p9, p10);//XBEE Dout (xbee p2) <--> mbed rx p10, XBEE Din (xbee p3) <--> mbed tx p9 +DigitalOut xbee_reset(p8);//XBEE Reset (xbee p5) <--> mbed digital out p8 +DigitalIn xbee_power(p11);//XBEE Power Indicator (xbee p13) Digital In +//DigitalIn xbee_associate(p12);//XBEE Association (xbee p15) Digital In +DigitalIn xbee_CTS(p13);//XBEE pin 12 CTS High = Signal to stop data transfer over UART +DigitalOut xbee_sleep(p14);//XBEE SLEEP_RQ (p9) +unsigned xbeeon_off = 0;//Default OFF + +/*************************************************************************************************** + Functions +***************************************************************************************************/ + +//Event Based Functions +void MeterReader_On();//Called at module power on +void Reading_Handler();//Manage "GasCounter" Transfer and File Update +void SensorInput();//Called at sensor input + +//File Handling Functions +unsigned CheckCounterFile();//Check reading counter file +void UpdateCounterFile();//Keeps Record of GasCounter +void PreviousData_Indication();//Called when improper module shutdown or coordinator not found + +//XBee Handling Functions +void TransmitGasCounter( unsigned forced);//Transmit Readings +void Xbee_Check();//Xbee Power and Xbee Range +unsigned Xbee_RangeCheck();//XBEE Range Check (Check for END DEVICE) +unsigned Xbee_On_Off();//Return XBEE Power Status +void XbeeSleep(unsigned sleep);//XBEE Pin Sleep +void Xbee_Reset();//Reset xbee +unsigned CTS();//returns 1 when mbed is Clear To Send +void EndDevice_Indication();//Flash LED2 + +//Battery Check Functions +unsigned BatteryCheck();//Check Battery Voltage +void BatteryLow_Indication();//Flash all LEDs indicating Low Battery + +//Boiler On Indication +void BoilerSafeOn(); +/**************************************************************************************************** + Battery Check +****************************************************************************************************/ + +unsigned BatteryCheck() { + + float battery = 0.0;//Stores sum of three supplyin values + float supply = 0.0;//Stores real battery voltage + + for (int i=0; i<3; i++) {//Takes three values 0-2 + battery = battery + supplyin.read(); + //pc.printf("Loop %d\t", i);//////////////.......DEBUG + wait(0.2); + } + supply = (battery /3) * 3.5 ;//Reading Avg * Logic High (battery '1' => 100% '3.5') + //pc.printf("%f\n", supply);/////////.......DEBUG + battery = 0.0; + if ( supply < 3.1 )//Voltage dropped is greater than 0.4V (max of 0.5V drop is acceptable for operation) + return 1; + else + return 0; +} + +void BatteryLow_Indication() {////Flash from LED1 to LED4 + for (int i=0; i<4; i++) { + BatteryLow = 1 << i; + wait(0.25); + } +} + +/**************************************************************** + XBEE Control Functios +****************************************************************/ + +void TransmitGasCounter(unsigned forced) { + pc.printf("\nTransmitGasCounter called GasCounter = %u",GasCounter);//.............DEBUG + if ( (GasCounter >= 5) || (forced == 1) ) {//Previous Gas Counter (Due To Improper Shut Down) (Forced used for previous GasCounter) + while ( !(CTS()) );//Wait Till mbed is not Clear To Send + xbee.putc('*');//Special Character Identifying Reading Transmit + xbee.putc('\r'); + //xbee.printf("%u\r", GasCounter);//%u", GasCounter); + xbee.printf("%u", GasCounter);//***TRANSMIT GAS COUNTER*** + GasCounter = 0; + //UpdateCounterFile(); + } +} + +void Xbee_Check() {//Check Xbee Power and Range + while (Xbee_On_Off() );//Execute Till XBEE is Powered OFF + while (Xbee_RangeCheck() );//Execute Till End DEVICE is not Powered ON +} + +unsigned Xbee_On_Off() {//Return XBEE Power Status + if (!xbee_power) {//XBEE Powered On + XbeeOff = 1;//XBEE OFF Indicator + xbeeon_off = 1; + return 1;//Retrun XBEE is OFF + } else {//Xbee is On + XbeeOff = 0;//Will Send a Ground Signal (LED will Blink) + xbeeon_off = 0; + return 0;//Return XBEE is ON + } +} + +unsigned Xbee_RangeCheck() { + + char response[5]; + wait(10);//Allow Time For Communication + for (int i=1 ; i<=3 ; i++) {//Enter XBEE in AT Command Mode + xbee.putc('+'); + wait(0.05); + } + xbee.scanf("%s",response);//Get Xbee Response + //pc.printf("\n%s\n",response);//////////////...........DEBUG + + //XBEE IS IN COMMAND MODE AND OK RESPONSE IS READ + xbee.printf("ATNDLOGGER");//AT(AT Command Mode) DN(Destination Node Command) LOGGER(Node Identifier "NI" for END DEVICE) + xbee.putc('\r');//Carriage Return + xbee.scanf("%s",response);//Get Response + //pc.printf("\n%s\n",response);/////////////.............DEBUG + xbee.printf("ATCN"); + xbee.putc('\r'); + if (response[0] == 'E') {//Could Not Find End Device ("ERROR"\r returned) + pc.printf("\nCound not find END DEVICE\n");/////////.............DEBUG + EndDevice_Indication(); + return 1;//Return No End Device + + } else {//End Device is Active ("OK"\r returned) + //pc.printf("\nEnd Device Responded\n");/////////.............DEBUG + return 0;//Return End Device is ON + } +} + +unsigned CTS() {//returns 1 when mbed is Clear To Send + if (xbee_CTS == 0) return 1;//mbed is Clear To Send + else return 0; +} + +void Xbee_Reset() { + xbee_reset = 0;//RESET + wait_ms(1); + xbee_reset = 1;//Back To Operation + wait_ms(1); +} + +void XbeeSleep(unsigned sleep) { + //pc.printf("\nSleep Called\n");////////////............DEBUG + if (sleep == 1) xbee_sleep = 1;//SLEEP_RQ pin 9 + else xbee_sleep = 0; + wait(2);//Time for XBEE to Respond +} + +void EndDevice_Indication() {//Flash LED2 => NO END DEVICE + for (unsigned i=0; i<=5 ; i++) { + EndDeviceOff = 1; + wait(0.2); + EndDeviceOff = 0; + wait(0.2); + EndDeviceOff = 1; + wait(0.2); + EndDeviceOff = 0; + } +} + +void BoilerSafeOn() {//LED2 + BoilerOn = 1; + wait(4); + BoilerOn = 0; +} +/**************************************************************** + FILE MANIPULATION FUNCTIONS + +Checks if reading record file is present. File is created if not +found or else it will be read for previous untransmitted counter. +Variable previous_consumption has global scope. +****************************************************************/ + +unsigned CheckCounterFile() {// Checks For Previous Readings + + FILE *counter;// Pointer for COUNTER.txt (Gas consumption data) + + if ( (counter = fopen("/fs/COUNTER.txt", "r")) == NULL) {// Check if the file exist + pc.printf("File not found so created\n");//////////////////////................DEBUG + counter = fopen("/fs/COUNTER.txt", "w");//File created mode = w + + } else {//File exist + + fscanf( counter,"%u", &GasCounter) ;//Update GasCounter + pc.printf( "previous value %u\n", GasCounter);////////................DEBUG + + + } + fclose(counter);//close file handler + + //Return status for indication activation + if (GasCounter > 0) { + + return 1;//Return There Were Previous Readings + } else return 0;//Return No Previous Reading + +} + +void UpdateCounterFile() { + pc.printf("\nUpdateCounterFile called GasCounter = %u",GasCounter);//.............DEBUG + unsigned PreviousCounter = 0; + FILE *counter;// Pointer for COUNTER.txt (Gas consumption data) + if (GasCounter == 0) + counter = fopen("/fs/COUNTER.txt", "w");//Contents Discarded + else { + counter = fopen("/fs/COUNTER.txt", "r"); + fscanf( counter,"%u", &PreviousCounter); + fclose(counter); + counter = fopen("/fs/COUNTER.txt", "w");//Contents Discarded + GasCounter = GasCounter + PreviousCounter; + fprintf( counter, "%u", GasCounter ); + pc.printf("\rCounter file update: %u\r");///////......DEBUG + GasCounter = 0; + } + fclose(counter); +} + + + +void PreviousData_Indication() {//LED4 is Flashed (Indicating previous shut down was not safe) + for (unsigned i=0; i<=5 ; i++) { + PreviousData = 1; + wait(0.2); + PreviousData = 0; + wait(0.2); + PreviousData = 1; + wait(0.2); + PreviousData = 0; + + } +} + +///////////////////////////////////////////////////////////////// +void MeterReader_On() { + pc.printf("\nMeterReader_On called GasCounter = %u",GasCounter);//.............DEBUG + //Battery Voltage Check + while ( BatteryCheck() )//Till Battery is not sufficiently charged + BatteryLow_Indication();//Battery Low Indication + + //Last Shutdown Check + if ( CheckCounterFile() )//GasCounter update from previous untransmitted record and return status + PreviousData_Indication();//LED 4 Flash + + + //Reset XBEE + Xbee_Reset(); + + //Check XBEE Power and Communication + Xbee_Check();//Checks for XBEE and provides LED indication + //Will not move forward in case of an error + + //Check For Previous Counter and Transmit if any + if (GasCounter > 0)TransmitGasCounter(1);//FORCE TO TRANSMIT PREVIOUS READINGS IF ANY + //TransmitGasCounter will reset GasCounter after reading transmition + + //XBEE to sleep + XbeeSleep(1); + + //Boiler Can Be Turned On + BoilerSafeOn(); + +// Xbee_Check();////XBee should be powered off//////..........DEBUG +// SafeShutdown = 1;//////////////.............DEBUG + // deepsleep(); + //SafeShutdown = 0;//////////////////..........DEBUG + +} + +void Reading_Handler() { + pc.printf("\nReading_Handler called GasCounter = %u",GasCounter);//.............DEBUG + if (GasCounter >= 4) {//Function Internal Check + XbeeSleep(0); + wait(5); + TransmitGasCounter(1);//Readings are above limit SO FORCE TRANSMIT + + UpdateCounterFile();//Update GasCounter in file (Record is maintained in file to prevent power off data loss) + } + + + XbeeSleep(1); + //SafeShutdown = !SafeShutdown;////LED1//////////.............DEBUG + //deepsleep(); +} + +void SensorInput() { + if ((SensorIn_Filter.read()) == 0) { + SensorIn_Filter.start(); + CounterIncrement = 1;///////LED2.............DEBUG + } + while (1) { + if ( (SensorIn_Filter.read() ) >= 2) {//Readings within last 2 sec from call are ignored as SensorIn noise + + GasCounter = GasCounter + 1;//Update Gas Counter as a result of sensor input + pc.printf("\nSensorInput incremented GasCountre: %u", GasCounter);//////////.........DEBUG + + SensorIn_Filter.stop(); + SensorIn_Filter.reset(); + CounterIncrement = 0; + break; + } + } +} + +int main() { + + SensorIn.rise(&SensorInput); + MeterReader_On(); + while (1) { + + if (GasCounter>=5) { + + Reading_Handler(); + } + } + +}