A dabble in AVR Assembly (II)
In an earlier blog I looked at putting a very tired (128kHz) Attiny13a to sleep using some assembler code. But when it's awake, maybe we want to make it act like a candle and flicker. "First learn stand, then learn fly" Mr Miyagi said, so instead of a deep dive I will see if I can get one PWM channel on the μC to ramp up and down, then maybe I can get the two of them to move randomly-ish?First we choose a pin to output to:
We also want to use Fast PWM mode so in assembler (copy 3 [binary 11] into WGM00); these instructions look like this:
ldi r16, 0b10100011 ; load immediate binary 10100011 to r16 register out TCCR0A, r16 ; move out the byte from r16 to TCCR0A
The full code is a little too boring for one blog - but you can find it linked here at github, and I go over it a little in the video linked below.
Now to randomise the PWM ramping up and down (flickering), the code will need some way of generating a "random" number. The simplest way is to use a basic linear feedback shift register (LFSR) algorithm as described on page 71-ish of my Attiny13A Assembler by Example booklet.
For an 8-bit shift, I start at 0x29 (Decimal 41) and do the LSL operation (documented in this link). There is a branch then depending on the carry bit, and an XOR operation may also be performed (in this case with 0x8B). If all goes well, the algorithm produces numbers shown in green in the right hand column.
Of course - it is only "pseudo" random as the constant starting point and XOR number ensures a set pattern each time - but it'll do for our candley-goodness. You can set it to be more random by sampling a pin and using that as a starting point.
Then having achieved "randomness" we will have to keep track of a few numbers in order to vary the ramping.
Fast Low High - the largest low value for the fast LED (FLH = 140)
Fast High Low - the smallest high value for the fast LED (FHL = 180)
Fast High High - the largest high value for the fast LED (FHH = 220)
Slow Ramping (two LEDs)
Slow Low Low - the smallest low value for the slow LED (SLL = 15)
Slow Low High - the largest low value for the slow LED (SLH = 40)
Slow High Low - the smallest high value for the slow LED (SHL = 150)
Slow High High - the largest high value for the slow LED (SHH = 220)
Fast Ramping (one LED)
Fast Low Low - the smallest low value for the fast LED (FLL = 100)Fast Low High - the largest low value for the fast LED (FLH = 140)
Fast High Low - the smallest high value for the fast LED (FHL = 180)
Fast High High - the largest high value for the fast LED (FHH = 220)
The plan is to generate a "random number" between 0 and 255 using our LFSR, and then when it falls between the SLL and SLH we nab it for the starting slow ramp low value. Likewise for the slow ramp high value, the fast ramp low value and the fast ramp high value.
The loop just checks where each ramp is, and when it reaches one of the limits, generates a new limit and bounces towards that number. A little delay (a time worth varying using this site) means we can see the LEDs ramp up and down with the naked eye and we have a "candle"!
The loop just checks where each ramp is, and when it reaches one of the limits, generates a new limit and bounces towards that number. A little delay (a time worth varying using this site) means we can see the LEDs ramp up and down with the naked eye and we have a "candle"!