Meter Reader for mbed 1768

Dependencies:   mbed

main.cpp

Committer:
harrisjunaid
Date:
2012-04-29
Revision:
0:c98a5d4d4855

File content as of revision 0:c98a5d4d4855:


#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();
        }
    }

}