Embed:
(wiki syntax)
Show/hide line numbers
VBus.cpp
00001 /* 00002 Copyright (c) 2010 Wimpie 00003 00004 Based on the VBus� Protocol Specification see http://goo.gl/HP6ZY 00005 and http://hobbyelektronik.org/w/index.php/VBus-Decoder 00006 00007 VBus� en Resol� are registrated trademarks see http://www.resol.de 00008 00009 Debugtrace.h -> http://mbed.org/users/snatch59/programs/DebugTrace/gpdz54 00010 00011 Permission is hereby granted, free of charge, to any person obtaining a copy 00012 of this software and associated documentation files (the "Software"), to deal 00013 in the Software without restriction, including without limitation the rights 00014 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00015 copies of the Software, and to permit persons to whom the Software is 00016 furnished to do so, subject to the following conditions: 00017 00018 The above copyright notice and this permission notice shall be included in 00019 all copies or substantial portions of the Software. 00020 00021 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00022 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00023 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00024 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00025 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00026 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00027 THE SOFTWARE. 00028 */ 00029 00030 #include "VBus.h" 00031 #define DEBUG 0 00032 00033 #if DEBUG 00034 #include "DebugTrace.h" 00035 DebugTrace pc_VBus(ON, TO_SERIAL); 00036 #endif 00037 00038 static uint8_t CalcCrc(const unsigned char *Buffer, int Offset, int Length); 00039 float CalcTemp(char Byte1, char Byte2); 00040 00041 VBus::VBus(PinName tx, PinName rx) 00042 : _Serial(tx, rx) { 00043 _sdcard=false; 00044 _all=false; 00045 ClearMax(); 00046 Init(0); 00047 } 00048 00049 void VBus::Init(int addr=0) { 00050 00051 _Serial.baud(9600); 00052 _Serial.format(8,Serial::None,1); 00053 m_timeout=2; 00054 00055 if (addr!=0) 00056 networkaddress=addr; 00057 else 00058 networkaddress=ResolAddress; 00059 00060 } 00061 00062 void VBus::SDcardAvailable(bool status) { 00063 _sdcard=status; 00064 } 00065 00066 void VBus::InjectSeptet(unsigned char *Buffer, int Offset, int Length) { 00067 for (unsigned int i = 0; i < Length; i++) { 00068 if (Septet & (1 << i)) { 00069 Buffer [Offset + i] |= 0x80; 00070 } 00071 } 00072 } 00073 00074 bool VBus::Read() { 00075 int F; 00076 char c; 00077 bool start,stop,quit; 00078 00079 start = true; 00080 stop = false; 00081 quit = false; 00082 Bufferlength=0; 00083 00084 m_timer.reset(); 00085 m_timer.start(); 00086 00087 while ((!stop) and (!quit)) { 00088 if (_Serial.readable()) { 00089 c=_Serial.getc(); 00090 00091 if (c == Sync) { 00092 if (start) { 00093 start=false; 00094 Bufferlength=0; 00095 //#if DEBUG 00096 // pc_VBus.traceOut("\r\n"); 00097 //#endif 00098 } else { 00099 if (Bufferlength<20) { 00100 m_timer.stop(); 00101 m_timer.reset(); 00102 m_timer.start(); 00103 Bufferlength=0; 00104 } else 00105 stop=true; 00106 } 00107 } 00108 //#if DEBUG 00109 // pc_VBus.traceOut("%X ",c); 00110 //#endif 00111 if ((!start) and (!stop)) { 00112 Buffer[Bufferlength]=c; 00113 Bufferlength++; 00114 } 00115 } 00116 if ((m_timeout > 0) && (m_timer.read() > m_timeout )) { 00117 quit=true; 00118 //#if DEBUG 00119 // pc_VBus.traceOut("Timeout %i",m_timer.read()); 00120 //#endif 00121 } 00122 } 00123 00124 m_timer.stop(); 00125 00126 #if DEBUG 00127 00128 pc_VBus.traceOut("\r\nBuffer %i \r\n",Bufferlength); 00129 for (int i=0; i<Bufferlength;i++) { 00130 pc_VBus.traceOut("%X ",Buffer[i]); 00131 } 00132 pc_VBus.traceOut("\r\n"); 00133 00134 #endif 00135 if (!quit) { 00136 Destination_address = Buffer[2] << 8; 00137 Destination_address |= Buffer[1]; 00138 Source_address = Buffer[4] << 8; 00139 Source_address |= Buffer[3]; 00140 ProtocolVersion = (Buffer[5]>>4) + (Buffer[5] &(1<<15)); 00141 00142 Command = Buffer[7] << 8; 00143 Command |= Buffer[6]; 00144 Framecnt = Buffer[8]; 00145 Checksum = Buffer[9]; //TODO check if Checksum is OK 00146 #if DEBUG 00147 pc_VBus.traceOut("\r\nDestination %X",Destination_address); 00148 pc_VBus.traceOut("\r\nSource %X",Source_address); 00149 pc_VBus.traceOut("\r\nProtocol version %X",ProtocolVersion); 00150 pc_VBus.traceOut("\r\nCommand %X",Command); 00151 pc_VBus.traceOut("\r\nFramecnt %X", Framecnt); 00152 pc_VBus.traceOut("\r\nChecksum %X\r\n", Checksum); 00153 #endif 00154 // only analyse Commands 0x100 = Packet Contains data for slave 00155 // with correct length = 10 bytes for HEADER and 6 Bytes for each frame 00156 00157 if ((Command==0x0100) and (Bufferlength==10+Framecnt*6)) { 00158 00159 // Frame info for the Resol ConergyDT5 00160 // check VBusprotocol specification for other products 00161 00162 // This library is made for the ConergyDT5 (0x3271) 00163 00164 //Offset Size Mask Name Factor Unit 00165 //0 2 Temperature sensor 1 0.1 �C 00166 //2 2 Temperature sensor 2 0.1 �C 00167 //4 2 Temperature sensor 3 0.1 �C 00168 //6 2 Temperature sensor 4 0.1 �C 00169 //8 1 Pump speed pump 1 1 00170 //9 1 Pump speed pump 2 1 00171 //10 1 Relay mask 1 00172 //11 1 Error mask 1 00173 //12 2 System time 1 00174 //14 1 Scheme 1 00175 //15 1 1 Option PostPulse 1 00176 //15 1 2 Option thermostat 1 00177 //15 1 4 Option HQM 1 00178 //16 2 Operating hours relay 1 1 00179 //18 2 Operating hours relay 2 1 00180 //20 2 Heat quantity 1 Wh 00181 //22 2 Heat quantity 1000 Wh 00182 //24 2 Heat quantity 1000000 Wh 00183 //26 2 Version 0.01 00184 // 00185 // Each frame has 6 bytes 00186 // byte 1 to 4 are data bytes -> MSB of each bytes 00187 // byte 5 is a septet and contains MSB of bytes 1 to 4 00188 // byte 6 is a checksum 00189 // 00190 //******************* Frame 1 ******************* 00191 00192 F=FOffset; 00193 00194 Septet=Buffer[F+FSeptet]; 00195 InjectSeptet(Buffer,F,4); 00196 00197 // 'collector1' Temperatur Sensor 1, 15 bits, factor 0.1 in C 00198 Sensor1_temp =CalcTemp(Buffer[F+1], Buffer[F]); 00199 // 'store1' Temperature sensor 2, 15 bits, factor 0.1 in C 00200 Sensor2_temp =CalcTemp(Buffer[F+3], Buffer[F+2]); 00201 00202 //******************* Frame 2 ******************* 00203 F=FOffset+FLength; 00204 00205 Septet=Buffer[F+FSeptet]; 00206 InjectSeptet(Buffer,F,4); 00207 00208 Sensor3_temp =CalcTemp(Buffer[F+1], Buffer[F]); 00209 Sensor4_temp =CalcTemp(Buffer[F+3], Buffer[F+2]); 00210 00211 //******************* Frame 3 ******************* 00212 F=FOffset+FLength*2; 00213 00214 Septet=Buffer[F+FSeptet]; 00215 InjectSeptet(Buffer,F,4); 00216 00217 PumpSpeed1 = (Buffer[F] & 0X7F); 00218 PumpSpeed2 = (Buffer[F+1] & 0X7F); 00219 RelaisMask = Buffer[F+2]; 00220 ErrorMask = Buffer[F+3]; 00221 00222 //******************* Frame 4 ******************* 00223 F=FOffset+FLength*3; 00224 00225 Septet=Buffer[F+FSeptet]; 00226 InjectSeptet(Buffer,F,4); 00227 #if DEBUG 00228 pc_VBus.traceOut("\r\nFrame 4 %i %i %i %i ",Buffer[F],Buffer[F+1],Buffer[F+2],Buffer[F+3]); 00229 #endif 00230 SystemTime = Buffer[F+1] << 8 | Buffer[F]; 00231 Scheme = Buffer[F+2]; 00232 00233 OptionPostPulse = (Buffer[F+3] & 0x01); 00234 OptionThermostat = ((Buffer[F+3] & 0x02) >> 1); 00235 OptionHQM = ((Buffer[F+3] & 0x04) >> 2); 00236 00237 //******************* Frame 5 ******************* 00238 F=FOffset+FLength*4; 00239 00240 Septet=Buffer[F+FSeptet]; 00241 InjectSeptet(Buffer,F,4); 00242 #if DEBUG 00243 pc_VBus.traceOut("\r\nFrame 5 %i %i %i %i ",Buffer[F],Buffer[F+1],Buffer[F+2],Buffer[F+3]); 00244 #endif 00245 OperatingHoursRelais1=Buffer[F+1] << 8 | Buffer[F]; 00246 OperatingHoursRelais2=Buffer[F+3] << 8| Buffer[F+2]; 00247 00248 //******************* Frame 6 ******************* 00249 F=FOffset+FLength*5; 00250 00251 Septet=Buffer[F+FSeptet]; 00252 InjectSeptet(Buffer,F,4); 00253 #if DEBUG 00254 pc_VBus.traceOut("\r\nFrame 6 %i %i %i %i ",Buffer[F],Buffer[F+1],Buffer[F+2],Buffer[F+3]); 00255 #endif 00256 HeatQuantity=(Buffer[F+1] << 8 | Buffer[F])+(Buffer[F+3] << 8| Buffer[F+2])*1000; 00257 00258 //******************* Frame 7 ******************* 00259 F=FOffset+FLength*6; 00260 00261 Septet=Buffer[F+FSeptet]; 00262 InjectSeptet(Buffer,F,4); 00263 #if DEBUG 00264 pc_VBus.traceOut("\r\nFrame 7 %i %i %i %i ",Buffer[F],Buffer[F+1],Buffer[F+2],Buffer[F+3]); 00265 #endif 00266 HeatQuantity=HeatQuantity+(Buffer[F+1] << 8 | Buffer[F])*1000000; 00267 Version=Buffer[F+3] << 8| Buffer[F+2]; 00268 00269 ///******************* End of frames **************** 00270 00271 if (Sensor1_temp>Sensor1_temp_max) 00272 Sensor1_temp_max=Sensor1_temp; 00273 if (Sensor2_temp>Sensor2_temp_max) 00274 Sensor2_temp_max=Sensor2_temp; 00275 if (Sensor3_temp>Sensor3_temp_max) 00276 Sensor3_temp_max=Sensor3_temp; 00277 if (Sensor4_temp>Sensor4_temp_max) 00278 Sensor4_temp_max=Sensor4_temp; 00279 00280 #if DEBUG 00281 00282 /* pc_VBus.traceOut("\r\nSensor 1 %f", Sensor1_temp); 00283 pc_VBus.traceOut("\r\nSensor 2 %f", Sensor2_temp); 00284 pc_VBus.traceOut("\r\nSensor 3 %f", Sensor3_temp); 00285 pc_VBus.traceOut("\r\nSensor 4 %f", Sensor4_temp); 00286 pc_VBus.traceOut("\r\nPumpSpeed1 %i", PumpSpeed1); 00287 pc_VBus.traceOut("\r\nPumpSpeed2 %i", PumpSpeed2); 00288 pc_VBus.traceOut("\r\nRelaismask %i", RelaisMask); 00289 pc_VBus.traceOut("\r\nErrorMask %i", ErrorMask); 00290 pc_VBus.traceOut("\r\nSystemTime %i", SystemTime); 00291 pc_VBus.traceOut("\r\nSystem %i", Scheme); 00292 pc_VBus.traceOut("\r\nOptionPostPulse %i", OptionPostPulse); 00293 pc_VBus.traceOut("\r\nOptionThermostat %i", OptionThermostat); 00294 pc_VBus.traceOut("\r\nOptionHQM %i", OptionHQM); 00295 pc_VBus.traceOut("\r\nOperatingHoursRelais1 %i", OperatingHoursRelais1); 00296 pc_VBus.traceOut("\r\nOperatingHoursRelais2 %i", OperatingHoursRelais2);*/ 00297 pc_VBus.traceOut("\r\nHeatQuantity %i", HeatQuantity); 00298 00299 #endif 00300 } 00301 } 00302 00303 return !quit; 00304 } 00305 00306 void VBus::SaveToSDcard(char* datetime, char* date,char* dayfn) { 00307 char fn[17]; 00308 strcpy(fn,"/sd/vb"); 00309 strcat(fn,dayfn); 00310 strcat(fn,".csv"); 00311 00312 //**************** 00313 // filename vbyymmdd.csv 00314 // 00315 // detailed dayinfo, each 5 minutes 00316 // 00317 // dd.mm.yy hh:mm:ss;v1;v2;v3;v4;v5;v6;v7;... 00318 // 00319 //**************** 00320 #if DEBUG 00321 pc_VBus.traceOut("%s;%4.1f;%4.1f;%4.1f;%4.1f;%i;%i;%i;%i;%i;%i;%i;%i;%i;%i;%i%;%i;%i\r\n",datetime, 00322 Sensor1_temp, Sensor2_temp,Sensor3_temp, Sensor4_temp, 00323 PumpSpeed1,PumpSpeed2, 00324 RelaisMask,ErrorMask,SystemTime,Scheme,OptionPostPulse, 00325 OptionThermostat, OptionHQM, OperatingHoursRelais1,OperatingHoursRelais2,HeatQuantity,Version 00326 ); 00327 #endif 00328 00329 if (_sdcard) { 00330 FILE *fp = fopen(fn, "a"); 00331 if (fp) { 00332 fprintf(fp,"%s;%4.1f;%4.1f;%4.1f;%4.1f;%i;%i;%i;%i;%i;%i;%i;%i;%i;%i;%i%;%i;%i\r\n",datetime, 00333 Sensor1_temp, Sensor2_temp,Sensor3_temp, Sensor4_temp, 00334 PumpSpeed1,PumpSpeed2, 00335 RelaisMask,ErrorMask,SystemTime,Scheme,OptionPostPulse, 00336 OptionThermostat, OptionHQM, OperatingHoursRelais1,OperatingHoursRelais2,HeatQuantity,Version 00337 ); 00338 fclose(fp); 00339 } 00340 } 00341 } 00342 00343 void VBus::ClearMax() { 00344 Sensor1_temp_max=0.0; 00345 Sensor2_temp_max=0.0; 00346 Sensor3_temp_max=0.0; 00347 Sensor4_temp_max=0.0; 00348 } 00349 00350 void VBus::make_Header (unsigned int DAdr,unsigned int SAdr,unsigned char Ver,unsigned int Cmd,unsigned char AFrames) { 00351 unsigned char Buffer[10]={Sync,(uint8_t)DAdr,DAdr>>8,(uint8_t)SAdr,SAdr>>8,Ver,(uint8_t)Cmd,Cmd>>8,AFrames}; 00352 Buffer[9]=CalcCrc(Buffer,1,8); 00353 for (unsigned bo=0;bo<=9;bo++) { 00354 _Serial.putc(Buffer[bo]); 00355 } 00356 } 00357 00358 static uint8_t CalcCrc(const unsigned char *Buffer, int Offset, int Length) { 00359 static uint8_t Crc= 0x7F; 00360 00361 for (unsigned int i = 0; i < Length; i++) { 00362 Crc = (Crc - Buffer [Offset + i]) & 0x7F; 00363 } 00364 return Crc; 00365 } 00366 00367 float CalcTemp(char Byte1, char Byte2) { 00368 int v; 00369 v = Byte1 << 8 | Byte2; 00370 00371 if (Byte1 == 0xFF) 00372 v = v - 0x10000; 00373 00374 if (v==SENSORNOTCONNECTED) 00375 v=0; 00376 return (float)((float) v * 0.1); 00377 }
Generated on Wed Jul 13 2022 11:26:46 by 1.7.2