HA! Yes. I am not sure what ID is the write ID though, so I guess I can modify the code to run through all IDs 0-64 . . .
Webasto HVH50
-
- Posts: 80
- Joined: Sun Oct 30, 2022 2:21 am
- Has thanked: 4 times
- Been thanked: 9 times
Re: Webasto HVH50
-
- Posts: 80
- Joined: Sun Oct 30, 2022 2:21 am
- Has thanked: 4 times
- Been thanked: 9 times
Re: Webasto HVH50
OK! So I reinstated the royhen99 code with some modifications and hooked everything up to water, 320V and 12V and ground. I had the controller run through all IDs on the lin.order command and used ID 39 for the lin.response, since this is the only ID that does not return -1. Power set for 1000, Temp set for 100 and UDC in was around 320V.
The Serial Monitor began working FINALLY and the readings looked like this.
I am working to correct the information being spit out from Serial Monitor. I changed up the code to print out each of the numbered data lines [1]-[8] and this is the printout:
I am curious why the final data byte 8 goes back and forth between 0 and 1. The wiki page lists the 8 bytes out. I wonder if the 0,1 back and forth is trying to turn the heater on, but it is not appearing in the correct location.
For some reason, the formula in the STM32 version used to decode the data is not giving me accurate info:
Interesting to me that the data readouts by each number are different that the printout of the linRXdata repones of:
Code: Select all
#include "lin_bus.h"
// Create an IntervalTimer object
IntervalTimer myTimer;
int ledState = LOW; // ledState used to set the LED
unsigned long interval = 200000; // interval at which to blinkLED to run every 0.2 seconds
LIN lin;
int lin_cs = 32; // cs and serial port set for skpang LIN / FDCAN board
int led1 = 23;
int lin_fault = 28;
uint16_t Power = 1000; // set to required power
uint8_t Temperature = 100; //set to required temperature
uint16_t tmpheater = 0;
uint16_t udcheater = 0;
uint16_t powerheater = 0;
uint8_t CRC = 0;
uint8_t orderID = 0;
//uint8_t responseID = 0;
uint8_t data[8];
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
pinMode(lin_fault,INPUT);
pinMode(lin_cs, OUTPUT);
digitalWrite(lin_cs, HIGH); // enable MCP2004 LIN transceiver
digitalWrite(LED_BUILTIN, HIGH);
Serial.begin(115200);
//Serial.print("HVH50 Heater demo");
//lin.begin(&Serial3, 9600);
lin.begin(&Serial3, 19200); /// Change to this for 19200 /////
delay(1000);
pinMode(led1,OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
myTimer.begin(blinkLED, interval);
}
void loop() {
// heater
SendLin();
delay(1000); // wait 1000ms
//Serial.print(" Heater test\n");
}
void blinkLED() {
ledState = !ledState;
digitalWrite(LED_BUILTIN, ledState);
digitalWrite(led1, ledState);
}
static void SendLin()
{
for (orderID = 0; orderID < 64; orderID++) {
static bool read = true;
uint8_t data[8];
delay(1000); // wait 1000ms
uint8_t lindata[] = {uint8_t(Power/40), uint8_t(Temperature+40), 0, 8};
lin.order(orderID, lindata, 4, lin2x);
delay(100);
if (lin.response(39, data, 8, lin2x) >=0) // -1 indicates crc error, 19200
{
tmpheater = data[1] - 40;
udcheater = data[4] | (data[5] & 3) << 8;
powerheater =((data[5] >> 2) | (data[6] << 8)) * 20;
Serial.print("orderID:");
Serial.print(orderID);
Serial.print(",");
Serial.print("Temp:");
Serial.print(tmpheater);
Serial.print(",");
Serial.print("Udc:");
Serial.print(udcheater);
Serial.print(",");
Serial.print("Power:");
Serial.println(powerheater);
Serial.print("CRC:");
Serial.print(CRC);
Serial.print(",");
}
else if (read)
{
lin.order(orderID, lindata, 4, lin2x);
}
else
{
uint8_t lindata[] = {uint8_t(Power/40), uint8_t(Temperature+40), 0, 8};
lin.order(orderID, lindata, 4, lin2x);
//Serial.print("\n Sending power and temperature");
}
read = !read;
}
}
Code: Select all
CRC:0,orderID:0,Temp:21,Udc:60,Power:400
CRC:0,orderID:1,Temp:21,Udc:60,Power:400
CRC:0,orderID:2,Temp:21,Udc:60,Power:400
CRC:0,orderID:3,Temp:21,Udc:60,Power:400
CRC:0,orderID:4,Temp:21,Udc:60,Power:400
CRC:0,orderID:5,Temp:21,Udc:60,Power:400
CRC:0,orderID:6,Temp:21,Udc:60,Power:400
CRC:0,orderID:7,Temp:21,Udc:60,Power:400
CRC:0,orderID:8,Temp:21,Udc:60,Power:400
CRC:0,orderID:9,Temp:21,Udc:60,Power:400
CRC:0,orderID:10,Temp:21,Udc:60,Power:400
CRC:0,orderID:11,Temp:21,Udc:60,Power:400
CRC:0,orderID:12,Temp:21,Udc:60,Power:400
CRC:0,orderID:13,Temp:21,Udc:60,Power:400
CRC:0,orderID:14,Temp:21,Udc:60,Power:400
CRC:0,orderID:15,Temp:21,Udc:60,Power:400
CRC:0,orderID:16,Temp:21,Udc:60,Power:400
CRC:0,orderID:17,Temp:21,Udc:60,Power:400
CRC:0,orderID:18,Temp:21,Udc:60,Power:400
CRC:0,orderID:19,Temp:21,Udc:60,Power:400
CRC:0,orderID:20,Temp:21,Udc:60,Power:400
CRC:0,orderID:21,Temp:21,Udc:60,Power:400
CRC:0,orderID:22,Temp:21,Udc:60,Power:400
CRC:0,orderID:23,Temp:21,Udc:60,Power:1040
CRC:0,orderID:24,Temp:21,Udc:60,Power:400
CRC:0,orderID:25,Temp:21,Udc:60,Power:400
CRC:0,orderID:26,Temp:21,Udc:60,Power:400
CRC:0,orderID:27,Temp:21,Udc:60,Power:400
CRC:0,orderID:28,Temp:21,Udc:60,Power:400
CRC:0,orderID:29,Temp:21,Udc:60,Power:400
CRC:0,orderID:30,Temp:21,Udc:60,Power:400
CRC:0,orderID:31,Temp:21,Udc:60,Power:400
CRC:0,orderID:32,Temp:21,Udc:60,Power:400
CRC:0,orderID:33,Temp:21,Udc:60,Power:400
CRC:0,orderID:34,Temp:21,Udc:60,Power:400
CRC:0,orderID:35,Temp:21,Udc:60,Power:400
CRC:0,orderID:36,Temp:21,Udc:60,Power:400
CRC:0,orderID:37,Temp:21,Udc:60,Power:400
CRC:0,orderID:38,Temp:21,Udc:60,Power:400
CRC:0,orderID:39,Temp:21,Udc:60,Power:1040
CRC:0,orderID:40,Temp:21,Udc:60,Power:400
CRC:0,orderID:41,Temp:21,Udc:60,Power:400
CRC:0,orderID:42,Temp:21,Udc:60,Power:400
CRC:0,orderID:43,Temp:21,Udc:60,Power:400
CRC:0,orderID:44,Temp:21,Udc:60,Power:400
CRC:0,orderID:45,Temp:21,Udc:60,Power:400
CRC:0,orderID:46,Temp:21,Udc:60,Power:400
CRC:0,orderID:47,Temp:21,Udc:60,Power:400
CRC:0,orderID:48,Temp:21,Udc:60,Power:400
CRC:0,orderID:49,Temp:21,Udc:60,Power:400
CRC:0,orderID:50,Temp:21,Udc:60,Power:400
CRC:0,orderID:51,Temp:21,Udc:60,Power:400
CRC:0,orderID:52,Temp:21,Udc:60,Power:400
CRC:0,orderID:53,Temp:21,Udc:60,Power:400
CRC:0,orderID:54,Temp:21,Udc:60,Power:400
CRC:0,orderID:55,Temp:21,Udc:60,Power:400
CRC:0,orderID:56,Temp:21,Udc:60,Power:400
CRC:0,orderID:57,Temp:21,Udc:60,Power:400
CRC:0,orderID:58,Temp:21,Udc:60,Power:400
CRC:0,orderID:59,Temp:21,Udc:60,Power:400
CRC:0,orderID:60,Temp:21,Udc:60,Power:1040
CRC:0,orderID:61,Temp:21,Udc:60,Power:400
CRC:0,orderID:62,Temp:21,Udc:60,Power:400
CRC:0,orderID:63,Temp:21,Udc:60,Power:400
Code: Select all
61,0,0,61,192,0,100,1
61,0,0,60,192,0,100,0
61,0,0,60,192,0,100,1
61,0,0,60,192,0,100,0
61,0,0,60,192,0,100,1
61,0,0,60,192,0,101,0
61,0,0,60,192,0,100,1
61,0,0,60,192,0,100,0
61,0,0,61,192,0,99,1
61,0,0,61,192,0,99,0
61,0,0,60,192,0,101,1
61,0,0,60,192,0,100,0
61,0,0,60,192,0,101,1
Code: Select all
Status
4=running
Outlet temp
Scaling as above
Inlet temp -
Voltage LSB
Voltage MSB - 2 bits
Power LSB - 6 bits / Power MSB 1 digit=20W
Unknown
Interesting to me that the data readouts by each number are different that the printout of the linRXdata repones of:
Code: Select all
59, 0, 114, 58, 64,0, 239, 0
-
- Posts: 80
- Joined: Sun Oct 30, 2022 2:21 am
- Has thanked: 4 times
- Been thanked: 9 times
Re: Webasto HVH50
I HAVE HOT WATER!!!!!!
So I went to bed last night thinking about what I was missing and woke up with the thought that there might be info hidden in DATA[0] since DATA[1] was used to calculate temp and I recall Johan mentioning that the on status would be in byte 0, so I modified the code to print out DATA[0] through DATA [8] using lin.response ID 39 and running through all of the lin.order IDs.
I ran this code:
with this response:
DATA[0] showed 0s until ID 35 and it jumped to 128 at that point. Therefore, I assumed ID34 was causing the change in DATA[0].
I then modified the lin.order command to ID34 with the lin.response on ID39 and water started to heat.
Here is the code I was running:
Serial Plotter:
Not sure why the 128 in the first bit drops to 32 at some point, but it did not affect the heating as far as I could tell. You can see that the final bit seems to increase over time and I am pretty sure is the temperature. I pasted examples along the way of the number increasing. With an offset of 40, I assume the temps are between 80 and 110 C. I will need to work on the formulas for the output on serial plotter, but I assume those are just for my knowledge and do not affect the heating of the water.
This was only on the VOLVO HVH50 heater out of a CX90, so I will need to sniff the other heaters for their lin.response ID and then lin.order ID, but now I have the blueprints and steps to do it.
--------------------------
THANK YOU THANK YOU THANK YOU ROYHEN99! I would not have been able to do this without your help. You created the initial coding and talked me though the issues I was having and taught me about hoe to code on my own! Thank you Johan for forging the path on the STM32 version to allow us to have the blueprints we needed. The guys at the Teensy forum were invaluable with the lin2x fix, the linbus.cpp fix, the sketches to sniff out a response ID and just teaching me enough that I could experiment on my own to get to this place.
I will update the wiki page with the info for this VOLVO heater. I have two other heaters (from Chrysler Pacificas I believe) and will try to sniff them out as well and will update the wiki page if I figure them out.
So I went to bed last night thinking about what I was missing and woke up with the thought that there might be info hidden in DATA[0] since DATA[1] was used to calculate temp and I recall Johan mentioning that the on status would be in byte 0, so I modified the code to print out DATA[0] through DATA [8] using lin.response ID 39 and running through all of the lin.order IDs.
I ran this code:
Code: Select all
#include "lin_bus.h"
// Create an IntervalTimer object
IntervalTimer myTimer;
int ledState = LOW; // ledState used to set the LED
unsigned long interval = 200000; // interval at which to blinkLED to run every 0.2 seconds
LIN lin;
int lin_cs = 32; // cs and serial port set for skpang LIN / FDCAN board
int led1 = 23;
int lin_fault = 28;
uint16_t Power = 40; // set to required power
uint8_t Temperature = 85; //set to required temperature
uint16_t tmpheater = 0;
uint16_t udcheater = 0;
uint16_t powerheater = 0;
uint8_t CRC = 0;
uint8_t orderID = 0;
uint8_t responseID = 0;
//uint8_t data[8];
uint8_t linTXdata[4] = { 0, 0, 0, 0 }; // 40W, 45C, heater on
uint8_t linRXdata[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
//uint8_t CRC = 0;
//uint8_t orderID = 0;
//uint8_t responseID = 0;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
pinMode(lin_fault,INPUT);
pinMode(lin_cs, OUTPUT);
digitalWrite(lin_cs, HIGH); // enable MCP2004 LIN transceiver
digitalWrite(LED_BUILTIN, HIGH);
Serial.begin(115200);
//Serial.print("HVH50 Heater demo");
//lin.begin(&Serial3, 9600);
lin.begin(&Serial3, 19200); /// Change to this for 19200 /////
delay(1000);
pinMode(led1,OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
myTimer.begin(blinkLED, interval);
}
void loop() {
// heater
SendLin();
delay(100); // wait 100ms
//Serial.print(" Heater test\n");
}
void blinkLED() {
ledState = !ledState;
digitalWrite(LED_BUILTIN, ledState);
digitalWrite(led1, ledState);
}
static void SendLin()
{
for (orderID = 0; orderID < 64; orderID++) {
static bool read = true;
uint8_t data[8];
delay(1000); // wait 1000ms
lin.order(34, linTXdata, 4, lin2x);
delay(100);
CRC = lin.response(39, linRXdata, 8, lin2x);
lin.response(39, linRXdata, 8, lin2x); //>=0) // -1 indicates crc error, 19200
{
tmpheater = linRXdata[1] - 40;
udcheater = linRXdata[4] | (linRXdata[5] & 3) << 8;
powerheater =((linRXdata[5] >> 2) | (linRXdata[6] << 8)) * 20;
//Serial.print("orderID:");
//Serial.print(orderID);
//Serial.print(",");
Serial.print("Temp:");
Serial.print(tmpheater);
Serial.print(",");
Serial.print("Udc:");
Serial.print(udcheater);
Serial.print(",");
Serial.print("Power:");
Serial.println(powerheater);
Serial.print("CRC:");
Serial.println(CRC);
Serial.print(linRXdata[0]);
Serial.print(",");
Serial.print(linRXdata[1]);
Serial.print(",");
Serial.print(linRXdata[2]);
Serial.print(",");
Serial.print(linRXdata[2]);
Serial.print(",");
Serial.print(linRXdata[4]);
Serial.print(",");
Serial.print(linRXdata[5]);
Serial.print(",");
Serial.print(linRXdata[6]);
Serial.print(",");
Serial.print(linRXdata[7]);
Serial.print(",");
Serial.println(linRXdata[8]);
//Serial.println(data);
}
//else if (read)
// {
lin.order(34, linTXdata, 4, lin2x);
//}
// else
{
//uint8_t linTXdata[] = {uint8_t(Power/40), uint8_t(Temperature+40), 0, 8};
lin.order(34, linTXdata, 4, lin2x);
//Serial.print("\n Sending power and temperature");
}
read = !read;
}
}
Code: Select all
orderID:30,Temp:19,Udc:58,Power:320
CRC:0
0,59,0,0,58,64,0,238,27
orderID:31,Temp:19,Udc:58,Power:320
CRC:0
0,59,0,0,58,64,0,238,27
orderID:32,Temp:19,Udc:58,Power:320
CRC:0
0,59,0,0,58,64,0,237,27
orderID:33,Temp:19,Udc:58,Power:320
CRC:0
0,59,0,0,58,64,0,237,27
orderID:34,Temp:19,Udc:58,Power:320
CRC:0
0,59,0,0,58,64,0,239,27
orderID:35,Temp:19,Udc:58,Power:320
CRC:0
128,59,0,0,58,64,0,110,27
orderID:36,Temp:19,Udc:58,Power:320
CRC:0
0,59,0,0,58,64,0,237,27
orderID:37,Temp:19,Udc:58,Power:320
CRC:0
0,59,0,0,58,64,0,237,27
I then modified the lin.order command to ID34 with the lin.response on ID39 and water started to heat.
Here is the code I was running:
Code: Select all
#include "lin_bus.h"
// Create an IntervalTimer object
IntervalTimer myTimer;
int ledState = LOW; // ledState used to set the LED
unsigned long interval = 200000; // interval at which to blinkLED to run every 0.2 seconds
LIN lin;
uint16_t Power = 400; // set to required power
uint8_t Temperature = 100; //set to required temperature
int lin_cs = 32; // pin 23 for my LIN board
int led1 = 23;
int lin_fault = 28;
uint8_t linTXdata[4] = { Power, Temperature, 0, 8 }; // 40W, 45C, heater on
uint8_t linRXdata[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
uint8_t CRC = 0;
uint8_t orderID = 0;
uint8_t responseID = 0;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
pinMode(lin_fault, INPUT);
pinMode(lin_cs, OUTPUT);
digitalWrite(lin_cs, HIGH); // enable MCP2004 LIN transceiver
digitalWrite(LED_BUILTIN, HIGH);
Serial.begin(115200);
lin.begin(&Serial3, 19200); // or
//lin.begin(&Serial3, 9600);
delay(1000);
pinMode(led1, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
}
void loop() {
//for (orderID = 0; orderID < 64; orderID++) {
//for (responseID = 0; responseID < 64; responseID++) {
lin.order(34, linTXdata, 4, lin2x);
delay(100);
CRC = lin.response(39, linRXdata, 8, lin2x);
delay(100);
Serial.print(34, HEX);
Serial.print("\t");
Serial.print(39, HEX);
Serial.print("\t");
Serial.println(CRC, HEX);
for (int i = 0; i < 8; i++) { // display the raw data
Serial.print(linRXdata[i]);
Serial.print("\t");
Serial.print("\t");
Serial.print(" ");
Serial.println();
delay(10);
}
}
//}
//}
Serial Plotter:
Code: Select all
22 27 0
128
95
2
116
91
80
0
22
22 27 0
128
95
2
114
91
80
0
24
22 27 0
32
95
0
114
91
80
0
122
22 27 0
32
95
0
115
91
80
0
121
22 27 0
32
89
0
117
89
80
0
127
22 27 0
32
88
0
115
88
80
0
131
22 27 0
32
84
0
116
83
80
0
139
22 27 0
32
84
0
115
83
80
0
140
22 27 0
32
82
0
116
81
80
0
143
22 27 0
32
82
0
115
81
80
0
144
22 27 0
32
80
0
116
80
80
0
146
22 27 0
32
80
0
116
79
80
0
147
22 27 0
32
79
0
116
78
80
0
149
22 27 0
32
79
0
115
78
80
0
150
This was only on the VOLVO HVH50 heater out of a CX90, so I will need to sniff the other heaters for their lin.response ID and then lin.order ID, but now I have the blueprints and steps to do it.
--------------------------
THANK YOU THANK YOU THANK YOU ROYHEN99! I would not have been able to do this without your help. You created the initial coding and talked me though the issues I was having and taught me about hoe to code on my own! Thank you Johan for forging the path on the STM32 version to allow us to have the blueprints we needed. The guys at the Teensy forum were invaluable with the lin2x fix, the linbus.cpp fix, the sketches to sniff out a response ID and just teaching me enough that I could experiment on my own to get to this place.
I will update the wiki page with the info for this VOLVO heater. I have two other heaters (from Chrysler Pacificas I believe) and will try to sniff them out as well and will update the wiki page if I figure them out.
-
- Posts: 261
- Joined: Sun Feb 20, 2022 4:23 am
- Location: N. Wiltshire. UK
- Has thanked: 22 times
- Been thanked: 130 times
Re: Webasto HVH50
Good to see that you are getting heat but I think you are looking at the status ID data rather than the measurement ID. From your update in the wiki this seemed a posibility and checking back in some of the previous data there was also a response on ID 23. Maybe check if ID 23 is Read Meas and 39 is Read Status command. Status is 3 bytes so only data[0] to [2] will be valid values.
Couple of other points: you set power to 400 and wrote to an 8 bit variable which has maximum vaule of 255 ( the power set was actually (400-256)*40 = 5760W). The receive array is 8 bytes so only data[0] to data[7] are valid, data[8} is whatever (random) value is in the next memory address.
Couple of other points: you set power to 400 and wrote to an 8 bit variable which has maximum vaule of 255 ( the power set was actually (400-256)*40 = 5760W). The receive array is 8 bytes so only data[0] to data[7] are valid, data[8} is whatever (random) value is in the next memory address.
-
- Posts: 80
- Joined: Sun Oct 30, 2022 2:21 am
- Has thanked: 4 times
- Been thanked: 9 times
Re: Webasto HVH50
If that is the case, do I need to change it from 8 to 16? The heater can handle up to 5000W on the HVH50 and 7000W on the HVH70.
If I use the max 8 bit value of 255, by the formula of (255-256)*40 = -40, right???
I will do this for sure and let you know.
-
- Posts: 261
- Joined: Sun Feb 20, 2022 4:23 am
- Location: N. Wiltshire. UK
- Has thanked: 22 times
- Been thanked: 130 times
Re: Webasto HVH50
No, the simplist way it to put the code back to how it was originally with the power sent over LIN the required power / 40.jsimonkeller wrote: ↑Mon Mar 04, 2024 4:58 am If I use the max 8 bit value of 255, by the formula of (255-256)*40 = -40, right???
The 400 - 256 is just truncating a 9 bit number to 8 bits, it's not a general formula for calculating the power. 400 = 0x190, truncating to 8 bits gives 0x90 which is 144, i.e. 400 - 256.
-
- Posts: 80
- Joined: Sun Oct 30, 2022 2:21 am
- Has thanked: 4 times
- Been thanked: 9 times
Re: Webasto HVH50
I am now convinced I got heated water through dumb luck and wish to re-create it but with solid understanding and the ability to re-create it on command. I went back to the beginning and followed all of our steps again. This time, I used the the scope to help me. At this point, I have confirmed that ID 39 is the Lin Read with 7 bits showing on the scope and ID 23 is the LIN READ STATUS with 3 bits showing. This happens with Lin.Response and the heater powered on with and without HV.
Now I assumed that 34 was the proper ID for Lin.Order because when I was sending all IDs the day I got heat, the data at byte 0 jumped from 0 to 118 and then held at 32. I have not been able to recreate this, though.
I have tried 34 and 35 with no success. I am now considering whether I should be focusing on how the heater initiates and what I might have done accidentally. I am looking at timing and synch. Looking at the node attributes in the HVH100 LDF file, I see:
I am not sure if any of this needs to be incorporated into the linbus.h or cpp file or my code that is not already there.
Assuming the LDF for the HVH100 is compatible with the HVH50, the frame structure shows:
With my German translator, it would seen that the ON command will appear at BIT 8, which is the first bit of the second Databyte and not the fourth one right?
Anyways, I am wondering if you had any ideas for a sketch to sniff this part out, now that we have definitive response and status IDs and try to cause some reaction on their parts or how to incorporate any of the info from the LDF to help us get a response again.
I also wonder if the 255 lin bit value for the initial/power request value needs to be sent before the heater will turn on?
Now I assumed that 34 was the proper ID for Lin.Order because when I was sending all IDs the day I got heat, the data at byte 0 jumped from 0 to 118 and then held at 32. I have not been able to recreate this, though.
Code: Select all
orderID:33,Temp:19,Udc:58,Power:320
CRC:0
0,59,0,115,58,64,0,237,27
orderID:34,Temp:19,Udc:58,Power:320
CRC:0
0,59,0,115,58,64,0,239,27
orderID:35,Temp:19,Udc:58,Power:320
CRC:0
128,59,0,115,58,64,0,110,27
orderID:36,Temp:19,Udc:58,Power:320
CRC:0
0,59,0,115,58,64,0,237,27
Code: Select all
Node_attributes {
HVH_100{
LIN_protocol = "2.0" ;
configured_NAD = 0x5F ;
product_id = 0x0, 0x0, 0 ;
response_error = PTC_ResponseError ;
P2_min = 10 ms ;
ST_min = 10 ms ;
configurable_frames {
HV_He_01 = 0x401C ;
HV_Hs_01 = 0x4030 ;
HV_Hs_02 = 0x400C ;
Assuming the LDF for the HVH100 is compatible with the HVH50, the frame structure shows:
Code: Select all
Frames {
HV_He_01: 28, Controller, 4 {
KL_HV_PTC_soll, 0 ;
KL_PTC_ein, 8 ;
}
H
V_Hs_01: 48, HVH_100, 8 {
PTC_HV_I_ist, 0 ;
PTC_HV_ERR, 8 ;
PTC_HV_Status_PTC, 16 ;
PTC_Status_UBatt, 19 ;
PTC_ResponseError, 21 ;
PTC_TimeOut_Fehler, 22 ;
PTC_HV_Err_Heizkreis_1, 24 ;
PTC_HV_Err_Heizkreis_2, 25 ;
PTC_HV_Err_Heizkreis_3, 26 ;
PTC_HV_Err_Leckagestrom, 27 ;
PTC_HV_Err_Ueberstromabschaltung, 28 ;
PTC_HV_Err_Temperaturschutz, 29 ;
PTC_HV_Err_intern, 30 ;
PTC_UBatt, 32 ;
PTC_Temp_PCB, 40 ;
PTC_HV_Heizmedium_Sensor_1, 48 ;
PTC_HV_Heizmedium_Sensor_2, 56 ;
}
HV_Hs_02: 12, HVH_100, 8 {
HVH_HV_Voltage, 32 ;
HVH_HV_Voltage_Offset, 41 ;
HVH_HV_Ilock_Status, 45 ;
HVH_ParameterChange, 61 ;
HVH_ErrMem_State, 62 ;
}
}
Schedule_tables {
ST1 {
HV_He_01 delay 20 ms ;
HV_Hs_01 delay 20 ms ;
HV_Hs_02 delay 20 ms ;
}
DiagRequest {
MasterReq delay 10 ms ;
}
DiagResponse {
SlaveResp delay 10 ms ;
}
}
Anyways, I am wondering if you had any ideas for a sketch to sniff this part out, now that we have definitive response and status IDs and try to cause some reaction on their parts or how to incorporate any of the info from the LDF to help us get a response again.
I also wonder if the 255 lin bit value for the initial/power request value needs to be sent before the heater will turn on?
-
- Posts: 80
- Joined: Sun Oct 30, 2022 2:21 am
- Has thanked: 4 times
- Been thanked: 9 times
Re: Webasto HVH50
No luck yet. As it got hot in Nashville TN in May, I have not been in desperate need of heat (more a/c please) but I do not want to let this go until November, when I will need the heat again!
Re: Webasto HVH50
I am going to open this thing up and trace out the circuit.
As I understand it, all that is happening is there is an IGBT on one side of each PTC element that acts like a switch, connecting it to one side of the HV.
The other side is always connected to the opposite polarity of the HV.
As PTC elements are self regulating, there is no temperature control, it just turns on more elements for more heat.
It may be simple to control the IGBTs with a +12VDC on/off and bypass all the software control, I certainly do not need it.
Webasto actually makes a version that is controlled with +12VDC directly, but good luck finding one to purchase!
As I understand it, all that is happening is there is an IGBT on one side of each PTC element that acts like a switch, connecting it to one side of the HV.
The other side is always connected to the opposite polarity of the HV.
As PTC elements are self regulating, there is no temperature control, it just turns on more elements for more heat.
It may be simple to control the IGBTs with a +12VDC on/off and bypass all the software control, I certainly do not need it.
Webasto actually makes a version that is controlled with +12VDC directly, but good luck finding one to purchase!
-
- Posts: 80
- Joined: Sun Oct 30, 2022 2:21 am
- Has thanked: 4 times
- Been thanked: 9 times
Re: Webasto HVH50
Just so you know, I did this as well a while back. Here is a photo of the board. I purchased an extra heater at a good price that was sold without warranty it was functioning. I opened in up and started checking for continuity and I was able to identify some of the pathways, such as the HVIL loop and the 12V line pathway to a dead end after the resistor at a small black chip (circled below), which might be the gateway that opens when the proper LIN command is received. I assume this could be bypassed, but I abandoned this in favor of learning how to program the LIN with a sealed unit. I also discovered that there is a GND wire in the 8 wire setup (#8) that I started using with the board outside of the metal case, just to make sure the board was getting a good GND signal. I actually got some sparks with the 12v only attached when the multimeter prong touched across a couple of lines accidentally. I agree that there should be a way to bypass the lockout of 12V on and off that is closed in programming.
Re: Webasto HVH50
Thanks for showing that, it looks plenty complicated!
If only they would sell the 12VDC controlled model, or if there were information on what application it was used in...
With the help you have provided I will pursue getting the local college's programming school to take it on as a project.
If only they would sell the 12VDC controlled model, or if there were information on what application it was used in...
With the help you have provided I will pursue getting the local college's programming school to take it on as a project.
-
- Posts: 80
- Joined: Sun Oct 30, 2022 2:21 am
- Has thanked: 4 times
- Been thanked: 9 times
Re: Webasto HVH50
Hello everyone. I have finally SOLVED the HV heater issue and can set out a path for anyone still trying to incorporate an HV coolant heater into their EV build.
After not having much luck with the various HV50 or HV70 heaters from various companies like Volvo and Chrysler, I looked into other options and found this company and their HV Heater.
https://www.auto-parkingheater.com/elec ... -cars.html Ask for Luda.
The form factor for this HV Heater is almost identical to the Webasto HV50/70, probably a little smaller actually. The cost, including international FedEx shipping to my home in the USA was under $350.00 AND it came with all of the mating connectors, already wired up. The LV connector is identical to the Webasto LV connector. The HV connector is similar to the Webasto one, but has a slightly different key at the top. Also, it is brand new and not harvested from a junked EV.
Best part about this is that it came with the manual and all of the LIN commands and IDs and baud rate and the proper LDF (Lin Description File) and tech support to get things working. I was able to salvage the code we started on this post and completed with the help of folks on the teensy forum site. I ran the final code tonight and it was heating the water on my test bench to 80C.
Here is the code for anyone that wants to go this route [UPDATED ON 8-19-24]:
The code will printout the following info in the serial monitor (below are pulled from the serial monitor at different points in time):
After not having much luck with the various HV50 or HV70 heaters from various companies like Volvo and Chrysler, I looked into other options and found this company and their HV Heater.
https://www.auto-parkingheater.com/elec ... -cars.html Ask for Luda.
The form factor for this HV Heater is almost identical to the Webasto HV50/70, probably a little smaller actually. The cost, including international FedEx shipping to my home in the USA was under $350.00 AND it came with all of the mating connectors, already wired up. The LV connector is identical to the Webasto LV connector. The HV connector is similar to the Webasto one, but has a slightly different key at the top. Also, it is brand new and not harvested from a junked EV.
Best part about this is that it came with the manual and all of the LIN commands and IDs and baud rate and the proper LDF (Lin Description File) and tech support to get things working. I was able to salvage the code we started on this post and completed with the help of folks on the teensy forum site. I ran the final code tonight and it was heating the water on my test bench to 80C.
Here is the code for anyone that wants to go this route [UPDATED ON 8-19-24]:
Code: Select all
#include "lin_bus.h"
// Create an IntervalTimer object
IntervalTimer myTimer;
int ledState = LOW; // ledState used to set the LED
unsigned long interval = 200000; // interval at which to blinkLED to run every 0.2 seconds
uint16_t requestedpower = 0;
uint16_t actualpower = 0;
uint16_t inwatertemp = 0;
uint16_t outwatertemp = 0;
uint16_t lowvoltage = 0;
uint16_t currentconsumption = 0;
LIN lin;
int lin_cs = 32; // cs and serial port set for skpang LIN / FDCAN board
int led1 = 23; // sk pang board builtin led
int lin_fault = 28;
uint8_t CRC = 0;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
pinMode(lin_fault, INPUT);
pinMode(lin_cs, OUTPUT);
digitalWrite(lin_cs, HIGH); // enable MCP2004 LIN transceiver
digitalWrite(LED_BUILTIN, HIGH);
Serial.begin(115200);
//Serial.print("Heater demo");
lin.begin(&Serial3, 19200);// Baud Rate for the SR02-2 Heater
delay(100); // wait 100ms
pinMode(led1, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
myTimer.begin(blinkLED, interval);
}
void loop() {
// heater
SendLin();
delay(100); // wait 100ms
//Serial.print(" Heater test\n");
}
void blinkLED() {
ledState = !ledState;
digitalWrite(LED_BUILTIN, ledState);
digitalWrite(led1, ledState);
}
static void SendLin()
{
//static bool read = true;
uint8_t data[8];
delay(100); // wait 100ms
// read ID27 register
lin.response(0x27, data, 7, lin2x); //
delay(10);
// write ID33 register
uint8_t lindata0[] = { 0x00, 0x10 }; // chechksum 0, counter 0, HvCooltHeatrEnadWhE2EHvchEnad = 1 which is 0x10 Hex
lin.order(0x33, lindata0, 2, lin2x);
delay(10);
// write ID22 register again, HvWtrHeatrPwrCnsAllwd = 6000W based on top voltage of 350V for my car
uint8_t lindata2[] = { 0x96, 0x78, 0xFF, 0xD0 }; // 6000w power, 80C target temp, max flow, enable
lin.order(0x22, lindata2, 4, lin2x);
delay(10);
// read ID17 register
lin.response(0x17, data, 3, lin2x); // we need 10+10 bits according to spec, so request 3 bytes
{
requestedpower = data[1] * 20;//(20w/bit) offset
actualpower = data[0] * 20;//(20w/bit) offset
Serial.print("RequestedPower:");
Serial.print(requestedpower);
Serial.println(",");
Serial.print("ActualPower:");
Serial.print(actualpower);
Serial.println("");
}
// read ID27 register
lin.response(0x27, data, 7, lin2x); // we need 56 bits according to spec, so request 7 bytes
inwatertemp = data[4];//(1℃/bit) offset
outwatertemp = data[1];//(1℃/bit) offset
lowvoltage = data[3] / 10;//(0.1V/bit) offset
currentconsumption = data[2] / 4;//(0.25A/bit) offset
Serial.print("WaterTempIn:");
Serial.print(inwatertemp);
Serial.println(",");
Serial.print("WaterTempOut:");
Serial.print(outwatertemp);
Serial.println(",");
Serial.print("CurrentConsumption:");
Serial.print(currentconsumption);
Serial.println(",");
Serial.print("LowVoltageReading:");
Serial.print(lowvoltage);
Serial.println("");
Serial.println("");
delay(500);
}
Code: Select all
RequestedPower:3520,
ActualPower:320
WaterTempIn:61,
WaterTempOut:61,
CurrentConsumption:1,
LowVoltageReading:13
RequestedPower:3680,
ActualPower:2180
WaterTempIn:120,
WaterTempOut:122,
CurrentConsumption:6,
LowVoltageReading:13
RequestedPower:1280,
ActualPower:1580
WaterTempIn:123,
WaterTempOut:124,
CurrentConsumption:4,
LowVoltageReading:13
RequestedPower:4000,
ActualPower:980
WaterTempIn:126,
WaterTempOut:127,
CurrentConsumption:3,
LowVoltageReading:12