Problem 1: The speed that my rainbow cycles are running at are way too fast. I need to slow them down.
Problem 2: Once I have entered the rainbow portions of the code, I can not get back to the first 4 modes that are controlled with the color picker.
Problem 3: I would like my sparkle mode to light more than 1 pixel at a time.
The other modes are ok. I realize that the code in them is not the best, but are running satisfactorily.
- Code: Select all | TOGGLE FULL SIZE
// BLUEFRUIT LE UART FRIEND MUST BE SWITCHED TO 'UART' MODE
#include <SoftwareSerial.h>
#include <Adafruit_NeoPixel.h>
#ifdef __AVR_ATtiny85__
#include <avr/power.h>
#include <avr/sleep.h>
#endif
#define RX_PIN 1 // Connect this pin to BLE 'TXO' pin
#define CTS_PIN 3 // Connect this pin to BLE 'CTS' pin
#define LED_PIN 2 // Connect NeoPixels to this pin
#define NUM_LEDS 73 // Number of led lights
#define FPS 30 // Animation frames/second (ish)
SoftwareSerial ser(RX_PIN, -0);
Adafruit_NeoPixel pixels(NUM_LEDS, LED_PIN);
void setup() {
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000L)
// MUST do this on 16 MHz Trinket for serial & NeoPixels!
clock_prescale_set(clock_div_1);
#endif
// Stop incoming data & init software serial
pinMode(CTS_PIN, OUTPUT); digitalWrite(CTS_PIN, HIGH);
pixels.setBrightness(25); // set LED brightness here
ser.begin(9600);
pixels.begin(); // NeoPixel init
// Flash space is tight on Trinket/Gemma, so setBrightness() is avoided --
// it adds ~200 bytes. Instead the color picker input is 'manually' scaled.
}
uint8_t buf[3], // Enough for RGB parse; expand if using sensors
animMode = 1, // Current animation mode
animPos = 0; // Current animation position
uint32_t color = 0x400000, // Current animation color (red by default)
prevTime = 0L; // For animation timing
void loop(void) {
int c;
uint32_t t;
// Animation happens at about 30 frames/sec. Rendering frames takes less
// than that, so the idle time is used to monitor incoming serial data.
digitalWrite(CTS_PIN, LOW); // Signal to BLE, OK to send data!
for (;;) {
t = micros(); // Current time
if ((t - prevTime) >= (1000000L / FPS)) { // 1/30 sec elapsed?
prevTime = t;
break; // Yes, go update LEDs
} // otherwise...
if ((c = ser.read()) == '!') { // Received UART app input?
while ((c = ser.read()) < 0); // Yes, wait for command byte
switch (c) {
case 'B': // Button (Control Pad)
if (readAndCheckCRC(255 - '!' - 'B', buf, 2) & (buf[1] == '1')) {
buttonPress(buf[0]); // Handle button-press message
}
break;
case 'C': // Color Picker
if (readAndCheckCRC(255 - '!' - 'C', buf, 3)) {
// As mentioned earlier, setBrightness() was avoided to save space.
// Instead, results from the color picker (in buf[]) are divided
// by 4; essentially equivalent to setBrightness(64). This is to
// improve battery run time (NeoPixels are still plenty bright).
color = pixels.Color(buf[0] / 4, buf[1] / 4, buf[2] / 4);
}
break;
case 'Q': // Quaternion
skipBytes(17); // 4 floats + CRC (see note below re: parsing)
break;
case 'A': // Accelerometer
#if 0
// The phone sensors are NOT used by this sketch, but this shows how
// they might be read. First, buf[] must be delared large enough for
// the expected data packet (minus header & CRC) -- that's 16 bytes
// for quaternions (above), or 12 bytes for most of the others.
// Second, the first arg to readAndCheckCRC() must be modified to
// match the data type (e.g. 'A' here for accelerometer). Finally,
// values can be directly type-converted to float by using a suitable
// offset into buf[] (e.g. 0, 4, 8, 12) ... it's not used in this
// example because floating-point math uses lots of RAM and code
// space, not suitable for the space-constrained Trinket/Gemma, but
// maybe you're using a Pro Trinket, Teensy, etc.
if (readAndCheckCRC(255 - '!' - 'A', buf, 12)) {
float x = *(float *)(&buf[0]),
y = *(float *)(&buf[4]),
z = *(float *)(&buf[8]);
}
// In all likelihood, updates from the buttons and color picker
// alone are infrequent enough that you could do without any mention
// of the CTS pin in this code. It's the extra sensors that really
// start the firehose of data.
break;
#endif
case 'G': // Gyroscope
case 'M': // Magnetometer
case 'L': // Location
skipBytes(13); // 3 floats + CRC
}
}
}
digitalWrite(CTS_PIN, HIGH); // BLE STOP!
// Show pixels calculated on *prior* pass; this ensures more uniform timing
pixels.show();
// Then calculate pixels for *next* frame...
switch (animMode) {
case 0: // chasing mode
for(uint8_t i = 0; i < NUM_LEDS / 1; i++) {
uint32_t c = 0;
if (((animPos + i) & 15) < 4) c = color; //16 total pixels, 4 lit at a time
pixels.setPixelColor( i, c);
}
animPos++;
break;
case 1: // Sparkle mode
pixels.setPixelColor(animPos, 0); // Erase old dot
animPos = random(NUM_LEDS); // Pick a new one
pixels.setPixelColor(animPos, color); // and light it
break;
case 2: //solid mode
for(uint8_t i = 0; i < NUM_LEDS; i++) {
uint32_t c = 0;
if (((animPos) & 15) < 15) c = color; // all pixels lit
pixels.setPixelColor( i, c);
}
break;
case 3: //blinking mode
for(uint8_t i = 0; i < NUM_LEDS / 1; i++) {
uint32_t c = 0;
if (((animPos + 1) & 15) < 2) c = color; // all pixels lit
pixels.setPixelColor( i, c);
}
animPos++;
break;
case 4: // Up = rainbowCycle
{
uint16_t i, j;
for(j=0; j<256; j++) { // cycles of all colors on wheel
for(i=0; i< pixels.numPixels(); i++) {
pixels.setPixelColor(i, Wheel(((i * 256 / pixels.numPixels()) + j) & 255));
}
pixels.show();
}
}
break;
case 5: // Down = theaterChaseRainbow
{
for(int j=0; j < 256; j++) { // cycle all 256 colors in the wheel
for(int q=0; q < 3; q++) {
for(uint16_t i=0; i < pixels.numPixels(); i=i+3) {
pixels.setPixelColor(i+q, Wheel( (i+j) % 255)); //turn every third pixel on
}
pixels.show();
for(uint16_t i=0; i < pixels.numPixels(); i=i+3) {
pixels.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
break;
case 6: // left button - rainbow
{
uint16_t i, j;
for(j=0; j<256; j++) {
for(i=0; i<pixels.numPixels(); i++) {
pixels.setPixelColor(i, Wheel((i+j) & 255));
}
pixels.show();
}
}
break;
case 7: // right button - rainbow sparkle mode
{
uint16_t i, j;
for(j=0; j<256; j++) {
for(i=0; i<pixels.numPixels(); i++) {
if (random(pixels.numPixels()) == i)
pixels.setPixelColor(i,255, 255, 255);
else
pixels.setPixelColor(i, Wheel((i+j) & 255));
}
pixels.show();
}
}
break;
}
}
boolean readAndCheckCRC(uint8_t sum, uint8_t *buf, uint8_t n) {
for (int c;;) {
while ((c = ser.read()) < 0); // Wait for next byte
if (!n--) return (c == sum); // If CRC byte, we're done
*buf++ = c; // Else store in buffer
sum -= c; // and accumulate sum
}
}
void skipBytes(uint8_t n) {
while (n--) {
while (ser.read() < 0);
}
}
void buttonPress(char c) {
pixels.clear(); // Clear pixel data when switching modes (else residue)
switch (c) {
case '1':
animMode = 0; // Switch to chase mode
break;
case '2':
animMode = 1; // Switch to sparkle mode
break;
case '3':
animMode = 2; // Switch to solid mode
break;
case '4':
animMode = 3; // Switch to blinking mode
break;
case '5':
animMode = 4; // Up = rainbowCycle
break;
case '6':
animMode = 5; // Down = theaterChaseRainbow
break;
case '7':
animMode = 6; // Left =
break;
case '8':
animMode = 7; // Right = rainbowSparkle
break;
}
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return pixels.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if(WheelPos < 170) {
WheelPos -= 85;
return pixels.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return pixels.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
This shoe is running the simple buttoncycler code and is the pair I am trying to convert to BT.
https://www.instagram.com/p/BnNYhezArz3 ... _copy_link