Giter Site home page Giter Site logo

khoih-prog / esp8266timerinterrupt Goto Github PK

View Code? Open in Web Editor NEW
96.0 8.0 25.0 279 KB

This library enables you to use Interrupt from Hardware Timers on an ESP8266-based board. It now supports 16 ISR-based timers, while consuming only 1 hardware Timer. Timers' interval is very long (ulong millisecs). The most important feature is they're ISR-based timers. Therefore, their executions are not blocked by bad-behaving functions or tasks. This important feature is absolutely necessary for mission-critical tasks.

License: MIT License

C++ 53.66% C 46.11% Shell 0.23%
hardware-timers isr wifi accuracy arduino arduino-libraries delay millis board non-blocking

esp8266timerinterrupt's Introduction

ESP8266TimerInterrupt Library

arduino-library-badge GitHub release GitHub contributions welcome GitHub issues

Donate to my libraries using BuyMeACoffee



Table of Contents



Important Change from v1.6.0

Please have a look at HOWTO Fix Multiple Definitions Linker Error



Why do we need this ESP8266TimerInterrupt library

Features

This library enables you to use Interrupt from Hardware Timers on an ESP8266-based board.

As Hardware Timers are rare, and very precious assets of any board, this library now enables you to use up to 16 ISR-based Timers, while consuming only 1 Hardware Timer. Timers' interval is very long (ulong millisecs).

Now with these new 16 ISR-based timers, the maximum interval is practically unlimited (limited only by unsigned long milliseconds) while the accuracy is nearly perfect compared to software timers.

The most important feature is they're ISR-based timers. Therefore, their executions are not blocked by bad-behaving functions / tasks. This important feature is absolutely necessary for mission-critical tasks.

The ISR_Timer_Complex example will demonstrate the nearly perfect accuracy compared to software timers by printing the actual elapsed millisecs of each type of timers.

Being ISR-based timers, their executions are not blocked by bad-behaving functions / tasks, such as connecting to WiFi, Internet and Blynk services. You can also have many (up to 16) timers to use.

This non-being-blocked important feature is absolutely necessary for mission-critical tasks.

You'll see blynkTimer Software is blocked while system is connecting to WiFi / Internet / Blynk, as well as by blocking task in loop(), using delay() function as an example. The elapsed time then is very unaccurate

Why using ISR-based Hardware Timer Interrupt is better

Imagine you have a system with a mission-critical function, measuring water level and control the sump pump or doing something much more important. You normally use a software timer to poll, or even place the function in loop(). But what if another function is blocking the loop() or setup().

So your function might not be executed, and the result would be disastrous.

You'd prefer to have your function called, no matter what happening with other functions (busy loop, bug, etc.).

The correct choice is to use a Hardware Timer with Interrupt to call your function.

These hardware timers, using interrupt, still work even if other functions are blocking. Moreover, they are much more precise (certainly depending on clock frequency accuracy) than other software timers using millis() or micros(). That's necessary if you need to measure some data requiring better accuracy.

Functions using normal software timers, relying on loop() and calling millis(), won't work if the loop() or setup() is blocked by certain operation. For example, certain function is blocking while it's connecting to WiFi or some services.

The catch is your function is now part of an ISR (Interrupt Service Routine), and must be lean / mean, and follow certain rules. More to read on:

HOWTO Attach Interrupt


Currently supported Boards

  1. ESP8266-based boards

Important Notes about ISR

  1. Inside the attached function, delay() won’t work and the value returned by millis() will not increment. Serial data received while in the function may be lost. You should declare as volatile any variables that you modify within the attached function.

  2. Typically global variables are used to pass data between an ISR and the main program. To make sure variables shared between an ISR and the main program are updated correctly, declare them as volatile.



Prerequisites

  1. Arduino IDE 1.8.19+ for Arduino. GitHub release
  2. ESP8266 Core 3.0.2+ for ESP8266-based boards. Latest release. To use ESP8266 core 2.7.1+ for LittleFS.
  3. SimpleTimer library to use with some examples.


Installation

Use Arduino Library Manager

The best and easiest way is to use Arduino Library Manager. Search for ESP8266TimerInterrupt, then select / install the latest version. You can also use this link arduino-library-badge for more detailed instructions.

Manual Install

Another way to install is to:

  1. Navigate to ESP8266TimerInterrupt page.
  2. Download the latest release ESP8266TimerInterrupt-master.zip.
  3. Extract the zip file to ESP8266TimerInterrupt-master directory
  4. Copy whole ESP8266TimerInterrupt-master folder to Arduino libraries' directory such as ~/Arduino/libraries/.

VS Code & PlatformIO

  1. Install VS Code
  2. Install PlatformIO
  3. Install ESP8266TimerInterrupt library by using Library Manager. Search for ESP8266TimerInterrupt in Platform.io Author's Libraries
  4. Use included platformio.ini file from examples to ensure that all dependent libraries will installed automatically. Please visit documentation for the other options and examples at Project Configuration File


HOWTO Fix Multiple Definitions Linker Error

The current library implementation, using xyz-Impl.h instead of standard xyz.cpp, possibly creates certain Multiple Definitions Linker error in certain use cases.

You can use

#include "ESP8266TimerInterrupt.h"             //https://github.com/khoih-prog/ESP8266TimerInterrupt
#include "ESP8266_ISR_Timer.hpp"               //https://github.com/khoih-prog/ESP8266TimerInterrupt

in many files. But be sure to use the following #include <ESP8266_ISR_Timer.h> in just 1 .h, .cpp or .ino file, which must not be included in any other file, to avoid Multiple Definitions Linker Error

// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
#include "ESP8266_ISR_Timer.h"                //https://github.com/khoih-prog/ESP8266TimerInterrupt

Check the new multiFileProject example for a HOWTO demo.

Have a look at the discussion in Different behaviour using the src_cpp or src_h lib #80



HOWTO Use PWM analogWrite() with ESP8266 running Timer1 Interrupt

Please have a look at ESP8266TimerInterrupt Issue 8: ESP8266Timer and PWM --> wdt reset to have more detailed description and solution of the issue.

1. ESP8266 has only 2 hardware timers, named Timer0 and Timer1

2. ESP8266 hardware timers' functions

  • Timer0 has been used for WiFi and it's not advisable to use while using WiFi (if not using WiFi, why select ESP8266 ??)
  • Timer1 is used by this ESP8266TimerInterrupt Library

3. How to use PWM analogWrite() functions while using this library

  1. If possible, use software timer instead of ESP8266TimerInterrupt Hardware Timer1
  2. If using ESP8266TimerInterrupt Hardware Timer1 is a must, you can either


More useful Information

The ESP8266 timers are badly designed, using only 23-bit counter along with maximum 256 prescaler. They're only better than UNO / Mega. The ESP8266 has two hardware timers, but timer0 has been used for WiFi and it's not advisable to use. Only timer1 is available. The timer1's 23-bit counter terribly can count only up to 8,388,607. So the timer1 maximum interval is very short. Using 256 prescaler, maximum timer1 interval is only 26.843542 seconds !!!

The timer1 counters can be configured to support automatic reload.


Now with these new 16 ISR-based timers, the maximum interval is practically unlimited (limited only by unsigned long milliseconds).

The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers. Therefore, their executions are not blocked by bad-behaving functions / tasks.

This important feature is absolutely necessary for mission-critical tasks.

The ISR_Timer_Complex example will demonstrate the nearly perfect accuracy compared to software timers by printing the actual elapsed millisecs of each type of timers.

Being ISR-based timers, their executions are not blocked by bad-behaving functions / tasks, such as connecting to WiFi, Internet and Blynk services. You can also have many (up to 16) timers to use. This non-being-blocked important feature is absolutely necessary for mission-critical tasks.

You'll see blynkTimer Software is blocked while system is connecting to WiFi / Internet / Blynk, as well as by blocking task in loop(), using delay() function as an example. The elapsed time then is very unaccurate



Usage

The ESP8266 timers are badly designed, using only 23-bit counter along with maximum 256 prescaler. They're only better than UNO / Mega.

The ESP8266 has two hardware timers, but Timer0 has been used for WiFi and it's not advisable to use. Only Timer1 is available.

The Timer1's 23-bit counter can terribly count only up to 8,388,607. So the timer1 maximum interval is very short. Using 256 prescaler, maximum Timer1 interval is only 26.843542 seconds !!!

1. Using only Hardware Timer directly

1.1 Init Hardware Timer

// Select a Timer Clock
#define USING_TIM_DIV1                false           // for shortest and most accurate timer
#define USING_TIM_DIV16               false           // for medium time and medium accurate timer
#define USING_TIM_DIV256              true            // for longest timer but least accurate. Default

// Init ESP8266 only and only Timer 1
ESP8266Timer ITimer;

1.2 Set Hardware Timer Interval and attach Timer Interrupt Handler function

Use one of these functions with interval in unsigned long milliseconds

// interval (in microseconds)
bool setInterval(unsigned long interval, timer_callback callback)

// interval (in microseconds)
bool attachInterruptInterval(unsigned long interval, timer_callback callback)

as follows

void IRAM_ATTR TimerHandler()
{
  // Doing something here inside ISR
}

#define TIMER_INTERVAL_MS        1000

void setup()
{
  ....
  
  // Interval in microsecs
  if (ITimer.attachInterruptInterval(TIMER_INTERVAL_MS * 1000, TimerHandler))
  {
    lastMillis = millis();
    Serial.print(F("Starting  ITimer OK, millis() = ")); Serial.println(lastMillis);
  }
  else
    Serial.println(F("Can't set ITimer correctly. Select another freq. or interval"));
}  

1.3 Set Hardware Timer Frequency and attach Timer Interrupt Handler function

Use one of these functions with frequency in float Hz

// frequency (in hertz)
bool setFrequency(float frequency, timer_callback callback)

// frequency (in hertz)
bool attachInterrupt(float frequency, timer_callback callback)

as follows

