Сохранение состояния реле

Otto
Offline
Зарегистрирован: 26.06.2016

Здравствуйте, помогите новичку разобраться. Есть простейший Web сервер на плате Ethernet Shild W5100.

Хочу сделать, что бы при отключении питания сохранялся статус питания на реле (либо вкл. / либо выкл.), что бы при подаче питания состояния реле восстановились. Много гуглил, не могу понять как как правильно применить EEPROM.

Пока что 2 реле (планирую использовать в дальнейшем до 8 релюшик).

Был бы очень благодарен за помощь!

Здравствуйте, помогите новичку разобраться. Есть простейший Web сервер на плате Ethernet Shild W5100.

Хочу сделать, что бы при отключении питания сохранялся статус питания на реле (либо вкл. / либо выкл.), что бы при подаче питания состояния реле восстановились. Много гуглил, не могу понять как как правильно применить EEPROM.

Пока что 2 реле (планирую использовать в дальнейшем до 8 релюшик).

Был бы очень благодарен за помощь!

/*
  Ethernet Web Server
  Управление реле при нажатии кнопки on/off (вводе разных URL адресов) в браузере

  Адрес включения светодиода:
  IP-АДРЕС - тот IP, полученный при запуске примера DhcpAdressPrinter

  http://IP-АДРЕС/$1

  Для того, чтобы выключить:
  http://IP-АДРЕС/$2

  и так далее....
*/
#include <EEPROM.h>           //библиотека энергонезависимой памяти
#include <SPI.h>             //библиотека для работы с SPI
#include <Ethernet.h>        //библиотека для работы с Ethernet 
boolean newInfo = 0;        //переменная для новой информации
//MAC адрес вашего Ethernet-модуля, если его у вас нет, введите любой
//или оставьте тот, что в примере
byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDA, 0x02 };

//указываем IP адрес
//будьте внимательны! IP адрес указывается тот, который вы получили запустив пример DhcpAdressPrinter
IPAddress ip(192, 168, 1, 74); //пример МОЕГО IP адреса, вы вводите сюда СВОЙ

//инифиализация библиотеки Ethernet server library
EthernetServer server(80);


int i; //Для циклов for

void setup()
{
  pinMode(8, OUTPUT);       //инициализируем 8 пин как выход для реле
  pinMode(9, OUTPUT);       //инициализируем 9 пин как выход для реле


  //запускаем сервер с указанными ранее MAC и вашим IP
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.begin(9600);
}

