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

NodeMCU v3 + Blynk, проблема с EEPROM

CodeNameHawk

Moderator
Команда форума
так а зачем доп прога была нужна?
Сделать сброс есп, послать ей данные на сом порт, просто удобней, например перенос по строкам, видны спец. символы.
Когда ардуино иде занято заливкой по ОТА, просмотр лога, через СОМ порт.
 

SPAX

Member
Дальше все проще добавляете нужную строку, если надо добавляете вывод используемых переменных и смотрите работает ли.
А что конкретно то добавить? я и так уже, вроде, удалил всё лишнее, оставил только еепром, и чтение датчика....
Вы можете просто поправить мой код, чтоб оно работало?
Код:
#include <OneWire.h>
#include <Wire.h>

//датчик температуры пола DS18B20
#define DS         D6               //объявляем пин датчика температуры пола DS18B20 как GPIO 12 (D6)
OneWire  ds1(DS);
float tempPol  = 99.0;              // Текущие показания от датчика теплого пола ds18b20

// датчик влажн почвы
#define SENS_HUM A0                 //объявляем пин датчика влажн почвы как GPIO 17 (A0)
#define But_Min D7                  //Виртуальная кнопка колибровки Min значения влажности почвы
#define But_Max D8                 //Виртуальная кнопка колибровки Max значения влажности почвы

// датчик влажн почвы
int32_t humIn;                      // Читаем показания датчика влажности почвы Аналоговый вход
int32_t humOut;                     // Оброботанные показания от датчика влажности почвы 0-100%
float MIN_SENS = 480;               // Калибровка 0%
float MAX_SENS = 210;               // Калибровка 100%


////////////////////////EEPROM//////////////////////////////////////////////////////////
#include <EEPROM.h>
//#include "EEPROMAnything.h"

void setupAddrEEPROM(){

    EEPROM.begin(8);
    //EEPROM_readAnything(0, MIN_SENS);
    //EEPROM_readAnything(4, MAX_SENS);
    EEPROM.get(0, MIN_SENS);
    EEPROM.get(4, MAX_SENS);
    EEPROM.end();

}
   
////////////////////////EEPROM-END//////////////////////////////////////////////////////

void sendSensor()
{

  byte data1[2];

  ds1.reset();
  ds1.write(0xCC);
  ds1.write(0x44);

// Читаем данные с ds18b20
    ds1.reset();
    ds1.write(0xCC);
    ds1.write(0xBE);
    data1[0] = ds1.read();
    data1[1] = ds1.read();
    tempPol = ((data1[1] << 8) | data1[0]) * 0.0625;
// Выводим показания в монитор порта
    Serial.print("tempPol:");
    Serial.println(tempPol);

// Читаем показания датчика влажности почвы
    humIn = analogRead(SENS_HUM);
       
// Обрабатываем показания и представляем в виде от 0 до 100
   humOut = map(humIn, int32_t(MIN_SENS), int32_t(MAX_SENS), 0, 100);
   //humOut = map(humIn, 480, 210, 0, 100);
// Выводим показания в монитор порта
    Serial.print("humIn:");
    Serial.println(humIn);
    Serial.print("MIN_SENS:");  
    Serial.println(MIN_SENS);
    Serial.print("MAX_SENS:");  
    Serial.println(MAX_SENS);
    Serial.print("humOut:");  
    Serial.println(humOut);
   
}

void setup()
{

// Debug console
  Serial.begin(9600);
   
// Загружаем данные из EEPROM
  setupAddrEEPROM();
  delay(1000);

// Инициализация PIN-ов Arduino
  pinMode(SENS_HUM, INPUT);
  delay(50);
     
// Инициализация датчика OneWire для DS18B20
  Wire.begin();
  delay(50);

}

void loop()
{

if( digitalRead(But_Min) == HIGH  )
{
    EEPROM.begin(8);
    //EEPROM_writeAnything(0, MIN_SENS);
    EEPROM.put(0, MIN_SENS);
    EEPROM.end();
    delay(50);
}
if( digitalRead(But_Max) == HIGH  )
{
    EEPROM.begin(8);
    //EEPROM_writeAnything(4, MAX_SENS);
    EEPROM.put(4, MAX_SENS);
    EEPROM.end();
    delay(50);
}    
   
sendSensor();

}
 

SPAX