void TimerHandler()
{
  // Doing something here inside ISR
}

#define TIMER_FREQ_HZ        5555.555

void setup()
{
  ....
  
  // Frequency in float Hz
  if (ITimer.attachInterrupt(TIMER_FREQ_HZ, TimerHandler))
    Serial.println("Starting  ITimer OK, millis() = " + String(millis()));
  else
    Serial.println("Can't set ITimer. Select another freq. or timer");
}  

2. Using 16 ISR_based Timers from 1 Hardware Timer

2.1 Important Note

The 16 ISR_based Timers, designed for long timer intervals, only support using unsigned long millisec intervals. If you have to use much higher frequency or sub-millisecond interval, you have to use the Hardware Timers directly as in 1.3 Set Hardware Timer Frequency and attach Timer Interrupt Handler function

2.2 Init Hardware Timer and ISR-based Timer

// Select a Timer Clock
#define USING_TIM_DIV1                false           // for shortest and most accurate timer
#define USING_TIM_DIV16               false           // for medium time and medium accurate timer
#define USING_TIM_DIV256              true            // for longest timer but least accurate. Default

#include "ESP8266TimerInterrupt.h"
#include "ESP8266_ISR_Timer.h"

// Init ESP8266 timer 1
ESP8266Timer ITimer;

// Init ESP8266_ISR_Timer
ESP8266_ISR_Timer ISR_Timer;

2.3 Set Hardware Timer Interval and attach Timer Interrupt Handler functions

void IRAM_ATTR TimerHandler()
{
  ISR_timer.run();
}

#define HW_TIMER_INTERVAL_MS          50L

#define TIMER_INTERVAL_2S             2000L
#define TIMER_INTERVAL_5S             5000L
#define TIMER_INTERVAL_11S            11000L
#define TIMER_INTERVAL_101S           101000L

// In AVR, avoid doing something fancy in ISR, for example complex Serial.print with String() argument
// The pure simple Serial.prints here are just for demonstration and testing. Must be eliminate in working environment
// Or you can get this run-time error / crash
void doingSomething2s()
{
  // Doing something here inside ISR every 2 seconds
}
  
void doingSomething5s()
{
  // Doing something here inside ISR every 5 seconds
}

void doingSomething11s()
{
  // Doing something here inside ISR  every 11 seconds
}

void doingSomething101s()
{
  // Doing something here inside ISR every 101 seconds
}

void setup()
{
  ....
  
  // Interval in microsecs
  if (ITimer.attachInterruptInterval(HW_TIMER_INTERVAL_MS * 1000, TimerHandler))
  {
    startMillis = millis();
    Serial.print(F("Starting ITimer OK, millis() = ")); Serial.println(startMillis);
  }
  else
    Serial.println(F("Can't set ITimer. Select another freq. or timer"));

  // Just to demonstrate, don't use too many ISR Timers if not absolutely necessary
  // You can use up to 16 timer for each ISR_Timer
  ISR_timer.setInterval(TIMER_INTERVAL_2S, doingSomething2s);
  ISR_timer.setInterval(TIMER_INTERVAL_5S, doingSomething5s);
  ISR_timer.setInterval(TIMER_INTERVAL_11S, doingSomething11s);
  ISR_timer.setInterval(TIMER_INTERVAL_101S, doingSomething101s);
}  

2.4 Set One-Shot Hardware Timer Interval

// Just to demonstrate, don't use too many ISR Timers if not absolutely necessary
// You can use up to 16 timer for each SAMD_ISR_Timer
for (uint16_t i = 0; i < NUMBER_ISR_TIMERS; i++)
{
//ISR_Timer.setInterval(TimerInterval[i], irqCallbackFunc[i]);
// Use this for one shot ISR TImer
ISR_Timer.setTimeout(TimerInterval[i], irqCallbackFunc[i]);
}



Examples:

  1. Argument_None
  2. ISR_RPM_Measure
  3. RPM_Measure
  4. SwitchDebounce
  5. TimerInterruptTest
  6. Change_Interval.
  7. ISR_16_Timers_Array
  8. ISR_16_Timers_Array_Complex
  9. ISR_16_Timers_Array_OneShot New
  10. multiFileProject New


#if !defined(ESP8266)
#error This code is designed to run on ESP8266 and ESP8266-based boards! Please check your Tools->Board setting.
#endif
// These define's must be placed at the beginning before #include "ESP8266TimerInterrupt.h"
// _TIMERINTERRUPT_LOGLEVEL_ from 0 to 4
// Don't define _TIMERINTERRUPT_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
#define TIMER_INTERRUPT_DEBUG 0
#define _TIMERINTERRUPT_LOGLEVEL_ 0
// Select a Timer Clock
#define USING_TIM_DIV1 false // for shortest and most accurate timer
#define USING_TIM_DIV16 false // for medium time and medium accurate timer
#define USING_TIM_DIV256 true // for longest timer but least accurate. Default
#include "ESP8266TimerInterrupt.h"
#ifndef LED_BUILTIN
#define LED_BUILTIN D4 // Pin D4 mapped to pin GPIO2/TXD1 of ESP8266, NodeMCU and WeMoS, control on-board LED
#endif
#define TIMER_INTERVAL_MS 500 //1000
volatile uint32_t TimerCount = 0;
// Init ESP8266 timer 1
ESP8266Timer ITimer;
void printResult(uint32_t currTime)
{
Serial.print(F("Time = ")); Serial.print(currTime);
Serial.print(F(", TimerCount = ")); Serial.println(TimerCount);
}
void TimerHandler()
{
static bool toggle = false;
// Flag for checking to be sure ISR is working as Serial.print is not OK here in ISR
TimerCount++;
//timer interrupt toggles pin LED_BUILTIN
digitalWrite(LED_BUILTIN, toggle);
toggle = !toggle;
}
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
while (!Serial);
delay(300);
Serial.print(F("\nStarting Change_Interval on ")); Serial.println(ARDUINO_BOARD);
Serial.println(ESP8266_TIMER_INTERRUPT_VERSION);
Serial.print(F("CPU Frequency = ")); Serial.print(F_CPU / 1000000); Serial.println(F(" MHz"));
// Interval in microsecs
if (ITimer.attachInterruptInterval(TIMER_INTERVAL_MS * 1000, TimerHandler))
{
Serial.print(F("Starting ITimer OK, millis() = ")); Serial.println(millis());
}
else
Serial.println(F("Can't set ITimer. Select another freq. or timer"));
}
#define CHECK_INTERVAL_MS 10000L
#define CHANGE_INTERVAL_MS 20000L
void loop()
{
static uint32_t lastTime = 0;
static uint32_t lastChangeTime = 0;
static uint32_t currTime;
static uint32_t multFactor = 0;
currTime = millis();
if (currTime - lastTime > CHECK_INTERVAL_MS)
{
printResult(currTime);
lastTime = currTime;
if (currTime - lastChangeTime > CHANGE_INTERVAL_MS)
{
//setInterval(unsigned long interval, timerCallback callback)
multFactor = (multFactor + 1) % 2;
ITimer.setInterval(TIMER_INTERVAL_MS * 1000 * (multFactor + 1), TimerHandler);
Serial.print(F("Changing Interval, Timer = ")); Serial.println(TIMER_INTERVAL_MS * (multFactor + 1));
lastChangeTime = currTime;
}
}
}



Debug Terminal Output Samples

1. TimerInterruptTest on ESP8266_NODEMCU_ESP12E

The following is the sample terminal output when running example TimerInterruptTest on ESP8266_NODEMCU_ESP12E to demonstrate the accuracy of Hardware Timers.

Starting TimerInterruptTest on ESP8266_NODEMCU_ESP12E
ESP8266TimerInterrupt v1.6.0
CPU Frequency = 160 MHz
ESP8266TimerInterrupt: _fre = 312500.00, _count = 312500
Starting  ITimer OK, millis() = 262
Delta ms = 1000
Delta ms = 1000
Delta ms = 1000
Delta ms = 1000
Delta ms = 1000
Delta ms = 1000
Delta ms = 1000
Delta ms = 1000
Delta ms = 1000
Delta ms = 1000
Delta ms = 1000
Delta ms = 1000
Delta ms = 1000
Delta ms = 1000
Delta ms = 1000
Delta ms = 1000
Delta ms = 1000

2. Change_Interval on ESP8266_NODEMCU_ESP12E

The following is the sample terminal output when running example Change_Interval on ESP8266_NODEMCU_ESP12E to demonstrate how to change Timer Interval on-the-fly

Starting Change_Interval on ESP8266_NODEMCU_ESP12E
ESP8266TimerInterrupt v1.6.0
CPU Frequency = 160 MHz
Starting  ITimer OK, millis() = 162
Time = 10001, TimerCount = 19
Time = 20002, TimerCount = 39
Changing Interval, Timer = 1000
Time = 30003, TimerCount = 49
Time = 40004, TimerCount = 59
Changing Interval, Timer = 500
Time = 50005, TimerCount = 79
Time = 60006, TimerCount = 99
Changing Interval, Timer = 1000
Time = 70007, TimerCount = 109
Time = 80008, TimerCount = 119
Changing Interval, Timer = 500
Time = 90009, TimerCount = 139
Time = 100010, TimerCount = 159
Changing Interval, Timer = 1000
Time = 110011, TimerCount = 169
Time = 120012, TimerCount = 179
Changing Interval, Timer = 500
Time = 130013, TimerCount = 199
Time = 140014, TimerCount = 219
Changing Interval, Timer = 1000
Time = 150015, TimerCount = 229
Time = 160016, TimerCount = 239
Changing Interval, Timer = 500
Time = 170017, TimerCount = 259
Time = 180018, TimerCount = 279

3. ISR_16_Timers_Array on ESP8266_NODEMCU_ESP12E