void loop()
{

  //принимаем данные, посылаемые клиентом
  EthernetClient client = server.available();
  if (client) {                                     //если запрос оканчивается пустой строкой
    boolean currentLineIsBlank = true;                //ставим метку об окончании запроса (дословно: текущая линия чиста)
    while (client.connected()) {                      //пока есть соединение с клиентом
      if (client.available()) {                       //если клиент активен
        char c = client.read();                       //считываем посылаемую информацию в переменную "с"

        if (newInfo && c == ' ') {                    //если переменная новой информации = 1 и "с", в которой записан запрос, равен пустой строке
          newInfo = 0;                                //то обнуляем переменную поступления новой информации
        }

        if (c == '$') {                               //если переменная "с", несущая отправленный нам запрос, содержит символ $
          //(все новые запросы) - "$" подразумевает разделение получаемой информации (символов)
          newInfo = 1;                                //то пришла новая информация, ставим метку новой информации в 1
        }

        /************************************************************************************************
          Примечание:
          Символ $ используется как обычный символ, который разделяет 1 от 2  и так далее...
          На практике применяют символ &, который разделяет новые переменные от последующих
          Это использьуется, например, в GET-запросах, которые выглядят подобным образом:
          client.print("GET /controlbar/wp-content/data.php?uid=" + ID + "&type=" + type + "&value=" + value);
          как видите, знак & разделяет значение переменной - ID и переменную type
        ***************************************************************************************************/

        //Проверяем содержание URL - присутствует $1 или $2 Реле №1
        if (newInfo == 1) {                            //если есть новая информация
          Serial.println(c);
          if (c == '2') {                              //и "с" содержит 2
            Serial.println("ON");
            digitalWrite(8, HIGH);                    //гасим реле
          }

          if (c == '1') {                            //если "с" содержит 1
            Serial.println("OFF");
            digitalWrite(8, LOW);                     //то зажигаем реле
          }
        }


        //Проверяем содержание URL - присутствует $3 или $4 Реле №2
        if (newInfo == 1) {                            //если есть новая информация
          Serial.println(c);
          if (c == '4') {                            //и "с" содержит 4
            Serial.println("ON");
            digitalWrite(9, HIGH);                    //гасим реле
          }

          if (c == '3') {                            //если "с" содержит 3
            Serial.println("OFF");
            digitalWrite(9, LOW);                     //то зажигаем реле
          }
        }


        if (c == '\n') {                              //если "с" равен символу новой строки
          currentLineIsBlank = true;                  //то начинаем новую строку
        }
        else if (c != '\r') {                         //иначе, если "с" не равен символу возврата курсора на начало строки
          currentLineIsBlank = false;                 //то получаем символ на текущей строке
        }

        if (c == '\n' && currentLineIsBlank) {        //выводим HTML страницу

          // =============Формируем HTML-страницу=================================================
          client.println("HTTP/1.1 200 OK");          //заголовочная информация
          client.println("Content-Type: text/html; charset=utf-8");  //тип и кодировка страницы
          client.println("Connection: close");
          // client.println("Refresh: 30");              //автоматическое обновление каждые 30 сек
          client.println();
          client.println("<!DOCTYPE HTML>");          //HTML тип документа

          //==============Вывод значений на Web-страницу============================
          client.println("<html>");                   //открытие тега HTML
          client.print("<title>Arduino Web Server</title>");             //название страницы
          client.print("<H1>Управление освещением через Реле</H1>");     //заголовк на странице
          client.println("==============================");             //линия из символом =
          client.println("<br />");     //Переходим на новую строку
          // Далее идут кнопки...
          client.print("<div>Реле №1 (кухня)</div>");                   //надпись над кнопкой
          client.print("<a href=\"/$1\"><button>On</button></a>");       //кнопка включить  №1
          client.print("<a href=\"/$2\"><button>Off</button></a>");      //кнопка выключить №1
          client.println("<br />");       //Переходим на новую строку
          client.println("<br />");       //Переходим на новую строку

          client.print("<div>Реле №2 (Родительская комната)</div>");                   //надпись над кнопкой
          client.print("<a href=\"/$3\"><button>On</button></a>");       //кнопка включить  №2
          client.print("<a href=\"/$4\"><button>Off</button></a>");      //кнопка выключить №2
          client.println("<br />");      //Переходим на новую строку

          //Блок Таблицы зарезирвирован на НЗ.
          //          client.print("<table border=\"1\">");                           //создаём табличку
          //          client.print("<tr><th>Кухня</th><th>Зал</th></tr>");           //заголовки таблиц (жирным цветом)
          //          client.print("<tr><td>"); client.print("<a href=\"/$1\"><button>On</button></a>");  ("</td><td>");
          //          client.print("<tr><td>"); client.print("<a href=\"/$2\"><button>Off</button></a>"); ("</td><td>");
          //          client.print("</table>");                                      //закрывает табличку

          client.println("</html>");    //закрываем тег HTML
          break;                        //выход из цикла
        }

      }

    }
    delay(1);                                          //время на получение новых данных
    client.stop();                                     //закрываем соеднение
  }
}

 

gena
Offline
Зарегистрирован: 04.11.2012

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

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Вообще-то задача элементарна:

1. В setup() вставляете чтение из EEPROM и установку состояния реле.

2. В loop() в каждом месте, где меняете состояние реле, делаете запись а EEPROM.

 

