Статьи » Разработки
Добавить статью

Ethernet shield w5100 управление нагрузками

2015-12-04 в 21:49 (последнее изменение 2023-11-09 в 12:25)

Это было в наших планах. Предыдущая часть требовала продолжения На форуме наши читатели просили сделать систему управления нагрузками с веб страницы нашей метеостанции, что собственно вам сейчас и предлагаем.

ethernet shield w5100 управление нагрузками

Как заметили, наша страница в браузере теперь имеет другое название. Ведь это уже не совсем Arduino WEB-метеостанция. Но вы можете сами это изменить. Показания датчиков MQ-2 и DHT-11 осталось не тронутым. А уже ниже расположились наши кнопки управления четырех реле (у меня не было реле, вместо этого установил пару светодиодов).

Но просто сделать обычные кнопки не интересно. По этому сделали активные кнопки "Хамелеоны" которые меняют свой цвет в зависимости от состояния пина. Если кнопка зеленая то пин активен, если красный - не активен. Обновляется страница как мы помним из предыдущих частей данного проекта, один раз в секунду. Так что не стоит паниковать если кнопка у вас изменит цвет не сразу.

Давайте разберемся как сделать красивые кнопочки.

За их дизайн будут отвечать пару строк в файле my.css. Стиль кнопки в отключенном состоянии будет такой:

Код

.button_disabled {color: #fff; /* цвет текста */
  background: rgb(212, 75, 56);/* фон кнопки */
  border: none; /* не показывать границу */
  border-radius:5px; /* закругление углов */
  cursor: pointer /* ставим другой курсор */
  }

.button_disabled:hover {background: rgb(232, 95, 76);}/* при наведении курсора мышки */
.button_disabled:active {background: rgb(152, 15, 0);}/* при нажатии */

Стиль кнопки во включенном состоянии будет немного другой:

Код

.button_enabled {color: #000; /* цвет текста */
  background: rgb(17,237,105); /* фон кнопки */
  border: none; /* не показывать границу */
  border-radius:5px; /* закругление углов */
  cursor: pointer /* ставим другой курсор */
  }

.button_enabled:hover { background: rgb(94,242,153); } /* при наведении курсора мышки */
.button_enabled:active { background: rgb(84,184,124); } /* при нажатии */

Как заметили, отличаются только цветом. Как видите в комментариях, вы можете легко поправить под свой нрав. Вдруг вам не нравится красный цвет...

Тогда файл стилей my.css нашей страницы будет иметь следующее содержание:

Код

.form {
  width: 400px;
  height: 270px;
  border: 3px solid rgb(0, 117, 178);
  background: rgb(6, 144, 207);
  color: #fff;
}

td{color: #fff}

h2 {
  font-family: Arial;
  font-weight: normal;
  margin: 20px;
  text-align: center
}

.button_disabled {color: #fff; /* цвет текста */
  background: rgb(212, 75, 56);/* фон кнопки */
  border: none; /* не показывать границу */
  border-radius:5px; /* закругление углов */
  cursor: pointer /* ставим другой курсор */
  }

.button_disabled:hover {background: rgb(232, 95, 76);}/* при наведении курсора мышки */
.button_disabled:active {background: rgb(152, 15, 0);}/* при нажатии */

.button_enabled {color: #000; /* цвет текста */
  background: rgb(17,237,105); /* фон кнопки */
  border: none; /* не показывать границу */
  border-radius:5px; /* закругление углов */
  cursor: pointer /* ставим другой курсор */
  }

.button_enabled:hover { background: rgb(94,242,153); } /* при наведении курсора мышки */
.button_enabled:active { background: rgb(84,184,124); } /* при нажатии */

html-код кнопок выглядит так:

<button type="button" id="led_1" class="button_disabled" onClick="onClick(1)">Реле №1</button>
<button type="button" id="led_2" class="button_disabled" onClick="onClick(2)">Реле №2</button>
<button type="button" id="led_3" class="button_disabled" onClick="onClick(3)">Реле №3</button>
<button type="button" id="led_4" class="button_disabled" onClick="onClick(4)">Реле №4</button>

Файл index.htm со всеми изменениями теперь такой:

Код

<html>

<head>
  <meta http-equiv='content-type' content='text/html; charset=UTF-8'>
  <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
  <title>Данные с датчиков</title>
  <link type="text/css" rel="StyleSheet" href="/my.css" />
 <script>
function GetFlameState() {
nocache = "&nocache=" + Math.random() * 1000000;
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (this.readyState == 4) {
if (this.status == 200) {
if (this.responseText != null) {
var arrayOfStrings = this.responseText.split(":");

document.getElementById("flame_txt").innerHTML = arrayOfStrings[0];
document.getElementById("temp_txt").innerHTML = arrayOfStrings[1];
document.getElementById("humid_txt").innerHTML = arrayOfStrings[2];
for(var i = 1 ; i < 5 ; i++)
if(arrayOfStrings[2+i] == "1")
document.getElementById("led_"+i).setAttribute("class","button_enabled");
else
document.getElementById("led_"+i).setAttribute("class","button_disabled");
}
}
}
}
request.open("GET", "ajax_flame" + nocache, true);
request.send(null);
setTimeout('GetFlameState()', 1000);
}
function onClick(pin){
var request = new XMLHttpRequest();
request.open("GET", "\setpin?pin=" + pin, false);
request.send(null);
}
</script>

