#include #include #include #include "pico/stdlib.h" #include "plasma2040.hpp" #include "common/pimoroni_common.hpp" #include "bme68x.hpp" #include "rgbled.hpp" #include "button.hpp" /* Press "A" to cycle to the next mode. Press "B" to cycle to the previous mode. */ using namespace pimoroni; using namespace plasma; // Set how many LEDs you have const uint N_LEDS = 30; // How many times the LEDs will be updated per second const uint UPDATES = 60; // The temperature range to show (in degrees celsius) constexpr float TEMPERATURE_C_MIN = 20.0f; constexpr float TEMPERATURE_C_MAX = 35.0f; // The pressure range to show (in pascals) constexpr float PRESSURE_PA_MIN = 87000.0f; constexpr float PRESSURE_PA_MAX = 108500.0f; // The humidity range to show (in percent) constexpr float HUMIDITY_MIN = 0.0f; constexpr float HUMIDITY_MAX = 100.0f; // The start and end hues for the temperature range constexpr float TEMPERATURE_HUE_START = 0.667f; constexpr float TEMPERATURE_HUE_END = 1.0f; // The start and end hues for the pressure range constexpr float PRESSURE_HUE_START = 0.333f; constexpr float PRESSURE_HUE_END = 0.0f; // The start and end hues for the humidity range constexpr float HUMIDITY_HUE_START = 0.333f; constexpr float HUMIDITY_HUE_END = 0.667f; // Pick *one* LED type by uncommenting the relevant line below: // APA102-style LEDs with Data/Clock lines. AKA DotStar //APA102 led_strip(N_LEDS, pio0, 0, plasma2040::DAT, plasma2040::CLK); // WS28X-style LEDs with a single signal line. AKA NeoPixel WS2812 led_strip(N_LEDS, pio0, 0, plasma2040::DAT); Button button_a(plasma2040::BUTTON_A, ACTIVE_LOW, 0); Button button_b(plasma2040::BUTTON_B, ACTIVE_LOW, 0); RGBLED led(plasma2040::LED_R, plasma2040::LED_G, plasma2040::LED_B); I2C i2c(BOARD::PICO_EXPLORER); BME68X bme68x(&i2c); enum DisplayMode { ALL, TEMPERATURE, PRESSURE, HUMIDITY }; // Maps a value from one range to another float map(float x, float in_min, float in_max, float out_min, float out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } // Sets a section of the led strip to show a hue gradient based on the provided percent void colour_gauge(float percent, uint start_led, uint end_led, float start_hue, float end_hue) { if(end_led > start_led) { uint range = end_led - start_led; float light_pixels = percent * range; for(uint i = 0; i < range; i++) { float h = map(i, 0.0f, (float)range - 1, start_hue, end_hue); uint i2 = i + 1; if(i2 <= light_pixels) { led_strip.set_hsv(i + start_led, h, 1.0f, 1.0f); } else if(i <= light_pixels) { float scale = map(light_pixels, (float)i, (float)i2, 0.0f, 1.0f); led_strip.set_hsv(i + start_led, h, 1.0f, scale); } else { led_strip.set_hsv(i + start_led, 0.0f, 0.0f, 0.0f); } } } } int main() { stdio_init_all(); led_strip.start(UPDATES); bool bme_detected = bme68x.init(); uint first_third = led_strip.num_leds / 3; uint second_third = (led_strip.num_leds * 2) / 3; float t = 0.0f; DisplayMode mode = DisplayMode::ALL; while(true) { if(bme_detected) { bme68x_data data; auto result = bme68x.read_forced(&data); (void)result; printf("%.2fc, %.2fPa, %.2f%%\n", data.temperature, data.pressure, data.humidity); switch(mode) { case DisplayMode::ALL: t = map(data.temperature, TEMPERATURE_C_MIN, TEMPERATURE_C_MAX, 0.0f, 1.0f); colour_gauge(t, 0, first_third, TEMPERATURE_HUE_START, TEMPERATURE_HUE_END); t = map(data.pressure, PRESSURE_PA_MIN, PRESSURE_PA_MAX, 0.0f, 1.0f); colour_gauge(t, first_third, second_third, PRESSURE_HUE_START, PRESSURE_HUE_END); t = map(data.humidity, HUMIDITY_MIN, HUMIDITY_MAX, 0.0f, 1.0f); colour_gauge(t, second_third, led_strip.num_leds, HUMIDITY_HUE_START, HUMIDITY_HUE_END); break; case DisplayMode::TEMPERATURE: t = map(data.temperature, TEMPERATURE_C_MIN, TEMPERATURE_C_MAX, 0.0f, 1.0f); colour_gauge(t, 0, led_strip.num_leds, TEMPERATURE_HUE_START, TEMPERATURE_HUE_END); break; case DisplayMode::PRESSURE: t = map(data.pressure, PRESSURE_PA_MIN, PRESSURE_PA_MAX, 0.0f, 1.0f); colour_gauge(t, 0, led_strip.num_leds, PRESSURE_HUE_START, PRESSURE_HUE_END); break; case DisplayMode::HUMIDITY: t = map(data.humidity, HUMIDITY_MIN, HUMIDITY_MAX, 0.0f, 1.0f); colour_gauge(t, 0, led_strip.num_leds, HUMIDITY_HUE_START, HUMIDITY_HUE_END); break; } } bool a_pressed = button_a.read(); bool b_pressed = button_b.read(); switch(mode) { case DisplayMode::ALL: led.set_rgb(127, 127, 127); if(a_pressed) mode = DisplayMode::TEMPERATURE; else if(b_pressed) mode = DisplayMode::HUMIDITY; break; case DisplayMode::TEMPERATURE: led.set_rgb(255, 0, 255); if(a_pressed) mode = DisplayMode::PRESSURE; else if(b_pressed) mode = DisplayMode::ALL; break; case DisplayMode::PRESSURE: led.set_rgb(255, 255, 0); if(a_pressed) mode = DisplayMode::HUMIDITY; else if(b_pressed) mode = DisplayMode::TEMPERATURE; break; case DisplayMode::HUMIDITY: led.set_rgb(0, 255, 255); if(a_pressed) mode = DisplayMode::ALL; else if(b_pressed) mode = DisplayMode::PRESSURE; break; } } }