Lotfi
Lotfi

Reputation: 721

ESP8266 Timer1 conflicts with Neopixels WS2812 library

I want to add a Timer1 ISR to have a firing every 0.25 s and do some light motion with the WS2812 240 strip led.

Things were working well on Arduino Nano because it has a

  cli(); 
  TCCR1A = 0;   // pas de PWM ou OCR
  TCCR1B = (0<<WGM13) | (1<<WGM12) | 4; // Clear Timer on Compare match (CTC) mode, OCR1A= PRD
                                                                                // CS12 CS11 CS10 = 0b100 = 4 =>256 prescaler
  OCR1A = 15625; // 62.5 ns * 15625 * 256 prescaler = 0.250 s
  // pas de compteur logiciel
  TIMSK1 = 1<<OCIE1A; // ISR on Output Compare1 (TCNT1==OCR1)
    TIFR1 = 0;  // clear T1 IF
  TCNT1 = 0; // RAZ T1
  sei(); 

now that I moved to the ESP8266, to use also Wifi in my project, there is no OCR, so I tried with Timer1 ISR (Timer0 is for Wifi).

Alone it works:

//setup
timer1_attachInterrupt(myTimer1_ISR);
timer1_enable(TIM_DIV16, TIM_EDGE, TIM_SINGLE);
timer1_write(300000); //120000 us/2
...

void ICACHE_RAM_ATTR myTimer1_ISR()
{ 
//.....
timer1_write(300000);//12us/2
}

but with the NeoPixels library it gives me conflicts:

error: void myTimer1_ISR() causes a section type conflict with static volatile void NeoEsp8266DmaMethodBase::i2s_slc_isr() [with T_SPEED = NeoEsp8266DmaSpeed400Kbps]

void ICACHE_RAM_ATTR myTimer1_ISR(){

In file included from ...Arduino\libraries\NeoPixelBus_by_Makuna\src/NeoPixelBus.h:67:0,

I believe, the NeoPixel code uses the Timer1 also? How can I manage that? Thanks

Upvotes: 1

Views: 1053

Answers (1)

nPn
nPn

Reputation: 16758

ESP8266 has a Ticker class which might serve your purpose.

I has a quirk if you try to run something that takes too long inside the callback in which case the recommended way to use it is to just set a flag and then check for the flag in your loop, do your stuff and reset the flag. If you have something short, you can just do it directly in the callback.

Here is an example.

#include <Ticker.h>

bool doEveryOneMsStuffNow = false; // start with flag false
Ticker everyOneMs;

void setup() {
  // ... 
 everyOneMs.attach(0.001, []() { doEveryOneMsStuffNow = true; });  // lambda call back - this one just sets the flag to true
  // ...
}

void loop() {
  // ...
  if (doEveryOneMsStuffNow) {
    doEveryOneMsStuffNow = false;  // reset the flag
    // do what needs to be done every 1 ms
  }
  // ...
}

Upvotes: 1

Related Questions