-
-
Save SamDecrock/80e30c9bae734858d50d to your computer and use it in GitHub Desktop.
// 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(); | |
} | |
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?
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.
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.