Your new topic does not fit any of the above??? Check first. Then post here. Thanks.

Moderator: igrr

User avatar
By Jason Stapels
#16655 Thanks again for the disable interrupt hints! I can't get mine to glitch at all now, even with a mini webserver running. Very cool!!!

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.

Code: Select all//////////
// 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.
//////////
User avatar
By andrew melvin
#16670 Really good work guys!

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.
User avatar
By Makuna
#16673
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.