The following is the sample terminal output when running example ISR_16_Timers_Array on ESP8266_NODEMCU_ESP12E to demonstrate of ISR Hardware Timer, especially when system is very busy or blocked. The 16 independent ISR timers are programmed to be activated repetitively after certain intervals, is activated exactly after that programmed interval !!!

Starting ISR_16_Timers_Array on ESP8266_NODEMCU_ESP12E
ESP8266TimerInterrupt v1.6.0
CPU Frequency = 160 MHz
Starting ITimer OK, millis() = 175
1s: Delta ms = 1003, ms = 1178
1s: Delta ms = 999, ms = 2177
2s: Delta ms = 2002, ms = 2177
1s: Delta ms = 1000, ms = 3177
3s: Delta ms = 3002, ms = 3177
1s: Delta ms = 1000, ms = 4177
2s: Delta ms = 2000, ms = 4177
4s: Delta ms = 4002, ms = 4177
1s: Delta ms = 1000, ms = 5177
5s: Delta ms = 5002, ms = 5177
1s: Delta ms = 1000, ms = 6177
2s: Delta ms = 2001, ms = 6178
3s: Delta ms = 3001, ms = 6178
6s: Delta ms = 6003, ms = 6178
1s: Delta ms = 1000, ms = 7177
7s: Delta ms = 7002, ms = 7177
1s: Delta ms = 1000, ms = 8177
2s: Delta ms = 1999, ms = 8177
4s: Delta ms = 4000, ms = 8177
8s: Delta ms = 8002, ms = 8177
1s: Delta ms = 1000, ms = 9177
3s: Delta ms = 2999, ms = 9177
9s: Delta ms = 9002, ms = 9177
simpleTimerDoingSomething2s: Delta programmed ms = 2000, actual = 10002
1s: Delta ms = 1000, ms = 10177
2s: Delta ms = 2000, ms = 10177
5s: Delta ms = 5001, ms = 10178
10s: Delta ms = 10006, ms = 10181
1s: Delta ms = 1000, ms = 11177
11s: Delta ms = 11003, ms = 11178
1s: Delta ms = 1000, ms = 12177
2s: Delta ms = 2000, ms = 12177
3s: Delta ms = 3000, ms = 12177
4s: Delta ms = 4000, ms = 12177
6s: Delta ms = 5999, ms = 12177
12s: Delta ms = 12005, ms = 12180
1s: Delta ms = 1000, ms = 13177
13s: Delta ms = 13002, ms = 13177
1s: Delta ms = 1000, ms = 14177
2s: Delta ms = 2000, ms = 14177
7s: Delta ms = 7000, ms = 14177
14s: Delta ms = 14002, ms = 14177
1s: Delta ms = 1000, ms = 15177
3s: Delta ms = 3000, ms = 15177
5s: Delta ms = 4999, ms = 15177
15s: Delta ms = 15002, ms = 15177
1s: Delta ms = 1000, ms = 16177
2s: Delta ms = 2000, ms = 16177
4s: Delta ms = 4001, ms = 16178
8s: Delta ms = 8001, ms = 16178
16s: Delta ms = 16003, ms = 16178
1s: Delta ms = 1000, ms = 17177
1s: Delta ms = 1000, ms = 18177
2s: Delta ms = 2000, ms = 18177
3s: Delta ms = 3000, ms = 18177
6s: Delta ms = 6000, ms = 18177
9s: Delta ms = 9001, ms = 18178
1s: Delta ms = 1000, ms = 19177
simpleTimerDoingSomething2s: Delta programmed ms = 2000, actual = 10000

4. ISR_16_Timers_Array_Complex on ESP8266_NODEMCU_ESP12E

The following is the sample terminal output when running example ISR_16_Timers_Array_Complex on ESP8266_NODEMCU_ESP12E to demonstrate the ISR Hardware Timer, especially when system is very busy or blocked. The 16 independent ISR timers are programmed to be activated repetitively after certain intervals, is activated exactly after that programmed interval !!!

Starting ISR_16_Timers_Array_Complex on ESP8266_NODEMCU_ESP12E
ESP8266TimerInterrupt v1.6.0
CPU Frequency = 160 MHz
Starting ITimer OK, millis() = 177
SimpleTimer : 2, ms : 10179, Dms : 10000
Timer : 0, programmed : 5000, actual : 5008
Timer : 1, programmed : 10000, actual : 0
Timer : 2, programmed : 15000, actual : 0
Timer : 3, programmed : 20000, actual : 0
Timer : 4, programmed : 25000, actual : 0
Timer : 5, programmed : 30000, actual : 0
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 20232, Dms : 10053
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15008
Timer : 3, programmed : 20000, actual : 20008
Timer : 4, programmed : 25000, actual : 0
Timer : 5, programmed : 30000, actual : 0
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 30286, Dms : 10054
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20008
Timer : 4, programmed : 25000, actual : 25008
Timer : 5, programmed : 30000, actual : 30008
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 40341, Dms : 10055
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25008
Timer : 5, programmed : 30000, actual : 30008
Timer : 6, programmed : 35000, actual : 35008
Timer : 7, programmed : 40000, actual : 40008
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 50396, Dms : 10055
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30008
Timer : 6, programmed : 35000, actual : 35008
Timer : 7, programmed : 40000, actual : 40008
Timer : 8, programmed : 45000, actual : 45008
Timer : 9, programmed : 50000, actual : 50008
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 60452, Dms : 10056
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30000
Timer : 6, programmed : 35000, actual : 35008
Timer : 7, programmed : 40000, actual : 40008
Timer : 8, programmed : 45000, actual : 45008
Timer : 9, programmed : 50000, actual : 50008
Timer : 10, programmed : 55000, actual : 55008
Timer : 11, programmed : 60000, actual : 60008
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 70509, Dms : 10057
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30000
Timer : 6, programmed : 35000, actual : 35000
Timer : 7, programmed : 40000, actual : 40008
Timer : 8, programmed : 45000, actual : 45008
Timer : 9, programmed : 50000, actual : 50008
Timer : 10, programmed : 55000, actual : 55008
Timer : 11, programmed : 60000, actual : 60008
Timer : 12, programmed : 65000, actual : 65008
Timer : 13, programmed : 70000, actual : 70008
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 80566, Dms : 10057
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30000
Timer : 6, programmed : 35000, actual : 35000
Timer : 7, programmed : 40000, actual : 40000
Timer : 8, programmed : 45000, actual : 45008
Timer : 9, programmed : 50000, actual : 50008
Timer : 10, programmed : 55000, actual : 55008
Timer : 11, programmed : 60000, actual : 60008
Timer : 12, programmed : 65000, actual : 65008
Timer : 13, programmed : 70000, actual : 70008
Timer : 14, programmed : 75000, actual : 75008
Timer : 15, programmed : 80000, actual : 80008

5. ISR_16_Timers_Array_OneShot on ESP8266_NODEMCU_ESP12E

The following is the sample terminal output when running example ISR_16_Timers_Array_OneShot on ESP8266_NODEMCU_ESP12E to demonstrate the One-Shot ISR Hardware Timer, especially when system is very busy or blocked. The 16 independent ISR timers are programmed to be activated repetitively after certain intervals, is activated exactly after that programmed interval !!!

Starting ISR_16_Timers_Array_OneShot on ESP8266_NODEMCU_ESP12E
ESP8266TimerInterrupt v1.6.0
CPU Frequency = 160 MHz
Starting ITimer OK, millis() = 365
1s: Delta ms = 1002, ms = 1367
2s: Delta ms = 2002, ms = 2367
3s: Delta ms = 3002, ms = 3367
4s: Delta ms = 4002, ms = 4367
5s: Delta ms = 5002, ms = 5367
6s: Delta ms = 6002, ms = 6367
7s: Delta ms = 7002, ms = 7367
8s: Delta ms = 8002, ms = 8367
9s: Delta ms = 9002, ms = 9367
10s: Delta ms = 10002, ms = 10367
simpleTimerDoingSomething2s: Delta programmed ms = 2000, actual = 10002
11s: Delta ms = 11002, ms = 11367
12s: Delta ms = 12002, ms = 12367
13s: Delta ms = 13002, ms = 13367
14s: Delta ms = 14002, ms = 14367
15s: Delta ms = 15002, ms = 15367
16s: Delta ms = 16002, ms = 16367
simpleTimerDoingSomething2s: Delta programmed ms = 2000, actual = 10000
simpleTimerDoingSomething2s: Delta programmed ms = 2000, actual = 10000
simpleTimerDoingSomething2s: Delta programmed ms = 2000, actual = 10001
simpleTimerDoingSomething2s: Delta programmed ms = 2000, actual = 10000
simpleTimerDoingSomething2s: Delta programmed ms = 2000, actual = 10000
simpleTimerDoingSomething2s: Delta programmed ms = 2000, actual = 10000
simpleTimerDoingSomething2s: Delta programmed ms = 2000, actual = 10000


Debug

Debug is enabled by default on Serial.

You can also change the debugging level (TIMERINTERRUPT_LOGLEVEL) from 0 to 4

// These define's must be placed at the beginning before #include "ESP8266TimerInterrupt.h"
// _TIMERINTERRUPT_LOGLEVEL_ from 0 to 4
// Don't define _TIMERINTERRUPT_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
#define TIMER_INTERRUPT_DEBUG         0
#define _TIMERINTERRUPT_LOGLEVEL_     0

Troubleshooting

If you get compilation errors, more often than not, you may need to install a newer version of the core for Arduino boards.

Sometimes, the library will only work if you update the board core to the latest version because I am using newly added functions.



Issues

Submit issues to: ESP8266TimerInterrupt issues



TO DO

  1. Search for bug and improvement.