Araris
Онлайн
Зарегистрирован: 09.11.2012

Otto, там всё проще, чем Вам кажется. Сначала читаете http://arduino.ru/Reference/Library/EEPROM и описание двух функций.

 Дальше идея такая :

1. Определяете две ячейки(адреса) памяти, например 1 и 2.

2. В моменты получения команд и переключения реле вставляете запись текущего состояния реле в определённую ему ячейку(адрес). То есть после 87-й строки вставляете EEPROM.write(1, 1);, после 92-й строки - EEPROM.write(1, 0);, ну и для второго реле (и адреса 2) аналогично сами  додумайте.

3. В функцию setup() после 44-й строки вставляете if ( EEPROM.read(1) ) {digitalWrite(8, HIGH);} else {digitalWrite(8, LOW);} для первого реле и if ( EEPROM.read(2) ) {digitalWrite(9, HIGH);else {digitalWrite(9, LOW);}. При самом первом запуске скетча из ячеек прочитаются 255, а после срабатывания строк из п.2 - значения, записанные скетчем.

Ну и всё, собственно.

Otto
Offline
Зарегистрирован: 26.06.2016

Araris пишет:

Otto, там всё проще, чем Вам кажется. Сначала читаете http://arduino.ru/Reference/Library/EEPROM и описание двух функций.

 Дальше идея такая :

1. Определяете две ячейки(адреса) памяти, например 1 и 2.

2. В моменты получения команд и переключения реле вставляете запись текущего состояния реле в определённую ему ячейку(адрес). То есть после 87-й строки вставляете EEPROM.write(1, 1);, после 92-й строки - EEPROM.write(1, 0);, ну и для второго реле (и адреса 2) аналогично сами  додумайте.

3. В функцию setup() после 44-й строки вставляете if ( EEPROM.read(1) ) {digitalWrite(8, HIGH);} else {digitalWrite(8, LOW);} для первого реле и if ( EEPROM.read(2) ) {digitalWrite(9, HIGH);else {digitalWrite(9, LOW);}. При самом первом запуске скетча из ячеек прочитаются 255, а после срабатывания строк из п.2 - значения, записанные скетчем.

Ну и всё, собственно.

Спасибо большое, то, что нужно! Я сколько читал на форумах, не мог понять смысл как работает и куда нужно вставлять код чтения/записи EEPROM. Посидел, разобрался в ваших пояснениях, всё получилось. Спасибо!)

Buzzer2010
Buzzer2010 аватар
Offline
Зарегистрирован: 10.03.2016

А вот вопрос. Продаются микросхемки такие  - паяются на шилд дисплея и тоже называются EEPROM. Их, интересно, можно вот так же использовать ? Или они не так называются, я уже забыл. Но то что это какая-то разновидность FLASH памяти, это я хорошо запомнил.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Buzzer2010 пишет:

А вот вопрос. Продаются микросхемки такие  - паяются на шилд дисплея и тоже называются EEPROM. Их, интересно, можно вот так же использовать ? Или они не так называются, я уже забыл. Но то что это какая-то разновидность FLASH памяти, это я хорошо запомнил.

Легко. На Али даже есть готовые модули под I2C, чтоб не парится: http://ru.aliexpress.com/item/1PCS-AT24C256-Serial-EEPROM-I2C-Interface-EEPROM-Data-Storage-Module-For-Arduino/32666835023.html?spm=2114.30010708.3.47.KAEUyX&ws_ab_test=searchweb201556_8,searchweb201602_3_10048_10037_10017_405_10046_507_10033_10045_10032,searchweb201603_1&btsid=ddbf5bfa-99b3-42d4-a043-875a41972640

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

Если у Вас не самая древняя IDE, то с EEPROM можно работать как с массивом:

byte a = 123;
...
EEPROM[12] = a; // Запись переменной a в EEPROM по адресу 12
...
a = EEPROM[10]; // Чтение из адреса 10 EEPROM в переменную a