</head>

<body onload="GetFlameState()">
  <div class="form">
    <h2>Arduino WEB контроль</h2>
    <hr noshade size="1px" color="white">
    <table align="center">
      <tr>
        <td><img src='flame.png' /></td>
        <td valign="center">Датчик дыма</td>
        <td><span id="flame_txt"> 0</span></td>
      </tr>

      <tr>
        <td><img src='temp.png' /></td>
        <td valign="center">Температура</td>
        <td><span id="temp_txt">0</span> °C</td>
      </tr>

      <tr>
        <td><img src='humid.png' /></td>
        <td valign="center">Влажность</td>
        <td><span id="humid_txt">0</span> %</td>
      </tr>
    </table>
    <br>
    <center>
      <button type="button" id="led_1" class="button_disabled" onClick="onClick(1)">Реле №1</button>
      <button type="button" id="led_2" class="button_disabled" onClick="onClick(2)">Реле №2</button>
      <button type="button" id="led_3" class="button_disabled" onClick="onClick(3)">Реле №3</button>
      <button type="button" id="led_4" class="button_disabled" onClick="onClick(4)">Реле №4</button>
    </center>
</div>
    </Body>
</html>

Не забывайте, что файл необходимо сохранить в кодировке "utf-8",
Настало время нарисовать окончательную схему нашего проекта. (Извините за пэинт, нарисуете лучше, буду рад выложить=))

arduino управление нагрзуками

Пояснение по схеме. Подключаем это все в плату Ethernet Shield W5100. Он у нас здесь вроде "ломтика сыра", а кусочком хлеба Arduino UNO. Датчик температуры и влажности DHT-11 подключен к цифровому входу 7. Датчик газов и дыма к аналоговому входу А0. Реле управления нагрузками (в моем случае светодиоды) подключаются к цифровым выходам 2, 3, 5, 6.
Датчики как вы понимаете можно цеплять любые. Просто я подключил то, что было под рукой.

Осталось разобраться с прошивкой. Прошивка из предыдущих статей была совсем немного изменена. Что то по отдельности описывать не стану. Вот сразу весь код прошивки.

Код

#include <dht11.h>
#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>
#define DHT11_PIN 7
#define REQ_BUF_SZ 20

dht11 DHT;
File webFile;
char HTTP_req[REQ_BUF_SZ] = {0}; // buffered HTTP request stored as null terminated string
char req_index = 0; // index into HTTP_req buffer
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 0, 20);

EthernetServer server(80);
bool pin1;
bool pin2;
bool pin3;
bool pin4;
void setup() {
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);

  SD.begin(4);
  Ethernet.begin(mac, ip);
  server.begin();
  pin1 = pin2 = pin3 = pin4 = 0;
}