DONE

  1. Basic hardware timers for ESP8266.
  2. More hardware-initiated software-enabled timers
  3. Longer time interval
  4. Similar features for remaining Arduino boards such as AVR, Teensy, SAMD21, SAMD51, SAM-DUE, nRF52, ESP32, STM32, etc.
  5. Update to match new ESP8266 core v3.0.0
  6. Fix compiler errors due to conflict to some libraries.
  7. Add complex examples.
  8. Update to match new ESP8266 core v3.0.2
  9. Fix multiple-definitions linker error. Drop src_cpp and src_h directories
  10. Add feature to select among highest, medium or lowest accuracy for Timers for shortest, medium or longest time
  11. Convert to h-only style.
  12. Optimize code by using passing by reference instead of by value
  13. Add example multiFileProject to demo for multiple-file project
  14. Add example ISR_16_Timers_Array_OneShot to demo how to use one-shot ISR-based timer


Contributions and thanks

  1. Thanks to Holger Lembke to report ESP8266TimerInterrupt Issue 8: ESP8266Timer and PWM --> wdt reset, leading to the HOWTO Use PWM analogWrite() with ESP8266 running Timer1 Interrupt notes.
  2. Thanks to Eugene to make bug-fixing PR and discussion in bugfix: reattachInterrupt() pass wrong frequency value to setFrequency() #19, leading to v1.5.0
  3. Thanks to absalom-muc to make enhancement request in One shot operating mode #20, leading to v1.6.0 to add example to demo how to use one-shot ISR-based timer
holgerlembke
Holger Lembke

RushOnline
Eugene

absalom-muc
absalom-muc


Contributing

If you want to contribute to this project:

  • Report bugs and errors
  • Ask for enhancements
  • Create issues and pull requests
  • Tell other people about this library

License

  • The library is licensed under MIT

Copyright

Copyright 2019- Khoi Hoang

esp8266timerinterrupt's People

Contributors

dependabot[bot] avatar khoih-prog avatar rushonline avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

esp8266timerinterrupt's Issues

ESP8266Timer and PWM --> wdt reset

Hi,

I try to create a "glow" at certain intervals. Current design is that I loop through my sinus-table with 60 ms and do a analogWrite(), stop at the end of the sinus-loop, then wait some time and then rinse repeat. Looping the 60 ms does not work soooo well, as you already wrote.

To run more smoothly I thought of using the ESP8266Timer to switch the 60 ms-pwm change. For demonstration the restart is done in a simple ticker-loop().

All I get is nothing near a glow but watchdog resets. "analogWrite();" seems to be the offender.

Any ideas? What did I miss?

#include "ESP8266TimerInterrupt.h"

#ifndef LED_BUILTIN
#define LED_BUILTIN       2         // Pin D4 mapped to pin GPIO2/TXD1 of ESP8266, NodeMCU and WeMoS, control on-board LED
#endif

const int sinus[] = {  0, 20, 45, 89, 134, 178, 221, 265, 308, 350, 391, 432,
                       472, 512, 550, 587, 623, 658, 691, 723, 754, 784,
                       812, 838, 863, 886, 907, 927, 945, 961, 976, 988,
                       999, 1007, 1014, 1019, 1022, 1023, 1023, 1023
                    };
const int sinuslen = sizeof(sinus) / sizeof(sinus[0]);
const int sinusschrittzeit = 60;
const long sinusdauer = sinusschrittzeit * sinuslen;

volatile int step = 0;
volatile int direction = 1;

ESP8266Timer ITimer;

void ICACHE_RAM_ATTR TimerHandler(void)
{
  analogWrite(LED_BUILTIN, sinus[step]);
  step += direction;
  if (step < 0) {
    step = 0;
    direction = 1;
    ITimer.disableTimer();
  }
  if (step > sinuslen - 1) {
    step = sinuslen - 1;
    direction = -1;
  }
}

void setup()
{
  Serial.begin(115200);
  while (!Serial);

  pinMode(LED_BUILTIN, OUTPUT);

  // Interval in microsecs
  if (ITimer.attachInterruptInterval(60L * 1000L, TimerHandler))
  {
    ITimer.disableTimer();
    Serial.println("\n\nStarting  ITimer OK");
  }
  else
    Serial.println("\n\nCan't set ITimer correctly. Select another freq. or interval");
}

void loop()
{
  static unsigned long ticker = 0;

  if  (millis() - ticker > 6000) {
    step = 0;
    direction = 1;
    ticker = millis();
    ITimer.enableTimer();
  }
}

Generating slow PWM

Not an issue, but a query/request: please can you give me a hint how to generate 2 seconds cycle PWM with this timer ?
More exactly 50% would mean one second on, one second off on a selected GPIO pin, 25% would mean 0.5/1.5 second ratio, etc.
Resolution needs to be about 5 millisecond, i.e. 400 steps, or 0.25% per step, for the whole cycle range.

Thank you !

ESP8266TimerInterrupt with ESP8266WiFi crashs if disconnected

For my clock with wemos D1 I use the ESP8266TimerInterrupt library. I need also the ESP8266WiFi library to get the temperature. Then there is no wifi connection the clock should still work. But with both libraries the wemos crash if there is no connection. I have attached a test file

Test.zip

Question related to multiFileProject example for sharing ISRTimer

Your multiFileProject example works well. However, I was not able to share ISRTimer for multiFileProject.cpp and for multiFileProject.ino for using the ISRTimer in both files.
Adding the declaration to multiFileProject.h, i.e.
extern ESP8266_ISR_Timer ISRTimer;
and the defintion to multiFileProject.cpp, i.e.
ESP8266_ISR_Timer ISRTimer;
results in the following error message:

In file included from C:\Users\absalom\AppData\Local\Temp\arduino_build_366313\sketch\multiFileProject.h:16,
                 from C:\Users\absalom\AppData\Local\Temp\arduino_build_366313\sketch\multiFileProject.cpp:12:
C:\Users\absalom\Documents\Arduino\libraries\ESP8266TimerInterrupt\src/ESP8266_ISR_Timer.hpp:88:27: error: 'ISRTimer' does not name a type

Do you have an idea how to resolve it? (but to make clear: your lib works very well, my question is more related to my poor C++ skills)
Thank you.

ISR_Timer callback function is not getting called

Hi, Thanks for the Library.
Can you please check why is my callback function not getting called in the below program ? Please ignore the rest of the program.

#include "hw_timer.h"
#include "ESP8266TimerInterrupt.h"
#include "ESP8266_ISR_Timer.h"
#define TIMER_INTERVAL_MS1 1000
#define TIMER_INTERVAL_MS2 2000
const byte zcPin = 12;
const byte pwmPin = 13;
uint32_t ts1 = micros();
uint32_t diff1 = micros();

uint32_t ts2 = millis();
uint32_t diff2 = millis();

bool hasDitectedZC = false;
byte zcState = 0;
int dimDelay = 8550;

void ICACHE_RAM_ATTR zcDetectISR ();
//ESP8266Timer ITimer;
//ESP8266Timer ITimer2;
ESP8266_ISR_Timer ISR_Timer;

void ICACHE_RAM_ATTR TimerHandler()
{

diff1 = millis() - ts1;
ts1 = millis();

Serial.println("Called TimerHandler1");

}

void ICACHE_RAM_ATTR TimerHandler2()
{
diff2 = millis() - ts2;
ts2 = millis();
Serial.println("Called TimerHandler2");
}

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial.println("Initializing the program");
pinMode(zcPin, INPUT_PULLUP);
// pinMode(pwmPin, OUTPUT);

attachInterrupt(zcPin, zcDetectISR, RISING); // Attach an Interupt to Pin 2 (interupt 0) for Zero Cross Detection
// hw_timer_init(NMI_SOURCE, 0);
// hw_timer_set_func(dimTimerISR);

// if (ITimer.attachInterruptInterval(TIMER_INTERVAL_MS1 * 1000, TimerHandler))
// Serial.println("Starting ITimer1 OK, millis() = " + String(millis()));
//
// if (ITimer2.attachInterruptInterval(TIMER_INTERVAL_MS2 * 1000, TimerHandler2))
// Serial.println("Starting ITimer2 OK, millis() = " + String(millis()));

ISR_Timer.setInterval(2000L, TimerHandler);
ISR_Timer.run();
}

void loop() {
// put your main code here, to run repeatedly:
// delay(500);
//if(diff > 11000 || diff < 9000)
//{ Serial.print("Zero Cross Deletection Frequency : ");
// Serial.print(diff);
// Serial.print(" micro Second");
// Serial.println();
//}
delay(2000);
Serial.print("Diff1 : ");
Serial.println(diff1);
//Serial.print("Diff2 : ");
//Serial.println(diff2);
}

void dimTimerISR(){
digitalWrite(pwmPin, 0);
delayMicroseconds(100);
digitalWrite(pwmPin, 1);
zcState = 0;
}

void initiateDimmer(){
if(zcState == 0)
{
digitalWrite(pwmPin, 1); // off
// hw_timer_arm(dimDelay);
}
}

void zcDetectISR(){
if(!hasDitectedZC)
{
hasDitectedZC = true;
// initiateDimmer();
}
// diff = micros()-ts1;
// ts1 = micros();
}

unattach ?

Hi Khoih,
thank you very much for the esp8266interrupt library!
Could you please tell me howto stop calling the interrupt handler routine correctly?
thank you again
Wulf

Use std::function for callbacks?

At the moment you use function pointers for the timer callbacks, but would there be an issue with using std::functions? I ask because i would like to use class methods as callbacks (bound to an instance of course), but i am wondering if using std::functions for callbacks would cause an issue.

BTW the ticker library for esp8266 uses std::function but does not use the hardware timer

Possible error in RPM_Measure.ino

I was looking at you code for RPM_Measure.ino to understand this library as it does not 'play nicely' with your servo library. You calculate avgRPM in the program then never use it.
should the line:

Serial.println("RPM = " + String(RPM) + ", rotationTime ms = " + String(rotationTime * TIMER_INTERVAL_MS) );

be:

Serial.println("RPM = " + String(avgRPM) + ", rotationTime ms = " + String(rotationTime * TIMER_INTERVAL_MS) );

Anyway, if you can suggest which library would be best to run one servo and run a short routine exactly every 20 miliseconds I would appreciate it.

