Support library for reading the Kamstrup FlowIQ2000 water meter via its serial interface.
This library provides support for reading a Kamstrup FlowIQ2000 water meter's serial interface. Interfacing to the meter from the C027 board requires a small interface circuit (note that this diagram also includes a water pump control circuit, which is needed by the IotMessage library):
This library is intended for use with the WaterMeterDemo project.
WaterMeterApi.hpp@0:0730cba56168, 2015-05-22 (annotated)
- Committer:
- RobMeades
- Date:
- Fri May 22 11:40:35 2015 +0000
- Revision:
- 0:0730cba56168
Initial commit of FlowIQ2000 water meter support to mbed cloud.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
RobMeades | 0:0730cba56168 | 1 | /* Water Meter HW driver for Water Meter Demo |
RobMeades | 0:0730cba56168 | 2 | * |
RobMeades | 0:0730cba56168 | 3 | * Copyright (C) u-blox Melbourn Ltd |
RobMeades | 0:0730cba56168 | 4 | * u-blox Melbourn Ltd, Melbourn, UK |
RobMeades | 0:0730cba56168 | 5 | * |
RobMeades | 0:0730cba56168 | 6 | * All rights reserved. |
RobMeades | 0:0730cba56168 | 7 | * |
RobMeades | 0:0730cba56168 | 8 | * This source file is the sole property of u-blox Melbourn Ltd. |
RobMeades | 0:0730cba56168 | 9 | * Reproduction or utilization of this source in whole or part is |
RobMeades | 0:0730cba56168 | 10 | * forbidden without the written consent of u-blox Melbourn Ltd. |
RobMeades | 0:0730cba56168 | 11 | */ |
RobMeades | 0:0730cba56168 | 12 | |
RobMeades | 0:0730cba56168 | 13 | #ifndef WATER_METER_API_HPP |
RobMeades | 0:0730cba56168 | 14 | #define WATER_METER_API_HPP |
RobMeades | 0:0730cba56168 | 15 | |
RobMeades | 0:0730cba56168 | 16 | /** |
RobMeades | 0:0730cba56168 | 17 | * @file water_meter_api.h |
RobMeades | 0:0730cba56168 | 18 | * This file defines the API to the water meter HW |
RobMeades | 0:0730cba56168 | 19 | * for the MWC demo 2015. |
RobMeades | 0:0730cba56168 | 20 | */ |
RobMeades | 0:0730cba56168 | 21 | |
RobMeades | 0:0730cba56168 | 22 | // ---------------------------------------------------------------- |
RobMeades | 0:0730cba56168 | 23 | // HARDWARE |
RobMeades | 0:0730cba56168 | 24 | // The code in this library is setup to expect a FlowIQ2100 water |
RobMeades | 0:0730cba56168 | 25 | // meter to be connected through this circuit: |
RobMeades | 0:0730cba56168 | 26 | // |
RobMeades | 0:0730cba56168 | 27 | // C027N board Water Meter |
RobMeades | 0:0730cba56168 | 28 | // |
RobMeades | 0:0730cba56168 | 29 | // 5V o-------------------o-------------o------o Red (pwr/clk) |
RobMeades | 0:0730cba56168 | 30 | // | | |
RobMeades | 0:0730cba56168 | 31 | // | | |
RobMeades | 0:0730cba56168 | 32 | // | | |
RobMeades | 0:0730cba56168 | 33 | // | | |
RobMeades | 0:0730cba56168 | 34 | // | | |
RobMeades | 0:0730cba56168 | 35 | // | | |
RobMeades | 0:0730cba56168 | 36 | // | | |
RobMeades | 0:0730cba56168 | 37 | // | | | |
RobMeades | 0:0730cba56168 | 38 | // | | 10k Ohm | |
RobMeades | 0:0730cba56168 | 39 | // | | | |
RobMeades | 0:0730cba56168 | 40 | // | | |
RobMeades | 0:0730cba56168 | 41 | // 1k Ohm o-------------|------o Black (gnd) |
RobMeades | 0:0730cba56168 | 42 | // ____ / | |
RobMeades | 0:0730cba56168 | 43 | // D4 o--|____|--------| (transistor) | |
RobMeades | 0:0730cba56168 | 44 | // _\/ | |
RobMeades | 0:0730cba56168 | 45 | // | | | |
RobMeades | 0:0730cba56168 | 46 | // | | | 10k Ohm |
RobMeades | 0:0730cba56168 | 47 | // | | | |
RobMeades | 0:0730cba56168 | 48 | // | | |
RobMeades | 0:0730cba56168 | 49 | // D2 o--------------------------------o------o Green (data) |
RobMeades | 0:0730cba56168 | 50 | // | |
RobMeades | 0:0730cba56168 | 51 | // | |
RobMeades | 0:0730cba56168 | 52 | // Gnd o------------------o |
RobMeades | 0:0730cba56168 | 53 | // |
RobMeades | 0:0730cba56168 | 54 | // ---------------------------------------------------------------- |
RobMeades | 0:0730cba56168 | 55 | |
RobMeades | 0:0730cba56168 | 56 | // ---------------------------------------------------------------- |
RobMeades | 0:0730cba56168 | 57 | // GENERAL COMPILE-TIME CONSTANTS |
RobMeades | 0:0730cba56168 | 58 | // ---------------------------------------------------------------- |
RobMeades | 0:0730cba56168 | 59 | |
RobMeades | 0:0730cba56168 | 60 | // ---------------------------------------------------------------- |
RobMeades | 0:0730cba56168 | 61 | // CLASSES |
RobMeades | 0:0730cba56168 | 62 | // ---------------------------------------------------------------- |
RobMeades | 0:0730cba56168 | 63 | |
RobMeades | 0:0730cba56168 | 64 | class WaterMeterHandler { |
RobMeades | 0:0730cba56168 | 65 | public: |
RobMeades | 0:0730cba56168 | 66 | /// Constructor. |
RobMeades | 0:0730cba56168 | 67 | WaterMeterHandler (void); |
RobMeades | 0:0730cba56168 | 68 | /// Destructor. |
RobMeades | 0:0730cba56168 | 69 | ~WaterMeterHandler(void); |
RobMeades | 0:0730cba56168 | 70 | /// Initialise the water meter, ensuring that there |
RobMeades | 0:0730cba56168 | 71 | // is an electrical connection and that at least |
RobMeades | 0:0730cba56168 | 72 | // a single character can be correctly received from |
RobMeades | 0:0730cba56168 | 73 | // it (by checking parity). |
RobMeades | 0:0730cba56168 | 74 | // \param data pin to use for receiving data on the |
RobMeades | 0:0730cba56168 | 75 | // C027N board. |
RobMeades | 0:0730cba56168 | 76 | // \param pwrClk pin to use to send pwr/clk on the |
RobMeades | 0:0730cba56168 | 77 | // C027N board. |
RobMeades | 0:0730cba56168 | 78 | // \param clkRateHz the clock rate to use when |
RobMeades | 0:0730cba56168 | 79 | // reading out data bits. |
RobMeades | 0:0730cba56168 | 80 | // \return true if successful, otherwise false. |
RobMeades | 0:0730cba56168 | 81 | bool init (PinName dataPin = D2, PinName pwrClkPin = D4, uint32_t clkRateHz = 1000); |
RobMeades | 0:0730cba56168 | 82 | |
RobMeades | 0:0730cba56168 | 83 | /// Take a water volume reading from the meter. |
RobMeades | 0:0730cba56168 | 84 | // \param a pointer to somewhere to put the reading. |
RobMeades | 0:0730cba56168 | 85 | // Only written-to if the outcome is true. May be NULL, |
RobMeades | 0:0730cba56168 | 86 | // in which case the success check is still carried out. |
RobMeades | 0:0730cba56168 | 87 | // \\return success if true, otherwise false. |
RobMeades | 0:0730cba56168 | 88 | bool readLitres (uint32_t * pValue); |
RobMeades | 0:0730cba56168 | 89 | |
RobMeades | 0:0730cba56168 | 90 | /// Read the serial number from the meter. |
RobMeades | 0:0730cba56168 | 91 | // \param a pointer to somewhere to put the serial number. |
RobMeades | 0:0730cba56168 | 92 | // Only written-to if the outcome is true. May be NULL, |
RobMeades | 0:0730cba56168 | 93 | // in which case the success check is still carried out. |
RobMeades | 0:0730cba56168 | 94 | // \\return success if true, otherwise false. |
RobMeades | 0:0730cba56168 | 95 | bool readSerialNumber (uint32_t * pValue); |
RobMeades | 0:0730cba56168 | 96 | |
RobMeades | 0:0730cba56168 | 97 | /// Set debug to bool. |
RobMeades | 0:0730cba56168 | 98 | // \param onNotOff debug will come out if this is true. |
RobMeades | 0:0730cba56168 | 99 | // Default is no debug. |
RobMeades | 0:0730cba56168 | 100 | void setDebugOn (bool onNotOff); |
RobMeades | 0:0730cba56168 | 101 | |
RobMeades | 0:0730cba56168 | 102 | private: |
RobMeades | 0:0730cba56168 | 103 | /// Set this to true once initialised. |
RobMeades | 0:0730cba56168 | 104 | bool ready; |
RobMeades | 0:0730cba56168 | 105 | /// Set this to true for debug. |
RobMeades | 0:0730cba56168 | 106 | bool debug; |
RobMeades | 0:0730cba56168 | 107 | /// The pin on the C027N board to use for data reception |
RobMeades | 0:0730cba56168 | 108 | // from the meter. |
RobMeades | 0:0730cba56168 | 109 | DigitalIn *pData; |
RobMeades | 0:0730cba56168 | 110 | /// The pin on the C027N board to use for pwr/clock to |
RobMeades | 0:0730cba56168 | 111 | // the meter. |
RobMeades | 0:0730cba56168 | 112 | DigitalOut *pPwrClk; |
RobMeades | 0:0730cba56168 | 113 | /// The length of half a clock period in microseconds to |
RobMeades | 0:0730cba56168 | 114 | // use when reading data off the water meter. |
RobMeades | 0:0730cba56168 | 115 | uint32_t halfClkPeriodUs; |
RobMeades | 0:0730cba56168 | 116 | /// Power on the meter (by toggling the pwrClk line until |
RobMeades | 0:0730cba56168 | 117 | // the data line goes low). |
RobMeades | 0:0730cba56168 | 118 | // \return true if successful, otherwise false. |
RobMeades | 0:0730cba56168 | 119 | bool pwrOn (void); |
RobMeades | 0:0730cba56168 | 120 | /// Power off the meter (by setting the pwrClk line low). |
RobMeades | 0:0730cba56168 | 121 | void pwrOff (void); |
RobMeades | 0:0730cba56168 | 122 | /// Read a start bit from the meter. |
RobMeades | 0:0730cba56168 | 123 | // \return true if successful, otherwise false. |
RobMeades | 0:0730cba56168 | 124 | bool readStartBit (void); |
RobMeades | 0:0730cba56168 | 125 | /// Read a stop bit from the meter. |
RobMeades | 0:0730cba56168 | 126 | // \return true if successful, otherwise false. |
RobMeades | 0:0730cba56168 | 127 | bool readStopBit (void); |
RobMeades | 0:0730cba56168 | 128 | /// Toggle the pwrClk line to read a data bit from the water |
RobMeades | 0:0730cba56168 | 129 | // meter. |
RobMeades | 0:0730cba56168 | 130 | // \return true if a 1 is read, false if a 0 is read. |
RobMeades | 0:0730cba56168 | 131 | bool readDataBit (void); |
RobMeades | 0:0730cba56168 | 132 | /// Check that parity is good |
RobMeades | 0:0730cba56168 | 133 | // \return true if successful, otherwise false. |
RobMeades | 0:0730cba56168 | 134 | bool parityIsGood (uint8_t numOnes); |
RobMeades | 0:0730cba56168 | 135 | /// Read a character from the meter and check parity. |
RobMeades | 0:0730cba56168 | 136 | // \param pChar a pointer to a location where the received |
RobMeades | 0:0730cba56168 | 137 | // character can be stored. Only filled in if the read is |
RobMeades | 0:0730cba56168 | 138 | // successful. May be NULL, in which case the parity check |
RobMeades | 0:0730cba56168 | 139 | // is still carried out. |
RobMeades | 0:0730cba56168 | 140 | // \return true if successful, otherwise false. |
RobMeades | 0:0730cba56168 | 141 | bool readChar (char *pChar); |
RobMeades | 0:0730cba56168 | 142 | /// Read a whole fixed-length message from the water meter. |
RobMeades | 0:0730cba56168 | 143 | // Reading stops when a parity error occurs or when the |
RobMeades | 0:0730cba56168 | 144 | // requested number of bytes has been read. |
RobMeades | 0:0730cba56168 | 145 | // \param pChars a pointer to a location where the received |
RobMeades | 0:0730cba56168 | 146 | // data bytes can be stored. Must be at least numBytes big. |
RobMeades | 0:0730cba56168 | 147 | // \return the number of bytes read. |
RobMeades | 0:0730cba56168 | 148 | // \param numChars the number of bytes to read. |
RobMeades | 0:0730cba56168 | 149 | uint32_t readFixedLengthMsg (char *pChars, uint32_t numChars); |
RobMeades | 0:0730cba56168 | 150 | /// Convert a number of characters representing a decimal |
RobMeades | 0:0730cba56168 | 151 | // value into a uint32_t value. |
RobMeades | 0:0730cba56168 | 152 | // Characters are assumed to be ASCII, single byte values. |
RobMeades | 0:0730cba56168 | 153 | // If a non-numeric character (including a decimal point) |
RobMeades | 0:0730cba56168 | 154 | // is found then fail is returned. |
RobMeades | 0:0730cba56168 | 155 | // \param pChars a pointer to the start of the character array. |
RobMeades | 0:0730cba56168 | 156 | // \param numChars the number of characters. |
RobMeades | 0:0730cba56168 | 157 | // \param pValue the uint32_t value, only written-to if |
RobMeades | 0:0730cba56168 | 158 | // success is returned. May be NULL in which case the success |
RobMeades | 0:0730cba56168 | 159 | // check is still carried out. |
RobMeades | 0:0730cba56168 | 160 | // \return true if successful, otherwise false. |
RobMeades | 0:0730cba56168 | 161 | bool decCharsToUint32 (char * pChars, uint32_t numChars, uint32_t * pValue); |
RobMeades | 0:0730cba56168 | 162 | }; |
RobMeades | 0:0730cba56168 | 163 | |
RobMeades | 0:0730cba56168 | 164 | #endif |
RobMeades | 0:0730cba56168 | 165 | |
RobMeades | 0:0730cba56168 | 166 | // End Of File |