Skip to content

Commit d01d256

Browse files
committed
Added multiple interrupt timers (ESP8266TimerInterrupt)
- Added multiple interrupt timers (ESP8266TimerInterrupt) - Added HTTP GET INTERRUPT COUNT2 (TEXT) - Added HTTP GET INTERRUPT COUNT3 (TEXT)
1 parent a8c1dc3 commit d01d256

File tree

2 files changed

+148
-59
lines changed

2 files changed

+148
-59
lines changed

ESP8266-MyWidget-Demo.ino

Lines changed: 120 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/*
22
MIT License
33
4+
ESP8266-MyWidget-Demo.ino
5+
46
Copyright (c) 2021 Tony Keith
57
68
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -20,6 +22,8 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2022
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2123
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2224
SOFTWARE.
25+
26+
Version: 1.1.0
2327
*/
2428
#include <ESP8266WiFi.h>
2529
#include <WiFiClient.h>
@@ -28,27 +32,36 @@ SOFTWARE.
2832
#include <ESPAsyncWebServer.h>
2933
#include <ArduinoOTA.h>
3034
#include <LittleFS.h>
31-
#include <PangolinMQTT.h>
32-
#include <Ticker.h>
35+
#include <PangolinMQTT.h>
36+
#include <Ticker.h>
37+
#include <ESP8266TimerInterrupt.h>
38+
#include <ESP8266_ISR_Timer.h>
3339

3440
#define LIBRARY "PangolinMQTT "PANGO_VERSION
3541

42+
// MQTT Delay
3643
#define RECONNECT_DELAY_M 3
44+
// WIFI Delay
3745
#define RECONNECT_DELAY_W 5
3846

47+
// MQTT Port
3948
#define MQTT_PORT 1883
4049
#define START_WITH_CLEAN_SESSION true
4150

42-
// define timer multiplers for onboard LED flash speed
43-
#define INT_SLOW 2500000
44-
#define INT_MED 1250000
45-
#define INT_FAST 625000
46-
#define INT_FASTEST 312500
51+
// 1uS * 10000 = 10mS
52+
#define HW_TIMER_INTERVAL 10000
53+
54+
// define timer dividers for onboard LED flash speed
55+
#define INT_SLOW 1000 // 1hz
56+
#define INT_MED 500 // 5 hz
57+
#define INT_FAST 100 // 10 hz
58+
#define INT_FASTEST 50 // 20 hz
4759

4860
// Your ssid and password here
4961
const char* ssid = "YOUR-SSID";
5062
const char* password = "YOUR-SSID-PASSWORD";
5163

64+
5265
// Your MQTT broker address here
5366
#define MQTT_HOST IPAddress(192, 168, 0, 100)
5467

@@ -61,18 +74,49 @@ bool ledState1 = 0;
6174
int counter = 1;
6275

6376
// interrupt variables
64-
volatile unsigned int interruptCounter = 0;
65-
volatile unsigned int interruptSpeed = INT_SLOW;
77+
volatile unsigned long interruptCounter1 = 0;
78+
volatile unsigned long interruptCounter2 = 0;
79+
volatile unsigned long interruptCounter3 = 0;
80+
81+
unsigned long interruptInterval1 = INT_SLOW;
82+
unsigned long interruptInterval2 = INT_FAST;
83+
unsigned long interruptInterval3 = INT_FASTEST;
84+
85+
// interrupt interval index for changeInterval()
86+
int timer1_idx=0; // ledTimerISR()
87+
int timer2_idx=0; // counterTimer1ISR()
88+
int timer3_idx=0; // counterTimer2ISR()
89+
6690

