Close

ESP8266 Timer0 and ISR

A project log for Not Grbl

Well the Grbl Firmware for the Arduino is great. It's so good that why bother writing your own? Other than for the hell of it!

agp.cooperagp.cooper 10/12/2016 at 13:262 Comments

A timer and interrupt system for the ESP8266

The current method of managing timing signals for Not-GRBL is by a "blink without delay" style of programming.

It is somewhat restrictive but it works.

This style of programming is also called "polling" and is basically the same a the "Ticker" library.

What is really needed is access to a hardware timer and an Interrupt Service Vector.

The ESP8266 provided a simple non-resetable up counter (the so called software timer) called timer0.

Basically this timer counts clock cycles (i.e. at 80 MHz).

Here is a bit of code the write my own "servo sweep":

#define servoPin D4
volatile int servoPulse=0;
volatile int servoAngle=90;
volatile unsigned long next;
void inline servoISR(void){
  if (servoPulse==0) {
    next=next+40000+889*servoAngle;
  } else {
    next=next+1560000-889*servoAngle;    
  }
  timer0_write(next);
  servoPulse=1-servoPulse;
  digitalWrite(servoPin,servoPulse);
}

void setup()
{
  // Servo initialisation (uses D4)
  pinMode(D4,OUTPUT);
  noInterrupts();
  timer0_isr_init();
  timer0_attachInterrupt(servoISR);
  next=ESP.getCycleCount()+1000;
  timer0_write(next);
  interrupts();
  // Serial.begin(9600);
  // Serial.println();
}

void loop()
{
  const int minAngle=16;
  const int maxAngle=176;
  const int midAngle=96;
  static int servoDir=1;
  
  delay(50);
  // Next position
  if (servoAngle>maxAngle) servoAngle=maxAngle;
  if (servoAngle<minAngle) servoAngle=minAngle;
  if (servoAngle==maxAngle) servoDir=-servoDir;
  if (servoAngle==minAngle) servoDir=-servoDir;
  servoAngle+=servoDir;
  // Serial.println(servoAngle);
}

Here is the critical bit of code:

  noInterrupts();
  timer0_isr_init();
  timer0_attachInterrupt(servoISR);
  next=ESP.getCycleCount()+1000;
  timer0_write(next);
  interrupts();

What does it do?

It takes about 180 clock cycles to call the ISR.

Limitations

Other processes use the same timer and it has been reported that a 2 ms tick will crash the ESP6288 if you are using WiFi.

Other timers

There is also a timer1 (that needs investigation).

AlanX

Discussions

AtomosSPKT wrote 06/05/2017 at 12:55 point

Hello everybody!
Please let me ask a stupid question as to why timer0_write (ESP.getCycleCount () + 80000000L); // 80MHz == 1sec
(80MHz == 1sec?) Please direct, thanks everyone.

  Are you sure? yes | no

ryannining wrote 03/29/2017 at 01:17 point

Wow interesting, i was working on almost same but use os timer est_timer_arm_new in microseconds, and on 80Mhz able to pulse more than 100Khz, the problem is that it cannot alter the interval between interrupt, and the ets_timer_arm is to costly on cpu, so cannot be called inside the interrupt itself.

Your code is really great, cant wait to change my code using code like yours.

  Are you sure? yes | no