Skip to content

Instantly share code, notes, and snippets.

@SamDecrock
Last active February 20, 2017 03:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SamDecrock/80e30c9bae734858d50d to your computer and use it in GitHub Desktop.
Save SamDecrock/80e30c9bae734858d50d to your computer and use it in GitHub Desktop.
Controls a NeoPixel using an RFDuino board with functions that resemble the NeoPixel API
// WS2812_RFduino_Test
// By Thomas Olson
// teo20140220.01
// teo20140719.01 Modified for Arduino 1.5.7
// 20141022.. verified works with Arduino 1.5.8
// No complicated Pixel Library needed.
// Tested with WS2812B 4 pin versions.
// Modified by Sam Decrock to resemble NeoPixel API
const int ws2812pin = 6;
const int nPIXELS = 60;
const int nLEDs = nPIXELS * 3;
uint8_t ledBar[nLEDs];
uint8_t brightness = 255;
void setup() {
pinMode(ws2812pin, OUTPUT);
digitalWrite(ws2812pin, LOW);
clearStrip();
delay(1);
}
// Taken from neopixel strandtest:
void loop() {
colorWipe(Color(255, 0, 0), 50); // Red
colorWipe(Color(0, 255, 0), 50); // Green
colorWipe(Color(0, 0, 255), 50); // Blue
}
// Fill the dots one after the other with a color
void colorWipe(uint32_t color, uint8_t wait) {
for(uint16_t i=0; i<nPIXELS; i++) {
setPixelColor(i, color);
showStrip();
delay(wait);
}
}
// ============================
// NeoPixel API like functions:
// ============================
uint32_t Color(uint8_t r, uint8_t g, uint8_t b) {
return ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
}
void setPixelColor(int pixel, uint32_t color) {
uint8_t red = (uint8_t)(color >> 16);
uint8_t green = (uint8_t)(color >> 8);
uint8_t blue = (uint8_t)color;
red = (red * brightness) >> 8;
green = (green * brightness) >> 8;
blue = (blue * brightness) >> 8;
setPixelColor(pixel, red, green, blue);
}
void setPixelColor(int pixel, byte red, byte green, byte blue) {
ledBar[3*pixel] = green;
ledBar[3*pixel+1] = red;
ledBar[3*pixel+2] = blue;
}
void clearStrip() {
for(uint32_t i; i<64; i++) {
setPixelColor(i, 0);
}
showStrip();
}
void showStrip(){
noInterrupts();
for(int wsOut = 0; wsOut < nLEDs; wsOut++){
for(int x=7; x>=0; x--){
NRF_GPIO->OUTSET = (1UL << ws2812pin);
if(ledBar[wsOut] & (0x01 << x)) {
__ASM ( \
" NOP\n\t" \
" NOP\n\t" \
" NOP\n\t" \
" NOP\n\t" \
" NOP\n\t" \
);
NRF_GPIO->OUTCLR = (1UL << ws2812pin);
}else{
NRF_GPIO->OUTCLR = (1UL << ws2812pin);
__ASM ( \
" NOP\n\t" \
" NOP\n\t" \
" NOP\n\t" \
);
}
}
}
delayMicroseconds(50); // latch and reset WS2812.
interrupts();
}
@bikemule
Copy link

bikemule commented Sep 8, 2015

Hey. Saw this linked on the RFduino forum. I just tried it on a 240 pixel WS2812B strip controlled by an RFduino with the 1.6.5 IDE and nothing lights up. Any idea why?

@bikemule
Copy link

bikemule commented Sep 8, 2015

Hey. I realized that these ws2812bs that I have only run at 400Mhz, so I just doubled the NOPs and it worked, but it fails when I try to use BluetoothLE

@SamDecrock
Copy link
Author

I have no idea, I'm using BLE to change the LED Strip (actually it's a LED Matrix) so that works perfectly

@soamaven
Copy link

soamaven commented Apr 9, 2016

Any idea why this code works in Arduino 1.68, but Thomas Olsons modification does not? I get all white LEDs with his, but I can get a color wipe with this. I'd like to be able to use the strip as a library object but Olson's code doesnt work.

@jeffnyc
Copy link

jeffnyc commented Feb 20, 2017

I was having drop-out issues when using this code (actually tolsen's original version) to control 5 WS2812B's with a mobile app (Android). The LED controls would function fine for 10-30 seconds, but then my Simblee would lose connection with the phone, and the only way to regain connection would be to power cycle the device.
I suspected it was the nointerrupts() causing the drop-outs, and when I commented those out, the Simblee would no longer lose the connection. Unfortunately, the LEDs went haywire without this of course.
I may have found an easy fix however - I tried dropping the delayMicroseconds from (50) to (25) and everything seems to be working fine now. I'm only using 5 WS2812 LEDs so maybe that's what allows me to get away with a 50% shorter delay?
UPDATE: it dropped the connection after 5 or 10 minutes this time.

Any ideas for solutions here?

@jeffnyc
Copy link

jeffnyc commented Feb 20, 2017

Update - took the delayMicroseconds all the way down to (1) and seems to have solved the problem. LED's still work, and Simblee hasn't lost the connection to my phone in almost an hour. Hope this might be helpful for others.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment