esp8266 вывод данных онлайн
- Войдите на сайт для отправки комментариев
Пт, 04/12/2020 - 23:06
подскажите пожалуйста как лучше поступить. нужно показания счетчика вывести в локальной сети на страничку. для этих целей было решено применить esp8266. но столкнулся с некими трудностями. первая это не срабатывает событие onerror при обрыве соединения -
#include <ESP8266WebServer.h>
#include <WebSocketsServer.h>
String ssid = "xxx";
String password = "xxx";
ESP8266WebServer server(80);
WebSocketsServer socket = WebSocketsServer(91);
int i = 0;
void setup(void) {
server.begin();
socket.begin();
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
}
void loop(void) {
server.handleClient();
delay(10);
socket.loop();
String str = String(i++);
socket.broadcastTXT(str);
}
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("#status").text('Offline');
$("#status").css('color', 'red');
var socket = new WebSocket("ws://192.168.1.187:91/");
socket.onopen = function () {
$("#status").text('Online');
$("#status").css('color', 'green');
};
socket.onclose = function () {
$("#status").text('Offline');
$("#status").css('color', 'red');
};
socket.onerror = function(event) {
$("#status").text('Offline');
$("#status").css('color', 'red');
};
google.charts.load('current', {'packages': ['gauge']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Label', 'Value'],
['ESP8266', 0]
]);
var options = {
width: 800, height: 240,
redFrom: 90000, redTo: 100000,
yellowFrom: 75000, yellowTo: 90000,
minorTicks: 5, max: 100000
};
var chart = new google.visualization.Gauge(document.getElementById('chart_div'));
chart.draw(data, options);
socket.onmessage = function (event) {
data.setValue(0, 1, event.data);
chart.draw(data, options);
}
}
});
</script>
</head>
<body>
<div id="chart_div" style="width: 800px; height: 240px;"></div>
<div id="status"></div>
</body>
</html>
т. е если обесточить esp8266 данные поступать перестают, но статус не меняется
Обесточить - это не корректно разорвать соединение. Там ниче не гарантируется, особенно сразу. Отсылай по вебсокету периодический 'пинг'. Как он пропадает - разрыв значить.
просто не работал с сокетами и не знал таких вещей.
вторая трудность - счетчик сам ничего не сообщает. ему нужно отправлять команду и получать ответ. в начале я хотел загрузить список команд на esp8266 и получать с минимально возможным интервалом ответы, которые пересылать по вебсокету. но теперь, наверное , логичнее их и использовать как пинг? но новая трудность в виде таскания за собой html странички. ведь вряд ли esp8266 потянет даже то что я привел выше?
Так сделай чтоб счётчик отправлял сам. Периодически или при изменении значения. Оно в socketW.onmessage и прилетит. Хотя и запрос-ответ вполне удобно.
Такую страничку esp вполне потянет. Но можно хранить страничку на совершенно левом сервере, а esp тогда только вебсокет будет поддерживать. В общем как удобней - так и делай. Единственное, помню, были проблемы, когда здоровенную статическую страницу одним сендом пытался отправить то падало. А по частям и 100КБ уходят.
Обесточить - это не корректно разорвать соединение. Там ниче не гарантируется, особенно сразу. Отсылай по вебсокету периодический 'пинг'. Как он пропадает - разрыв значить.
а на ESP32 ping в какой библиотеке, вчера что-то не нашёл (пришли два девайса, пытаюсь до вэбсокетов добраться в изучении)?
Сам и отвечу - <ESP32Ping.h>
пока сделал так, но что-то мне подсказывает что не удачно -
void loop(void) { socket.loop(); Serial.write(powerParameters, sizeof(powerParameters)); delay(2); if (Serial.available() > 0) { for (int i = 0; i < 15; i++) { str += String(Serial.read(), HEX); } socket.loop(); socket.broadcastTXT(str); str = ""; } delay(500); }socket.onmessage = function (event) { data.setValue(0, 1, (parseInt(event.data.substring(3, 7).toString(16),16))/100 ); chart.draw(data, options); }void loop() { jsonString = ""; doc["powerParameters"] = getParam(powerParameters, sizeof(powerParameters)); serializeJson(doc, jsonString); delay(5000); } //00 03 0A 59 34 00 00 00 00 20 00 13 8C 94 CD //3й байт - размер ответа String getParam(byte *command, int leng) { String str = ""; Serial.write(command, leng); delay(200); if (Serial.available() > 0) { Serial.read(); Serial.read(); int len = Serial.read(); for (int i = 0; i < len + 2; i++) { str += String(Serial.read(), HEX); } } return str; }сделал отправку в виде json, что гораздо удобнее.
да с библиотекой json проблемы. периодически вместо данных null отправляет.
я сделал чтение с проверкой crc. есть ли смысл отправлять crc и в браузере еще раз проверять или вебсокет сам контролирует целостность?
Вебсокет поверх ТСР работает, а ТСР сам все контролирует. Потому в дополнительном crc смыслу особого нет. Правельней конечно найти багу и пофиксить, а не костыль лепить.
Вебсокет поверх ТСР работает...
вот ты меня озадачил, теперь думаю как на апач с инжинксом вэбсокет прикрутить )))
что то похоже не правильно делаю. если сделать вот так -
void loop(void) { socket.loop(); String str = String(i++); socket.broadcastTXT(str); }то данные идут. при обновлении страницы соединение моментально устанавливается и данные продолжают поступать.
если сделать так -
void loop(void) { jsonString = ""; doc["powerParameters"] = getParam(powerParameters, sizeof(powerParameters)); serializeJson(doc, jsonString); socket.loop(); socket.broadcastTXT(jsonString); }то -
соединение устанавливается очень долго
при обновлении страницы так же нет сразу соединения