Browse Source

Add simple example firmware for pulsating the leds

tags/v1.0
Klemens Schölhorn 4 months ago
parent
commit
b07a332092
1 changed files with 126 additions and 0 deletions
  1. +126
    -0
      firmware/pulsating-sketch/pulsating-sketch.ino

+ 126
- 0
firmware/pulsating-sketch/pulsating-sketch.ino View File

@@ -0,0 +1,126 @@
const uint16_t PWM_MAX_VALUE = 128;
const uint16_t PWM_CYCLE = 30; // us

// digitalWrite is too slow…
inline void set_pin(uint8_t pin) {
if(pin < 8) {
PORTA |= 1 << pin;
} else {
PORTB |= 1 << (10 - pin);
}
}
inline void reset_pin(uint8_t pin) {
if(pin < 8) {
PORTA &= ~(1 << pin);
} else {
PORTB &= ~(1 << (10 - pin));
}
}

struct PwmPin {
uint8_t location;
uint16_t value;
uint16_t tick;
};

enum Leds {
LED_LEFT_R,
LED_LEFT_B,
LED_RIGHT_R,
LED_RIGHT_B,
LED_TOP_R,
LED_TOP_B,
};

PwmPin pins[] = {
{ 0, 20, 0},
{ 1, 20, 0},
{ 2, 10, 0},
{ 3, 10, 0},
{10, 5, 0},
{ 9, 5, 0},
};

unsigned long last_micros = 0;
void pwm_tick() {
if(micros() - last_micros > PWM_CYCLE) {
for(auto& pin : pins) {
if(pin.tick < pin.value) {
set_pin(pin.location);
} else {
reset_pin(pin.location);
}

pin.tick = (pin.tick + 1) % PWM_MAX_VALUE;
}

last_micros = micros();
}
}

void setup() {
for(auto& pin : pins) {
pinMode(pin.location, OUTPUT);
}
}


struct FadeStep {
uint16_t target;
uint16_t step_width;
};

FadeStep pulsating_pattern_top[] = {
{21, 1},
{2, 1},
{0, 0},
};
FadeStep pulsating_pattern_left[] = {
{35, 1},
{6, 1},
{0, 0},
};
FadeStep pulsating_pattern_right[] = {
{40, 1},
{9, 1},
{0, 0},
};

struct PatternState {
uint8_t pin;
FadeStep* pattern_start;
FadeStep* pattern_current;
};

PatternState patterns[] = {
{LED_TOP_R, pulsating_pattern_top, pulsating_pattern_top},
{LED_TOP_B, pulsating_pattern_top, pulsating_pattern_top},
{LED_LEFT_R, pulsating_pattern_left, pulsating_pattern_left},
{LED_LEFT_B, pulsating_pattern_left, pulsating_pattern_left},
{LED_RIGHT_R, pulsating_pattern_right, pulsating_pattern_right},
{LED_RIGHT_B, pulsating_pattern_right, pulsating_pattern_right},
};

unsigned long last_millis = 0;
void loop() {
pwm_tick();

if(millis() - last_millis > 100) {
for(auto& pattern : patterns) {
if(pins[pattern.pin].value > pattern.pattern_current->target) {
pins[pattern.pin].value = max(pins[pattern.pin].value - pattern.pattern_current->step_width, pattern.pattern_current->target);
} else if(pins[pattern.pin].value < pattern.pattern_current->target) {
pins[pattern.pin].value = min(pins[pattern.pin].value + pattern.pattern_current->step_width, pattern.pattern_current->target);
}

if(pins[pattern.pin].value == pattern.pattern_current->target) {
pattern.pattern_current = pattern.pattern_current + 1;
if(pattern.pattern_current->step_width == 0) {
pattern.pattern_current = pattern.pattern_start;
}
}
}

last_millis = millis();
}
}

Loading…
Cancel
Save