kopia lustrzana https://github.com/pimoroni/pimoroni-pico
				
				
				
			
		
			
				
	
	
		
			219 wiersze
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			219 wiersze
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
#include <stdio.h>
 | 
						|
#include <math.h>
 | 
						|
#include <cstdint>
 | 
						|
 | 
						|
#include "pico/stdlib.h"
 | 
						|
 | 
						|
#include "plasma2040.hpp"
 | 
						|
 | 
						|
#include "common/pimoroni_common.hpp"
 | 
						|
#include "breakout_encoder.hpp"
 | 
						|
#include "rgbled.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 plasma;
 | 
						|
 | 
						|
// Set how many LEDs you have
 | 
						|
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
 | 
						|
const uint UPDATES = 60;
 | 
						|
 | 
						|
 | 
						|
// 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 user_sw(plasma2040::USER_SW, Polarity::ACTIVE_LOW, 0);
 | 
						|
Button button_a(plasma2040::BUTTON_A, Polarity::ACTIVE_LOW, 0);
 | 
						|
Button button_b(plasma2040::BUTTON_B, Polarity::ACTIVE_LOW, 0);
 | 
						|
 | 
						|
RGBLED led(plasma2040::LED_R, plasma2040::LED_G, plasma2040::LED_B);
 | 
						|
 | 
						|
I2C i2c(BOARD::PICO_EXPLORER);
 | 
						|
BreakoutEncoder enc(&i2c);
 | 
						|
 | 
						|
enum ENCODER_MODE {
 | 
						|
  COLOUR,
 | 
						|
  ANGLE,
 | 
						|
  BRIGHTNESS,
 | 
						|
  SPEED
 | 
						|
};
 | 
						|
 | 
						|
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) {
 | 
						|
  t /= 200.0f;
 | 
						|
 | 
						|
  for(auto i = 0u; i < led_strip.num_leds; ++i) {
 | 
						|
    float percent_along = (float)i / led_strip.num_leds;
 | 
						|
    float offset = sinf((percent_along + 0.5f + t) * M_PI) * angle;
 | 
						|
    float h = wrap((hue + offset) / 360.0f, 0.0f, 1.0f);
 | 
						|
    led_strip.set_hsv(i, h, 1.0f, 1.0f);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void speed_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, 0, 255, 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() {
 | 
						|
  stdio_init_all();
 | 
						|
 | 
						|
  led_strip.start(UPDATES);
 | 
						|
 | 
						|
  bool encoder_detected = enc.init();
 | 
						|
  enc.clear_interrupt_flag();
 | 
						|
 | 
						|
  //Initialise the default values
 | 
						|
  int16_t speed = DEFAULT_SPEED;
 | 
						|
  int16_t hue = DEFAULT_HUE;
 | 
						|
  int16_t angle = DEFAULT_ANGLE;
 | 
						|
  int16_t brightness = DEFAULT_BRIGHTNESS;
 | 
						|
 | 
						|
  bool cycle = true;
 | 
						|
  ENCODER_MODE mode = ENCODER_MODE::COLOUR;
 | 
						|
  uint32_t start_time = millis();
 | 
						|
  while(true) {
 | 
						|
    uint32_t t = millis() - start_time;
 | 
						|
    if(encoder_detected) {
 | 
						|
      if(enc.get_interrupt_flag()) {
 | 
						|
        int16_t count = enc.read();
 | 
						|
        enc.clear_interrupt_flag();
 | 
						|
        enc.clear();
 | 
						|
 | 
						|
        cycle = false;
 | 
						|
        switch(mode) {
 | 
						|
          case ENCODER_MODE::COLOUR:
 | 
						|
            hue += count;
 | 
						|
            hue = std::min((int16_t)359, std::max((int16_t)0, hue));
 | 
						|
            colour_cycle((float)hue, 0, (float)angle);
 | 
						|
            break;
 | 
						|
 | 
						|
          case ENCODER_MODE::ANGLE:
 | 
						|
            angle += count;
 | 
						|
            angle = std::min((int16_t)359, std::max((int16_t)0, angle));
 | 
						|
            colour_cycle((float)hue, 0, (float)angle);
 | 
						|
            break;
 | 
						|
 | 
						|
          case ENCODER_MODE::BRIGHTNESS:
 | 
						|
            brightness += count;
 | 
						|
            brightness = std::min((int16_t)31, std::max((int16_t)0, brightness));
 | 
						|
            led_strip.set_brightness((uint8_t)brightness);
 | 
						|
            brightness_gauge(brightness, 31);
 | 
						|
            break;
 | 
						|
 | 
						|
          case ENCODER_MODE::SPEED:
 | 
						|
            speed += count;
 | 
						|
            speed = std::min((int16_t)100, std::max((int16_t)0, speed));
 | 
						|
            speed_gauge(speed, 100);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    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::SPEED;
 | 
						|
        break;
 | 
						|
 | 
						|
      case ENCODER_MODE::SPEED:
 | 
						|
        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 mid_led = led_strip.get(led_strip.num_leds / 2);
 | 
						|
    enc.set_led(mid_led.r, mid_led.g, mid_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);
 | 
						|
  }
 | 
						|
}
 |