Using callback with classes.

Since few days I was trying to write simple class which has few status variables and every X milliseconds it updates itself via ISR interrupt. My Question is how I can pass object to callback function. Callback isn't taking any parameters ex. void* with which I possibly could pass my object and assign interrupt with specific object, how could I achieve that? edit: Sorry, my english is not very good.

One shot operating mode

I use your lib for periodic interrupts - works like a charm, thank you for that!

Addtionally I would like to use it in an one shot operating mode. So the interrupt should be triggered only once. It could be also solved by providing a duration as described here, but when my understanding is correct, the duration is not implemented so far.

Edit: Maybe there could be a way to detach an interrupt, e.g. by providing a reference by ITimer.attachInterruptInterval

**The cycle is 1ms, esp8266 is easy to crash**

void ICACHE_RAM_ATTR TimerHandler(void)
{
	Serial.println("1");
}
if (ITimer.attachInterruptInterval(TIMER_INTERVAL_MS*5, TimerHandler))
  {
    DEBUG_LN("Starting  ITimer OK");
  }
  else
    DEBUG_LN("Can't set ITimer correctly. Select another freq. or interval");

It will crash after running for a while

`Exception (0):
epc1=0x4020140c epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

>>>stack>>>

ctx: sys
sp: 3fffec10 end: 3fffffb0 offset: 0190
3fffeda0:  00000000 3ffedc70 00000002 401003c8  
3fffedb0:  402163c0 3ffeea94 3ffeb597 401001f8  
3fffedc0:  4021d131 3fffee80 3fffc230 4000050c  
3fffedd0:  4000437b 00000030 00000010 ffffffff  
3fffede0:  60000200 00000008 00020300 80000000  
3fffedf0:  20000000 3ffef6e8 80000000 200fc1a0  
3fffee00:  80000000 3fffc6fc 00000001 3ffef6ec  
3fffee10:  000000d4 000fc1a0 60000600 00000030  
3fffee20:  40216e05 401001b0 00000020 40100105  
3fffee30:  401016cd 004d29cf 3ffeeaac 00000000  
3fffee40:  3ffe8830 3ffeeaac 00000000 4021b87b  
3fffee50:  00000000 00308d97 4021b8e6 3ffeeaac  
3fffee60:  3ffeea94 ffffffe3 00000000 ffffffff  
3fffee70:  40000f3d 00000023 00000000 3fffd9d0  
3fffee80:  00000000 00310808 00640104 00000047  
3fffee90:  3ffeb530 000000ea 3ffeb547 3ffeb524  
3fffeea0:  00000c70 4bc6a7f0 36872b02 00000000  
3fffeeb0:  00000000 00000000 4bc6a7f0 60000600  
3fffeec0:  00000002 400042db 00000020 40100a58  
3fffeed0:  40004b31 3ffef5cc 000001f4 000fc080  
3fffeee0:  40102164 3ffecdb0 3ffe8fb0 40100cb0  
3fffeef0:  40102391 3ffef5cc 00000000 009c0be8  
3fffef00:  009be30e 3ffe8830 3ffe8fb0 40231cd6  
3fffef10:  40230d09 40230d12 3ffe8e24 3ffe8830  
3fffef20:  40223e65 3ffe8e24 3ffe8830 009be30e  
3fffef30:  40223eaa 3fffdab0 00000000 3fffdcb0  
3fffef40:  3ffe8848 3fffdad0 3ffee39c 40201928  
3fffef50:  40000f49 40000f49 3fffdab0 40000f49  
3fffef60:  40000e19 00000005 00040f10 00000000  
3fffef70:  00000000 aa55aa55 00000012 40100e39  
3fffef80:  40100e3f 00040f10 00000000 0c0c5200  
3fffef90:  4010000d 40503450 09614283 2200d416  
3fffefa0:  00000000 3fffef3c 00000000 00000000  
3fffefb0:  3fffffc0 00000000 00000000 feefeffe  
3fffefc0:  feefeffe feefeffe feefeffe feefeffe  
3fffefd0:  feefeffe feefeffe feefeffe feefeffe  
3fffefe0:  feefeffe feefeffe feefeffe feefeffe  
3fffeff0:  feefeffe feefeffe feefeffe feefeffe  
3ffff000:  feefeffe feefeffe feefeffe feefeffe  
3ffff010:  feefeffe feefeffe feefeffe feefeffe  
3ffff020:  feefeffe feefeffe feefeffe feefeffe  
3ffff030:  feefeffe feefeffe feefeffe feefeffe  
3ffff040:  feefeffe feefeffe feefeffe feefeffe  
3ffff050:  feefeffe feefeffe feefeffe feefeffe  
3ffff060:  feefeffe feefeffe feefeffe feefeffe  
3ffff070:  feefeffe feefeffe feefeffe feefeffe  
3ffff080:  feefeffe feefeffe feefeffe feefeffe  
3ffff090:  feefeffe feefeffe feefeffe feefeffe  
3ffff0a0:  feefeffe feefeffe feefeffe feefeffe  
3ffff0b0:  feefeffe feefeffe feefeffe feefeffe  
3ffff0c0:  feefeffe feefeffe feefeffe feefeffe  
3ffff0d0:  feefeffe feefeffe feefeffe feefeffe  
3ffff0e0:  feefeffe feefeffe feefeffe feefeffe  
3ffff0f0:  feefeffe feefeffe feefeffe feefeffe  
3ffff100:  feefeffe feefeffe feefeffe feefeffe  
3ffff110:  feefeffe feefeffe feefeffe feefeffe  
3ffff120:  feefeffe feefeffe feefeffe feefeffe  
3ffff130:  feefeffe feefeffe feefeffe feefeffe  
3ffff140:  feefeffe feefeffe feefeffe feefeffe  
3ffff150:  feefeffe feefeffe feefeffe feefeffe  
3ffff160:  feefeffe feefeffe feefeffe feefeffe  
3ffff170:  feefeffe feefeffe feefeffe feefeffe  
3ffff180:  feefeffe feefeffe feefeffe feefeffe  
3ffff190:  feefeffe feefeffe feefeffe feefeffe  
3ffff1a0:  feefeffe feefeffe feefeffe feefeffe  
3ffff1b0:  feefeffe feefeffe feefeffe feefeffe  
3ffff1c0:  feefeffe feefeffe feefeffe feefeffe  
3ffff1d0:  feefeffe feefeffe feefeffe feefeffe  
3ffff1e0:  feefeffe feefeffe feefeffe feefeffe  
3ffff1f0:  feefeffe feefeffe feefeffe feefeffe  
3ffff200:  feefeffe feefeffe feefeffe feefeffe  
3ffff210:  feefeffe feefeffe feefeffe feefeffe  
3ffff220:  feefeffe feefeffe feefeffe feefeffe  
3ffff230:  feefeffe feefeffe feefeffe feefeffe  
3ffff240:  feefeffe feefeffe feefeffe feefeffe  
3ffff250:  feefeffe feefeffe feefeffe feefeffe  
3ffff260:  feefeffe feefeffe feefeffe feefeffe  
3ffff270:  feefeffe feefeffe feefeffe feefeffe  
3ffff280:  feefeffe feefeffe feefeffe feefeffe  
3ffff290:  feefeffe feefeffe feefeffe feefeffe  
3ffff2a0:  feefeffe feefeffe feefeffe feefeffe  
3ffff2b0:  feefeffe feefeffe feefeffe feefeffe  
3ffff2c0:  feefeffe feefeffe feefeffe feefeffe  
3ffff2d0:  feefeffe feefeffe feefeffe feefeffe  
3ffff2e0:  feefeffe feefeffe feefeffe feefeffe  
3ffff2f0:  feefeffe feefeffe feefeffe feefeffe  
3ffff300:  feefeffe feefeffe feefeffe feefeffe  
3ffff310:  feefeffe feefeffe feefeffe feefeffe  
3ffff320:  feefeffe feefeffe feefeffe feefeffe  
3ffff330:  feefeffe feefeffe feefeffe feefeffe  
3ffff340:  feefeffe feefeffe feefeffe feefeffe  
3ffff350:  feefeffe feefeffe feefeffe feefeffe  
3ffff360:  feefeffe feefeffe feefeffe feefeffe  
3ffff370:  feefeffe feefeffe feefeffe feefeffe  
3ffff380:  feefeffe feefeffe feefeffe feefeffe  
3ffff390:  feefeffe feefeffe feefeffe feefeffe  
3ffff3a0:  feefeffe feefeffe feefeffe feefeffe  
3ffff3b0:  feefeffe feefeffe feefeffe feefeffe  
3ffff3c0:  feefeffe feefeffe feefeffe feefeffe  
3ffff3d0:  feefeffe feefeffe feefeffe feefeffe  
3ffff3e0:  feefeffe feefeffe feefeffe feefeffe  
3ffff3f0:  feefeffe feefeffe feefeffe feefeffe  
3ffff400:  feefeffe feefeffe feefeffe feefeffe  
3ffff410:  feefeffe feefeffe feefeffe feefeffe  
3ffff420:  feefeffe feefeffe feefeffe feefeffe  
3ffff430:  feefeffe feefeffe feefeffe feefeffe  
3ffff440:  feefeffe feefeffe feefeffe feefeffe  
3ffff450:  feefeffe feefeffe feefeffe feefeffe  
3ffff460:  feefeffe feefeffe feefeffe feefeffe  
3ffff470:  feefeffe feefeffe feefeffe feefeffe  
3ffff480:  feefeffe feefeffe feefeffe feefeffe  
3ffff490:  feefeffe feefeffe feefeffe feefeffe  
3ffff4a0:  feefeffe feefeffe feefeffe feefeffe  
3ffff4b0:  feefeffe feefeffe feefeffe feefeffe  
3ffff4c0:  feefeffe feefeffe feefeffe feefeffe  
3ffff4d0:  feefeffe feefeffe feefeffe feefeffe  
3ffff4e0:  feefeffe feefeffe feefeffe feefeffe  
3ffff4f0:  feefeffe feefeffe feefeffe feefeffe  
3ffff500:  feefeffe feefeffe feefeffe feefeffe  
3ffff510:  feefeffe feefeffe feefeffe feefeffe  
3ffff520:  feefeffe feefeffe feefeffe feefeffe  
3ffff530:  feefeffe feefeffe feefeffe feefeffe  
3ffff540:  feefeffe feefeffe feefeffe feefeffe  
3ffff550:  feefeffe feefeffe feefeffe feefeffe  
3ffff560:  feefeffe feefeffe feefeffe feefeffe  
3ffff570:  feefeffe feefeffe feefeffe feefeffe  
3ffff580:  feefeffe feefeffe feefeffe feefeffe  
3ffff590:  feefeffe feefeffe feefeffe feefeffe  
3ffff5a0:  feefeffe feefeffe feefeffe feefeffe  
3ffff5b0:  feefeffe feefeffe feefeffe feefeffe  
3ffff5c0:  feefeffe feefeffe feefeffe feefeffe  
3ffff5d0:  feefeffe feefeffe feefeffe feefeffe  
3ffff5e0:  feefeffe feefeffe feefeffe feefeffe  
3ffff5f0:  feefeffe feefeffe feefeffe feefeffe  
3ffff600:  feefeffe feefeffe feefeffe feefeffe  
3ffff610:  feefeffe feefeffe feefeffe feefeffe  
3ffff620:  feefeffe feefeffe feefeffe feefeffe  
3ffff630:  feefeffe feefeffe feefeffe feefeffe  
3ffff640:  feefeffe feefeffe feefeffe feefeffe  
3ffff650:  feefeffe feefeffe feefeffe feefeffe  
3ffff660:  feefeffe feefeffe feefeffe feefeffe  
3ffff670:  feefeffe feefeffe feefeffe feefeffe  
3ffff680:  feefeffe feefeffe feefeffe feefeffe  
3ffff690:  feefeffe feefeffe feefeffe feefeffe  
3ffff6a0:  feefeffe feefeffe feefeffe feefeffe  
3ffff6b0:  feefeffe feefeffe feefeffe feefeffe  
3ffff6c0:  feefeffe feefeffe feefeffe feefeffe  
3ffff6d0:  feefeffe feefeffe feefeffe feefeffe  
3ffff6e0:  feefeffe feefeffe feefeffe feefeffe  
3ffff6f0:  feefeffe feefeffe feefeffe feefeffe  
3ffff700:  feefeffe feefeffe feefeffe feefeffe  
3ffff710:  feefeffe feefeffe feefeffe feefeffe  
3ffff720:  feefeffe feefeffe feefeffe feefeffe  
3ffff730:  feefeffe feefeffe feefeffe feefeffe  
3ffff740:  feefeffe feefeffe feefeffe feefeffe  
3ffff750:  feefeffe feefeffe feefeffe feefeffe  
3ffff760:  feefeffe feefeffe feefeffe feefeffe  
3ffff770:  feefeffe feefeffe feefeffe feefeffe  
3ffff780:  feefeffe feefeffe feefeffe feefeffe  
3ffff790:  feefeffe feefeffe feefeffe feefeffe  
3ffff7a0:  feefeffe feefeffe feefeffe feefeffe  
3ffff7b0:  feefeffe feefeffe feefeffe feefeffe  
3ffff7c0:  feefeffe feefeffe feefeffe feefeffe  
3ffff7d0:  feefeffe feefeffe feefeffe feefeffe  
3ffff7e0:  feefeffe feefeffe feefeffe feefeffe  
3ffff7f0:  feefeffe feefeffe feefeffe feefeffe  
3ffff800:  feefeffe feefeffe feefeffe feefeffe  
3ffff810:  feefeffe feefeffe feefeffe feefeffe  
3ffff820:  feefeffe feefeffe feefeffe feefeffe  
3ffff830:  feefeffe feefeffe feefeffe feefeffe  
3ffff840:  feefeffe feefeffe feefeffe feefeffe  
3ffff850:  feefeffe feefeffe feefeffe feefeffe  
3ffff860:  feefeffe feefeffe feefeffe feefeffe  
3ffff870:  feefeffe feefeffe feefeffe feefeffe  
3ffff880:  feefeffe feefeffe feefeffe feefeffe  
3ffff890:  feefeffe feefeffe feefeffe feefeffe  
3ffff8a0:  feefeffe feefeffe feefeffe feefeffe  
3ffff8b0:  feefeffe feefeffe feefeffe feefeffe  
3ffff8c0:  feefeffe feefeffe feefeffe feefeffe  
3ffff8d0:  feefeffe feefeffe feefeffe feefeffe  
3ffff8e0:  feefeffe feefeffe feefeffe feefeffe  
3ffff8f0:  feefeffe feefeffe feefeffe feefeffe  
3ffff900:  feefeffe feefeffe feefeffe feefeffe  
3ffff910:  feefeffe feefeffe feefeffe feefeffe  
3ffff920:  feefeffe feefeffe feefeffe feefeffe  
3ffff930:  feefeffe feefeffe feefeffe feefeffe  
3ffff940:  feefeffe feefeffe feefeffe feefeffe  
3ffff950:  feefeffe feefeffe feefeffe feefeffe  
3ffff960:  feefeffe feefeffe feefeffe feefeffe  
3ffff970:  feefeffe feefeffe feefeffe feefeffe  
3ffff980:  feefeffe feefeffe feefeffe feefeffe  
3ffff990:  feefeffe feefeffe feefeffe feefeffe  
3ffff9a0:  feefeffe feefeffe feefeffe feefeffe  
3ffff9b0:  feefeffe feefeffe feefeffe feefeffe  
3ffff9c0:  feefeffe feefeffe feefeffe feefeffe  
3ffff9d0:  feefeffe feefeffe feefeffe feefeffe  
3ffff9e0:  feefeffe feefeffe feefeffe feefeffe  
3ffff9f0:  feefeffe feefeffe feefeffe feefeffe  
3ffffa00:  feefeffe feefeffe feefeffe feefeffe  
3ffffa10:  feefeffe feefeffe feefeffe feefeffe  
3ffffa20:  feefeffe feefeffe feefeffe feefeffe  
3ffffa30:  feefeffe feefeffe feefeffe feefeffe  
3ffffa40:  feefeffe feefeffe feefeffe feefeffe  
3ffffa50:  feefeffe feefeffe feefeffe feefeffe  
3ffffa60:  feefeffe feefeffe feefeffe feefeffe  
3ffffa70:  feefeffe feefeffe feefeffe feefeffe  
3ffffa80:  feefeffe feefeffe feefeffe feefeffe  
3ffffa90:  feefeffe feefeffe feefeffe feefeffe  
3ffffaa0:  feefeffe feefeffe feefeffe feefeffe  
3ffffab0:  feefeffe feefeffe feefeffe feefeffe  
3ffffac0:  feefeffe feefeffe feefeffe feefeffe  
3ffffad0:  feefeffe feefeffe feefeffe feefeffe  
3ffffae0:  feefeffe feefeffe feefeffe feefeffe  
3ffffaf0:  feefeffe feefeffe feefeffe feefeffe  
3ffffb00:  feefeffe feefeffe feefeffe feefeffe  
3ffffb10:  feefeffe feefeffe feefeffe feefeffe  
3ffffb20:  feefeffe feefeffe feefeffe feefeffe  
3ffffb30:  feefeffe feefeffe feefeffe feefeffe  
3ffffb40:  feefeffe feefeffe feefeffe feefeffe  
3ffffb50:  feefeffe feefeffe feefeffe feefeffe  
3ffffb60:  feefeffe feefeffe feefeffe feefeffe  
3ffffb70:  feefeffe feefeffe feefeffe feefeffe  
3ffffb80:  feefeffe feefeffe feefeffe feefeffe  
3ffffb90:  feefeffe feefeffe feefeffe feefeffe  
3ffffba0:  feefeffe feefeffe feefeffe feefeffe  
3ffffbb0:  feefeffe feefeffe feefeffe feefeffe  
3ffffbc0:  feefeffe feefeffe feefeffe feefeffe  
3ffffbd0:  feefeffe feefeffe feefeffe feefeffe  
3ffffbe0:  feefeffe feefeffe feefeffe feefeffe  
3ffffbf0:  feefeffe feefeffe feefeffe feefeffe  
3ffffc00:  feefeffe feefeffe feefeffe feefeffe  
3ffffc10:  feefeffe feefeffe feefeffe feefeffe  
3ffffc20:  feefeffe feefeffe feefeffe feefeffe  
3ffffc30:  feefeffe feefeffe feefeffe feefeffe  
3ffffc40:  feefeffe feefeffe feefeffe feefeffe  
3ffffc50:  feefeffe feefeffe feefeffe feefeffe  
3ffffc60:  feefeffe feefeffe feefeffe feefeffe  
3ffffc70:  feefeffe feefeffe feefeffe feefeffe  
3ffffc80:  feefeffe feefeffe feefeffe feefeffe  
3ffffc90:  feefeffe feefeffe feefeffe feefeffe  
3ffffca0:  feefeffe feefeffe feefeffe feefeffe  
3ffffcb0:  feefeffe feefeffe feefeffe feefeffe  
3ffffcc0:  feefeffe feefeffe feefeffe feefeffe  
3ffffcd0:  feefeffe feefeffe feefeffe feefeffe  
3ffffce0:  feefeffe feefeffe feefeffe feefeffe  
3ffffcf0:  feefeffe feefeffe feefeffe feefeffe  
3ffffd00:  feefeffe feefeffe feefeffe feefeffe  
3ffffd10:  feefeffe feefeffe feefeffe feefeffe  
3ffffd20:  00000000 00000000 0000001f 40100178  
3ffffd30:  feefeffe feefeffe 3fffc228 40101589  
3ffffd40:  4000050c feefeffe feefeffe feefeffe  
3ffffd50:  401001fb 00000030 00000000 fffffc00  
3ffffd60:  401001f8 00000003 6000001c 3ffe864d  
3ffffd70:  00000000 00000000 00000000 fffffffe  
3ffffd80:  ffffffff 3fffc6fc 00000001 00000020  
3ffffd90:  401001b0 3fffc200 00000022 00000030  
3ffffda0:  00000005 00000000 00000020 40100178  
3ffffdb0:  401001fb 00000030 00000005 401049e8  
3ffffdc0:  00000005 00000000 00000020 40100178  
3ffffdd0:  3ffe864d 00000000 00000005 401049e8  
3ffffde0:  3ffe864d 00000000 0000000a 402027d9  
3ffffdf0:  3ffe864d 00000000 0000000a 402027d9  
3ffffe00:  3ffe864d 00000000 530a0031 402027d9  
3ffffe10:  3ffe8611 00000000 530a0031 00000022  
3ffffe20:  4020117c 3ffee334 3ffe864b 40201188  
3ffffe30:  4020117c 3ffee334 3ffe864b 40201385  
3ffffe40:  3fffc200 00000001 3ffee334 402013d8  
3ffffe50:  3fffc200 401001b0 3ffee334 40201424  
3ffffe60:  3fffc200 401001b0 00000020 40100105  
3ffffe70:  3fffc200 401001b0 00000020 401001f8  
3ffffe80:  3fffc200 401001b0 3fffc230 4000050c  
3ffffe90:  00000000 00000000 0000001f 40100178  
3ffffea0:  40100199 00000001 3fffc228 40101589  
3ffffeb0:  4000050c 00000000 00000000 fffffffe  
3ffffec0:  40100ce5 00000030 00000010 ffffffff  
3ffffed0:  40100ce5 00000000 00000001 00000001  
3ffffee0:  3fffdab0 00000000 3fffd9d0 3ffee39c  
3ffffef0:  00000000 00000000 00000001 3ffe84e0  
3fffff00:  00000000 3fffdad0 3ffee39c 00000030  
3fffff10:  00000790 000000f2 000000f2 40100784  
3fffff20:  3ffef10e 0000000a 3fffff8c 3ffee39c  
3fffff30:  3fffdad0 3ffee314 00000020 40100a23  
3fffff40:  4020117c 3ffee334 3ffe864b 40201385  
3fffff50:  3fffdad0 00000022 3fffff80 4020150d  
3fffff60:  007a1200 30c3b5cb 3ffee300 4020152c  
3fffff70:  00000000 3ffee314 3ffee334 402010d8  
3fffff80:  00000000 00000000 00000001 40100178  
3fffff90:  3fffdad0 00000000 3ffee35c 40100199  
3fffffa0:  feefeffe 00000000 3ffee35c 40201ad9  
<<<stack<<<

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 3456, room 16 
tail 0
chksum 0x84
csum 0x84
vce0e63f6
~ld`

