Moderator: igrr
Incidentally, this also fixed some occasional crashes I was getting with the WiFiServer class when changing LEDs while in the middle of processing a client connection request.
//////////
// BEGIN EspNeoPixel functions.
//
// Clear and return current interrupt level.
#define CLEAR_INTERRUPTS() ({ \
uint32_t __lvl; \
__asm__ __volatile__( "rsil %0, 15 \n" \
: "=a" (__lvl) : : "memory" ); \
__lvl; \
})
// Restore interrupt level.
#define RESTORE_INTERRUPTS(lvl) do { \
uint32_t __lvl = (lvl); \
__asm__ __volatile__( "wsr %0, PS \n" \
"rsync \n" \
: : "a" (__lvl) : "memory" ); \
} while(0)
// The number of cycles per nanosecond.
#define NS_TO_CYCLES(n) (n / (1000000000L / F_CPU))
// Store the cycle count to a variable.
#define CYCLE_COUNT() ({ \
uint32_t __cc; \
__asm__ __volatile__("rsr %0, CCOUNT \n" : "=a" (__cc)); \
__cc; \
})
// Delay an arbitrary number of cycles past the specified cycle count.
#define DELAY_CYCLES(cs, cycles) do { \
uint32_t __cc; \
do { \
__cc = CYCLE_COUNT(); \
} while ((__cc - cs) < cycles); \
} while(0)
// Set pins high for a specified number of nanoseconds.
#define DIGITAL_HIGH_NS(mask, ns) do { \
uint32_t __cs; \
__cs = CYCLE_COUNT(); \
GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, mask); \
DELAY_CYCLES(__cs, NS_TO_CYCLES(ns)); \
} while(0)
// Set pins low for a specified number of nanoseconds.
#define DIGITAL_LOW_NS(mask, ns) do { \
uint32_t __cs; \
__cs = CYCLE_COUNT(); \
GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, mask); \
DELAY_CYCLES(__cs, NS_TO_CYCLES(ns)); \
} while(0)
// Holds the pin mask for EspNeoPixel
uint16_t enpPinMask;
uint32_t enpIntrMask;
//
// EspNeoPixel start.
//
// This disable interrupts and enables the pin for output.
//
// Call this before a sequence of pin updates with the pin the WS2812's are hooked up to.
// Note that this could be make to accept a pinMask in case you wanted to control multiple
// strips at the same time (albeit with the same colors).
//
// pin - The pin the WS2812's are hooked up to.
//
void enpStart(uint8_t pin) {
enpPinMask = 1 << pin;
pinMode(pin, OUTPUT); // set pin as output
digitalWrite(pin, LOW); // set it low
delay(10);
enpIntrMask = CLEAR_INTERRUPTS();
}
//
// EspNeoPixel send byte.
//
// This sends a byte out to the WS2812. It should be called three times per pixel,
// once for green, once for red, and once for blue.
//
// The timing in this function is absolutely critical, more info can be found here:
// http://wp.josh.com/2014/05/13/ws2812-neopixels-are-not-so-finicky-once-you-get-to-know-them/
//
// val - An unsigned byte encoded with 8 bits of color information.
//
void ICACHE_FLASH_ATTR enpSendByte(uint8_t data) {
uint8_t b = 8;
while (b > 0) { // loop 8 times, once for each bit
b--;
if ((data & (1 << b))) { // check if current bit is high/low
DIGITAL_HIGH_NS(enpPinMask, 700); // send WS2812 '1'
DIGITAL_LOW_NS(enpPinMask, 600);
} else {
DIGITAL_HIGH_NS(enpPinMask, 350); // send WS2812 '0'
DIGITAL_LOW_NS(enpPinMask, 800);
}
}
}
//
// EspNeoPixel send pixel.
//
// This sends out three bytes (in the correct order) to light a single pixel.
//
// red - unsigned byte of red color information
// grn - unsigned byte of green color information
// blu - unsigned byte of blue color information
//
void ICACHE_FLASH_ATTR enpSendPixel(uint8_t red, uint8_t grn, uint8_t blu) {
enpSendByte(grn);
enpSendByte(red);
enpSendByte(blu);
}
//
// EspNeoPixel stop sending data.
//
// This will re-enable interrupts and wait a small amount of time to enable the pixels.
//
void enpStop() {
RESTORE_INTERRUPTS(enpIntrMask);
delayMicroseconds(50);
}
//
// END EspNeoPixel functions.
//////////
I have a question. With the neopixel lib for the arudino the number of pixels was set at compile. With the ESP, it is now possible to deploy it and update settings via a web interface, mqtt...... etc
with the adafruit lib, it was not possible to change the number of pixels at run time, i tried... it would change it, if i queried it it would say the new number, but then after it completed a loop it went back to before.
Have you got any ideas / would be willing to add this @Makuna to your lib.
andrew melvin wrote:with the adafruit lib, it was not possible to change the number of pixels at run time,... would be willing to add this @Makuna to your lib.
Add an issue to the NeoPixelBus github project for this, seems like a reasonable ask and I don't think it will be that hard.