led_bikewheel/led_bikewheel.ino
2020-12-30 19:19:27 +01:00

130 lines
3.9 KiB
C++

// uncomment next line if you want to use NEOPIXEL (3 pins) instead of APA102 (4 pins)
//#define NEOPIXEL
// uncomment next line for image test modus, this will change the segments every 1/2 second
//#define TEST_STRIPES
#include "images.h"
#ifdef NEOPIXEL
#include <Adafruit_NeoPixel.h>
#else
#include <FastGPIO.h>
#define APA102_USE_FAST_GPIO
#include <APA102.h>
#endif
// CONFIGURE please configure next lines depending on your stripe arragmentment
#define HALL_PIN 2 // digital pin of hall sensor
#define ROUND_COUNT 1 // how many rounds to take time (minimum 1)
#define NUM_SEGMENTS 360 // how much segements to divide image (gives an angle precision of 360 / NUM_SEGMENTS)
#define LED_COUNT 26 // how many LEDs on one stripe
#define LED_STRIPES 4 // how many LEDs stripes on wheel
int strip_matrix_offset[LED_STRIPES] = {0, 0, (NUM_SEGMENTS / 2), (NUM_SEGMENTS / 2)}; // given offset in segments for stripe
bool strip_matrix_invert[LED_STRIPES] = {false, true, false, true}; // set LEDs in revert order for stripe
// \CONFIGURE
// LED stripes
#ifdef NEOPIXEL
#define LED_PIN 6 // data pin for neopixel LED stripe
#define BRIGHTNESS 10 // brightness for LED strip [0-255]
Adafruit_NeoPixel ledStrip(LED_COUNT *LED_STRIPES, LED_PIN, NEO_GRB + NEO_KHZ800);
#else
#define LED_DATA_PIN 10 // data pin for LED strip
#define LED_CLOCK_PIN 11 // clock pin for LED strip
APA102<LED_DATA_PIN, LED_CLOCK_PIN> ledStrip;
#define BRIGHTNESS 1 // brightness for LED strip [0-31]
rgb_color color_buffer[LED_COUNT * LED_STRIPES]; // color buffer to write to LED stripe
#endif
float passed = 0;
int current_image_index = 0;
uint8_t *current_palette;
uint8_t *current_pixels;
int current_state = 0;
void setup()
{
Serial.begin(115200);
pinMode(HALL_PIN, INPUT);
pinMode(LED_BUILTIN, INPUT);
current_palette = (uint8_t *)pgm_read_word(&images[current_image_index].palette);
current_pixels = (uint8_t *)pgm_read_word(&images[current_image_index].pixels);
#ifdef NEOPIXEL
ledStrip.begin();
ledStrip.show();
ledStrip.setBrightness(BRIGHTNESS);
#endif
}
void loop()
{
float start = micros();
int count = 0;
bool change = false;
while (count <= ROUND_COUNT)
{
if (digitalRead(HALL_PIN) == LOW)
{
digitalWrite(LED_BUILTIN, HIGH);
if (!change)
{
change = true;
count++;
}
}
else
{
digitalWrite(LED_BUILTIN, LOW);
change = false;
}
float current_diff = micros() - start;
#ifndef TEST_STRIPES
current_state = ((float)passed / current_diff * NUM_SEGMENTS);
#else
int state = (micros() / 500000) % NUM_SEGMENTS;
if (state == current_state)
{
return;
}
Serial.println(current_state);
current_state = state;
#endif
for (int strip = 0; strip < LED_STRIPES; strip++)
{
uint8_t pixel_color_index;
uint8_t *current_pixel = (uint8_t *)&current_pixels[((current_state + strip_matrix_offset[strip]) % NUM_SEGMENTS) * LED_COUNT];
for (int i = 0; i < LED_COUNT; i++)
{
pixel_color_index = pgm_read_byte(current_pixel++) * 3;
uint8_t pixel_index = strip * LED_COUNT + (strip_matrix_invert[strip] ? (LED_COUNT - i) : i);
#ifdef NEOPIXEL
#define LED_PIN 6
ledStrip.setPixelColor(pixel_index, pgm_read_byte(&current_palette[pixel_color_index]),
pgm_read_byte(&current_palette[pixel_color_index + 1]),
pgm_read_byte(&current_palette[pixel_color_index + 2]));
#else
color_buffer[pixel_index] = rgb_color(
pgm_read_byte(&current_palette[pixel_color_index]),
pgm_read_byte(&current_palette[pixel_color_index + 1]),
pgm_read_byte(&current_palette[pixel_color_index + 2]));
#endif
}
}
#ifdef NEOPIXEL
ledStrip.show();
#else
ledStrip.write(color_buffer, LED_COUNT * LED_STRIPES, BRIGHTNESS);
#endif
}
passed = (micros() - start);
}