• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

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

CodeNameHawk

Moderator
Команда форума
Так по нажатию кнопки-то не работает...(
Я бы описал вопрос так :
Есть такая схема..., которая питается от...
В есп залит такой скетч.
Если есть внешний сервер, то он присылает то то и то то....
При нажатии на кнопку есп в сериал выдает такую отладочную информацию, а мне кажется, что она должна быть такой...
 

CodeNameHawk

Moderator
Команда форума
В правильном устройстве такие зависимости снимают в лабораторных условиях и прописывают их во флеш
Если вас почитать, то телевизор с функцией запоминания последнего канала неправильное устройство.
Поэтому калибровку либо делаем на стадии изготовления устройства либо грузим по воздуху
Можно и по воздуху, но намного удобней посмотреть на индикаторе и внести нужную калибровку в память.
через интерфейс в процессе эксплуатации устройства
Так это он и пытается сделать.
 
Последнее редактирование:

SPAX

Member
Вроде победил, но как-то топорно мне кажется....

Если изначально чистая ЕСП, то сыпятся ошибки оно и понятно, т.к. в памяти нет значений MIN_SENS и MAX_SENS...как только пропишешь кнопкой эти значения, то всё работает, но мне кажется это не правильно как-то....

Можете посмотреть, как этот код вообще на правильность написан?

Код:
#define BLYNK_PRINT Serial


#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#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 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.get(0, MIN_SENS);
    EEPROM.get(4, MAX_SENS);
    EEPROM.end();
  }
    

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

void pressVButton_Min() {
    EEPROM.begin(8);
    MIN_SENS = analogRead(SENS_HUM);
    EEPROM.put(0, MIN_SENS);
    EEPROM.end();
    delay(50);
}

BLYNK_WRITE(But_Min){
  int pinValue = param.asInt();
  Serial.print("But_Min: ");
  Serial.println(pinValue); 
  if(pinValue == 1) {
    pressVButton_Min();
    }
 }
 
void pressVButton_Max() {
    EEPROM.begin(8);
    MAX_SENS = analogRead(SENS_HUM);
    EEPROM.put(4, MAX_SENS);
    EEPROM.end();
    delay(50);
}
 
BLYNK_WRITE(But_Max){
  int pinValue2 = param.asInt();
  Serial.print("But_Max: ");
  Serial.println(pinValue2); 
  if(pinValue2 == 1) {
    pressVButton_Max();
    }
 }

void sendSensor()
{
 
  byte data1[2];
 
  ds1.reset();
  ds1.write(0xCC);
  ds1.write(0x44);
      
  Blynk.virtualWrite(V5, tempPol);
  Blynk.virtualWrite(V8, humOut);
    
// Читаем данные с 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);

// Выводим показания в монитор порта
    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(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()
{
  if (Blynk.connected()){ Blynk.run();}
  timer.run();
}
 

CodeNameHawk

Moderator
Команда форума
Если изначально чистая ЕСП, то сыпятся ошибки оно и понятно, т.к. в памяти нет значений MIN_SENS и MAX_SENS...как только пропишешь кнопкой эти значения, то всё работает, но мне кажется это не правильно как-то....
Ну так нужна проверка того, что считали с еепром и если MIN_SENS и MAX_SENS равны нулю или вы точно знаете, что они не правильны, заменяете на правильные значения. Это например когда MIN_SENS больше MAX_SENS.
Это вам и советовал nikolz.

Если изначально чистая ЕСП, то сыпятся ошибки оно и понятно, т.к. в памяти нет значений MIN_SENS и MAX_SENS...
Это про то, что я и говорил, если бы добавили вывод отладочной информации о том, что считали с еепром, то давно бы победили этот код.
 

SPAX

Member
Ну так нужна проверка того, что считали с еепром и если MIN_SENS и MAX_SENS равны нулю или вы точно знаете, что они не правильны, заменяете на правильные значения. Это например когда MIN_SENS больше MAX_SENS.
Получилось)
Могли бы вы весь код глянуть на наличие каких-нибудь недочётов?

Код:
#define BLYNK_PRINT Serial


#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#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 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.get(0, MIN_SENS);
    EEPROM.get(4, MAX_SENS);
    if(int16_t(MIN_SENS) == 0)
    {
      EEPROM.begin(8);
      MIN_SENS = 480;
      EEPROM.put(0, MIN_SENS);
      EEPROM.end();
    }
    if(int16_t(MAX_SENS) == 0)
    {
      EEPROM.begin(8);
      MAX_SENS = 210;
      EEPROM.put(4, MAX_SENS);
      EEPROM.end();
    }
    EEPROM.end();
  }
    

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

void pressVButton_Min() {
    EEPROM.begin(8);
    MIN_SENS = analogRead(SENS_HUM);
    EEPROM.put(0, MIN_SENS);
    EEPROM.end();
    delay(50);
}

