Here I am, full of tests and doubts.
Attached you can find a file with performed tests i'll explan below.
I first tested the performance of three differents IRS codes: the result can be seen in the attached image
First, predict code
ISR(TIMER2_COMPA_vect){ // version 1 = predict
static uint8_t cnt = 0;
if (cnt++ == 0) {
for (int i = 0; i < 9; i++) pwm[i].currentPWM = 255; // 0 with next increase
}
for (int i = 0; i < 9; i++){
if ( (++ pwm[i].currentPWM < pwm[i].pwmvalue) && !pwm[i].currentState) { *pwm[i].outport |= pwm[i].pinmask; pwm[i].currentState = true; }
else if ( (pwm[i].currentPWM >= pwm[i].pwmvalue) && pwm[i].currentState ) { *pwm[i].outport &= ~(pwm[i].pinmask); pwm[i].currentState = false; }
}
}
Second, simple code (similar to the one used with SoftPWM
ISR(TIMER2_COMPA_vect){ // version 2 = simple
static uint8_t cnt = 0;
if (cnt++ == 0) {
for (int i = 0; i < 9; i++) {
if ( pwm[i].pwmvalue) *pwm[i].outport |= pwm[i].pinmask;
}
}
for (int i = 0; i < 9; i++){
if ( cnt == pwm[i].pwmvalue) { *pwm[i].outport &= ~(pwm[i].pinmask); }
}
}
Third, a plain text version of 2
ISR(TIMER2_COMPA_vect){ // version 3 = plain
static uint8_t cnt = 0;
static uint8_t v[9] = {0,0,0,0,0,0,0,0,0};
if (++cnt == 0) {
if (pwm[0].pwmvalue) *pwm[0].outport |= pwm[0].pinmask;
if (pwm[1].pwmvalue) *pwm[1].outport |= pwm[1].pinmask;
if (pwm[2].pwmvalue) *pwm[2].outport |= pwm[2].pinmask;
if (pwm[3].pwmvalue) *pwm[3].outport |= pwm[3].pinmask;
if (pwm[4].pwmvalue) *pwm[4].outport |= pwm[4].pinmask;
if (pwm[5].pwmvalue) *pwm[5].outport |= pwm[5].pinmask;
if (pwm[6].pwmvalue) *pwm[6].outport |= pwm[6].pinmask;
if (pwm[7].pwmvalue) *pwm[7].outport |= pwm[7].pinmask;
if (pwm[8].pwmvalue) *pwm[8].outport |= pwm[8].pinmask;
}
if ( cnt == pwm[0].pwmvalue) { *pwm[0].outport &= ~(pwm[0].pinmask); }
if ( cnt == pwm[1].pwmvalue) { *pwm[1].outport &= ~(pwm[1].pinmask); }
if ( cnt == pwm[2].pwmvalue) { *pwm[2].outport &= ~(pwm[2].pinmask); }
if ( cnt == pwm[3].pwmvalue) { *pwm[3].outport &= ~(pwm[3].pinmask); }
if ( cnt == pwm[4].pwmvalue) { *pwm[4].outport &= ~(pwm[4].pinmask); }
if ( cnt == pwm[5].pwmvalue) { *pwm[5].outport &= ~(pwm[5].pinmask); }
if ( cnt == pwm[6].pwmvalue) { *pwm[6].outport &= ~(pwm[6].pinmask); }
if ( cnt == pwm[7].pwmvalue) { *pwm[7].outport &= ~(pwm[7].pinmask); }
if ( cnt == pwm[8].pwmvalue) { *pwm[8].outport &= ~(pwm[8].pinmask); }
}
When I increase the speed (400Hz) the problem is reduced, but still present. Having high frequency is also not good for mosftet for a temperature reason
I tested making a copy of the pwm Values but with the same results as before
ISR(TIMER2_COMPA_vect){ // version 4 = copy
static uint8_t cnt = 0;
static uint8_t v[9] = {0,0,0,0,0,0,0,0,0};
if (++cnt == 0) {
v[0] = pwm[0].pwmvalue;
v[1] = pwm[1].pwmvalue;
v[2] = pwm[2].pwmvalue;
v[3] = pwm[3].pwmvalue;
v[4] = pwm[4].pwmvalue;
v[5] = pwm[5].pwmvalue;
v[6] = pwm[6].pwmvalue;
v[7] = pwm[7].pwmvalue;
v[8] = pwm[8].pwmvalue;
if (v[0]) *pwm[0].outport |= pwm[0].pinmask;
if (v[1]) *pwm[1].outport |= pwm[1].pinmask;
if (v[2]) *pwm[2].outport |= pwm[2].pinmask;
if (v[3]) *pwm[3].outport |= pwm[3].pinmask;
if (v[4]) *pwm[4].outport |= pwm[4].pinmask;
if (v[5]) *pwm[5].outport |= pwm[5].pinmask;
if (v[6]) *pwm[6].outport |= pwm[6].pinmask;
if (v[7]) *pwm[7].outport |= pwm[7].pinmask;
if (v[8]) *pwm[8].outport |= pwm[8].pinmask;
}
if ( cnt == v[0]) { *pwm[0].outport &= ~(pwm[0].pinmask); }
if ( cnt == v[1]) { *pwm[1].outport &= ~(pwm[1].pinmask); }
if ( cnt == v[2]) { *pwm[2].outport &= ~(pwm[2].pinmask); }
if ( cnt == v[3]) { *pwm[3].outport &= ~(pwm[3].pinmask); }
if ( cnt == v[4]) { *pwm[4].outport &= ~(pwm[4].pinmask); }
if ( cnt == v[5]) { *pwm[5].outport &= ~(pwm[5].pinmask); }
if ( cnt == v[6]) { *pwm[6].outport &= ~(pwm[6].pinmask); }
if ( cnt == v[7]) { *pwm[7].outport &= ~(pwm[7].pinmask); }
if ( cnt == v[8]) { *pwm[8].outport &= ~(pwm[8].pinmask); }
}
Can you understand where is the problem? If i move the blinking speed to 2000ms i see a stable dimmed light...
testPWM.ino (6.43 KB)
