PWM, the right (wrong) way

A project log for Cap-sense name card

Combine PCB art and cap-sense activated LEDs to create a worthy maker name card

uri.shaniuri.shani 09/09/2018 at 10:380 Comments

While migrating the code from my initial trials with the Uno, it was obvious the LEDs do not get the correct values - even though I started out with the exact same sketch that worked on the Uno. As it was my first time working with a ATtiny85 / ATtiny13, I did some digging to find the root of the problem. I didn't actually nail the reason down yet, but I found a solution for the time being: following the advice given here, I set up the PWM registers to work in an inverted state.

// Configure counter/timer0 for fast PWM w/inverted input on PB0 and PB1
TCCR0A = _BV(COM0A0) | _BV(COM0A1) | _BV(COM0B0) | _BV(COM0B1) | _BV(WGM00) | _BV(WGM01);

At first I thought it had something to do with the implementation of analogWrite() in the cores I used, but a quick look at wiring_analog.h proved me wrong. My next guess will be the setup of timer 0, which is used both in ATtinyCore and microCore for millis() and delay() - though I did not check that out yet.

Anyway - inverting the registers works, and the only thing needed to work with the connected pins is the simple conversion (output value) = 255 - (intended value). I went ahead and pre-programmed the values for the breathing LED animation, but you can still see this conversion in the flickering scripts. Also, turning the LEDs off after calibration of the ADCTouch is done by turning the pins "high", because of this inversion:

if (ref0 > 0) PORTB |= (1 << PINB0) | (1 << PINB1); //Confirm ref0 initialization