Member
Опа, что то получилось....
добавил пару строк
EEPROM.put(0, MIN_SENS);
EEPROM.put(4, MAX_SENS);
В void setupAddrEEPROM(){
и заработало, НО не пишет в память по нажатию кнопок в блинке((

Код:
#define BLYNK_PRINT Serial


#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <OneWire.h>
#include <Wire.h>

//  период чтения датчиков не менее 2сек(2000UL)
//#define READ_DATA  2000UL
//uint32_t ms;      // Текущее время в милисекундах

//датчик температуры пола DS18B20
#define DS         D6               //объявляем пин датчика температуры пола DS18B20 как GPIO 12 (D6)
OneWire  ds1(DS);
float tempPol  = 99.0;              // Текущие показания от датчика теплого пола ds18b20

// датчик влажн почвы
#define SENS_HUM A0                 //объявляем пин датчика влажн почвы как GPIO 17 (A0)
#define But_Min V9                  //Виртуальная кнопка колибровки Min значения влажности почвы
#define But_Max V10                 //Виртуальная кнопка колибровки Max значения влажности почвы

// датчик влажн почвы
int16_t humIn;                      // Читаем показания датчика влажности почвы Аналоговый вход
int16_t humOut;                     // Оброботанные показания от датчика влажности почвы 0-100%
float MIN_SENS = 480;               // Калибровка 0%
float MAX_SENS = 210;               // Калибровка 100%


BlynkTimer timer;

////////////////////////////CONNECT////////////////////////////////////////////////
#define USE_LOCAL_SERVER

#ifdef USE_LOCAL_SERVER
      #define SERVER IPAddress(192, 168, 1, 17) // Свой IP пишите
      
#endif

/*
   Wifi Credentials
*/

#define WIFI_SSID               "***"  //Имя точки доступа WIFI VVK   AndroidAP
#define WIFI_PASS               "***" //пароль точки доступа WIFI vtb24admin 1234567890

/*
     Blynk Auth Code
*/
#define AUTH                      "***"


///////////////////////////////////////////////////////
//          Функции для подключения к Blynk          //

void ConnectBlynk()
{
  //*******************************************************
  // Запускаем WiFi
    if (WiFi.status() != WL_CONNECTED)// Если нет WiFi, то коннектимся
    {
      BLYNK_LOG(WIFI_SSID);
      
      WiFi.begin(WIFI_SSID, WIFI_PASS);

      int8_t count=0;
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
        Serial.print(WiFi.status());
        count++;
        if (count >= 5){break;Serial.println("WiFi not connected");}
      }
    }
  /*  Дисконект - для справки
    WiFi.disconnect(); // отключаемся от сети
    Serial.println("Disconnect WiFi.");
  */
 
  //*******************************************************
  // Запускаем Blynk

  if (WiFi.status() == WL_CONNECTED)// Если нет WiFi, то не коннектимся
    {
          // CONNECT TO BLYNK
          #ifdef USE_LOCAL_SERVER // Если используются локальный сервер
            Blynk.config(AUTH, SERVER, 8080);
            Blynk.connect();
          #else // Иначе конектимся постаринке к блинку
            Blynk.config(AUTH);
            Blynk.connect();
          #endif
    }

 
  // До бесконечности будем оставаться в цикле while
  // пока не установим связь с сервером
  //  while (Blynk.connect() == false) {}
 
}//ConnectBlynk()


// Реконектимся если обрыв связи
void reconnectBlynk() {
  if (!Blynk.connected())
  {
    BLYNK_LOG("Disconnected now");
    ConnectBlynk();
    if (Blynk.connected())
    {
      BLYNK_LOG("Reconnected");     
    }
    else
    {
      BLYNK_LOG("Not reconnected");     
    }
  }
}
////////////////////////////CONNECT-END//////////////////////////////////////////////////

////////////////////////EEPROM//////////////////////////////////////////////////////////
#include <EEPROM.h>
//

void setupAddrEEPROM(){
 
    EEPROM.begin(8);
    EEPROM.put(0, MIN_SENS);
    EEPROM.put(4, MAX_SENS);
    EEPROM.get(0, MIN_SENS);
    EEPROM.get(4, MAX_SENS);
    EEPROM.end();
 
}
    

////////////////////////EEPROM-END//////////////////////////////////////////////////////

void sendSensor()
{
 // static uint32_t msDHT = 0;
 
  byte data1[2];
 
  ds1.reset();
  ds1.write(0xCC);
  ds1.write(0x44);
 
//  if (ms - msDHT >= READ_DATA)
//  {
    
  Blynk.virtualWrite(V5, tempPol);
  Blynk.virtualWrite(V8, humOut);

  //Blynk.virtualWrite(But_Min, HIGH);
  //Blynk.virtualWrite(But_Max, HIGH);

 
// Читаем данные с ds18b20
    ds1.reset();
    ds1.write(0xCC);
    ds1.write(0xBE);
    data1[0] = ds1.read();
    data1[1] = ds1.read();
    tempPol = ((data1[1] << 8) | data1[0]) * 0.0625;
// Выводим показания в монитор порта
    Serial.print("tempPol:");
    Serial.println(tempPol);

// Читаем показания датчика влажности почвы
    humIn = analogRead(SENS_HUM);
        
// Обрабатываем показания и представляем в виде от 0 до 100
   humOut = map(humIn, int16_t(MIN_SENS), int16_t(MAX_SENS), 0, 100);
   //humOut = map(humIn, 480, 210, 0, 100);
// Выводим показания в монитор порта
    Serial.print("humIn:");
    Serial.println(humIn);
    Serial.print("MIN_SENS:");   
    Serial.println(MIN_SENS);
    Serial.print("MAX_SENS:");   
    Serial.println(MAX_SENS);
    Serial.print("humOut:");   
    Serial.println(humOut);
    

 //   msDHT = ms;
//  }
}

void setup()
{

// Debug console
  Serial.begin(9600);
    
// Загружаем данные из EEPROM
  setupAddrEEPROM();
  delay(2000); 
 
// Инициализация PIN-ов Arduino
  pinMode(SENS_HUM, INPUT);
  delay(50);
 
// Вызываем функцию подключения к Blynk
   reconnectBlynk();   

// Задаем интервальные таймеры
   timer.setInterval(30000, reconnectBlynk); // Проверяем есть ли связь с сервером

   timer.setInterval(1500L, sendSensor);
    
// Инициализация датчика OneWire для DS18B20
  Wire.begin();
  delay(50);
 
}

void loop()
{
  //ms = millis();
 
if( digitalRead(But_Min) == HIGH  )
 {
    EEPROM.begin(8);
    EEPROM.put(0, MIN_SENS);
    EEPROM.end();
    delay(50);
 }
 if( digitalRead(But_Max) == HIGH  )
 {
    EEPROM.begin(8);
    EEPROM.put(4, MAX_SENS);
    EEPROM.end();
    delay(50);
 }     
    
 // sendSensor();
  if (Blynk.connected()){ Blynk.run();}
  timer.run();
}
 

SPAX

Member
Дружище здесь не раздают рыбу, здесь раздают удочки :)
Это хорошо, осталось дело за малым) и пнуть в нужную сторону)
Сейчас запарка на записи в еепром по нажатию конпки в приложении блинк...когда нажимаю, ничего не происходить, запись в еепром не менятеся..
 