void loop() {
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {

    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (req_index < (REQ_BUF_SZ - 1)) {
          HTTP_req[req_index] = c; // save HTTP request character
          req_index++;
        }
        if (c == '\n' && currentLineIsBlank) {
          if (StrContains(HTTP_req, "GET / ") || StrContains(HTTP_req, "GET /index.htm")) {
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html");
            client.println("Connnection: close");
            client.println();
            webFile = SD.open("index.htm");
          } else if (StrContains(HTTP_req, "GET /favicon.ico")) {
            webFile = SD.open("favicon.ico");
            if (webFile) {
              client.println("HTTP/1.1 200 OK");
              client.println();
            }
          } else if (StrContains(HTTP_req, "GET /temp.png")) {
            webFile = SD.open("temp.png");
            if (webFile) {
              client.println("HTTP/1.1 200 OK");
              client.println();
            }
          } else if (StrContains(HTTP_req, "GET /humid.png")) {
            webFile = SD.open("humid.png");
            if (webFile) {
              client.println("HTTP/1.1 200 OK");
              client.println();
            }
          } else if (StrContains(HTTP_req, "GET /flame.png")) {
            webFile = SD.open("flame.png");
            if (webFile) {
              client.println("HTTP/1.1 200 OK");
              client.println();
            }
          } else if (StrContains(HTTP_req, "GET /my.css")) {
            webFile = SD.open("my.css");
            if (webFile) {
              client.println("HTTP/1.1 200 OK");
              client.println();
            }
          } else if (StrContains(HTTP_req, "ajax_flame")) {
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html");
            client.println("Connection: keep-alive");
            client.println();
            int smoke_gas = 0; //пин на котором подключен MQ-2
            int sensorReading = analogRead(smoke_gas);
            int chk;
            chk = DHT.read(DHT11_PIN);
            client.print(sensorReading);
            client.print(":");
            client.print(DHT.temperature);
            client.print(":");
            client.print(DHT.humidity);
            client.print(":");
            client.print((digitalRead(2)) ? "1" : "0");
            client.print(":");
            client.print((digitalRead(3)) ? "1" : "0");
            client.print(":");
            client.print((digitalRead(5)) ? "1" : "0");
            client.print(":");
            client.print((digitalRead(6)) ? "1" : "0");

          } else if (StrContains(HTTP_req, "setpin?pin=1")) {
            pin1 = !pin1;
            digitalWrite(2, pin1);
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html");
            client.println("Connnection: close");
            client.println();
          } else if (StrContains(HTTP_req, "setpin?pin=2")) {
            pin2 = !pin2;
            digitalWrite(3, pin2);
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html");
            client.println("Connnection: close");
            client.println();
          } else if (StrContains(HTTP_req, "setpin?pin=3")) {
            pin3 = !pin3;
            digitalWrite(5, pin3);
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html");
            client.println("Connnection: close");
            client.println();
          } else if (StrContains(HTTP_req, "setpin?pin=4")) {
            pin4 = !pin4;
            digitalWrite(6, pin4);
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html");
            client.println("Connnection: close");
            client.println();
          }

          if (webFile) {
            while (webFile.available()) {
              client.write(webFile.read()); // send web page to client
            }
            webFile.close();
          }
          req_index = 0;
          StrClear(HTTP_req, REQ_BUF_SZ);
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
  }
}

void StrClear(char *str, char length)
{
  for (int i = 0; i < length; i++) {
    str[i] = 0;
  }
}

char StrContains(char *str, char *sfind)
{
  char found = 0;
  char index = 0;
  char len;
  len = strlen(str);
  if (strlen(sfind) > len) {
    return 0;
  }
  while (index < len) {
    if (str[index] == sfind[found]) {
      found++;
      if (strlen(sfind) == found) {
        return 1;
      }
    }
    else {
      found = 0;
    }
    index++;
  }
  return 0;
}

Видео работы данного проекта.

Архив с картинками для имен датчиков. Скачать.
Файлы "my.css" и "index.htm" все также загружаем в корень карты памяти. Картинки распаковываем и туда же их.
Кстати! Если вы вдруг талантливый веб-дизайнер и можете предложить другой и более правильный вариант оформления страницы, будем рады вас услышать.

З.Ы. Небольшой спойлер. Уже в процессе подготовки интереснейший проект. Он будет для тех, кто бережет свою фигуру либо просто следит за своим весом. Так что ждите, и скоро вы все сами поймете)
З.Ы.Ы. Внесли изменения и дополнения. Теперь с нашей странички можно регулировать мощность с помощью ползунка. Читать.

Список электронных компонентов.

