Thanks Gus,
i finally did it with a schematic i found here VBus-Decoder – Hobbyelektronik.org
class VBUS
{
// for testing: static byte[] VALUE = new byte[] { 0xAA, 0x10, 0x00, 0x21, 0x73, 0x10, 0x00, 0x01, 0x12, 0x38, 0x5E, 0x04, 0x5E, 0x01, 0x05, 0x39, 0x45, 0x01, 0x38, 0x22, 0x04, 0x5B, 0x38, 0x22, 0x38, 0x22, 0x05, 0x46, 0x6C, 0x01, 0x38, 0x22, 0x05, 0x33, 0x38, 0x22, 0x38, 0x22, 0x05, 0x46, 0x38, 0x22, 0x38, 0x22, 0x05, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x38, 0x0F, 0x00, 0x00, 0x01, 0x37, 0x47, 0x00, 0x00, 0x00, 0x00, 0x38, 0x64, 0x64, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x43, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x02, 0x00, 0x00, 0x7D, 0x01, 0x03, 0x60, 0x02, 0x04, 0x15, 0x02, 0x00, 0x00, 0x00, 0x00, 0x7D };
private static byte CRC(ref byte[] Buffer, int Offset, int Length)
{
byte Crc = 0x7F;
for (int i = 0; i < Length; i++)
{
Crc = (byte)(Crc - Buffer[Offset + i]);
Crc = (byte)(Crc & 0x7F);
}
return Crc;
}
private static void Ext7(ref byte[] Buffer, int Offset, int Length)
{
byte Septett = 0;
for (int i = 0; i < Length; i++)
{
if ((Buffer[Offset + i] & 0x80) == 1)
{
Buffer[Offset + i] &= 0x7F;
Septett |= (byte)(1 << i);
}
}
Buffer[Offset + Length] = Septett;
}
private static byte[] Inj7(byte[] Buffer, int Offset, int Length)
{
byte Septett = Buffer[Offset + Length];
for (int i = 0; i < Length; i++)
{
if ((Septett & (1 << i)) == 1)
{
Buffer[Offset + i] |= 0x80;
}
}
return Buffer;
}
private static string b2h(byte[] comByte)
{
String builder = "";
foreach (byte data in comByte) builder += Byte2Hex(data);
return builder;
}
private static string Byte2Hex(byte b)
{
const string hex = "0123456789ABCDEF";
int ln = b & 0x0F;
int hn = (b & 0xF0) >> 4;
string s = new string(new char[] { hex[hn], hex[ln] });
return s;
}
static public void getData()
{
HIS.log.write("I", "VBUS : getData");
SerialPort UART = new SerialPort("COM2", 9600);
UART.ReadTimeout = 0;
UART.Open();
//for testing: UART.Flush();
//for testing: UART.Write(VALUE, 0, VALUE.Length);
//for testing: Thread.Sleep(100);
byte[] rx_byte = new byte[1];
byte Befehl = 0;
byte Frames = 0;
string Quelladresse = null;
string Zieladresse = null;
string Protokollversion = null;
int temp1 = 0;
int temp2 = 0;
int temp3 = 0;
int temp4 = 0;
while (Befehl != 0x01) // wait for reported data
{
while (rx_byte[0] != 0xAA) // wait for transmission begin
{
UART.Read(rx_byte, 0, 1);
}
byte[] header = new byte[9];
for (int i = 0; i < 9; i++)
{
UART.Read(rx_byte, 0, 1);
header[i] = rx_byte[0];
}
Quelladresse = b2h(new byte[] { header[3], header[2] });
Zieladresse = b2h(new byte[] { header[1], header[0] });
Protokollversion = b2h(new byte[] { header[4] });
Befehl = header[6];
Frames = header[7];
if (CRC(ref header, 0, 8) == header[8])
{
byte[] data = new byte[Frames * 6];
for (int i = 0; i < Frames * 6; i++)
{
UART.Read(rx_byte, 0, 1);
data[i] = rx_byte[0];
}
for (int i = 0; i < Frames; i++)
{
if (CRC(ref data, i * 6, 5) == data[i * 6 + 5])
{
data = Inj7(data, i * 6, 4);
switch (i)
{
case 0: // Frame1: "Temperatur Sensor 1", "Temperatur Sensor 1", "Temperatur Sensor 2", "Temperatur Sensor 2"
temp1 = data[i * 6 + 0] + 256 * data[i * 6 + 1];
temp2 = data[i * 6 + 2] + 256 * data[i * 6 + 3];
break;
case 1: // Frame2: "Temperatur Sensor 3", "Temperatur Sensor 3", "Temperatur Sensor 4", "Temperatur Sensor 4"
temp3 = data[i * 6 + 0] + 256 * data[i * 6 + 1];
temp4 = data[i * 6 + 2] + 256 * data[i * 6 + 3];
//$val[] = $VALUE[$i * 6 + 0 + 9] + 256 * $VALUE[$i * 6 + 1 + 9];
//$val[] = $VALUE[$i * 6 + 2 + 9] + 256 * $VALUE[$i * 6 + 3 + 9];
break;
case 2: // Frame3: "Betriebsstunden", "Betriebsstunden", "Drehzahl Relais 1", "Regelstatus"
//$val[] = $VALUE[$i * 6 + 0 + 9] + 256 * $VALUE[$i * 6 + 1 + 9];
//$val[] = $VALUE[$i * 6 + 2 + 9];
//$val[] = $VALUE[$i * 6 + 3 + 9];
break;
case 3: // Frame4: "Fehlermaske", "Leer", "Leer", "Leer"
//$val[] = $VALUE[$i * 6 + 0 + 9];
break;
}
}
}
}
if (temp1 > 1000) temp1 = temp1 - 32768;
HIS.log.write("I", "VBUS : " + Quelladresse + " reported temp1 " + ((long)temp1).ToString() + "°C, temp2 " + ((long)temp2).ToString() + "°C, temp3 " + ((long)temp3).ToString() + "°C");
HIS.ts1 += temp1;
HIS.ts2 += temp2;
HIS.ts3 += temp3;
HIS.tsc++;
Befehl = 0;
Thread.Sleep(1000 * 10);
//UART.Close();
//UART = null;
//return;
}
UART.Close();
//Thread.Sleep(Timeout.Infinite);
}
}
The ‘switch’-construct has to be modified according to the type of solar controller you use. When installing the RSC-software from Redirecting... you find some XMLs with definitions of various controllers to match the frames sent per controller type.