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

Делюсь опытом Аквариум на esp8266

Ildarmustafin86

Active member
Контроль температуры аквариума.
Функции, реализованные в данном проекте:
  1. Вывод показаний температуры на дисплей lcd1602 и веб интерфейс.
  2. Выводит график показаний температуры. Данные обновляются 1 раз в день. Данные усредненные. Делаются 4 замера в 3:00, 9:00, 15:00 и 21:00. Далее вычисляется среднее между этими значениями.
  3. Включение нагревателя по понижению температуры.
  4. Включение вентилятора по повышению температуры.
  5. Включение светодиодов по расписанию. Мин и макс яркость выставляется в %.
  6. Обновление прошивки через веб интерфейс
  7. Подключение к существующей точке доступа
При первом подключении создается точка доступа ESP8266_AQUA без пароля с IP адресом 192.168.4.1. При сохранении данных на сервер страница не перезагружается. Данные загружаются в json формате GET запросом. Текущее состояние реле, дата и температура передаются посредством Websocket с частотой в 2 сек.

Веб интерфейс создан на программе WYSIWYG Web Builder 15 (64-bit)
Библиотеки, используемые в скетче, находятся в архиве libs.7z.
Распиновка:
  1. D1 // SCL адрес LCD1602 0х27
  2. D2 // SDA адрес LCD1602 0х27
  3. D3 // DS18B20
  4. D4 // Реле вентилятора DIGITAL
  5. D5 // Реле нагревателя DIGITAL
  6. D6 // Реле светодиодов PWM
 

Вложения

enjoynering

Well-known member
спасибо за проект и за то, что не засунули все html в тело скеча, как это делает 90% всех ардунщиков.
 

Ildarmustafin86

Active member
Да не за что. Проект потихоньку совершенствую. Последняя версия всегда лежит на гитхабе.
Может кому то будет нужно. Выполнение нажатия кнопки на веб интерфейсе без перезагрузки страницы.
CSS:
.btn_success
{
   font-family: Arial;
   font-weight: bold;
   font-size: 13px;
   text-decoration: none;
   color: #32CD32;
   background-color: #3370B7;
   border: 1px solid #2E6DA4;
   border-radius: 4px;
   margin: 0px 0px 0px 0px;
}
.btn_beforeSend
{
   font-family: Arial;
   font-weight: bold;
   font-size: 13px;
   text-decoration: none;
   color: #FFFF00;
   background-color: #3370B7;
   border: 1px solid #2E6DA4;
   border-radius: 4px;
   margin: 0px 0px 0px 0px;
}
.btn_complete
{
   font-family: Arial;
   font-weight: normal;
   font-size: 13px;
   text-decoration: none;
   color: #FFFFFF;
   background-color: #3370B7;
   border: 1px solid #2E6DA4;
   border-radius: 4px;
   margin: 0px 0px 0px 0px;
}
.btn_error
{
   font-family: Arial;
   font-weight: bold;
   font-size: 13px;
   text-decoration: none;
   color: #FF0000;
   background-color: #3370B7;
   border: 1px solid #2E6DA4;
   border-radius: 4px;
   margin: 0px 0px 0px 0px;
}
JavaScript:
$('#Button6').click(function(){
   var eb43 = $('#Editbox43').val();
   var eb44 = $('#Editbox44').val();
   var jsonData = 'ssid=' + eb43 + '&password=' + eb44;
   $.ajax({
   type: "GET",
   url: "/ssid",
   data: jsonData,
   success: function() {
    console.log('success');   
    $('#Button6').attr('class', 'btn_success');
    $('#Button6').attr('value','Выполнено');
   },
   beforeSend: function() {
    console.log('beforeSend');     
    $('#Button6').attr('class', 'btn_beforeSend');
    $('#Button6').attr('value','Подождите...');
   },
   complete: function() {
    console.log('complete');   
     setTimeout(function() {
       $('#Button6').attr('class', 'btn_complete');
       $('#Button6').attr('value','Сохранить'); 
     },2000);   
   },
   error: function(jqXHR, textStatus, errorThrown) {
     console.log('error: ' + textStatus + ' | ' + errorThrown);
     $('#Button6').attr('class', 'btn_error');
     $('#Button6').attr('value','ОШИБКА');
   }
    });
    // openValues(); 
    return false;
});
Код:
  server.on("/ssid", HTTP_GET, []() {
    jsonWrite(configSetup, "ssid", String(server.arg("ssid")));
    jsonWrite(configSetup, "password", String(server.arg("password")));
    saveConfigSetup();
    server.send(200, "text/plain", "");
  });
 

Ildarmustafin86