Наименование Тип Количество Магазин
Arduino UNO R3 1 Найти
Ethernet Shield W5100 1 Найти
Датчик температуры и влажности DHT-11 1 Найти
Датчик дыма и газов MQ-2 1 Найти
Модуль реле 4 канала 1 Найти
Провода Dupont Папа-Мама Провода Dupont Папа-Мама 6 Найти
Cashback на Aliexpress

Не пропустите обновления! Подписывайтесь на нашу группу Вконтакте.
Так же у нас есть Telegram канал.
Вам понравился наш материал? Поделитесь с коллегами!

Просмотров: 44213. Оценка статьи: 4.8 из 5. Уже оценило 22 читателя

Об авторе - Администратор

More by Администратор

Всего комментариев: 12
humaxoid
humaxoid 2021-03-18 10:58
To Василий: Понимаю что уже не актуально, может комуто еще пригодится. Добавьте это 
Код
if DHT.temperature>=26) digitalWrite(2, HIGH);  
else digitalWrite(2, HIGH);
   
Пояснение: Если температура превысит 26 градусов, то на 2 пин (или куда у вас там подключено 4 реле?) будет подана 1.

stepan007
stepan007 2019-01-16 18:37
Доброго времени суток! Опробовал в сборке это устройство, в оригинале всё работает. Потом захотел я изменить устройство под себя, а именно, мне нужно управлять 24-ю реле, дописал в скетче переменные, в htm файле кнопки, всё откомпилировалось без ошибок и залилось в ардуино (использую mega2560), но при попытке включить реле от 10 до 24, включаются 1 (если включать с 10 по 19) и 2 (если включать с 20 по 24), такое ощущение, что запрос режет длину передаваемой переменной до 1 знака. Подскажите пожалуйста где это исправить. Заранее благодарю.

ValaS
ValaS 2018-08-24 16:14
Низкий Вам поклон за проделанную работу. Все завелось с полоборота, и работает!

Василий 2018-02-07 20:05
подскажите пожалуйста как сделать чтобы реле например номер 4 выключалось и включалось по заданной температуре??? очень нужно

Андрей 2017-03-07 18:53
Согласно схеме подключения у вас вывод "+" DHT11 подключается к PIN_7, а вывод "Out" подключается к +5В на Ардуине.

Константин 2017-01-01 23:37
Доброе время суток. С новым годом. Спасибо отличный проект. Я его переделал под давление, температуру и влажность. В процессе возникла идея, что информация по датчикам как бы не совсем необходима. Интереснее было бы ручное управление нагрузкой а также автоматическое по расписанию, которое выставляется в веб интерфейсе.

Валентин 2016-10-09 21:53
Если оставить кодировку в utf-8 то ромбики в браузере (хром), если удалить, то все нормально. семерка 64 бита

Дима 2016-10-04 20:23
arduino 1.6.12 ругается на команды StrContains и StrClear как можно заменить? и можете детальней описать что и как делает какая команда?
какой файл как открывает и тому подобное...

Виталий 2016-08-22 00:38
Спасибо за статью, делаю сам что то подобно, помогло очень.
Есть вопрос, а можно управлять светодиодной лентой с Mega2560 и 5100 на Nano подключенные по nRF24L01 и параллельно иметь возможность управлять этой лентой с Nano через тактовую кнопку? У меня получается что то одно, или с сайта или с кнопки angry

Дмитрий 2016-06-07 08:33
Еще раз спасибо за статью. С кодом разобрался, причиной отключения реле оказалась бракованная ардуинка. Заменил, все работает hands

Дмитрий 2016-06-05 20:00
Спасибо, очень поучительный цикл статей. Отличная работа. Правда у меня всплыл один баг, а именно, если включать "реле" по очереди (№1-№2-№3-№4), то при выключении четвертого, перестает гореть зеленым (становится ненажатой) вторая кнопка, хотя светодиод на данном пине остается гореть. И Это не единственная последовательность при которой слетает индикация включенного "реле".
Подскажите, пожалуйста, что происходит в данных строчке кода client.print((digitalRead(2)) ? "1" : "0"); Верно ли я понимаю что это идет опрос состояния пина и его отправка, для того что бы применить тот или иной стиль кнопки? Первый раз такое встретил, синтаксис понять не могу. Знак вопроса заменяет условие? Спасибо

Администратор
Администратор 2016-04-30 20:52
Юрий, попробуйте другую карту и все)

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]