Timer selection

Hi, this may sound dumb, but I am trying to select the timer using

#define USING_TIM_DIV1 true

however I get the warning

warning: #warning Default to using TIM_DIV256_CLOCK for longest timer but least accurate [-Wcpp]

which does not make much sense. What am I doing wrong here ? I should have get this warning instead :

#if ( defined(USING_TIM_DIV1) && USING_TIM_DIV1 )
#warning Using TIM_DIV1_CLOCK for shortest and most accurate timer
#define TIM_CLOCK_FREQ TIM_DIV1_CLOCK
#define TIM_DIV TIM_DIV1

I am using Microchip Studio with vMicro Arduino interface.
I also tried Arduino IDE, same message there as well.

image

Seems to be a problem with times and read/write files to flash

Hi

I am using the hardware time on the ESP8266.

Whenever I use either

#include <FS.h>
or
#include "LittleFS.h"

To write or read a file it crashes the ESP8266.

I get this stack trace

==============

Exception 0: Illegal instruction
PC: 0x402153b4
EXCVADDR: 0x00000000

Decoding stack results

0x401006e8: timer1_isr_handler(void*, void*) at C:\Users\Jason\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\core_esp8266_timer.cpp line 37
0x401001d8: Measure_ISR() at C:\Users\Jason\Documents\Arduino\ESP8266_Sketches\Wifi_Dust_Screen_v0_1/Wifi_Dust_Screen_v0_1.ino line 491
0x402023c3: lfs_fs_rawtraverse at c:\users\jason\appdata\local\arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\littlefs\lib\littlefs/lfs.c line 3846
0x40100730: timer1_isr_handler(void*, void*) at C:\Users\Jason\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\core_esp8266_timer.cpp line 44
0x40202640: lfs_bd_erase at c:\users\jason\appdata\local\arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\littlefs\lib\littlefs/lfs.c line 246
0x4020104c: lfs_alloc_lookahead at c:\users\jason\appdata\local\arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\littlefs\lib\littlefs/lfs.c line 505
0x40201718: lfs_dir_get at c:\users\jason\appdata\local\arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\littlefs\lib\littlefs/lfs.c line 644
0x4021d158: strnlen_P at /workdir/repo/newlib/newlib/libc/sys/xtensa/string_pgmspace.c line 40
0x40202358: lfs_fs_rawtraverse at c:\users\jason\appdata\local\arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\littlefs\lib\littlefs/lfs.c line 3818
0x40216422: EspClass::flashEraseSector(unsigned int) at C:\Users\Jason\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\Esp.cpp line 670
0x402157fb: flash_hal_erase(unsigned int, unsigned int) at C:\Users\Jason\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\flash_hal.cpp line 64
0x4020f65a: littlefs_impl::LittleFSImpl::lfs_flash_erase(lfs_config const*, unsigned int) at C:\Users\Jason\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\LittleFS\src\LittleFS.cpp line 186
0x40202640: lfs_bd_erase at c:\users\jason\appdata\local\arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\littlefs\lib\littlefs/lfs.c line 246
0x40202b61: lfs_file_relocate at c:\users\jason\appdata\local\arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\littlefs\lib\littlefs/lfs.c line 2647
0x40215e48: uart_write(uart_t*, char const*, size_t) at C:\Users\Jason\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\uart.cpp line 546
0x40202e9d: lfs_file_rawwrite at c:\users\jason\appdata\local\arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\littlefs\lib\littlefs/lfs.c line 2713
0x402120e8: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\Jason\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266/HardwareSerial.h line 193
0x402125cc: Print::write(char const*) at C:\Users\Jason\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266/Print.h line 59
0x402125f0: Print::write(char const*) at C:\Users\Jason\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266/Print.h line 57
0x402129f0: Print::printNumber (unsigned long, unsigned char) at C:\Users\Jason\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\Print.cpp line 262
0x40215e48: uart_write(uart_t*, char const*, size_t) at C:\Users\Jason\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\uart.cpp line 546
0x40204dbb: lfs_file_write at c:\users\jason\appdata\local\arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\littlefs\lib\littlefs/lfs.c line 5145
0x402120f4: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\Jason\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266/HardwareSerial.h line 193
0x402120e8: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\Jason\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266/HardwareSerial.h line 193
0x4020f4f0: littlefs_impl::LittleFSFileImpl::write(unsigned char const*, unsigned int) at C:\Users\Jason\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\LittleFS\src/LittleFS.h line 380
0x402186e8: fs::File::write(unsigned char const*, unsigned int) at C:\Users\Jason\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\FS.cpp line 39
0x40218a25: Print::print(String const&) at C:\Users\Jason\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266/Print.h line 63
0x40205c4c: append_file_in_flash() at C:\Users\Jason\Documents\Arduino\ESP8266_Sketches\Wifi_Dust_Screen_v0_1/Wifi_Dust_Screen_v0_1.ino line 799
0x402120f4: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\Jason\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266/HardwareSerial.h line 193
0x4020f78c: fs::FS::_defaultTimeCB() at C:\Users\Jason\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266/FS.h line 249
0x40205bce: store_data_in_mem() at C:\Users\Jason\Documents\Arduino\ESP8266_Sketches\Wifi_Dust_Screen_v0_1/Wifi_Dust_Screen_v0_1.ino line 772
0x40208557: loop() at C:\Users\Jason\Documents\Arduino\ESP8266_Sketches\Wifi_Dust_Screen_v0_1/Wifi_Dust_Screen_v0_1.ino line 445
0x4021457c: loop_wrapper() at C:\Users\Jason\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\core_esp8266_main.cpp line 201

