kopia lustrzana https://github.com/pimoroni/pimoroni-pico
Bug fix and tweaks to rotary example
rodzic
a5d9fcf48a
commit
a46ea3b097
|
@ -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);
|
||||||
|
|
||||||
|
@ -39,118 +59,161 @@ I2C i2c(BOARD::PICO_EXPLORER);
|
||||||
BreakoutEncoder enc(&i2c);
|
BreakoutEncoder enc(&i2c);
|
||||||
|
|
||||||
enum ENCODER_MODE {
|
enum ENCODER_MODE {
|
||||||
COLOUR,
|
COLOUR,
|
||||||
ANGLE,
|
ANGLE,
|
||||||
BRIGHTNESS,
|
BRIGHTNESS,
|
||||||
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 {
|
|
||||||
led_strip.set_rgb(i, 255, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
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();
|
||||||
|
|
||||||
led_strip.start(UPDATES);
|
led_strip.start(UPDATES);
|
||||||
|
|
||||||
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;
|
||||||
bool cycle = true;
|
int16_t brightness = DEFAULT_BRIGHTNESS;
|
||||||
ENCODER_MODE mode = ENCODER_MODE::COLOUR;
|
|
||||||
while (true) {
|
|
||||||
uint32_t t = millis();
|
|
||||||
if(encoder_detected) {
|
|
||||||
if(enc.get_interrupt_flag()) {
|
|
||||||
int count = enc.read();
|
|
||||||
enc.clear_interrupt_flag();
|
|
||||||
enc.clear();
|
|
||||||
|
|
||||||
cycle = false;
|
bool cycle = true;
|
||||||
switch(mode) {
|
ENCODER_MODE mode = ENCODER_MODE::COLOUR;
|
||||||
case ENCODER_MODE::COLOUR:
|
uint32_t start_time = millis();
|
||||||
hue += count;
|
while(true) {
|
||||||
brightness = std::min((int8_t)359, brightness);
|
uint32_t t = millis() - start_time;
|
||||||
brightness = std::max((int8_t)0, brightness);
|
if(encoder_detected) {
|
||||||
colour_cycle(hue, 0, (float)angle);
|
if(enc.get_interrupt_flag()) {
|
||||||
break;
|
int16_t count = enc.read();
|
||||||
case ENCODER_MODE::ANGLE:
|
enc.clear_interrupt_flag();
|
||||||
angle += count;
|
enc.clear();
|
||||||
angle = std::min((int)359, angle);
|
|
||||||
angle = std::max((int)0, angle);
|
|
||||||
colour_cycle(hue, 0, (float)angle);
|
|
||||||
break;
|
|
||||||
case ENCODER_MODE::BRIGHTNESS:
|
|
||||||
brightness += count;
|
|
||||||
brightness = std::min((int8_t)31, brightness);
|
|
||||||
brightness = std::max((int8_t)0, brightness);
|
|
||||||
led_strip.set_brightness(brightness);
|
|
||||||
gauge(brightness, 31);
|
|
||||||
break;
|
|
||||||
case ENCODER_MODE::TIME:
|
|
||||||
speed += count;
|
|
||||||
speed = std::min((int)100, speed);
|
|
||||||
speed = std::max((int)0, speed);
|
|
||||||
gauge(speed, 100);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bool a_pressed = button_a.read();
|
|
||||||
bool b_pressed = button_b.read();
|
|
||||||
|
|
||||||
if(b_pressed) cycle = true;
|
|
||||||
|
|
||||||
|
cycle = false;
|
||||||
switch(mode) {
|
switch(mode) {
|
||||||
case ENCODER_MODE::COLOUR:
|
case ENCODER_MODE::COLOUR:
|
||||||
led.set_rgb(255, 0, 0);
|
hue += count;
|
||||||
if(a_pressed) mode = ENCODER_MODE::ANGLE;
|
hue = std::min((int16_t)359, std::max((int16_t)0, hue));
|
||||||
break;
|
colour_cycle((float)hue, 0, (float)angle);
|
||||||
case ENCODER_MODE::ANGLE:
|
break;
|
||||||
led.set_rgb(255, 255, 0);
|
|
||||||
if(a_pressed) mode = ENCODER_MODE::BRIGHTNESS;
|
case ENCODER_MODE::ANGLE:
|
||||||
break;
|
angle += count;
|
||||||
case ENCODER_MODE::BRIGHTNESS:
|
angle = std::min((int16_t)359, std::max((int16_t)0, angle));
|
||||||
led.set_rgb(0, 255, 0);
|
colour_cycle((float)hue, 0, (float)angle);
|
||||||
if(a_pressed) mode = ENCODER_MODE::TIME;
|
break;
|
||||||
break;
|
|
||||||
case ENCODER_MODE::TIME:
|
case ENCODER_MODE::BRIGHTNESS:
|
||||||
led.set_rgb(0, 0, 255);
|
brightness += count;
|
||||||
if(a_pressed) mode = ENCODER_MODE::COLOUR;
|
brightness = std::min((int16_t)31, std::max((int16_t)0, brightness));
|
||||||
break;
|
led_strip.set_brightness((uint8_t)brightness);
|
||||||
|
brightness_gauge(brightness, 31);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ENCODER_MODE::TIME:
|
||||||
|
speed += count;
|
||||||
|
speed = std::min((int16_t)100, std::max((int16_t)0, speed));
|
||||||
|
speed_gauge(speed, 100);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if(cycle) colour_cycle(hue, t * speed / 100, (float)angle);
|
|
||||||
|
|
||||||
auto first_led = led_strip.get(0);
|
|
||||||
enc.set_led(first_led.r, first_led.g, first_led.b);
|
|
||||||
|
|
||||||
// Sleep time controls the rate at which the LED buffer is updated
|
|
||||||
// but *not* the actual framerate at which the buffer is sent to the LEDs
|
|
||||||
sleep_ms(1000 / UPDATES);
|
|
||||||
}
|
}
|
||||||
|
bool sw_pressed = user_sw.read();
|
||||||
|
bool a_pressed = button_a.read();
|
||||||
|
bool b_pressed = button_b.read();
|
||||||
|
|
||||||
|
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) {
|
||||||
|
case ENCODER_MODE::COLOUR:
|
||||||
|
led.set_rgb(255, 0, 0);
|
||||||
|
if(a_pressed) mode = ENCODER_MODE::ANGLE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ENCODER_MODE::ANGLE:
|
||||||
|
led.set_rgb(255, 255, 0);
|
||||||
|
if(a_pressed) mode = ENCODER_MODE::BRIGHTNESS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ENCODER_MODE::BRIGHTNESS:
|
||||||
|
led.set_rgb(0, 255, 0);
|
||||||
|
if(a_pressed) mode = ENCODER_MODE::TIME;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ENCODER_MODE::TIME:
|
||||||
|
led.set_rgb(0, 0, 255);
|
||||||
|
if(a_pressed) mode = ENCODER_MODE::COLOUR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cycle)
|
||||||
|
colour_cycle(hue, (float)(t * speed) / 100.0f, (float)angle);
|
||||||
|
|
||||||
|
auto first_led = led_strip.get(led_strip.num_leds / 2);
|
||||||
|
enc.set_led(first_led.r, first_led.g, first_led.b);
|
||||||
|
|
||||||
|
// Sleep time controls the rate at which the LED buffer is updated
|
||||||
|
// but *not* the actual framerate at which the buffer is sent to the LEDs
|
||||||
|
sleep_ms(1000 / UPDATES);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Ładowanie…
Reference in New Issue