• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Непонятная ошибка работы WEB страницы при переходе с ESP8266 на ESP32.

Есть у меня 2 метеостанции. Одна простая для квартиры, с 4 датчиками, вторая посложнее, для дачи с 6 датчиками и вот делаю для деревни новую, там будет 10 датчиков.(Там влажность, температура в 3 помещениях и на улице, давление атмосферное и датчик угарного газа.
Так вот две предыдущих построены на ESP8266, а новая будет на ESP32 плюс Attiny85. Странички все были одинаковые. Сверху выводились в динамике цифровые показатели, а внизу графики изменения температуры, влажности и давления.
Так вот на двух первых все работает. Я взял ту же страницу, добавил выводы новых датчиков на страницу. В цифровом виде все прекрасно работает. А вот графики перестали работать. При чем я брал код с работающей странички в квартире, подцеплял ее на новое устройство и тоже не работали графики. Вот сам код:
Код приложу в следующем сообщении.
 
Вот код:
Код:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="mc.css">
<script src="Chart.min.js"></script>
<script src="utils.js"></script>
    <title>MeteoClockV2</title>
</head>
 
<body>
    <div style="background-color: rgb(9, 43, 240);margin: auto;border-style: ridge;border-width: 8px;border-color: rgb(54, 203, 248);width: 900px;height: 1800px;">
        <div style="width: 100%;height: 4%;">
            <nav>
                <ul>
                    <li><a>Меню</a>
                        <ul>
                            <li><a>История</a>
                                <ul>
                                    <li><a>Таблица</a>
                                        <ul id="table"></ul>
                                    </li>
                                    <li><a>Графики</a>
                                        <ul id="chart"></ul>
                                    </li>
                                </ul>
                            </li>
                            <li><a href="files.htm">Список файлов</a></li>
                            <li><a href="edit.htm">Редактирование файлов</a></li>
                        </ul>
                    </li>
                    <li><a href="configuration.htm">Конфигурация</a></li>
                </ul>
            </nav>
        </div>
        <hr>
        <div style="width: 100%;height: 21%;">
        <a class="txt">Дата </a><label id="date" class="txtc"></label><hr>
        <a class="txt">Время </a><label id="time" class="txtc"></label><hr>
        <a class="txt">СО(угарный газ, допустимо ХХХХ)    </a><label id="COgaz" class="txtc"></label><hr>
        <table>
            <tr>
                <td style="text-align: center;">
                    <a class="txtsm">Где</a>
                </td>
                <td style="text-align: center;">
                    <a class="txtsm">Температура °C</a>
                </td>
                <td style="text-align: center;">
                    <a class="txtsm">Влажность %</a>
                </td>
                <td style="text-align: center;">
                    <a class="txtsm">Давление мм.рт.ст.</a>
                </td>
            </tr>
            <tr>
                <td style="text-align: center;">
                    <a class="txtsm">На улице</a>
                </td>
                <td style="text-align: center;">
                    <label id="tIn1" class="txtsmc"></label>
                </td>
                <td style="text-align: center;">
                    <label id="humidity1" class="txtsmc"></label>
                </td>
                <td style="text-align: center;border-bottom:none;">
                    <label id="pressure1" class="txtsmc"></label>
                </td>
            </tr>
            <tr>
                <td style="text-align: center;">
                    <a class="txtsm">1 этаж</a>
                </td>
                <td style="text-align: center;">
                    <label id="tIn2" class="txtsmc"></label>
                </td>
                <td style="text-align: center;">
                    <label id="humidity2" class="txtsmc"></label>
                </td>
                <td style="text-align: center;border-bottom:none;border-top:none;"></td>
            </tr>
            <tr>
                <td style="text-align: center;">
                    <a class="txtsm">2 этаж</a>
                </td>
                <td style="text-align: center;">
                    <label id="tIn3" class="txtsmc"></label>
                </td>
                <td style="text-align: center;">
                    <label id="humidity3" class="txtsmc"></label>
                </td>
                <td style="text-align: center;border-bottom:none;border-top:none;"></td>
            </tr>
            <tr>
                <td style="text-align: center;">
                    <a class="txtsm">Терраска</a>
                </td>
                <td style="text-align: center;">
                    <label id="tIn4" class="txtsmc"></label>
                </td>
                <td style="text-align: center;">
                    <label id="humidity4" class="txtsmc"></label>
                </td>
                <td style="text-align: center;border-top:none;"></td>
            </tr>
        </table>
        <label id="date2" style="visibility: hidden;"></label>
        </div><hr>
        <div style="width: 100%;height: 75%;">
            <div style="width: 50%; height: 19%;border-style: ridge;border-width: 2px;border-color: rgb(53, 32, 248);background-color: bisque;display: inline-block;"><canvas style="width: 100%;height: 100%;" id="canvas1"></canvas></div><div style="width: 49%; height: 19%;border-style: ridge;border-width: 2px;border-color: rgb(53, 32, 248);background-color: bisque;display: inline-block;"><canvas style="width: 100%;height: 100%;" id="canvas2"></canvas></div>
            <div style="width: 50%; height: 19%;border-style: ridge;border-width: 2px;border-color: rgb(53, 32, 248);background-color: bisque;display: inline-block;"><canvas style="width: 100%;height: 100%;" id="canvas3"></canvas></div><div style="width: 49%; height: 19%;border-style: ridge;border-width: 2px;border-color: rgb(53, 32, 248);background-color: bisque;display: inline-block;"><canvas style="width: 100%;height: 100%;" id="canvas4"></canvas></div>
            <div style="width: 50%; height: 19%;border-style: ridge;border-width: 2px;border-color: rgb(53, 32, 248);background-color: bisque;display: inline-block;"><canvas style="width: 100%;height: 100%;" id="canvas5"></canvas></div><div style="width: 49%; height: 19%;border-style: ridge;border-width: 2px;border-color: rgb(53, 32, 248);background-color: bisque;display: inline-block;"><canvas style="width: 100%;height: 100%;" id="canvas6"></canvas></div>
            <div style="width: 50%; height: 19%;border-style: ridge;border-width: 2px;border-color: rgb(53, 32, 248);background-color: bisque;display: inline-block;"><canvas style="width: 100%;height: 100%;" id="canvas7"></canvas></div><div style="width: 49%; height: 19%;border-style: ridge;border-width: 2px;border-color: rgb(53, 32, 248);background-color: bisque;display: inline-block;"><canvas style="width: 100%;height: 100%;" id="canvas8"></canvas></div>
            <div style="width: 99%; height: 19%;border-style: ridge;border-width: 2px;border-color: rgb(53, 32, 248);background-color: bisque;display: inline-block;"><canvas style="width: 100%;height: 100%;" id="canvas9"></canvas></div>
    </div>
<script>
var downline = [];
var tin1 = [];
var tin2 = [];
var tin3 = [];
var tin4 = [];
var hum1 = [];
var hum2 = [];
var hum3 = [];
var hum4 = [];
var pre = [];
//var COgaz = [];
var chart1;
var chart2;
var chart3;
var chart4;
var chart5;
var chart6;
var chart7;
var chart8;
var chart9;
var requestURL = '/config.json';
var request = new XMLHttpRequest();
request.open('GET', requestURL);
request.responseType = 'text';
request.send();
request.onload = function() {
    const SetupDataText = request.response;
    SetupData = JSON.parse(SetupDataText);
    console.log(SetupData);
    run_socket(SetupData['IP']);
    main();
}
//main();
 
function run_socket(IP) {
var ws = new WebSocket('ws://' + IP + ':81', ['arduino']);
 
 ws.onopen = function () {
     console.log('socket connection opened properly');
     ws.send("Hello World"); // send a message
     console.log('message sent');
 };
 
 /*ws.onmessage = function (evt) {
  var socket_data=JSON.parse(evt.data);
  console.log(socket_data);
  for(var key in socket_data) {
    document.getElementById(key).innerHTML = socket_data[key];
  }
};*/
 
    ws.onmessage = function(evt) {
        //console.log(evt.data);
        var socket_data=JSON.parse(evt.data);
        //console.log(socket_data);
        document.getElementById('time').innerHTML = socket_data['time'];
        document.getElementById('date').innerHTML = socket_data['date'];
        document.getElementById('tIn1').innerHTML = socket_data['tIn1'];
        document.getElementById('tIn2').innerHTML = socket_data['tIn2'];
        document.getElementById('tIn3').innerHTML = socket_data['tIn3'];
        document.getElementById('tIn4').innerHTML = socket_data['tIn4'];
        document.getElementById('humidity1').innerHTML = socket_data['humidity1'];
        document.getElementById('humidity2').innerHTML = socket_data['humidity2'];
        document.getElementById('humidity3').innerHTML = socket_data['humidity3'];
        document.getElementById('humidity4').innerHTML = socket_data['humidity4'];
        document.getElementById('pressure1').innerHTML = socket_data['pressure'];
        document.getElementById('COgaz').innerHTML = socket_data['COgaz'];
        downline.push(socket_data['time']);
        tin2.push(socket_data['tIn2']);
        hum2.push(socket_data['humidity2']);
        tin3.push(socket_data['tIn3']);
        hum3.push(socket_data['humidity3']);
        tin4.push(socket_data['tIn4']);
        hum4.push(socket_data['humidity4']);
        tin1.push(socket_data['tIn1']);
        hum1.push(socket_data['humidity1']);
        pre.push(socket_data['pressure']);
        console.log(downline);
        console.log(tin2);
        if (downline.length > 19) {
            downline.shift();
            tin2.shift();
            hum2.shift();
            tin3.shift();
            hum3.shift();
            tin4.shift();
            hum4.shift();
            tin1.shift();
            hum1.shift();
            pre.shift();
        }
        chart1.update();
        chart2.update();
        chart3.update();
        chart4.update();
        chart5.update();
        chart6.update();
        chart7.update();
        chart8.update();
        chart9.update();
    };
 
    ws.onclose = function () {
        // websocket is closed.
        console.log("Connection closed...");
    };
}
 
А вот вторая часть кода;
Код:
async function main(){

    const text = await GetList(this);

    var SD = JSON.parse(text);

    console.log(SD);

    SD = SD.sort(function (a,b) {

        return a.name.localeCompare(b.name);

    });

    var mtable = document.getElementById("table");

    var mchart = document.getElementById("chart");

    var str_code1 = '';

    var str_code2 = '';

    for (var i = 0; i < SD.length; i++) {

        if ((SD[i]['name']).indexOf("data_") == 0) {

            str_code1 += '<li><a href="bd.htm?file=' + SD[i]['name'] + '">' + SD[i]['name'] + '</a></li>';

            str_code2 += '<li><a href="charts.htm?file=' + SD[i]['name'] + '">' + SD[i]['name'] + '</a></li>';

        }

    }

    mtable.innerHTML = str_code1;

    mchart.innerHTML = str_code2;

 

        //График температуры на 1 этаже

        var ctx1 = document.getElementById('canvas1').getContext('2d');

        chart1 = new Chart(ctx1, {

            type: 'line',

                data: {

                    labels: downline,

                    datasets: [{

                        label: 'Температура 1 этаж',

                        backgroundColor: window.chartColors.blue,

                        borderColor: window.chartColors.blue,

                        data: tin2,

                        fill: false,

                    }]

                },

                options: {

                    responsive: true,

                    tooltips: {

                        mode: 'index',

                        intersect: false,

                    },

                    hover: {

                        mode: 'nearest',

                        intersect: true

                    },

                    scales: {

                        xAxes: [{

                            display: true,

                            scaleLabel: {

                                display: true,

                                labelString: 'Время'

                            }

                        }],

                        yAxes: [{

                            display: true,

                            scaleLabel: {

                                display: true,

                                labelString: 'Значения'

                            }

                        }]

                    }

                }

        });

 



}
 
И третья часть кода:
Код:
async function GetList(submit) {
    const url = '/list?dir=/';
    const result = await send_request(url);
    const defaultValue = '{}'
    return result || defaultValue
}

async function send_request(url) {
    const response = await fetch(url);
    if (response.ok) {
        return await response.text();
    } else {
        console.log("Ошибка HTTP: " + response.status);
        return null;
    }
}
</script>
</body>
</html>
Не приняло весь код. А часто на форумах просят выложить весь код.

Ошибка следующая:
FireFox выдает вот это: Uncaught TypeError: chart1 is undefined.
А скажем Edge вот это: Uncaught TypeError: Cannot read properties of undefined (reading 'update').
Ошибка в функции ws.onmessage, строка 207. При чем я оставил в ней обновление тока одного графика. Данные по нему собираются успешно и массив для вывода строится без проблем. Именно в Update какая-то хрень!

Я уже решил проверить не связано ли это с тем, что у меня теперь ESP32 вместо 8266. Заказал 8266 жду, что бы пересобрать на 8266. Но решил задать вопросы на форумах.
 
Код я на всякий случай приложил. Это одна страница.
Я подозреваю, что что-то не так либо с библиотекой ESP32WebServer, либо с самой железкой. К такому мнению приводит то, что я беру страничку прям с устройства работающего на ESP8266. Там она работает, а на ESP32 нет. Код даже переделывать практически не пришлось. Ну кроме прописания других библиотек (для ESP32). При чем на WEB странице не работают графики и страница, где запрашиваются данные по файлам на SD карте.
 

Сергей_Ф

Moderator
Команда форума
Насколько я понял, вы дали код только страницы на js. А проблема, скорее всего в коде для esp, который вы не привели.
Выкладывайте весь проект куда нибудь, может тогда кто-то и поможет
 
Нет. Там в 10 раз больше кода. К тому же код там 200% рабочий. Код там собирает значения с датчиков и отправляет их пока только на WEB страницу. До WEB страницы данные доходят.
 

Сергей_Ф

Moderator
Команда форума
Ну так то js совершенно всё равно какая у вас esp, он в браузере выполняется и ничего не знает о бэкенде. Дело точно не в нем, имхо.
 
Я тоже так думаю. Поэтому дождусь ESP8266 NodeMCU с алиэкспресса и соберу на ней. Если там WEB страницы будут работать, то получится, что дело именно в ESP. А скорее всего в библиотеке ESP32WebServer. Потому что только ей будет отличаться.
 

Сергей_Ф

Moderator
Команда форума
Так я и говорю, что дело в коде для esp. Может вы для 8266 использовали асинхронный сервер, а для 32-ой синхронный, или наоборот - вот и не работает. Так что без вашего скетча никто не поможет. Но дело не в esp, а в вашем коде.
 
Нет. Точно не асинхронный. Смотрел код. Там библиотека ESP8266WebServer. Собственно взят полностью старый, рабочий код. В коде подменены только библиотеки для WiFi и WebServer, потому что ESP32 не приняла их. Но весь остальной код, кроме задания библиотек совершенно один в один.
 
Да вроде когда идет отрисовка графиков SD карта вообще никак не задействована. Данные с датчиков собираются в переменную JSON, которая никуда не пишется, а отправляется через WebSocket на Web страницу. Ну хорошо. Поковыряюсь с SD картой.
 
Да он не супер секретный, он супер длинный. Раз в 10 длиннее страницы, что я выложил. Я его год или 2 назад уже выкладывал, когда на ESP8266 настраивал все.
Немножко разобрался и графики заработали.
Теперь ясно что не работает. Не работает именно функция GetList(this); 641 строка. Когда я отключил на странице index.htm строки с 225 по 242 графики заработали.
Получается я не могу получить данные о содержимом флешки. С 225 по 242 строку имено считываются данные с флешки и заполняется меню.
При чем я в коде для платы ESP32 смотрю и вижу, что код о содержимом флешки отправляется. Почему-то он не доходит. Ошибка, что выдается "net::ERR_INCOMPLETE_CHUNKED_ENCODING 200 (OK)" связана в основном с браузером (я в инете поискал ее), типа кэш почистить, браузер перегрузить, другой браузер попробовать. Но у меня не работает ни в одном браузере на компьютере, в Хромиуме на Ред ОС на виртуалке и на смартфоне. Получается данные режутся. При чем я принудительно сделал их короткими, в одну строку, они все равно не дошли! А с ESP-шки они отправляются.
Код:
void printDirectory() {
  String outp = "[";
  if(!HTTP.hasArg("dir")) return HTTP.send(500, "text/plain", "BAD ARGS");
  String path = HTTP.arg("dir");
  Serial.println(path);
  if(path != "/" && !SD.exists((char *)path.c_str())) return HTTP.send(500, "text/plain", "BAD PATH");
  File dir = SD.open((char *)path.c_str());
  path = String();
  if(!dir.isDirectory()){
    dir.close();
    return HTTP.send(500, "text/plain", "NO DIR");
  }
  dir.rewindDirectory();
  HTTP.setContentLength(CONTENT_LENGTH_UNKNOWN);
  HTTP.send(200, "text/json", "");
  WiFiClient client = HTTP.client();

  //HTTP.sendContent("[");
  for (int cnt = 0; true; ++cnt) {
    File entry = dir.openNextFile();
    if (!entry)
    break;

    String output;
    if (cnt > 0)
      output = ',';

    output += "{\"type\":\"";
    output += (entry.isDirectory()) ? "dir" : "file";
    output += "\",\"name\":\"";
    output += entry.name();
    output += "\",\"size\":\"";
    if (! entry.isDirectory()) output += entry.size();
    else output += "-";
    output += "\"}";
    //Serial.println(output);
    //HTTP.sendContent(output);
    outp += output;
    entry.close();
 }
 outp += "]";
 Serial.println(outp);
 HTTP.sendContent(outp);
 dir.close();
}
Вот эта функция вызывается когда приходит запрос считать домашнюю директорию /.
 
Выводит содержимое флешки в JSON формате:
Код:
[{"type":"dir","name":"System Volume Information","size":"-"}
,{"type":"file","name":"config.json","size":"176"}
,{"type":"file","name":"index.htm","size":"19948"}
,{"type":"file","name":"bd.htm","size":"5808"}
,{"type":"file","name":"bminus.png","size":"2046"}
,{"type":"file","name":"bplus.png","size":"2152"}
,{"type":"file","name":"files.htm","size":"4888"}
,{"type":"file","name":"Chart.min.js","size":"172812"}
,{"type":"file","name":"charts.htm","size":"12337"}
,{"type":"file","name":"configuration.htm","size":"7440"}
,{"type":"file","name":"edit.htm","size":"9542"}
,{"type":"file","name":"extra_clean_paper.png","size":"15455"}
,{"type":"file","name":"mc.css","size":"5728"}
,{"type":"file","name":"settime.htm","size":"14063"}
,{"type":"file","name":"utils.js","size":"3318"}
,{"type":"file","name":"ace.js","size":"340569"}
,{"type":"file","name":"Chart.min.css","size":"521"}
,{"type":"file","name":"data_20230603.txt","size":"9595"}
,{"type":"file","name":"data_20250127.txt","size":"10406"}]
А вот до странички Web это не доходит.
 
Да, это рудимент. Года 2 назад, код был откуда-то содран. Что-то ненужное убрал, что-то забыл. Убрал эту строку.
Я поэкспериментировал, получается вот эта строка задает длинну данных:
HTTP.setContentLength(CONTENT_LENGTH_UNKNOWN);

Есть еще один вариант.
//HTTP.setContentLength(CONTENT_LENGTH_NOT_SET);
Так вот если оставить второе или вообще закомментировать строку, ошибок нет, но и информация никакая не выводится. Если же оставить первое значение, то вылазит ошибка:
net::ERR_INCOMPLETE_CHUNKED_ENCODING 200 (ОК)
и результата все равно нет. Возможно в библиотеке для ESP8266 это было правильно отработано, а здесь нет.
 
Сверху Снизу