I have been chipping away at the endless list of little things.
Zombie is running the speedometer, but the cluster also has a Energiemeter (SOC) and a Econometer(power).
The board that I made to be the BMS controller. That whas back in october 2023

It has 3 outputs for contractors that I am not using. So I will use them to control the cluster.
the Econo meter is simply a PWM signal @122hz this matches well with the arduino. (16Mhz / 256 div / 256 pwm bits = 244 hz)
244 is double the frequency, When using centeralinged PWM the frequency halves. During the testing and calibrating of the gauge it stopped working completely. Checked the BMS PCB, checked the wiring all seems fine.
As a last option took the dashboard appard to get the cluster out. And disassemble it to get the PCB out that controls the Econometer. The reverse polarity diode dropped 12V instead of 0,6V. So replaced it, put the hole lot back together it worked again. This stupid diode caused at least 4 hour of troubleshooting. You just assume that it is the stuff you are adding that is broken somehow.
The Energie meter is a bit more annoying. Because it is a rev counter in disguise that why it needs a variable frequency signal. Using the 16bit timer on the Arduino this is not that bad. Using the CTC mode (Clear Timer on Compare Match) and the pin to toggle on compare match. it's easy to generate the necessary frequencies. There was a little bug in the code that caused the meter to fall and then jump back to the right value. Reading through the datasheet I found the problem.
Added a if to check if the TCNT1 is greater than OCR1A, and if so set TCNT1 to 0x0000. This fixed the problem.changing the TOP to a value close to BOTTOM when the counter is running with none
or a low prescaler value must be done with care since the CTC mode does not have the double buffering feature. If the new
value written to OCR1A or ICR1 is lower than the current value of TCNT1, the counter will miss the compare match. The
counter will then have to count to its maximum value (0xFFFF) and wrap around starting at 0x0000 before the compare
match can occur