67-
// interrupt handler
91+
// init ESP8266 timer
92+
ESP8266Timer ITimer;
93+
ESP8266_ISR_Timer ISR_Timer;
94+
95+
// interrupt timer handler
96+
void ICACHE_RAM_ATTR timerHandler() {
97+
ISR_Timer.run();
98+
} // timerHandler()
99+
100+
// interrupt handler to Toggle LED
68101
void ICACHE_RAM_ATTR ledTimerISR() {
69-
digitalWrite(LED_BUILTIN,!(digitalRead(LED_BUILTIN))); // Toggle LED Pin
70-
// set timer
71-
timer1_write(interruptSpeed);
72-
// inc counter
73-
interruptCounter++;
102+
// Toggle LED Pin
103+
digitalWrite(LED_BUILTIN,!(digitalRead(LED_BUILTIN)));
104+
// inc counter
105+
interruptCounter1++;
74106
} // ledTimerISR()
75107

108+
// interrupt handler to increment counter
109+
void ICACHE_RAM_ATTR counterTimer1ISR() {
110+
// inc counter
111+
interruptCounter2++;
112+
} // counterTimer1ISR()
113+
114+
// interrupt handler to increment counter
115+
void ICACHE_RAM_ATTR counterTimer2ISR() {
116+
// inc counter
117+
interruptCounter3++;
118+
} // counterTimer2ISR()
119+
76120
// file system structure
77121
FSInfo fs_info;
78122

@@ -88,7 +132,6 @@ AsyncWebSocket webSocket("/ws");
88132

