Diff: VBus.cpp
- Revision:
- 0:313c9e399e12
- Child:
- 1:d37117275b0b
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/VBus.cpp Thu Dec 30 16:02:59 2010 +0000
@@ -0,0 +1,260 @@
+/*
+ Copyright (c) 2010 Wim De Roeve
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+#include "VBus.h"
+#include "DebugTrace.h"
+
+#define DEBUG 0
+
+#if DEBUG
+DebugTrace pc_VBus(OFF, TO_SERIAL);
+#endif
+
+static uint8_t CalcCrc(const unsigned char *Buffer, int Offset, int Length);
+float CalcTemp(char Byte1, char Byte2);
+
+VBus::VBus(PinName tx, PinName rx)
+ : _Serial(tx, rx) {
+ Init(0);
+}
+
+void VBus::Init(int addr=0) {
+
+ _Serial.baud(9600);
+ _Serial.format(8,Serial::None,1);
+ m_timeout=2;
+
+ if (addr!=0)
+ networkaddress=addr;
+ else
+ networkaddress=ResolAddress;
+
+}
+
+void VBus::InjectSeptet(unsigned char *Buffer, int Offset, int Length) {
+ for (unsigned int i = 0; i < Length; i++) {
+ if (Septet & (1 << i)) {
+ Buffer [Offset + i] |= 0x80;
+ }
+ }
+}
+
+bool VBus::Read() {
+ int F;
+ char c;
+ bool start,stop,quit;
+
+ start = true;
+ stop = false;
+ quit = false;
+ Bufferlength=0;
+
+ m_timer.reset();
+ m_timer.start();
+
+ while ((!stop) and (!quit)) {
+ if (_Serial.readable()) {
+ c=_Serial.getc();
+
+ if (c == Sync) {
+ if (start) {
+ start=false;
+ Bufferlength=0;
+//#if DEBUG
+// pc_VBus.traceOut("\r\n");
+//#endif
+ } else {
+ if (Bufferlength<20) {
+ m_timer.stop();
+ m_timer.reset();
+ m_timer.start();
+ Bufferlength=0;
+ } else
+ stop=true;
+ }
+ }
+//#if DEBUG
+// pc_VBus.traceOut("%X ",c);
+//#endif
+ if ((!start) and (!stop)) {
+ Buffer[Bufferlength]=c;
+ Bufferlength++;
+ }
+ }
+ if ((m_timeout > 0) && (m_timer.read() > m_timeout )) {
+ quit=true;
+//#if DEBUG
+// pc_VBus.traceOut("Timeout %i",m_timer.read());
+//#endif
+ }
+ }
+
+ m_timer.stop();
+
+#if DEBUG
+
+ pc_VBus.traceOut("\r\nBuffer %i \r\n",Bufferlength);
+ for (i=0; i<Bufferlength;i++) {
+ pc_VBus.traceOut("%X ",Buffer[i]);
+ }
+ pc_VBus.traceOut("\r\n");
+
+#endif
+ if (!quit) {
+ Destination_address = Buffer[2] << 8;
+ Destination_address |= Buffer[1];
+ Source_address = Buffer[4] << 8;
+ Source_address |= Buffer[3];
+ ProtocolVersion = (Buffer[5]>>4) + (Buffer[5] &(1<<15));
+
+ Command = Buffer[7] << 8;
+ Command |= Buffer[6];
+ Framecnt = Buffer[8];
+ Checksum = Buffer[9]; //TODO check if Checksum is OK
+#if DEBUG
+ pc_VBus.traceOut("\r\nDestination %X",Destination_address);
+ pc_VBus.traceOut("\r\nSource %X",Source_address);
+ pc_VBus.traceOut("\r\nProtocol version %X",ProtocolVersion);
+ pc_VBus.traceOut("\r\nCommand %X",Command);
+ pc_VBus.traceOut("\r\nFramecnt %X", Framecnt);
+ pc_VBus.traceOut("\r\nChecksum %X\r\n", Checksum);
+#endif
+ // only analyse Commands 0x100 = Packet Contains data for slave
+ // with correct length = 10 bytes for HEADER and 6 Bytes for each frame
+
+ if ((Command==0x0100) and (Bufferlength==10+Framecnt*6)) {
+
+ // Frame info for the Resol ConergyDT5 used by IZEN
+ // check VBusprotocol specification for other products
+ //
+ // Each frame has 6 bytes
+ // byte 1 to 4 are data bytes -> MSB of each bytes
+ // byte 5 is a septet and contains MSB of bytes 1 to 4
+ // byte 6 is a checksum
+ //
+ //******************* Frame 1 *******************
+
+ F=FOffset;
+
+ Septet=Buffer[F+FSeptet];
+ InjectSeptet(Buffer,F,4);
+
+ // 'collector1' Temperatur Sensor 1, 15 bits, factor 0.1 in C
+ Sensor1_temp =CalcTemp(Buffer[F+1], Buffer[F]);
+ // 'store1' Temperature sensor 2, 15 bits, factor 0.1 in C
+ Sensor2_temp =CalcTemp(Buffer[F+3], Buffer[F+2]);
+
+ //******************* Frame 2 *******************
+ F=FOffset+FLength;
+
+ Septet=Buffer[F+FSeptet];
+ InjectSeptet(Buffer,F,4);
+
+ Sensor3_temp =CalcTemp(Buffer[F+1], Buffer[F]);
+ Sensor4_temp =CalcTemp(Buffer[F+3], Buffer[F+2]);
+
+ //******************* Frame 3 *******************
+ F=FOffset+FLength*2;
+
+ Septet=Buffer[F+FSeptet];
+ InjectSeptet(Buffer,F,4);
+
+ PumpSpeed1 = (Buffer[F] & 0X7F);
+ PumpSpeed2 = (Buffer[F+1] & 0X7F);
+ RelaisMask = Buffer[F+2];
+ ErrorMask = Buffer[F+3];
+
+ //******************* Frame 4 *******************
+ F=FOffset+FLength*3;
+
+ Septet=Buffer[F+FSeptet];
+ InjectSeptet(Buffer,F,4);
+
+ SystemTime = Buffer[F+1] << 8 | Buffer[F];
+ System = Buffer[F+2];
+
+ OptionPostPulse = (Buffer[F+3] & 0x01);
+ OptionThermostat = ((Buffer[F+3] & 0x02) >> 1);
+ OptionWMZ = ((Buffer[F+3] & 0x04) >> 2);
+
+ //******************* Frame 5 *******************
+ F=FOffset+FLength*4;
+
+ Septet=Buffer[F+FSeptet];
+ InjectSeptet(Buffer,F,4);
+
+ OperatingHoursRelais1=Buffer[F+1] << 8 | Buffer[F];
+ OperatingHoursRelais2=Buffer[F+3] << 8| Buffer[F+2];
+
+ ///******************* End of frames ****************
+
+#if DEBUG
+
+ pc_VBus.traceOut("\r\nSensor 1 %f", Sensor1_temp);
+ pc_VBus.traceOut("\r\nSensor 2 %f", Sensor2_temp);
+ pc_VBus.traceOut("\r\nSensor 3 %f", Sensor3_temp);
+ pc_VBus.traceOut("\r\nSensor 4 %f", Sensor4_temp);
+ pc_VBus.traceOut("\r\nPumpSpeed1 %i", PumpSpeed1);
+ pc_VBus.traceOut("\r\nPumpSpeed2 %i", PumpSpeed2);
+ pc_VBus.traceOut("\r\nRelaismask %i", RelaisMask);
+ pc_VBus.traceOut("\r\nErrorMask %i", ErrorMask);
+ pc_VBus.traceOut("\r\nSystemTime %i", SystemTime);
+ pc_VBus.traceOut("\r\nSystem %i", System);
+ pc_VBus.traceOut("\r\nOptionPostPulse %i", OptionPostPulse);
+ pc_VBus.traceOut("\r\nOptionThermostat %i", OptionThermostat);
+ pc_VBus.traceOut("\r\nOptionWMZ %i", OptionWMZ);
+ pc_VBus.traceOut("\r\nOperatingHoursRelais1 %i", OperatingHoursRelais1);
+ pc_VBus.traceOut("\r\nOperatingHoursRelais2 %i", OperatingHoursRelais2);
+
+#endif
+ }
+ }
+
+ return !quit;
+}
+
+void VBus::make_Header (unsigned int DAdr,unsigned int SAdr,unsigned char Ver,unsigned int Cmd,unsigned char AFrames) {
+ unsigned char Buffer[10]={Sync,(uint8_t)DAdr,DAdr>>8,(uint8_t)SAdr,SAdr>>8,Ver,(uint8_t)Cmd,Cmd>>8,AFrames};
+ Buffer[9]=CalcCrc(Buffer,1,8);
+// pc_VBus.traceOut("\r\nmake_Header\r\n");
+ for (unsigned bo=0;bo<=9;bo++) {
+ _Serial.putc(Buffer[bo]);
+ }
+// pc_VBus.traceOut("\r\n");
+}
+
+static uint8_t CalcCrc(const unsigned char *Buffer, int Offset, int Length) {
+ static uint8_t Crc= 0x7F;
+
+ for (unsigned int i = 0; i < Length; i++) {
+ Crc = (Crc - Buffer [Offset + i]) & 0x7F;
+ }
+ return Crc;
+}
+
+float CalcTemp(char Byte1, char Byte2) {
+ int v;
+ v = Byte1 << 8 | Byte2;
+ if (v==SENSORNOTCONNECTED)
+ v=0;
+ return (float)((float) v * 0.1);
+}
\ No newline at end of file