============================

Here is the relevant parts of my code


// Don't define _TIMERINTERRUPT_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
#define TIMER_INTERRUPT_DEBUG         0
#define _TIMERINTERRUPT_LOGLEVEL_     0


#include <ESP8266TimerInterrupt.h>
#include <ESP8266_ISR_Timer.h>

/ Select a Timer Clock
#define USING_TIM_DIV1                true           // for shortest and most accurate timer
#define USING_TIM_DIV16               false           // for medium time and medium accurate timer
#define USING_TIM_DIV256              false            // for longest timer but least accurate. Default

// Init ESP8266 only and only Timer 1
ESP8266Timer ITimer;


// Time defined in microseconds
// Define counts of 40us for base timer

#define Interrupt_Time_Base                  40

// Define counts in terms of unit of 40us interval for the sensor sampling
uint8_t Count_Time_To_LED_On = 242;
uint8_t Count_Time_To_Waveform_Sample = 7;
uint8_t Count_Time_To_LED_Off = 1;
uint8_t ISR_Count=0;

uint8_t Count_Time_Waveform_Sample = Count_Time_To_LED_On + Count_Time_To_Waveform_Sample;
uint8_t Count_Time_LED_Off = Count_Time_To_LED_On + Count_Time_To_Waveform_Sample + Count_Time_To_LED_Off;


void setup(void){
 //  Setup initial timer
  ITimer.setInterval(Interrupt_Time_Base, Measure_ISR);
}