CodeNameHawk

Moderator
Команда форума
А что конкретно то добавить?
Я предлагал добавить вывод в серял значений переменных, то что записываете в епппром, для того, что бы проверить, работает ли сохранение в еппром.
добавил пару строк
EEPROM.put(0, MIN_SENS);
EEPROM.put(4, MAX_SENS);
В void setupAddrEEPROM(){
советую называть функцию со смыслом, какой тут сетуп адрес?
Я бы назвал ReadMinMaxFromEpprom.
void setupAddrEEPROM(){ EEPROM.begin(8); EEPROM.put(0, MIN_SENS); EEPROM.put(4, MAX_SENS); EEPROM.get(0, MIN_SENS); EEPROM.get(4, MAX_SENS); EEPROM.end(); }
Я слабо что понимаю в программировании, объясните мне, для чего вы после записи, сразу читаете из нее, ведь, как известно, нужно время, для того, что бы запись завершилась и только тогда из нее можно читать.
Это хорошо, осталось дело за малым) и пнуть в нужную сторону)
Тут надо видеть конкретно, где вы находитесь.
 

nikolz

Well-known member
предположу что EEPROM вообще не требуется.
Возможно чел думает что если не сохранить,
то исчезнет (например, приняли в регистр и при выходе из функции регистр затрется.
Вот и пытается чел куда-то еще записать)
 

SPAX

Member
Я предлагал добавить вывод в серял значений переменных, то что записываете в епппром, для того, что бы проверить, работает ли сохранение в еппром.
Так выводится же... вот всегда было в коде...
Код:
    Serial.print("MIN_SENS:");   
    Serial.println(MIN_SENS);
    Serial.print("MAX_SENS:");   
    Serial.println(MAX_SENS);
