Bug fix and tweaks to rotary example

pull/194/head
ZodiusInfuser 2021-08-24 14:15:58 +01:00
rodzic a5d9fcf48a
commit a46ea3b097
1 zmienionych plików z 162 dodań i 99 usunięć

Wyświetl plik

@ -11,27 +11,47 @@
#include "rgbled.hpp" #include "rgbled.hpp"
#include "button.hpp" #include "button.hpp"
/*
Press "B" to enable cycling.
Press "A" to change the encoder mode.
Press "Boot" to reset the effects back to default.
*/
using namespace pimoroni; using namespace pimoroni;
using namespace plasma; using namespace plasma;
// Set how many LEDs you have // Set how many LEDs you have
const uint N_LEDS = 30; const uint N_LEDS = 30;
// The speed that the LEDs will start cycling at
const int16_t DEFAULT_SPEED = 20;
// The hue (in degrees) that the LEDs will start at
const int16_t DEFAULT_HUE = 0;
// The angle (in degrees) from the hue, that the LEDs will end at
const int16_t DEFAULT_ANGLE = 120;
// The brightness (between 0 and 31) to set the LEDs to
const int16_t DEFAULT_BRIGHTNESS = 16;
// How many times the LEDs will be updated per second // How many times the LEDs will be updated per second
const uint UPDATES = 60; const uint UPDATES = 60;
// Pick *one* LED type by uncommenting the relevant line below: // Pick *one* LED type by uncommenting the relevant line below:
// APA102-style LEDs with Data/Clock lines. AKA DotStar // APA102-style LEDs with Data/Clock lines. AKA DotStar
//APA102 led_strip(N_LEDS, pio0, 0, plasma2040::DAT, plasma2040::CLK); APA102 led_strip(N_LEDS, pio0, 0, plasma2040::DAT, plasma2040::CLK);
// WS28X-style LEDs with a single signal line. AKA NeoPixel // WS28X-style LEDs with a single signal line. AKA NeoPixel
WS2812 led_strip(N_LEDS, pio0, 0, plasma2040::DAT); //WS2812 led_strip(N_LEDS, pio0, 0, plasma2040::DAT);
Button user_sw(plasma2040::USER_SW, Polarity::ACTIVE_LOW, 0);
Button button_a(plasma2040::BUTTON_A); Button button_a(plasma2040::BUTTON_A, Polarity::ACTIVE_LOW, 0);
Button button_b(plasma2040::BUTTON_B); Button button_b(plasma2040::BUTTON_B, Polarity::ACTIVE_LOW, 0);
RGBLED led(plasma2040::LED_R, plasma2040::LED_G, plasma2040::LED_B); RGBLED led(plasma2040::LED_R, plasma2040::LED_G, plasma2040::LED_B);
@ -45,29 +65,54 @@ enum ENCODER_MODE {
TIME TIME
}; };
float wrap(float v, float min, float max) {
if(v <= min)
v += (max - min);
if(v > max)
v -= (max - min);
return v;
}
void colour_cycle(float hue, float t, float angle) { void colour_cycle(float hue, float t, float angle) {
t /= 200.0f; t /= 200.0f;
for (auto i = 0u; i < led_strip.num_leds; ++i) { for(auto i = 0u; i < led_strip.num_leds; ++i) {
float offset = (M_PI * i) / led_strip.num_leds; float percent_along = (float)i / led_strip.num_leds;
offset = sinf(offset + t) * angle; float offset = sinf((percent_along + 0.5f + t) * M_PI) * angle;
led_strip.set_hsv(i, (hue + offset) / 360.0f, 1.0f, 1.0f); float h = wrap((hue + offset) / 360.0f, 0.0f, 1.0f);
led_strip.set_hsv(i, h, 1.0f, 1.0f);
} }
} }
void gauge(uint v, uint vmax = 100) { void speed_gauge(uint v, uint vmax = 100) {
uint light_pixels = led_strip.num_leds * v / vmax; uint light_pixels = led_strip.num_leds * v / vmax;
for (auto i = 0u; i < led_strip.num_leds; ++i) { for(auto i = 0u; i < led_strip.num_leds; ++i) {
if(i < light_pixels) { if(i < light_pixels) {
led_strip.set_rgb(i, 0, 255, 0); led_strip.set_rgb(i, 0, 255, 0);
} else { }
else {
led_strip.set_rgb(i, 255, 0, 0); led_strip.set_rgb(i, 255, 0, 0);
} }
} }
} }
void brightness_gauge(uint v, uint vmax = 100) {
uint light_pixels = led_strip.num_leds * v / vmax;
for(auto i = 0u; i < led_strip.num_leds; ++i) {
if(i < light_pixels) {
led_strip.set_rgb(i, 64, 64, 64);
}
else {
led_strip.set_rgb(i, 0, 0, 0);
}
}
}
int main() { int main() {
stdio_init_all(); stdio_init_all();
@ -76,17 +121,20 @@ int main() {
bool encoder_detected = enc.init(); bool encoder_detected = enc.init();
enc.clear_interrupt_flag(); enc.clear_interrupt_flag();
int speed = 50; //Initialise the default values
float hue = 0; int16_t speed = DEFAULT_SPEED;
int angle = 120; int16_t hue = DEFAULT_HUE;
int8_t brightness = 16; int16_t angle = DEFAULT_ANGLE;
int16_t brightness = DEFAULT_BRIGHTNESS;
bool cycle = true; bool cycle = true;
ENCODER_MODE mode = ENCODER_MODE::COLOUR; ENCODER_MODE mode = ENCODER_MODE::COLOUR;
while (true) { uint32_t start_time = millis();
uint32_t t = millis(); while(true) {
uint32_t t = millis() - start_time;
if(encoder_detected) { if(encoder_detected) {
if(enc.get_interrupt_flag()) { if(enc.get_interrupt_flag()) {
int count = enc.read(); int16_t count = enc.read();
enc.clear_interrupt_flag(); enc.clear_interrupt_flag();
enc.clear(); enc.clear();
@ -94,59 +142,74 @@ int main() {
switch(mode) { switch(mode) {
case ENCODER_MODE::COLOUR: case ENCODER_MODE::COLOUR:
hue += count; hue += count;
brightness = std::min((int8_t)359, brightness); hue = std::min((int16_t)359, std::max((int16_t)0, hue));
brightness = std::max((int8_t)0, brightness); colour_cycle((float)hue, 0, (float)angle);
colour_cycle(hue, 0, (float)angle);
break; break;
case ENCODER_MODE::ANGLE: case ENCODER_MODE::ANGLE:
angle += count; angle += count;
angle = std::min((int)359, angle); angle = std::min((int16_t)359, std::max((int16_t)0, angle));
angle = std::max((int)0, angle); colour_cycle((float)hue, 0, (float)angle);
colour_cycle(hue, 0, (float)angle);
break; break;
case ENCODER_MODE::BRIGHTNESS: case ENCODER_MODE::BRIGHTNESS:
brightness += count; brightness += count;
brightness = std::min((int8_t)31, brightness); brightness = std::min((int16_t)31, std::max((int16_t)0, brightness));
brightness = std::max((int8_t)0, brightness); led_strip.set_brightness((uint8_t)brightness);
led_strip.set_brightness(brightness); brightness_gauge(brightness, 31);
gauge(brightness, 31);
break; break;
case ENCODER_MODE::TIME: case ENCODER_MODE::TIME:
speed += count; speed += count;
speed = std::min((int)100, speed); speed = std::min((int16_t)100, std::max((int16_t)0, speed));
speed = std::max((int)0, speed); speed_gauge(speed, 100);
gauge(speed, 100);
break; break;
} }
} }
} }
bool sw_pressed = user_sw.read();
bool a_pressed = button_a.read(); bool a_pressed = button_a.read();
bool b_pressed = button_b.read(); bool b_pressed = button_b.read();
if(b_pressed) cycle = true; if(sw_pressed) {
speed = DEFAULT_SPEED;
hue = DEFAULT_HUE;
angle = DEFAULT_ANGLE;
brightness = DEFAULT_BRIGHTNESS;
}
if(b_pressed) {
if(!cycle)
start_time = millis();
cycle = true;
}
switch(mode) { switch(mode) {
case ENCODER_MODE::COLOUR: case ENCODER_MODE::COLOUR:
led.set_rgb(255, 0, 0); led.set_rgb(255, 0, 0);
if(a_pressed) mode = ENCODER_MODE::ANGLE; if(a_pressed) mode = ENCODER_MODE::ANGLE;
break; break;
case ENCODER_MODE::ANGLE: case ENCODER_MODE::ANGLE:
led.set_rgb(255, 255, 0); led.set_rgb(255, 255, 0);
if(a_pressed) mode = ENCODER_MODE::BRIGHTNESS; if(a_pressed) mode = ENCODER_MODE::BRIGHTNESS;
break; break;
case ENCODER_MODE::BRIGHTNESS: case ENCODER_MODE::BRIGHTNESS:
led.set_rgb(0, 255, 0); led.set_rgb(0, 255, 0);
if(a_pressed) mode = ENCODER_MODE::TIME; if(a_pressed) mode = ENCODER_MODE::TIME;
break; break;
case ENCODER_MODE::TIME: case ENCODER_MODE::TIME:
led.set_rgb(0, 0, 255); led.set_rgb(0, 0, 255);
if(a_pressed) mode = ENCODER_MODE::COLOUR; if(a_pressed) mode = ENCODER_MODE::COLOUR;
break; break;
} }
if(cycle) colour_cycle(hue, t * speed / 100, (float)angle); if(cycle)
colour_cycle(hue, (float)(t * speed) / 100.0f, (float)angle);
auto first_led = led_strip.get(0); auto first_led = led_strip.get(led_strip.num_leds / 2);
enc.set_led(first_led.r, first_led.g, first_led.b); enc.set_led(first_led.r, first_led.g, first_led.b);
// Sleep time controls the rate at which the LED buffer is updated // Sleep time controls the rate at which the LED buffer is updated