void IRAM_ATTR Measure_ISR()
{
  ISR_Count++;
  
  if(ISR_Count==Count_Time_To_LED_On){
    digitalWrite(sample_sensorPin,HIGH);
  }
  if(ISR_Count==(Count_Time_Waveform_Sample)){
    measurement_val = analogRead(analogInPin);
    process_data_flag = true;
  }  
  if(ISR_Count==(Count_Time_LED_Off)){
    digitalWrite(sample_sensorPin,LOW);
    ISR_Count=0;
  }  
}



void start_file_system(){
 
  if(!LittleFS.begin()){
            Serial.println("An Error has occurred while mounting LittleFS");
  }  
}


void append_file_in_flash(){

  Serial.println("Buffer Contents");
  
  File PM2_5_Log = LittleFS.open("/PM2_5_Log.csv", "a"); // Write the time and the PM2.5 reading to the csv file
  
  for (int i=0 ; i<temp_storage_elements_stored; i++) {
    Serial.print(temp_time_storage[i]);
    Serial.print(',');
    Serial.println(temp_ave_ug_storage[i]);

    PM2_5_Log.print(temp_time_storage[i]);

  }
  Serial.println("End Buffer Contents");
  

  PM2_5_Log.close();

  append_file = false;
  temp_storage_element_count = 0;

  
}

This happens regardless of read and write. I can open and close a file, but as soon as I try to read anything or write anything it crashes.

OS Windows
Arduino IDE 1.8.19

I hope you can help

Thanks

Deepsleep functionality

Hello , sorry for asking for improvement via issue

is there any plan to add deep sleep functionality and time fetch from NTP (to keep time up-to-date) ? for making it battery friendly project

i have tried ESPDailyTaskNTP but that works like hit and try , not even managed by dev now

Esp8266 Reboot

ESP8266 Stuck and Reboot while Smart Config is in Running
Arduino IDE V1.8.13 is use

#include <Arduino.h>
#include "ESP8266TimerInterrupt.h"
#include <ESP8266WiFi.h>

#define TIMER_INTERVAL_MS 10
#define OneSec 100//11000/TIMER_INTERVAL_MS // Timer Interval is 10ms
#define FourMinCnt 24000//4
601000/TIMER_INTERVAL_MS// For Smart Config Time
#define FourMinCnt 24000//4
60*1000/TIMER_INTERVAL_MS// For Smart Config Time Out

unsigned int ProcessTrack;
unsigned int SmartConfigTO;
unsigned int serTmou;
unsigned int SrState;
unsigned int OneSecCnt;

ESP8266Timer ITimer;

void IRAM_ATTR TimerHandler()
{
if(serTmout)
{
serTmout--;
if(serTmout==0)
{
SrState = 0;
}
}
if(OneSecCnt)
{
OneSecCnt--;
}
if(SmartConfigTO)
{
SmartConfigTO--;
}
}

void setup()
{
unsigned char cnn=0;
Serial.begin(115200);
Serial.flush();
timeClient.begin();
WiFi.mode(WIFI_STA);// start Esp8266 WiFi Module in station mode
ITimer.attachInterruptInterval(TIMER_INTERVAL_MS * 1000, TimerHandler);
}
void loop()
{
//piece code in loop
switch(ProcessTrack)
{
case 1:WiFi.beginSmartConfig();// Smart Config Commd Set
SmartConfigTO=FourMinCnt;// Set Smart Config Time Out for 4Min
OneSecCnt=OneSec;;// Load One Sec Count
ProcessTrack++;// in Next Timer ISR Case 2 will be executed
break;
case 2:if(SmartConfigTO)// Time out for Smart Config is Not Over
{
if(OneSecCnt==0)
{
OneSecCnt=OneSec;// reload One Sec Count
if(WiFi.smartConfigDone())// Smart Config Command Sucessful
{
sendCmdSucessFulMes();// Send Message to Serial Port
WiFi.setAutoConnect(true);
}
else
{
SendBusyMes();// send Busy Message to Serial Port
}
}
}
else
{
SendErrorMes();
}
break;
}

When EspTouch Application Run from Cell Phone it Busy Message Correctly for 3-4 Sec and then Reboot the Esp8266

EspTouch Cell Phone App from Play Store is use for Smart Config & sendCmdSucessFulMes(""); Send out to serial port

Steps to reproduce the behavior. Including the MRE sketches

Smart Config Should be done and

A clear and concise description of what you expected to happen.

Actual behavior

Reboot Esp8266

Debug and AT-command log (if applicable)

A clear and concise description of what you expected to happen.

Screenshots

If applicable, add screenshots to help explain your problem.

Information

Please ensure to specify the following:

  • Arduino IDE version (e.g. 1.8.13) or Platform.io version
  • ESP8266,ESP32 or STM32 Core Version (e.g. ESP8266 core v2.7.4, ESP32 v1.0.5 or STM32 v1.9.0)
  • Contextual information (e.g. what you were trying to achieve)
  • Simplest possible steps to reproduce
  • Anything that might be relevant in your opinion, such as:
    • Operating system (Windows, Ubuntu, etc.) and the output of uname -a
    • Network configuration

Example

Arduino IDE version: 1.8.13
ESP32 Core Version 1.0.5
OS: Ubuntu 20.04 LTS
Linux xy-Inspiron-3593 5.4.0-66-generic #74-Ubuntu SMP Wed Jan 27 22:54:38 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

Context:
I encountered an endless loop while trying to connect to Local WiFi.

Steps to reproduce:
1. ...
2. ...
3. ...
4. ...

Additional context

Add any other context about the problem here.

analogWriteRange broke interrupts

Hello. Thanks for the library.
I made a project using your library and everything worked fine, until I decided to add a control for the brightness of the display backlight from the readings of the photoresistor.
I added just a few lines and interrupts stopped working.

I added to the setup:
analogWriteRange(1023);
analogWrite(D3, 1023);

and in loop:
int light = analogRead(A0);
analogWrite(D3, 1023-light);

I commented out these lines, but interrupts don't work now. I assume that the matter is in analogWriteRange(1023);
How to make the library work again? I tried analogWriteRange(256) but it doesn't help....

Why does my variable suddenly resets to 0

Arduino version I am using: 1.8.2
ESP8266 Core version I am using: 2.7.4
ESP8266TimerInterrupt version I am using: 1.0.3

I wrote test program which sends data from A0 port to serial. ESP8266TimerInterrupt is used to keep delays between data reading same.

How it works (or how it supposed to work):

  1. Create two buffers. While Serial sending data from one, we will fill another.
  2. Attach interrupt to onInterrupt() function
  3. In main loop:
    3.1. If one of buffers is full, send it
  4. On timer interrupt:
    4.1. Read signal from A0 and filter it with EMA (Exponential moving average)
    4.2. Add this data to buffer
    4.3. Check if buffer is filled, and if it is, change variable _useBuffer2 to use another buffer, set _bufferCounter to 0 and change _needToSendBufferN to determine that N'th buffer is full

I connected 3.3V pin to A0 to test code. Excepcted output: straight line at 1023
What I get:
Serial plot
If I replace (remove EMA)

lastRead = 0.1*analogRead(A0) + 0.9*lastRead;

with just

lastRead = analogRead(A0);

It will work as excepted

This means that lastRead variable is somehow becames 0 while changing buffers, but I have absolutely no idea why, because:

  1. lastRead is volatile, as it supposed to be
  2. Buffer changing code not touch lastRead var at all

I think that I've just made a typo or missed a brace somewhere, but I could not find it

Thank you!

Full code:

#include <ESP8266TimerInterrupt.h>

ESP8266Timer ITimer;

volatile float lastRead;

const int _maxBufferSize=1000;

volatile int _buffer1[_maxBufferSize];
volatile int _buffer2[_maxBufferSize];
volatile int _bufferCounter = 0;
volatile bool _useBuffer2 = false;
volatile bool _needToSendBuffer1 = false;
volatile bool _needToSendBuffer2 = false;

void ICACHE_RAM_ATTR onInterrupt() {
  lastRead = 0.1*analogRead(A0) + 0.9*lastRead;
  
  if(_useBuffer2) {
    _buffer2[_bufferCounter++] = (int)lastRead;
    if(_bufferCounter>_maxBufferSize) {
      _needToSendBuffer2=true;
      _bufferCounter = 0;
      _useBuffer2=false;
    }
  } else {
    _buffer1[_bufferCounter++] = (int)lastRead;
    if(_bufferCounter>_maxBufferSize) {
      _needToSendBuffer1=true;
      _bufferCounter = 0;
      _useBuffer2=true;
    }
  }
}

void setup() {
  pinMode(A0, INPUT);
  Serial.begin(115200);

  lastRead = 0;

  //        1000/_maxBufferSize     *      1000
  //     ms delay between sampling     convert to ns
  ITimer.attachInterruptInterval(1000000/_maxBufferSize, onInterrupt);
}

void loop() {
  if(_needToSendBuffer1) {
    for(int i=0;i<_maxBufferSize;i++)
      Serial.printf("$%d;", _buffer1[i]);
    _needToSendBuffer1=false;
  }
      
  if(_needToSendBuffer2) {
    for(int i=0;i<_maxBufferSize;i++)
      Serial.printf("$%d;", _buffer2[i]);
    _needToSendBuffer2=false;
  }
}

P.S. I know that this code is quite a mess, but it is only for testing

ESP8266TimerInterrupt listing is outdated

Hi @cdzombak

I saw your post in PIO forum ESP8266TimerInterrupt listing is outdated

I suggest you use the latest PIO from author khoih.prog not khoih-prog, such as PIO ESP8266TimerInterrupt Installation

Similar issue happened to many of my libraries, that's why I had to create a new author khoih.prog to be sure all libraries are updated with latest versions.

For example, check

  1. PlatformIO only has version 1.3.0 #65
  2. Platformio registry lists very old version and is outdated #11

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.