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