89133
void handleWebSocketMessage(AsyncWebSocket *server, AsyncWebSocketClient *client, void *arg, uint8_t *data, size_t len) {
90134
AwsFrameInfo *info = (AwsFrameInfo*)arg;
91-
92135

93136
if (info->final && info->index == 0 && info->len == len) {
94137
if(info->opcode == WS_TEXT) {
@@ -118,13 +161,13 @@ void handleWebSocketMessage(AsyncWebSocket *server, AsyncWebSocketClient *client
118161
} else if (!strcmp("speed", token)) {
119162
String speed;
120163
// speed
121-
if(interruptSpeed == INT_SLOW)
164+
if(interruptInterval1 == INT_SLOW)
122165
speed = "1";
123-
else if(interruptSpeed == INT_MED)
166+
else if(interruptInterval1 == INT_MED)
124167
speed = "2";
125-
else if(interruptSpeed == INT_FAST)
168+
else if(interruptInterval1 == INT_FAST)
126169
speed = "3";
127-
else if(interruptSpeed == INT_FASTEST)
170+
else if(interruptInterval1 == INT_FASTEST)
128171
speed = "4";
129172

130173
client->text("cmd:get:speed:" + String(speed));
@@ -154,19 +197,26 @@ void handleWebSocketMessage(AsyncWebSocket *server, AsyncWebSocketClient *client
154197
// toggle
155198
ledState1 = !ledState1;
156199
client->text("cmd:set:toggle:" + String(ledState1));
157-
} else if (!strcmp("speed", token)) {
200+
} else if (!strcmp("speed", token)) {
201+
unsigned long tmpSpeed;
158202
// speed
159203
char *speed = strtok(NULL, ":");
160204
Serial.println(speed);
161205
if(strlen(speed) == 1) {
162206
if(speed[0] == '1')
163-
interruptSpeed = INT_SLOW;
207+
tmpSpeed = INT_SLOW;
164208
else if (speed[0] == '2')
165-
interruptSpeed = INT_MED;
166-
else if (speed[0] == '3')
167-
interruptSpeed = INT_FAST;
168-
else if (speed[0] == '4')
169-
interruptSpeed = INT_FASTEST;
209+
tmpSpeed = INT_MED;
210+
else if (speed[0] == '3')
211+
tmpSpeed = INT_FAST;
212+
else if (speed[0] == '4')
213+
tmpSpeed = INT_FASTEST;
214+
215+
if(tmpSpeed != interruptInterval1) {
216+
interruptInterval1 = tmpSpeed;
217+
// update the interval for ledTimerISR
218+
ISR_Timer.changeInterval(timer1_idx, interruptInterval1);
219+
}
170220
}
171221
client->text("cmd:set:speed:" + String(speed));
172222
} else if (!strcmp("config", token)) {
@@ -284,22 +334,22 @@ void onMqttMessage(const char* topic, const uint8_t* payload, size_t len,uint8_t
284334

285335
void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type,
286336
void *arg, uint8_t *data, size_t len) {
287-
switch (type) {
288-
case WS_EVT_CONNECT:
289-
Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
290-
break;
291-
case WS_EVT_DISCONNECT:
292-
Serial.printf("WebSocket client #%u disconnected\n", client->id());
293-
break;
294-
case WS_EVT_DATA:
295-
handleWebSocketMessage(server, client, arg, data, len);
296-
break;
297-
case WS_EVT_PONG:
298-
Serial.println("ping");
299-
break;
300-
case WS_EVT_ERROR:
301-
Serial.println("error");
302-
break;
337+
switch (type) {
338+
case WS_EVT_CONNECT:
339+
Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
340+
break;
341+
case WS_EVT_DISCONNECT:
342+
Serial.printf("WebSocket client #%u disconnected\n", client->id());
343+
break;
344+
case WS_EVT_DATA:
345+
handleWebSocketMessage(server, client, arg, data, len);
346+
break;
347+
case WS_EVT_PONG:
348+
Serial.println("ping");
349+
break;
350+
case WS_EVT_ERROR:
351+
Serial.println("error");
352+
break;
303353
}
304354
} // onEvent()
305355

@@ -434,7 +484,17 @@ void initWeb() {
434484
// get intcount (TEXT response)
435485
webServer.on("/intcount", HTTP_GET, [](AsyncWebServerRequest *request) {
436486
Serial.println("GET intcount");
437-
request->send(200, "text/plain", "Interrupt Counter=" + String(interruptCounter));
487+
request->send(200, "text/plain", "Interrupt Counter=" + String(interruptCounter1));
488+
});
489+
// get intcount2 (TEXT response)
490+
webServer.on("/intcount2", HTTP_GET, [](AsyncWebServerRequest *request) {
491+
Serial.println("GET intcount2");
492+
request->send(200, "text/plain", "Interrupt Counter2=" + String(interruptCounter2));
493+
});
494+
// get intcount3 (TEXT response)
495+
webServer.on("/intcount3", HTTP_GET, [](AsyncWebServerRequest *request) {
496+
Serial.println("GET intcount3");
497+
request->send(200, "text/plain", "Interrupt Counter3=" + String(interruptCounter3));
438498
});
439499
// get status (TEXT response)
440500
webServer.on("/status", HTTP_GET, [](AsyncWebServerRequest* request) {
@@ -568,25 +628,30 @@ void setup() {
568628
while (dir.next()) {
569629
Serial.printf("%s - %d bytes\n", dir.fileName().c_str(), dir.fileSize());
570630
}
571-
631+
572632
// Initialize the LED_BUILTIN pin as an output
573633
pinMode(LED_BUILTIN, OUTPUT);
574634

575-
// Initialize Timer
576-
timer1_attachInterrupt(ledTimerISR);
577-
timer1_enable(TIM_DIV16, TIM_EDGE, TIM_SINGLE);
635+
// set timer to 100000/100 = 1000 hz
636+
if (! ITimer.attachInterruptInterval(HW_TIMER_INTERVAL, timerHandler)) {
637+
Serial.println("Can't set ITimer correctly. Select another freq. or interval");
638+
}
578639

579640
// The timers of the RTC are not affected by the CPU speed setting.
580641
// A given timer divisor produces the same rate of change of the RTC timer's COUNT register with both speed settings.
581642

582-
// TIM_DIV16 80 Mhz / 16 = 5 Mhz
583-
// 5 Mhz or 0.0000002 uS
584-
// 0.0000002 uS * 2,500,000 = 0.5s = 2 hz
585-
// 0.0000002 uS * 1,250,00 = 0.25s = 4 hz
586-
// 0.0000002 uS * 625,000 = 0.125s = 8 hz
587-
// 0.0000002 uS * 312,500 = 0.0625s = 16 hz
588-
timer1_write(interruptSpeed);
643+
// 100 = 1 hz (SLOW)
644+
// 50 = 5 hz (MEDIUM)
645+
// 10 = 10 hz (FAST)
646+
// 5 = 20 hz (FASTEST)
647+
648+
timer1_idx = ISR_Timer.setInterval(interruptInterval1, ledTimerISR);
649+
timer2_idx = ISR_Timer.setInterval(interruptInterval2, counterTimer1ISR);
650+
timer3_idx = ISR_Timer.setInterval(interruptInterval3, counterTimer2ISR);
589651

652+
Serial.printf("Timer1 Index=%d\n",timer1_idx);
653+
Serial.printf("Timer2 Index=%d\n",timer2_idx);
654+
Serial.printf("Timer3 Index=%d\n",timer3_idx);
590655
} // setup()
591656

592657
void onMqttDisconnect(int8_t reason) {

README.md

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ Extract the folder in each of these zip files and place it in the "library" fold
151151

152152
- HTTP GET INTERRUPT COUNT (TEXT)
153153
- URL: `http://mywidget.local/intcount`
154-
- Returns interrupt counter
154+
- Returns interrupt counter - interruptCounter1 variable
155155
- Request:
156156
- Name/Value Pair: N/A
157157
- Response:
@@ -160,6 +160,30 @@ Extract the folder in each of these zip files and place it in the "library" fold
160160
- `http://mywidget.local/intcount`
161161
- Example Response:
162162
- `Interrupt Counter=4533456`
163+
164+
- HTTP GET INTERRUPT COUNT2 (TEXT)
165+
- URL: `http://mywidget.local/intcount2`
166+
- Returns interrupt counter 2 - interruptCounter2 variable
167+
- Request:
168+
- Name/Value Pair: N/A
169+
- Response:
170+
- Interrupt Counter2=[Interrupt Counter 2]
171+
- Example Request:
172+
- `http://mywidget.local/intcount2`
173+
- Example Response:
174+
- `Interrupt Counter2=23236`
175+
176+
- HTTP GET INTERRUPT COUNT3 (TEXT)
177+
- URL: `http://mywidget.local/intcount3`
178+
- Returns interrupt counter 3 - interruptCounter3 variable
179+
- Request:
180+
- Name/Value Pair: N/A
181+
- Response:
182+
- Interrupt Counter3=[Interrupt Counter 3]
183+
- Example Request:
184+
- `http://mywidget.local/intcount3`
185+
- Example Response:
186+
- `Interrupt Counter3=98434445`
163187

164188
- HTTP GET STATUS (TEXT)
165189
- URL: `http://mywidget.local/status + query string (name/value pairs)`
@@ -319,8 +343,8 @@ Then I discovered [ESP8266TimerInterrupt](https://github.com/khoih-prog/ESP8266T
319343
- The interrupt timer is setup for 10 millisecond
320344

321345
- One ISR-based timer is used to flash the onboard timer (changeable speed - freq)
322-
- Second ISR-based timer is used to increment a counter (fixed speed - freq)
323-
- Third ISR-based timer is used to increment a counter (fixed speed - freq)
346+
- Second ISR-based timer is used to increment a counter - interruptCounter2 (fixed speed - freq)
347+
- Third ISR-based timer is used to increment a counter - interruptCounter3 (fixed speed - freq)
324348

325349

326350
## Test & Debug
@@ -344,7 +368,7 @@ Later I went back and added an HTTP GET with JSON response example without any J
344368

345369
## Future Enhancements
346370

347-
- [ ] Support multiple interrupt timers (ESP8266TimerInterrupt)
371+
- [X] Support multiple interrupt timers (ESP8266TimerInterrupt)
348372
- [ ] Asynch NTP support
349373
- [ ] Other?
350374

0 commit comments

Comments
 (0)