Я слабо что понимаю в программировании, объясните мне, для чего вы после записи, сразу читаете из нее, ведь, как известно, нужно время, для того, что бы запись завершилась и только тогда из нее можно читать.
Ну так я вчера добавил запись и заработало, до этого скетч не работал без предварительной записи....

Тут надо видеть конкретно, где вы находитесь.
На данный момент запарка в записи при нажатии кнопки...запись не происходит...

предположу что EEPROM вообще не требуется.
как не нужен то? При обрыве питания у меня все значения полетят же...и потом заново калибровать придётся...или я не прав?
 

nikolz

Well-known member
Возможно это поможет вариант
Для работы с Blynk пример №9
Если Вы про настройки логина и пароля для wifi, то они записываются во флеш и при новом старте их не надо вводить снова.
-------------------------
Что же касается других параметров, которые зависят от внешних датчиков,
то, когда у вас отключится питание, состояние внешних устройств будет одно,
а когда питание включится то состояние будет другое.
--------------------
Поэтому если вы что-то и запомнили, то где гарантия , что внешние устройства у вас не изменили свое состояние
после аварийного отключения и включения питания?
Гарантии нет никакой.
-------------------------
Поэтому в правильных устройствах не начинают работу с того момента когда было питание,
а при включении питания считывают новые показания устройств и начинают работу как первый раз в первый класс.
---------------------------------
Т е не надо надеяться что после смерти в новой жизни ваше устройство начнет с того места где оно умерло в прошлой жизни.
--------------------------
Всегда надо начинать как заново рожденное.
Тогда не будет сюрпризов типа "Вы думали что газ выключили, а он включен, а горелка потухла."
И вдруг - бабах и кирдык вашему дому.
 

CodeNameHawk

Moderator
Команда форума
Так выводится же... вот всегда было в коде...
Лыжи надо мазать сильнее.
Код:
    EEPROM.begin(8);
    EEPROM.get(0, MIN_SENS);
    EEPROM.get(4, MAX_SENS);
    EEPROM.end();
Вот вы прочитали значения с еппром, как вы можете сказать что в MIN_SENS, MAX_SENS, а то что там где то в коде есть вывод фигня, переменные уже пару раз могли поменяться.
 

CodeNameHawk

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

nikolz

Well-known member
Нормально работает сохранение параметров, если надо, проверяется на правильность считывания и нахождения в заданных пределах. И процедуры безопасности могут работать постоянно и проверять критически важные параметры работы.
Все допустимые диапазоны изменения параметров известны изначально и записываются в виде констант в программу.
многие датчики например DS позволяют записать диапазон в них и не требуют перезаписи при отключении питания.
Я же написал про правильные устройства, т е те, при разработке которых разработчик четко понимает что и как будет работать и чем он будет управлять.
есть еще неправильные - это как правило такие, которые делают не программисты , а аля-кулибины.
 

SPAX

Member
то, когда у вас отключится питание, состояние внешних устройств будет одно,
а когда питание включится то состояние будет другое.
В моём случае, какое было состояние датчика ДО выключения питания, такое оно и останется и значение не поменяется...(я про ёмкостной датчик влажности почвы)
 

CodeNameHawk

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

SPAX

Member
Не всегда, диапазон выходных напряжений того же емкостного датчика зависит не только от уровня влажности, но и от земли в которую он вставлен. Сделать калибровку для новых условий вполне адекватное решение.
Абсолютно верно.
Но что-то меня утомило уже этот ЕЕПРОМ, что склоняюсь уже сделать фиксированные значения и забить(..... простейший скетч уже месяц не могу сделать...
 

nikolz

Well-known member
Не всегда, диапазон выходных напряжений того же емкостного датчика зависит не только от уровня влажности, но и от земли в которую он вставлен. Сделать калибровку для новых условий вполне адекватное решение.
не возражаю,
но калибровка делается путем получения функциональной зависимости показаний датчика от значения заведомо известной влажности почвы
при этом разные виды почвы дадут разные зависимости
В итоге зависимость будет в виде таблицы
В правильном устройстве такие зависимости снимают в лабораторных условиях и прописывают их во флеш
Поэтому калибровку либо делаем на стадии изготовления устройства либо грузим по воздуху или через интерфейс в процессе эксплуатации устройства
Но для такого случая лучше и проще использовать файловую систему
и писать такие таблицы в файлы
----------------
Но я что-то сомневаюсь, что чел который не разбирается в программировании разбирается в метрологии и построении табличных функций
-------------
Как я понял чел хочет записать одно-два значения , не для калибровки, а непонятно зачем.
 
Сверху Снизу