Таймер с веб-сервером ESP8285
это мой первый проект по ESP. Я нашел код для таймера кофемолки, который запрограммирован для ESP8266, но, к сожалению, тем временем Sonoff сменился на ESP8285 со встроенной flash. Я предполагаю, что это и есть причина проблемы с памятью. По умолчанию время соответствует коду 1000 мс и 2000 мс, но на веб-странице отображаются следующие значения времени:
- Одиночный выстрел: 16711680 мс
- Двойной выстрел: 807611680 мс
Помимо этой проблемы, я не могу изменить эти значения, нажав кнопку сохранения. в чем моя ошибка?
// Библиотеки
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <TTBOUNCE.h>
#include <EEPROM.h>
extern "C" {
#include "user_interface.h"
}
//======СЕРВЕРНАЯ ЧАСТЬ======================================================
const char* ssid = "SSID";
const char* password = "password";
ESP8266WebServer server ( 80 );
char htmlResponse[3000];
//======ЧАСТЬ ЛОКАЛЕРА======================================================
os_timer_t myTimer;
bool tickOccured;
bool timerrunning;
int RelaisPin = 13; // GPIO13 Blaue LED auf dem Sonoff
TTBOUNCE b = TTBOUNCE(0);
int time_ss = 1000;
int time_ds = 2000;
void handleRoot() {
snprintf ( htmlResponse, 3000,
"<!DOCTYPE html>\
<html lang=\"en\">\
<head>\
<meta charset=\"utf-8\">\
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\
</head>\
<body>\
<h1>Zeiten für Singleshot und Doubleshot</h1>\
<h3>Singleshot: %d% ms </h3>\
<input type='text' name='date_ss' id='date_ss' size=2 autofocus> ms \
<h3>Doubleshot: %d% ms</h3>\
<input type='text' name='date_ds' id='date_ds' size=2 autofocus> ms \
<div>\
<br><button id=\"save_button\">Save</button>\
</div>\
<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js \"></скрипт>\
<script>\
var ds;\
var ss;\
$('#save_button').click(function(e){\
e.preventDefault();\
ss = $('#date_ss').val();\
ds = $('#date_ds').val();\
$.get('/save?ss=' + ss + '&ds=' + ds, function(data){\
console.log(data);\
});\
location.reload();\
});\
</script>\
</body>\
</html>",
time_ss,
time_ds
);
server.send ( 200, "text/html", htmlResponse );
}
void handleSave() {
if (server.arg("ss")!= ""){
Serial.println("Singleshot: " + server.arg("ss"));
time_ss = server.arg("ss").toInt();
eeWriteInt(0, server.arg("ss").toInt());
}
if (server.arg("ds")!= ""){
Serial.println("Doubleshot: " + server.arg("ds"));
time_ds = server.arg("ds").toInt();
eeWriteInt(4, server.arg("ds").toInt());
}
}
// запуск TimerCallback
void timerCallback(void *pArg) {
Serial.println("Tick OccurredCB");
tickOccured = true;
}
void setup() {
//======СЕРВЕРНАЯ ЧАСТЬ======================================================
// Запустить Serial
Serial.begin(115200);
delay(100);
WiFi.mode(WIFI_STA);
// Подключение к сети Wi-Fi
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
server.on ( "/", handleRoot );
server.on ("/save", handleSave);
server.begin();
Serial.println ( "HTTP server started" );
//======ЧАСТЬ ЛОКАЛЕРА======================================================
os_timer_setfn(&myTimer, timerCallback, NULL);
pinMode(RelaisPin, OUTPUT); // GPIO13 als Ausgang definieren
b.attachClick(click); // прикрепите метод щелчка к событию
b.attachDoubleClick(doubleClick);// прикрепите метод двойного щелчка к событию
b.attachPress(press); // прикрепите метод двойного щелчка к событию двойного щелчка метод нажатия
delay(50);
digitalWrite(RelaisPin, HIGH); // включить индикатор
tickOccured = false;
timerrunning = false;
EEPROM.begin(8); //Инициализировать EEPROM
time_ss = eeGetInt(0);
time_ds = eeGetInt(4);
}
void loop() {
//======СЕРВЕРНАЯ ЧАСТЬ======================================================
server.handleClient();
//======ЧАСТЬ ЛОКАЛЕРА======================================================
b.update();
delay(10);
if (tickOccured == true)
{
Serial.println("Timer ausgelaufen");
tickOccured = false;
digitalWrite(RelaisPin, HIGH);
os_timer_disarm(&myTimer);
timerrunning = false;
}
yield(); // или delay(0);
}
void click(){
if (!timerrunning)
{
Serial.println("Clicked");
digitalWrite(RelaisPin, LOW); // включить ИНДИКАТОР
os_timer_arm(&myTimer, time_ss, false);
timerrunning = true;
}
else
{
Serial.println("ABORT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
tickOccured = false;
digitalWrite(RelaisPin, HIGH);
os_timer_disarm(&myTimer);
timerrunning = false;
}
}
void doubleClick(){
if (!timerrunning)
{
Serial.println("DoubleClicked");
digitalWrite(RelaisPin, LOW); // включить ИНДИКАТОР
os_timer_arm(&myTimer, time_ds, false);
timerrunning = true;
}
else
{
Serial.println("ABORT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
tickOccured = false;
digitalWrite(RelaisPin, HIGH);
os_timer_disarm(&myTimer);
timerrunning = false;
}
}
void press(){
if (!timerrunning)
{
Serial.println("long_Clicked");
digitalWrite(RelaisPin, LOW); // включить ИНДИКАТОР
os_timer_arm(&myTimer, time_ds-time_ss, false);
timerrunning = true;
}
else
{
Serial.println("ABORT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
tickOccured = false;
digitalWrite(RelaisPin, HIGH);
os_timer_disarm(&myTimer);
timerrunning = false;
}
}
void eeWriteInt(int pos, int val) {
byte* p = (byte*) &val;
EEPROM.write(pos, *p);
EEPROM.write(pos + 1, *(p + 1));
EEPROM.write(pos + 2, *(p + 2));
EEPROM.write(pos + 3, *(p + 3));
EEPROM.commit();
}
int eeGetInt(int pos) {
int val;
byte* p = (byte*) &val;
*p = EEPROM.read(pos);
*(p + 1) = EEPROM.read(pos + 1);
*(p + 2) = EEPROM.read(pos + 2);
*(p + 3) = EEPROM.read(pos + 3);
return val;
}
@Niko, 👍1
Обсуждение1 ответ
По крайней мере, одна проблема заключается в следующем:
<h3>Singleshot: %d% ms </h3>\
Если вам нужен буквальный знак процента, вам нужно будет удвоить его, что является формой экранирования:
<h3>Singleshot: %d%% ms </h3>\
Не совсем ясно, как эта реализация snprintf обрабатывает %<пробел> , но эксперименты здесь показывают, что он не прощает и просто интерпретирует его как %% .
В C и C ++ и через прокси "arduino" смежные строковые литералы объединяются во время компиляции в один логический строковый литерал, так что вы можете сделать это вместо \ , что может показаться вам более чистым.
Также должна быть возможность просто печатать фрагменты вашей полезной нагрузки в потоке, а не собирать одну большую строку в качестве полезной нагрузки.
- Как читать и записывать EEPROM в ESP8266
- Как сделать выводы Tx и Rx на ESP-8266-01 в выводах GPIO?
- Как навсегда изменить скорость передачи данных ESP8266 (12e)?
- Как заставить 5-вольтовое реле работать с NodeMCU
- Как исправить: Invalid conversion from 'const char*' to 'char*' [-fpermissive]
- ESP8266 не подключается к Wi-Fi
- AT-команда не отвечает на последовательный монитор
- Разница между этими двумя платами NodeMCU?
с какой проблемой вы столкнулись? ... что ты пытаешься сделать?, @jsotola
Я бы начал с изменения %d% на %d, @Juraj
Где вы “нашли код”? Вы уверены, что код работал? Вы упомянули о “проблеме с памятью”. Что вы имеете в виду под этим? По моему опыту, программно нет почти никакой разницы между ESP8285 и ESP8266, кроме разницы в доступной флэш-памяти, которая, я не думаю, что здесь проблема. Почему вы упомянули Соноффа?, @StarCat
@jsotola: Я хочу запрограммировать таймер для моей кофемолки, на котором я могу регулировать продолжительность помола через WLAN., @Niko
Мой таймер на данный момент не поддается изменению и установлен на странные значения @StarCat: Я нашел код на Kaffee-Netz: https://www.kaffee-netz.de/threads/demoka-m203-timerumbau-und-totraum-minimierung.117220 / и он предназначен для работы на ESP8266. Моя проблема с памятью заключается в том, что длительность однократного и двойного выстрела не изменяется, а значения по умолчанию чрезвычайно высоки и не соответствуют коду 1000 и 2000 мс. Заранее спасибо, @Niko
@ Juraj: спасибо, поскольку я изменил это, я могу изменить значения при первой загрузке после перепрошивки. Но после этого я больше не могу менять значения. Нажатие кнопки сохранения не дает никакого эффекта., @Niko
Попробуйте удалить вызов
location.reload ();
- возможно, ваш браузер перезагружает страницу до завершения AJAX GET. Также вы должны обернуть свой Javascript в jQuery$(document).обработчик ready()
- вы можете погуглить его для получения более подробной информации., @romkey