Skip to content

Instantly share code, notes, and snippets.

@csexton
Created June 27, 2019 20:07
Show Gist options
  • Save csexton/f36b8e2205342f6171e69f15f64e7ce6 to your computer and use it in GitHub Desktop.
Save csexton/f36b8e2205342f6171e69f15f64e7ce6 to your computer and use it in GitHub Desktop.
Simple Neopixel with serial command control
// NeoPixel Ring simple sketch (c) 2013 Shae Erisson
// Released under the GPLv3 license to match the rest of the
// Adafruit NeoPixel library
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
// Which pin on the Arduino is connected to the NeoPixels?
#define PIN 6 // On Trinket or Gemma, suggest changing this to 1
// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS 24 // Popular NeoPixel ring size
// When setting up the NeoPixel library, we tell it how many pixels,
// and which pin to use to send signals. Note that for older NeoPixel
// strips you might need to change the third parameter -- see the
// strandtest example for more information on possible values.
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
#define DELAYVAL 100 // Time (in milliseconds) to pause between pixels
// Default birgness of the pixels
#define DEFAULT_BRIGHTNESS 60
#define MAX_INT 65535
void setup() {
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
// These lines are specifically to support the Adafruit Trinket 5V 16 MHz.
// Any other board, you can remove this part (but no harm leaving it):
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
clock_prescale_set(clock_div_1);
#endif
// END of Trinket-specific code.
pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
resetPixels();
}
void resetPixels() {
pixels.clear();
pixels.setBrightness(DEFAULT_BRIGHTNESS);
whitePulse();
pixels.show();
}
bool shouldStop() {
if (Serial.available() > 0) {
return true;
}
return false;
}
void loop() {
int incomingByte = 0;
resetPixels();
if (Serial.available() > 0) {
incomingByte = Serial.read(); // read the incoming byte:
if (incomingByte == 'A') {
rainbowCycle(1);
//colorWave(1, 1000);
}
if (incomingByte == 'B') {
greenPulse();
}
if (incomingByte == 'C') {
redPulse();
}
if (incomingByte == 'D') {
rainbow(10);
}
if (incomingByte == 'E') {
rainbowCycleStoppable(5);
}
if (incomingByte == 'F') {
colorWave(5, 2000);
}
if (incomingByte == 'G') {
bluePulse();
}
}
}
// Fill the dots one after the other with a color
void colorCircle(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<pixels.numPixels(); i++) {
pixels.setPixelColor(i, c);
pixels.setPixelColor(abs(i - pixels.numPixels()), c);
pixels.show();
delay(wait);
pixels.setPixelColor(i, 0, 0, 0);
}
}
// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<pixels.numPixels(); i++) {
pixels.setPixelColor(i, c);
pixels.show();
delay(wait);
}
}
void rainbowCycleStoppable(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256; j++) {
for(i=0; i< pixels.numPixels(); i++) {
pixels.setPixelColor(i, wheel(((i * 256 / pixels.numPixels()) + j) & 255));
}
pixels.show();
delay(wait);
if (shouldStop()) return;
}
}
void rainbowCycle(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256*2; j++) {
for(i=0; i< pixels.numPixels(); i++) {
pixels.setPixelColor(i, wheel(((i * 256 / pixels.numPixels()) + j) & 255));
}
pixels.show();
delay(wait);
}
}
void rainbow(uint8_t wait) {
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();
delay(wait);
}
}
// 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 position) {
if(position < 85) {
return pixels.Color(position * 3, 255 - position * 3, 0);
} else if(position < 170) {
position -= 85;
return pixels.Color(255 - position * 3, 0, position * 3);
} else {
position -= 170;
return pixels.Color(0, position * 3, 255 - position * 3);
}
}
void colorWave(uint8_t wait, int duration) {
int i, j, stripsize, cycle, elapsed = 0;
float ang, rsin, gsin, bsin, offset;
static int tick = 0;
stripsize = pixels.numPixels();
cycle = stripsize * 25; // times around the circle...
while (true) {
tick++;
offset = map2PI(tick);
for (i = 0; i < stripsize; i++) {
ang = map2PI(i) - offset;
rsin = sin(ang);
gsin = sin(2.0 * ang / 3.0 + map2PI(int(stripsize/6)));
bsin = sin(4.0 * ang / 5.0 + map2PI(int(stripsize/3)));
pixels.setPixelColor(i, pixels.Color(trigScale(rsin), trigScale(gsin), trigScale(bsin)));
}
pixels.show();
if (shouldStop()) goto done;
if (elapsed > duration) goto done;
delay(wait);
elapsed = elapsed+wait;
}
done:return;
}
/**
* Scale a value returned from a trig function to a byte value.
* [-1, +1] -> [0, 254]
* Note that we ignore the possible value of 255, for efficiency,
* and because nobody will be able to differentiate between the
* brightness levels of 254 and 255.
*/
byte trigScale(float val) {
val += 1.0; // move range to [0.0, 2.0]
val *= 127.0; // move range to [0.0, 254.0]
return int(val) & 255;
}
/**
* Map an integer so that [0, striplength] -> [0, 2PI]
*/
float map2PI(int i) {
return PI*2.0*float(i) / float(pixels.numPixels());
}
void redPulse() {
float maxBrightness = 55;
float speed = 0.05; // I don't actually know what would look good
float step = 5; // ms for a step delay on the lights
// Make the lights breathe
for (int i = 0; i < 65535; i++) {
// Intensity will go from 10 - maxBrightness in a "breathing" manner
float intensity = maxBrightness/2.0 * (1.0 + sin(speed * i));
pixels.setBrightness(intensity);
// Now set every LED to that color
for (int n=0; n<NUMPIXELS; n++) {
pixels.setPixelColor(n, 255, 0, 0);
}
pixels.show();
if (intensity < 1.0) return;
delay(step);
}
}
void greenPulse() {
float maxBrightness = 55;
float speed = 0.05; // I don't actually know what would look good
float step = 5; // ms for a step delay on the lights
// Make the lights breathe
for (int i = 0; i < 65535; i++) {
// Intensity will go from 10 - maxBrightness in a "breathing" manner
float intensity = maxBrightness/2.0 * (1.0 + sin(speed * i));
pixels.setBrightness(intensity);
// Now set every LED to that color
for (int n=0; n<NUMPIXELS; n++) {
pixels.setPixelColor(n, 0, 255, 0);
}
pixels.show();
if (intensity < 1.0) return;
delay(step);
}
}
void whitePulse() {
float maxBrightness = 8;
float speed = 0.006; // I don't actually know what would look good
float step = 2; // ms for a step delay on the lights
// Make the lights breathe
for (int i = 0; i < 65535; i++) {
// Intensity will go from 10 - maxBrightness in a "breathing" manner
float intensity = maxBrightness/2.0 * (1.0 + sin(speed * i));
intensity = intensity + 7;
pixels.setBrightness(intensity);
// Now set every LED to that color
for (int n=0; n<NUMPIXELS; n++) {
pixels.setPixelColor(n, 255, 255, 255);
}
pixels.show();
if (shouldStop()) return;
delay(step);
}
}
void bluePulse() {
float maxBrightness = 55;
float speed = 0.05; // I don't actually know what would look good
float step = 5; // ms for a step delay on the lights
// Make the lights breathe
for (int i = 0; i < 65535; i++) {
// Intensity will go from 10 - maxBrightness in a "breathing" manner
float intensity = maxBrightness/2.0 * (1.0 + sin(speed * i));
pixels.setBrightness(intensity);
// Now set every LED to that color
for (int n=0; n<NUMPIXELS; n++) {
pixels.setPixelColor(n, 0, 0, 255);
}
pixels.show();
if (intensity < 1.0) return;
delay(step);
}
}
void breathe() {
float maxBrightness = 55;
float speed = 0.05; // I don't actually know what would look good
float step = 5; // ms for a step delay on the lights
// Make the lights breathe
for (int i = 0; i < 65535; i++) {
// Intensity will go from 10 - maxBrightness in a "breathing" manner
float intensity = maxBrightness/2.0 * (1.0 + sin(speed * i));
pixels.setBrightness(intensity);
// Now set every LED to that color
for (int n=0; n<NUMPIXELS; n++) {
pixels.setPixelColor(n, 255, 0, 0);
}
pixels.show();
//Wait a bit before continuing to breathe
delay(step);
if (shouldStop()) return;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment