Bonfire/src/main.c

106 lines
2.1 KiB
C

#include <stdint.h>
#include <stdlib.h>
#include <avr/io.h>
#include <util/delay.h>
#include "ledpwmcurve.h"
#define PWMMin 128
#define PWMMax 1024
#define PWMRange (PWMMax - PWMMin)
#define PWMRandomValue() ((random() % PWMRange) + PWMMin)
#define DelayMin 5
#define DelayMax 50
#define DelayChange 1
#define DelayChangeSteps ((DelayMax - DelayMin) / DelayChange)
void var_delay_ms(int n);
int main()
{
uint16_t currentValue = PWMRandomValue();
uint16_t targetValue = currentValue;
uint16_t startValue = currentValue;
uint16_t speedUpUntil = currentValue;
uint16_t slowDownFrom = currentValue;
uint8_t delay = DelayMax;
#define goingUp (targetValue > currentValue)
// -- Set up PWM
// Set all ports as output (leave none as floating input)
DDRB = 0b11111111;
// Set Timer 0 to internal clock, no prescaling.
// See chapter 11.9 of the ATTiny85 datasheet
TCCR0B |= (1 << CS00);
// Set to 'Fast PWM' mode
TCCR0A |= (1 << WGM01) | (1 << WGM00);
// Clear OC0B output on compare match, upwards counting
TCCR0A |= (1 << COM0B1);
while (1)
{
if (targetValue == currentValue)
{
do
{
targetValue = PWMRandomValue();
} while (targetValue == currentValue);
startValue = currentValue;
speedUpUntil = goingUp ? startValue + DelayChangeSteps : startValue - DelayChangeSteps;
slowDownFrom = goingUp ? targetValue - DelayChangeSteps : targetValue + DelayChangeSteps;
}
if (goingUp)
{
currentValue++;
if (currentValue < speedUpUntil)
delay -= DelayChange;
else if (currentValue > slowDownFrom)
delay += DelayChange;
else
delay = DelayMin;
}
else
{
currentValue--;
if (currentValue > speedUpUntil)
delay -= DelayChange;
else if (currentValue < slowDownFrom)
delay += DelayChange;
else
delay = DelayMin;
}
// Update PWM value
OCR0B = antilog(currentValue);
var_delay_ms(delay);
}
return 0;
}
// Source: http://www.avrfreaks.net/forum/how-use-delay-variable
void var_delay_ms(int n)
{
while(n--)
_delay_ms(1);
}