Active member
Передача JSON из esp8266 на web интерфейс
JavaScript:
  function liveValues() {
    ws = new WebSocket("ws://" + window.location.host + ":81/");
    ws.onopen = function(event) {
    // var enableMessage = JSON.stringify({enableGestures: true});
      console.log("[open] Websocket-соединение установлено...");
    };
    ws.onmessage = function(event) {
      console.log("[message] Данные с сервера получены");
      //console.log(event.data);
      var json = jQuery.parseJSON(event.data);
      ds_day = json.ds_day;
    
      class_led = 'led_' + json.led;
      class_fan = 'fan_' + json.fan;
      class_ten = 'ten_' + json.ten;
      $('#wb_Picture2').attr('class', class_led);
      $('#wb_Picture3').attr('class', class_fan);
      $('#wb_Picture4').attr('class', class_ten);   
      if (json.temp == -127.00){
        $('#Heading28').text("--");
        $('#Heading28').css('color', 'red');
        $('#wb_Picture1').attr('class', 'tempna');      
      }
      else{
        $('#Heading28').text(json.temp + " °C");
        $('#Heading28').css('color', 'black');
        $('#wb_Picture1').attr('class', 'temp');       
      }
      if (json.ds_day == 165){
        $('#Heading29').text("ОБРЫВ RTC");
        $('#Heading29').css('color', 'red');
      }
      else{
        $('#Heading29').text(json.now);
        $('#Heading29').css('color', 'black');
      }
      if (json.ds_day == 00){
        $('#Heading29').text("ОШИБКА RTC");
        $('#Heading29').css('color', 'red');
      }
      else{
        $('#Heading29').text(json.now);
        $('#Heading29').css('color', 'black');
      }
      if (ds_day != old_ds_day){
        updateChart();
        old_ds_day = ds_day;
      }
    };
    ws.onclose = function(event) {
      ws = null;
      console.log("[close] Websocket-соединение разорвано...");
    };
    ws.onerror = function(event) {
      console.log("[error] Ошибка подключения...");
    };
  }
Код:
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
  switch (type) {
    case WStype_DISCONNECTED:
      Serial.printf("[%u] Websocket-соединение разорвано!\n", num);
      ws_working = 0;
      break;
    case WStype_CONNECTED:
      //IPAddress ip = webSocket.remoteIP(num);
      ws_working = 1;
      Serial.printf("Установлено Websocket-соединение с клиентом [%u]!\n", num);
      //  Serial.printf("[%u] Сообщение от IP: %d.%d.%d.%d: ", num, ip[0], ip[1], ip[2], ip[3], payload);
      //  webSocket.sendTXT(num, " connected");
      break;
    case WStype_TEXT:
      Serial.printf("[%u] Сообщение: %s\n", num, payload);
      ws_working = 1;
      //webSocket.sendTXT(num, jsonLive);
      //webSocket.broadcastTXT("message here");
      break;
    case WStype_BIN:
      Serial.printf("[%u] get binary length: %u\n", num, length);
      hexdump(payload, length);
      // webSocket.sendBIN(num, payload, length);
      break;
  }
}
Код:
  String jsonLive = "{\"temp\":\"--\",\"ds_day\":\"--\",\"now\":\"--.--.----\",\"led\":\"-\",\"fan\":\"-\",\"ten\":\"-\"}";
  char date_now[30];
  sprintf(date_now, "%02i.%02i.%02i | %02i:%02i:%02i",  ds_day, ds_month, ds_year, ds_hour, ds_min, ds_sec);
  String send_temp = String(round(tempC1 * 100) / 100);
  jsonWrite(jsonLive, "temp", send_temp);
  jsonWrite(jsonLive, "ds_day", ds_day);
  jsonWrite(jsonLive, "now", date_now);
  jsonWrite(jsonLive, "led", led_working);
  jsonWrite(jsonLive, "fan", fan_working);
  jsonWrite(jsonLive, "ten", ten_working);
  webSocket.broadcastTXT(jsonLive);
 

Ildarmustafin86

Active member
Сейчас переделываю весь проект. Ухожу от JQuery, делаю с применением bootstrap 4. Уменьшил время загрузки страницы. Будет адаптация к телефону, а точнее переключение вкладок свайпом
 
  • Like
Реакции: ivi

ivi

New member
Здравствуйте! Помогите разобраться - скомпилировал в IDE 1.8.12. Скетч залился - точка доступа появилась. Однако зайдя по 192.168.4.1 отображается только надпись FileNotFound.
 

Ildarmustafin86

Active member
Доступ к локальным файлам JSON, для небольшой отладки без использования контроллера и сервера. Для запуска необходимо в батнике указать путь к браузеру chrome. Запустить батник. Откроется браузер с отключенной защитой. Изменить путь к json файлу в Index.htm. Дальше перетащить htm файл на открытый браузер. Готово
<!doctype html>
<html lang="ru">
<head>
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<meta charset="utf-8">
<title>ReadFromFile</title>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<script>
window.onload = function() {
readTextFile("file:///C:/Users/ss/Desktop/LoadFromFile/data.json");
}
function readTextFile(file) {
var xhttp = new XMLHttpRequest();
xhttp.open("GET", file, true);
xhttp.onreadystatechange = function ()
{
if (xhttp.readyState === 4) {
if (xhttp.status === 200 || xhttp.status == 0) {
var allText = xhttp.responseText;
console.log(allText);
alert(allText);
document.getElementById("text").innerHTML = allText;
}
}
}
xhttp.send(null);
}
</script>
<span id="text"></span>
</body>
</html>

"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --disable-web-security --user-data-dir="D:\chrome"

{
"time_man":"21:45",
"timeZone":5,
"defaultLang":"RUS",
"lang":["RUS","ENG"]
}

P.S.: Путь к файлу измените на свой
 

Вложения

enjoynering

Well-known member
можно сделать проще - поставить расширение Web Server for Chrome Offered by: chromebeat.com. Из недостатков - не умеет gzip
 

enjoynering

Well-known member
конечно. я только так JSON и отлаживаю - кидаю нужный мне *.json файл и корень проекта и потом в *.html его вызываю через JavaScript.
 
Сверху Снизу