Paul van der Wielen
/
MT382_serial
Reading Utility metering data using MBED
mt382.h@4:1ebd1aabaa16, 2014-05-16 (annotated)
- Committer:
- pwheels
- Date:
- Fri May 16 21:44:01 2014 +0000
- Revision:
- 4:1ebd1aabaa16
- Parent:
- 2:b386810af678
unfortunnally the driver had some odd gps test code in it, this has been corrected
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
pwheels | 0:bacf1c9b9afc | 1 | #ifndef MBED_H |
pwheels | 0:bacf1c9b9afc | 2 | #include "mbed.h" |
pwheels | 0:bacf1c9b9afc | 3 | #endif |
pwheels | 0:bacf1c9b9afc | 4 | /* |
pwheels | 0:bacf1c9b9afc | 5 | * Copyright (c) 2012 Paul van der Wielen, Pro-Serv |
pwheels | 0:bacf1c9b9afc | 6 | * |
pwheels | 0:bacf1c9b9afc | 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
pwheels | 0:bacf1c9b9afc | 8 | * of this software and associated documentation files (the "Software"), to use |
pwheels | 0:bacf1c9b9afc | 9 | * and implement the software for none commercial reason and usage only and |
pwheels | 0:bacf1c9b9afc | 10 | * subject to the following conditions: |
pwheels | 0:bacf1c9b9afc | 11 | * |
pwheels | 0:bacf1c9b9afc | 12 | * The above copyright notice and this permission notice shall be included in |
pwheels | 0:bacf1c9b9afc | 13 | * all copies or substantial portions of the Software. |
pwheels | 0:bacf1c9b9afc | 14 | * |
pwheels | 0:bacf1c9b9afc | 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
pwheels | 0:bacf1c9b9afc | 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
pwheels | 0:bacf1c9b9afc | 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
pwheels | 0:bacf1c9b9afc | 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
pwheels | 0:bacf1c9b9afc | 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
pwheels | 0:bacf1c9b9afc | 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
pwheels | 0:bacf1c9b9afc | 21 | * THE SOFTWARE. |
pwheels | 0:bacf1c9b9afc | 22 | * |
pwheels | 0:bacf1c9b9afc | 23 | * Usage and assumptions: |
pwheels | 0:bacf1c9b9afc | 24 | * interfacing an MT382 smart meter using P1 port, schematic is fairly simple and |
pwheels | 0:bacf1c9b9afc | 25 | * provides for an isolated connection to the outside world, schematic to foloow in due time. |
pwheels | 0:bacf1c9b9afc | 26 | * |
pwheels | 0:bacf1c9b9afc | 27 | * Overview of used record codes & formats |
pwheels | 0:bacf1c9b9afc | 28 | * 0-0:96.1.1(5A424556303035303936303530313132) Serialno meter in hexadecimal ascii code |
pwheels | 1:633092f351c6 | 29 | * 1-0:1.8.1(00185.000*kWh) * Total consumpion tarif 1 (night) |
pwheels | 1:633092f351c6 | 30 | * 1-0:1.8.2(00084.000*kWh) * Total consumpion tarif 2 (day) |
pwheels | 1:633092f351c6 | 31 | * 1-0:2.8.1(00013.000*kWh) * Total delivery tarif 1 (night) |
pwheels | 1:633092f351c6 | 32 | * 1-0:2.8.2(00019.000*kWh) * Total delivery tarif 2 (day) |
pwheels | 1:633092f351c6 | 33 | * 0-0:96.14.0(0001) 1 Actual tarif (1) |
pwheels | 1:633092f351c6 | 34 | * 1-0:1.7.0(0000.98*kW) * Current usage |
pwheels | 1:633092f351c6 | 35 | * 1-0:2.7.0(0000.00*kW) * Current delivery |
pwheels | 1:633092f351c6 | 36 | * 0-0:17.0.0(999*A) Maximum current by phase |
pwheels | 1:633092f351c6 | 37 | * 0-0:96.3.10(1) Position of switch |
pwheels | 1:633092f351c6 | 38 | * 0-0:96.13.1() 1 Message (numeric) |
pwheels | 1:633092f351c6 | 39 | * 0-0:96.13.0() 1 Message (text) |
pwheels | 1:633092f351c6 | 40 | * 0-1:24.1.0(3) Other equipment on M-Bus |
pwheels | 1:633092f351c6 | 41 | * 0-1:96.1.0(3238313031353431323030333330313132) Serialno of gasmeter |
pwheels | 1:633092f351c6 | 42 | * 0-1:24.3.0(120517020000)(08)(60)(1)(0-1:24.2.1)(m3) Time of last gas measurement (120517020000 = 17 mei 2012 2uur |
pwheels | 1:633092f351c6 | 43 | * (00124.477) * Total consumption gas |
pwheels | 1:633092f351c6 | 44 | * 0-1:24.4.0(1) Position of gas valve? |
pwheels | 1:633092f351c6 | 45 | * *-Implemented, 1-planned for later date |
pwheels | 0:bacf1c9b9afc | 46 | */ |
pwheels | 0:bacf1c9b9afc | 47 | |
pwheels | 0:bacf1c9b9afc | 48 | namespace MT { |
pwheels | 0:bacf1c9b9afc | 49 | |
pwheels | 0:bacf1c9b9afc | 50 | class MT382 { |
pwheels | 0:bacf1c9b9afc | 51 | |
pwheels | 0:bacf1c9b9afc | 52 | protected: |
pwheels | 0:bacf1c9b9afc | 53 | DigitalOut *_out; |
pwheels | 0:bacf1c9b9afc | 54 | Timeout *_delay; |
pwheels | 0:bacf1c9b9afc | 55 | Serial *_dev; |
pwheels | 0:bacf1c9b9afc | 56 | float _defDelay; |
pwheels | 0:bacf1c9b9afc | 57 | int _defBaud; |
pwheels | 0:bacf1c9b9afc | 58 | int _defBits; |
pwheels | 0:bacf1c9b9afc | 59 | int _defParity; |
pwheels | 0:bacf1c9b9afc | 60 | int _defStop; |
pwheels | 0:bacf1c9b9afc | 61 | // array with items to find in data stream |
pwheels | 0:bacf1c9b9afc | 62 | char _l_mt[7][8]; |
pwheels | 0:bacf1c9b9afc | 63 | char _mt_temp[32]; |
pwheels | 0:bacf1c9b9afc | 64 | char _mt_line[64]; |
pwheels | 0:bacf1c9b9afc | 65 | char _mt_data[512]; |
pwheels | 0:bacf1c9b9afc | 66 | double _mt_res[7]; |
pwheels | 0:bacf1c9b9afc | 67 | // stream status (1 = start char , 2 = stop char) |
pwheels | 0:bacf1c9b9afc | 68 | int _mt_sts; |
pwheels | 0:bacf1c9b9afc | 69 | int _mt_pnt; |
pwheels | 0:bacf1c9b9afc | 70 | int _mt_flg; |
pwheels | 0:bacf1c9b9afc | 71 | |
pwheels | 0:bacf1c9b9afc | 72 | void init(PinName po, PinName tx, PinName rx) { |
pwheels | 0:bacf1c9b9afc | 73 | _out = new DigitalOut( po ); |
pwheels | 0:bacf1c9b9afc | 74 | _out->write(1); |
pwheels | 0:bacf1c9b9afc | 75 | _dev = new Serial(tx, rx); |
pwheels | 0:bacf1c9b9afc | 76 | _delay = new Timeout; |
pwheels | 0:bacf1c9b9afc | 77 | _defBaud = 9600; |
pwheels | 0:bacf1c9b9afc | 78 | _defBits = 7; |
pwheels | 0:bacf1c9b9afc | 79 | _defParity = 2; |
pwheels | 0:bacf1c9b9afc | 80 | _defStop = 1; |
pwheels | 0:bacf1c9b9afc | 81 | setComm(); |
pwheels | 0:bacf1c9b9afc | 82 | } |
pwheels | 0:bacf1c9b9afc | 83 | |
pwheels | 0:bacf1c9b9afc | 84 | public: |
pwheels | 0:bacf1c9b9afc | 85 | |
pwheels | 0:bacf1c9b9afc | 86 | friend class Timeout; |
pwheels | 0:bacf1c9b9afc | 87 | |
pwheels | 0:bacf1c9b9afc | 88 | /* PinDetect constructor(s) & overloading */ |
pwheels | 0:bacf1c9b9afc | 89 | MT382() { error("Provide valid PinName for out, tx & rx"); } |
pwheels | 0:bacf1c9b9afc | 90 | |
pwheels | 0:bacf1c9b9afc | 91 | MT382(PinName po, PinName tx, PinName rx) { |
pwheels | 0:bacf1c9b9afc | 92 | init( po, tx, rx); |
pwheels | 0:bacf1c9b9afc | 93 | } |
pwheels | 0:bacf1c9b9afc | 94 | |
pwheels | 0:bacf1c9b9afc | 95 | /* PinDetect destructor */ |
pwheels | 0:bacf1c9b9afc | 96 | ~MT382() { |
pwheels | 0:bacf1c9b9afc | 97 | if ( _delay ) delete( _delay ); |
pwheels | 0:bacf1c9b9afc | 98 | if ( _out ) delete( _out ); |
pwheels | 0:bacf1c9b9afc | 99 | if ( _dev ) delete( _dev ); |
pwheels | 0:bacf1c9b9afc | 100 | } |
pwheels | 0:bacf1c9b9afc | 101 | |
pwheels | 0:bacf1c9b9afc | 102 | // adjust communication parameters as needed |
pwheels | 0:bacf1c9b9afc | 103 | void setComm(int baud = 9600, int bits = 7, int parity = 2, int stop = 1) { |
pwheels | 0:bacf1c9b9afc | 104 | _defBaud = baud; |
pwheels | 0:bacf1c9b9afc | 105 | _dev->baud(_defBaud); |
pwheels | 0:bacf1c9b9afc | 106 | _defBits = bits; |
pwheels | 0:bacf1c9b9afc | 107 | _defParity = parity; |
pwheels | 0:bacf1c9b9afc | 108 | _defStop = stop; |
pwheels | 0:bacf1c9b9afc | 109 | |
pwheels | 0:bacf1c9b9afc | 110 | switch (_defParity) { |
pwheels | 0:bacf1c9b9afc | 111 | case 0: |
pwheels | 0:bacf1c9b9afc | 112 | _dev->format(_defBits, Serial::None, _defStop); |
pwheels | 0:bacf1c9b9afc | 113 | break; |
pwheels | 0:bacf1c9b9afc | 114 | case 1: |
pwheels | 0:bacf1c9b9afc | 115 | _dev->format(_defBits, Serial::Odd, _defStop); |
pwheels | 0:bacf1c9b9afc | 116 | break; |
pwheels | 0:bacf1c9b9afc | 117 | case 2: |
pwheels | 0:bacf1c9b9afc | 118 | _dev->format(_defBits, Serial::Even, _defStop); |
pwheels | 0:bacf1c9b9afc | 119 | break; |
pwheels | 0:bacf1c9b9afc | 120 | default: |
pwheels | 0:bacf1c9b9afc | 121 | _dev->format(_defBits, Serial::None, _defStop); |
pwheels | 0:bacf1c9b9afc | 122 | break; |
pwheels | 0:bacf1c9b9afc | 123 | } |
pwheels | 0:bacf1c9b9afc | 124 | } |
pwheels | 0:bacf1c9b9afc | 125 | |
pwheels | 0:bacf1c9b9afc | 126 | // adjust timeout value |
pwheels | 0:bacf1c9b9afc | 127 | void setTime(float maxtime = 5.0) { |
pwheels | 0:bacf1c9b9afc | 128 | _defDelay = maxtime; |
pwheels | 0:bacf1c9b9afc | 129 | } |
pwheels | 0:bacf1c9b9afc | 130 | |
pwheels | 0:bacf1c9b9afc | 131 | // adjust the value match strings |
pwheels | 0:bacf1c9b9afc | 132 | void setMatch(char * m0 = "", char * m1 = "", char * m2 = "", |
pwheels | 0:bacf1c9b9afc | 133 | char * m3 = "", char * m4 = "", char * m5 = "", char * m6 = "") { |
pwheels | 0:bacf1c9b9afc | 134 | strcpy (_l_mt[0],m0); |
pwheels | 0:bacf1c9b9afc | 135 | strcpy (_l_mt[1],m1); |
pwheels | 0:bacf1c9b9afc | 136 | strcpy (_l_mt[2],m2); |
pwheels | 0:bacf1c9b9afc | 137 | strcpy (_l_mt[3],m3); |
pwheels | 0:bacf1c9b9afc | 138 | strcpy (_l_mt[4],m4); |
pwheels | 0:bacf1c9b9afc | 139 | strcpy (_l_mt[5],m5); |
pwheels | 0:bacf1c9b9afc | 140 | strcpy (_l_mt[6],m6); |
pwheels | 0:bacf1c9b9afc | 141 | } |
pwheels | 0:bacf1c9b9afc | 142 | |
pwheels | 0:bacf1c9b9afc | 143 | // signal time out condition |
pwheels | 0:bacf1c9b9afc | 144 | void isr_delay() { |
pwheels | 0:bacf1c9b9afc | 145 | _mt_sts = 0x80; |
pwheels | 0:bacf1c9b9afc | 146 | _delay->detach(); |
pwheels | 0:bacf1c9b9afc | 147 | } |
pwheels | 0:bacf1c9b9afc | 148 | |
pwheels | 0:bacf1c9b9afc | 149 | // get data from 'smart meter' |
pwheels | 0:bacf1c9b9afc | 150 | int getReading () { |
pwheels | 0:bacf1c9b9afc | 151 | |
pwheels | 0:bacf1c9b9afc | 152 | _delay->attach(this, &MT382::isr_delay, _defDelay); |
pwheels | 0:bacf1c9b9afc | 153 | _out->write(0); |
pwheels | 0:bacf1c9b9afc | 154 | _mt_pnt = 0; |
pwheels | 0:bacf1c9b9afc | 155 | _mt_sts = 0; |
pwheels | 0:bacf1c9b9afc | 156 | |
pwheels | 0:bacf1c9b9afc | 157 | while((_mt_sts & 0x02) == 0 && (_mt_sts & 0x80) == 0) { |
pwheels | 0:bacf1c9b9afc | 158 | if(_dev->readable()) { |
pwheels | 1:633092f351c6 | 159 | // get available character from MT382 |
pwheels | 1:633092f351c6 | 160 | char mt_tst = _dev->getc(); |
pwheels | 1:633092f351c6 | 161 | // remove any ascii NULL character |
pwheels | 1:633092f351c6 | 162 | if (mt_tst != 0x00) { |
pwheels | 1:633092f351c6 | 163 | _mt_data[_mt_pnt++] = mt_tst; |
pwheels | 1:633092f351c6 | 164 | if (_mt_data[_mt_pnt-1] == '/') { |
pwheels | 1:633092f351c6 | 165 | _mt_sts = 1; |
pwheels | 1:633092f351c6 | 166 | } |
pwheels | 1:633092f351c6 | 167 | if (_mt_data[_mt_pnt-1] == '!') { |
pwheels | 1:633092f351c6 | 168 | _mt_sts = _mt_sts | 0x02; |
pwheels | 1:633092f351c6 | 169 | _delay->detach(); |
pwheels | 1:633092f351c6 | 170 | _out->write(1); |
pwheels | 1:633092f351c6 | 171 | } |
pwheels | 0:bacf1c9b9afc | 172 | } |
pwheels | 0:bacf1c9b9afc | 173 | } |
pwheels | 0:bacf1c9b9afc | 174 | } |
pwheels | 1:633092f351c6 | 175 | |
pwheels | 0:bacf1c9b9afc | 176 | int mt_tmp = 0; |
pwheels | 0:bacf1c9b9afc | 177 | _mt_flg = 0; |
pwheels | 0:bacf1c9b9afc | 178 | int mt_elem = sizeof(_l_mt)/sizeof(_l_mt[0]); |
pwheels | 0:bacf1c9b9afc | 179 | if ((_mt_sts == 0x03) && ((_mt_sts & 0x80) == 0)){ |
pwheels | 0:bacf1c9b9afc | 180 | for (int buf_pnt = 0; buf_pnt <= _mt_pnt; buf_pnt++) { |
pwheels | 0:bacf1c9b9afc | 181 | _mt_line[mt_tmp++] = _mt_data[buf_pnt]; |
pwheels | 0:bacf1c9b9afc | 182 | if (_mt_data[buf_pnt] == 0x0a) { |
pwheels | 0:bacf1c9b9afc | 183 | _mt_line[mt_tmp] = 0x00; |
pwheels | 0:bacf1c9b9afc | 184 | if ((_mt_flg & 0x01) == 0x01) { |
pwheels | 0:bacf1c9b9afc | 185 | // special case handling -> param 5 |
pwheels | 0:bacf1c9b9afc | 186 | strncpy (_mt_temp, strchr(_mt_line,'(') + 1, strchr(_mt_line,')') - strchr(_mt_line,'(') - 1); |
pwheels | 0:bacf1c9b9afc | 187 | _mt_res[(_mt_flg >> 4) & 0x0f] = strtod(_mt_temp, NULL); |
pwheels | 0:bacf1c9b9afc | 188 | _mt_flg = 0; |
pwheels | 0:bacf1c9b9afc | 189 | } |
pwheels | 0:bacf1c9b9afc | 190 | for (int j = 0; j < mt_elem; j++) { |
pwheels | 0:bacf1c9b9afc | 191 | if (strstr (_mt_line, _l_mt[j])) { |
pwheels | 0:bacf1c9b9afc | 192 | for (int cnt = 0; cnt < sizeof(_mt_temp); cnt++) { |
pwheels | 0:bacf1c9b9afc | 193 | _mt_temp[cnt] = 0x00; |
pwheels | 0:bacf1c9b9afc | 194 | } |
pwheels | 0:bacf1c9b9afc | 195 | if (j < 6) { |
pwheels | 0:bacf1c9b9afc | 196 | strncpy (_mt_temp, strchr(_mt_line,'(') + 1, strchr(_mt_line,'*') - strchr(_mt_line,'(') - 1); |
pwheels | 0:bacf1c9b9afc | 197 | } else { |
pwheels | 0:bacf1c9b9afc | 198 | // flag special case due to inconsistent formating of raw data |
pwheels | 0:bacf1c9b9afc | 199 | _mt_flg = j << 4 | 0x01; |
pwheels | 0:bacf1c9b9afc | 200 | } |
pwheels | 0:bacf1c9b9afc | 201 | _mt_res[j] = strtod(_mt_temp, NULL); |
pwheels | 0:bacf1c9b9afc | 202 | } |
pwheels | 0:bacf1c9b9afc | 203 | } |
pwheels | 0:bacf1c9b9afc | 204 | mt_tmp = 0; |
pwheels | 0:bacf1c9b9afc | 205 | } |
pwheels | 0:bacf1c9b9afc | 206 | } |
pwheels | 0:bacf1c9b9afc | 207 | } else { |
pwheels | 0:bacf1c9b9afc | 208 | return -1; |
pwheels | 0:bacf1c9b9afc | 209 | } |
pwheels | 0:bacf1c9b9afc | 210 | return 0; |
pwheels | 0:bacf1c9b9afc | 211 | } |
pwheels | 0:bacf1c9b9afc | 212 | |
pwheels | 1:633092f351c6 | 213 | // return raw data character count |
pwheels | 1:633092f351c6 | 214 | int getCount(void) { |
pwheels | 1:633092f351c6 | 215 | return _mt_pnt; |
pwheels | 1:633092f351c6 | 216 | } |
pwheels | 1:633092f351c6 | 217 | |
pwheels | 0:bacf1c9b9afc | 218 | // return selected value |
pwheels | 0:bacf1c9b9afc | 219 | double getValue(int param = 0) { |
pwheels | 0:bacf1c9b9afc | 220 | return _mt_res[param]; |
pwheels | 0:bacf1c9b9afc | 221 | } |
pwheels | 1:633092f351c6 | 222 | |
pwheels | 1:633092f351c6 | 223 | // return raw data |
pwheels | 1:633092f351c6 | 224 | char * getRaw(void) { |
pwheels | 1:633092f351c6 | 225 | return _mt_data; |
pwheels | 2:b386810af678 | 226 | } |
pwheels | 2:b386810af678 | 227 | |
pwheels | 2:b386810af678 | 228 | // return pointer to array with collected data |
pwheels | 2:b386810af678 | 229 | double * getArray(void) { |
pwheels | 2:b386810af678 | 230 | return _mt_res; |
pwheels | 2:b386810af678 | 231 | } |
pwheels | 0:bacf1c9b9afc | 232 | }; |
pwheels | 0:bacf1c9b9afc | 233 | |
pwheels | 0:bacf1c9b9afc | 234 | }; // namespace MT ends. |
pwheels | 0:bacf1c9b9afc | 235 | |
pwheels | 0:bacf1c9b9afc | 236 | using namespace MT; |