Добрый вечер!
Разбираюсь с технологией SSE. Сделал пример, в принципе работает. Но наблюдаются разрывы соединения буквально каждые 3-4 секунды. Потом соединение поднимается, но заметны фризы из-за обрывов соединения
Ниже код ESP и html
Разбираюсь с технологией SSE. Сделал пример, в принципе работает. Но наблюдаются разрывы соединения буквально каждые 3-4 секунды. Потом соединение поднимается, но заметны фризы из-за обрывов соединения
Ниже код ESP и html
Код:
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include "OTA.h"
#include "index_html.h"
#include "ets_sys.h"
#include "gpio.h"
#include "user_interface.h"
#define INTC_EDGE_EN (*(volatile uint32_t *)0x3FF00004)
#define TIMER_LOAD (*(volatile uint32_t *)0x60000600)
#define TIMER_COUNT (*(volatile uint32_t *)0x60000604)
#define TIMER_CTRL (*(volatile uint32_t *)0x60000608)
#define TIMER_INT (*(volatile uint32_t *)0x6000060c)
#define GPIO_OUT_W1TS (*(volatile uint32_t *)0x60000304)
#define GPIO_OUT_W1TC (*(volatile uint32_t *)0x60000308)
#define GPIO_OUTP (*(volatile uint32_t *)0x60000300)
#define GPIO_STATUS (*(volatile uint32_t *)0x6000031C)
#define GPIO_PIN2_CFG (*(volatile uint32_t *)0x60000330)
#define GPIO_STATUS_W1TC (*(volatile uint32_t *)0x60000324)
#define WDEV_NOW() (*(volatile uint32_t *)0x3ff20c00)
#define TIME_PULSE 50
#define MAX_DIMMING_VALUE 100
#define MIN_DIMMING_VALUE 0
#define HOST_NAME "remotedebug"
const char* ssid = "ASUS";
const char* password = "gCU8YNZs";
//const char* ssid = "SamsungS9+";
//const char* password = "qwert789";
static const int GPIO_OUT = 2; // GPIO2
static const int GPIO_IN = 1; // GPIO1
static const int GPIO_IN_SENS = 3; // GPIO3
uint32_t volatile dimDelay = 50 * 5; // in 0.2 us (0x007fffff max), min 12*5
uint32_t volatile pulseDelay = TIME_PULSE * 5; // in 0.2 us (0x007fffff max), min 12*5
uint8_t volatile targetSpeed = 15; //требуемое значение скорости в процентах
uint8_t volatile currentSpeed = 0; //текущее значение скорости в процентах
volatile unsigned long countZeroCross = 0;
volatile unsigned long countPeriod = 0;
volatile unsigned long countSysTimer = 0;
volatile unsigned long period = 0;
unsigned long lastMillis = 0;
unsigned long lastPeriodTime = 0;
unsigned long uptime = 0;
unsigned long previousMillis = 0; // храним крайнее обновление сенсоров
const long interval = 10000; // считываем значение с датчиков каждые 10 секунд
typedef enum {
OFF,
ON
} eState;
eState motorState = ON;
String outputState() {
if (motorState) {
return "checked";
}
else {
return "";
}
return "";
}
//переменные для асинхронного вэб-сервера
const char* PARAM_INPUT_1 = "state";
const char* PARAM_INPUT_2 = "value";
String dimmerSliderValue = String(targetSpeed);
String outputStateValue = outputState();
// создаем объект AsyncWebServer на 80-ом порту
AsyncWebServer server(80);
AsyncEventSource events("/events");
// Replaces placeholder with button section in your web page
String processor(const String& var) {
if (var == "BUTTONPLACEHOLDER") {
String buttons = "";
outputStateValue = outputState();
buttons += "outputStateValue";
return buttons;
}
else if (var == "DIMMERVALUE") {
return dimmerSliderValue;
}
else if (var == "UPTIME") {
return String(uptime);
}
return String();
}
void ICACHE_RAM_ATTR GPIOs_intr_handler(void *arg) {
(void)arg;
uint32_t tmp = GPIO_STATUS;
if (tmp & BIT(GPIO_IN)) {
TIMER_LOAD = dimDelay;
TIMER_CTRL = 4 | BIT(7); // TM_DIVDED_BY_16, NO TM_AUTO_RELOAD_CNT, TM_ENABLE_TIMER
countZeroCross++;
}
if (tmp & BIT(GPIO_IN_SENS)) {
period = millis() - lastPeriodTime;
lastPeriodTime = millis();
countPeriod++;
}
GPIO_STATUS_W1TC = tmp;
}
void ICACHE_RAM_ATTR TIMER_intr_cb(void *arg) {
(void)arg;
if (GPIO_OUTP & BIT(GPIO_OUT)) { //если симистор включен
GPIO_OUT_W1TC = BIT(GPIO_OUT); //выключаем симистор
TIMER_CTRL = 0; // stop timer
//gpio_pin_intr_state_set(GPIO_IN, GPIO_PIN_INTR_POSEDGE);
//gpio_pin_intr_state_set(GPIO_IN_SENS, GPIO_PIN_INTR_POSEDGE);
} else {
GPIO_OUT_W1TS = BIT(GPIO_OUT); //если симистор выключен, включаем
TIMER_LOAD = pulseDelay; //загружаем в таймер значение времени импульса открытия
}
countSysTimer++;
}
void dimmer_stop() {
ets_isr_mask(BIT(ETS_FRC_TIMER1_INUM) | BIT(ETS_GPIO_INUM)); // запретить прерывания GPIOs & Timer0
GPIO_OUT_W1TC = BIT(GPIO_OUT);
TIMER_CTRL = 0; // stop timer
}
void dimmer_start() {
dimmer_stop();
TIMER_COUNT = 0;
/* PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_GPIO1);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_GPIO3);
gpio_output_set(0, 0, BIT(GPIO_OUT), BIT(GPIO_IN));
gpio_output_set(0, 0, 0, BIT(GPIO_IN_SENS));
GPIO_PIN2_CFG &= ~BIT(2); // normal out (push-pull)
ets_isr_attach(ETS_GPIO_INUM, GPIOs_intr_handler, NULL);
ets_isr_attach(ETS_FRC_TIMER1_INUM, TIMER_intr_cb, NULL);
gpio_pin_intr_state_set(GPIO_IN, GPIO_PIN_INTR_POSEDGE);
gpio_pin_intr_state_set(GPIO_IN_SENS, GPIO_PIN_INTR_NEGEDGE);
INTC_EDGE_EN |= BIT(1); // + timer0
ets_isr_unmask(BIT(ETS_FRC_TIMER1_INUM) | BIT(ETS_GPIO_INUM)); // разрешить прерывания GPIOs & Timer0*/
}
void WiFi_init() {
Serial.print(F("Connecting to "));
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println(F("WiFi connected"));
Serial.print(F("IP address: "));
Serial.println(WiFi.localIP());
}
void setup() {
Serial.begin(115200);
Serial.println(F(""));
gpio_init();
Serial.println(F("GPIO init"));
dimmer_start();
Serial.println(F("dimmer start"));
WiFi_init();
OTA_init();
// Путь к корневой / web странице
server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
Serial.println(F("You called root page"));
request->send_P(200, "text/html", index_html, processor);
});
// Отправляем GET запрос на <ESP_IP>/update?state=<inputMessage>
server.on("/update", HTTP_GET, [] (AsyncWebServerRequest * request) {
String inputMessage;
// GET input1 value on <ESP_IP>/update?state=<inputMessage>
if (request->hasParam(PARAM_INPUT_1)) {
inputMessage = request->getParam(PARAM_INPUT_1)->value();
int tmpState = inputMessage.toInt();
motorState = tmpState ? ON : OFF;
}
else {
inputMessage = "No message sent";
}
// Serial.println(inputMessage);
Serial.print(F("Насос: "));
Serial.println(motorState);
request->send(200, "text/plain", "OK");
});
// Отправляем GET запрос на <ESP_IP>/slider?value=<inputMessage>
server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest * request) {
String inputMessage;
// GET input1 value on <ESP_IP>/slider?value=<inputMessage>
if (request->hasParam(PARAM_INPUT_2)) {
inputMessage = request->getParam(PARAM_INPUT_2)->value();
dimmerSliderValue = inputMessage;
targetSpeed = dimmerSliderValue.toInt();
}
else {
inputMessage = "No message sent";
}
// Serial.println(inputMessage);
Serial.print(F("Скорость насоса: "));
Serial.println(targetSpeed);
request->send(200, "text/plain", "OK");
});
// Обработка событий веб-сервера
events.onConnect([](AsyncEventSourceClient * client) {
if (client->lastId()) {
Serial.printf("Client reconnected! Last message ID that it got is: %u\n", client->lastId());
}
// отправка события "hello!", id текущие миллисекунды
// задержка повторного подключения 1 сек
client->send("hello!", NULL, millis(), 500);
});
server.addHandler(&events);
// Start server
server.begin();
Serial.println(F("HTTP server started"));
}
void loop() {
ArduinoOTA.handle();
static unsigned long lastEventTime = millis();
static const unsigned long EVENT_INTERVAL_MS = 200;
if (motorState == ON) {
currentSpeed = targetSpeed;
dimmer_start();
}
else {
currentSpeed = MIN_DIMMING_VALUE;
dimmer_stop();
}
if (currentSpeed == MIN_DIMMING_VALUE) {
motorState = OFF;
}
else if (currentSpeed == MAX_DIMMING_VALUE) {
motorState = ON;
}
dimDelay = 10 * 5 + (95 * (MAX_DIMMING_VALUE - currentSpeed)) * 5;
uptime = millis() / 1000;
// RemoteDebug handle
Debug.handle();
if ((millis() - lastEventTime) > EVENT_INTERVAL_MS) {
events.send(String(uptime).c_str(), "uptime", millis());
events.send(String(currentSpeed).c_str(), "currentSpeed", millis());
events.send(String(motorState).c_str(), "motorState", millis());
lastEventTime = millis();
}
}