BLYNK_WRITE(But_Min){
  int pinValue = param.asInt();
  Serial.print("But_Min: ");
  Serial.println(pinValue);
  if(pinValue == 1) {
    pressVButton_Min();
    }
 }
 
void pressVButton_Max() {
    EEPROM.begin(8);
    MAX_SENS = analogRead(SENS_HUM);
    EEPROM.put(4, MAX_SENS);
    EEPROM.end();
    delay(50);
}
 
BLYNK_WRITE(But_Max){
  int pinValue2 = param.asInt();
  Serial.print("But_Max: ");
  Serial.println(pinValue2);
  if(pinValue2 == 1) {
    pressVButton_Max();
    }
 }

void sendSensor()
{
 
  byte data1[2];
 
  ds1.reset();
  ds1.write(0xCC);
  ds1.write(0x44);
      
  Blynk.virtualWrite(V5, tempPol);
  Blynk.virtualWrite(V8, humOut);
    
// Читаем данные с 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);

// Выводим показания в монитор порта
    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(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()
{
  if (Blynk.connected()){ Blynk.run();}
  timer.run();
}

22:02:27.241 -> [2119]
22:02:27.275 -> ___ __ __
22:02:27.275 -> / _ )/ /_ _____ / /__
22:02:27.309 -> / _ / / // / _ \/ '_/
22:02:27.342 -> /____/_/\_, /_//_/_/\_\
22:02:27.376 -> /___/ v0.6.1 on NodeMCU
22:02:27.410 ->
22:02:27.410 -> [2168] Connecting to 192.168.1.17
22:02:27.444 -> [2256] Ready (ping: 17ms).
22:02:27.478 -> [2323] Reconnected
22:02:29.007 -> tempPol:27.38
22:02:29.007 -> humIn:442
22:02:29.007 -> MIN_SENS:476.00
22:02:29.041 -> MAX_SENS:229.00
22:02:29.041 -> humOut:14
 

nikolz

Well-known member
в качестве совета, есть параметр wifi, не знаю как он называется в ардуино потому что пишу на СИ и SDK
его установка в 1 включает автоматическое восстановление соединения в случае разрыва.
т е можно выкинуть то что вы нагородили с реконектом.
 

SPAX

Member
в качестве совета, есть параметр wifi, не знаю как он называется в ардуино потому что пишу на СИ и SDK
его установка в 1 включает автоматическое восстановление соединения в случае разрыва.
т е можно выкинуть то что вы нагородили с реконектом.
На сколько я помню, данный параметр повешает всю плату на переподключение, и будет до посинения искать коннект, пока он не найдется, тем самым повесит весь код...
Та функция, которая расписана у меня, не даёт повешаться основному коду, т.к. реконнект будет искаться только через заданные промежутки времени...(например 3 мин)
 

CodeNameHawk

Moderator
Команда форума
void setupAddrEEPROM()
{
EEPROM.begin(8);
EEPROM.get(0, MIN_SENS);
EEPROM.get(4, MAX_SENS);
if(int16_t(MIN_SENS) == 0)
{
EEPROM.begin(8);
MIN_SENS = 480;
EEPROM.put(0, MIN_SENS);
EEPROM.end();
}
if(int16_t(MAX_SENS) == 0)
{
EEPROM.begin(8); MAX_SENS = 210;
EEPROM.put(4, MAX_SENS);
EEPROM.end();
}
EEPROM.end(); }
После EEPROM.begin должно гарантированно наступить EEPROM.end , у вас же если будет ошибка, два раза подряд поступит EEPROM.begin
Попробуйте так
Код:
void setupAddrEEPROM()
{
EEPROM.begin(8);
EEPROM.get(0, MIN_SENS);
EEPROM.get(4, MAX_SENS);
EEPROM.end();
if(int16_t(MIN_SENS) == 0)
{
EEPROM.begin(8);
MIN_SENS = 480;
EEPROM.put(0, MIN_SENS);
EEPROM.end();
}
if(int16_t(MAX_SENS) == 0)
{
EEPROM.begin(8);
MAX_SENS = 210;
EEPROM.put(4, MAX_SENS);
EEPROM.end();
}
}
Есть функции WiFi.AutoConnect, WiFi.AutoReconect

И у вас MIN_SENS = 480; MAX_SENS = 210; так задумано?
 

SPAX

Member
После EEPROM.begin должно гарантированно наступить EEPROM.end , у вас же если будет ошибка, два раза подряд поступит EEPROM.begin
Понял, спасибо, исправил.
И у вас MIN_SENS = 480; MAX_SENS = 210; так задумано?
Да, это просто значения датчика на воздухе и в руке. Чтоб хоть какие-то примерные цифры записались....
 
Сверху Снизу