Некорректно считываются данные из EEPROM при питании в пин 5v или vin

Тема в разделе "Arduino & Shields", создана пользователем vpalchik, 27 окт 2019.

Метки:
  1. vpalchik

    vpalchik Нуб

    Здравствуйте.
    Собираю контроллер для автоматического управления светом и дверкой по времени и температуре. Использую плату Nano 3.0 atmega 328P, датчик температуры DS18B20, энкодер для управления, lcd дисплей 1602, rtc DC1302 для хранения текущего времени, релейный модуль для включения света и сервопривод для открывания дверки.

    Настраивается время включения, выключения и температура. Эти данные записываются в eeprom. При старте программы данные считываются из eeprom, далее считывается текущее время, потом идут условия, определяющие что делать со светом и с дверкой. Настраивается все с дисплея с помощью прерываний и энкодера.

    После отладки программы все собрал в готовое устройство и столкнулся с такой проблемой. Если питать плату прямо в порт usb, то все работает отлично. Данный корректно считываются и все работает правильно. А если питать плату в порт vin, то некоторые данные считываются некорректно (считывается 1024). Тоже самое если питать плату в пин 5v. Перепробовал все:
    1) пробовал питать плату 5ти вольтовым блоком в пин 5v
    2) пробовал питать плату 6 вольтовым блоком в пин Vin
    3) пробовал питать плату лабораторником и в пин 5v и в пин Vin разными напряжениями
    Данные считываются корректно, только если питать плату в порт usb, не зависимо от компьютера или от блока питания. Сломал уже голову разбираясь с этой проблемой.

    Код. Код еще сырой, куча лишнего, но работает.
    Код (C++):
    void setup() {
      Serial.begin(9600);
      lcd.init();
      lcd.backlight();
      lcd.clear();

      Timer1.initialize(250);
      Timer1.attachInterrupt(timerInterrupt, 250);
      pinMode(relayPin, OUTPUT);
      pinMode(buttonSvet,INPUT_PULLUP);
      pinMode(buttonDverka,INPUT_PULLUP);
      kn = 0;
      chekSvet = 0;
      chekDverka = 1;

      digitalWrite (relayPin, HIGH);


      if (EEPROM.read(1023) != 5) {
        //Serial.println("Первый запуск");
        EEPROM.write(1023, 5);
        for (byte i = 0; i < 500; i ++) {
          EEPROM.write(i, 0);
        }
      }

      readEEPROM();

      time.begin();
      time.gettime();
      timeHours = time.Hours;
      timeMinutes = time.minutes;

    dverkaFunc ();
    detectTemperatureFirst();


    if (dverka == 1)
    {
    if (timeHours == hoursOn1 && timeMinutes >= minutesOn1 && chekDverka == 0 && timeHours <= hoursOff1 && temperature > minTemperature)
    {
      if (timeHours < hoursOff1) dverkaFunc ();
      if (timeHours == hoursOff1)
        {
          if (timeMinutes < minutesOff1) dverkaFunc ();
        }
    }
    if (timeHours > hoursOn1 && timeHours <= hoursOff1 && chekDverka == 0 && temperature > minTemperature)
      {
        if (timeHours < hoursOff1) dverkaFunc ();
        if (timeHours == hoursOff1)
        {
          if (timeMinutes < minutesOff1) dverkaFunc ();
        }
      }
      Serial.print("dverka ");
    Serial.println(chekDverka);

    }



    if (svet == 1)
    {
      if (timeHours == hoursOn && timeMinutes >= minutesOn && chekSvet == 0 && timeHours <= hoursOff)
      {
        if (timeHours < hoursOff) svetFunc ();
        if (timeHours == hoursOff)
        {
          if (timeMinutes < minutesOff) svetFunc ();
        }
      }
      if (timeHours > hoursOn && timeHours <= hoursOff && chekSvet == 0)
      {
        if (timeHours < hoursOff) svetFunc ();
        if (timeHours == hoursOff)
        {
          if (timeMinutes < minutesOff) svetFunc ();
        }
      }
    }


    Функция чтения из памяти и записи в память
    }
    Код (C++):
    void readEEPROM () {
    EEPROM.get(12, hoursOn);
    EEPROM.get(14, minutesOn);
    EEPROM.get(16, hoursOff);
    EEPROM.get(18, minutesOff);

    EEPROM.get(20, hoursOn1);
    EEPROM.get(22, minutesOn1);
    EEPROM.get(24, hoursOff1);
    EEPROM.get(26, minutesOff1);

    EEPROM.get(28, minTemperature);
    EEPROM.get(30, svet);
    EEPROM.get(31, dverka);
    }

    void updateEEPROM () {
    EEPROM.put(12, hoursOn);
    EEPROM.put(14, minutesOn);
    EEPROM.put(16, hoursOff);
    EEPROM.put(18, minutesOff);

    EEPROM.put(20, hoursOn1);
    EEPROM.put(22, minutesOn1);
    EEPROM.put(24, hoursOff1);
    EEPROM.put(26, minutesOff1);

    EEPROM.put(28, minTemperature);
    EEPROM.put(30, svet);
    EEPROM.put(31, dverka);
    }
     
    На крайний случай можно, конечно, питать плату от двух блоков питания. Одним питать плату в разъем usb, а вторым питать сервопривод, или же можно подпаяться к контактам на разъеме и питать плату одним блоком 5v, или больше, но питание на плату подавать через dc-dc преобразователь.

    Помогите советом, пожалуйста.
     
  2. DetSimen

    DetSimen Guest

    конденсаторы После БП навешай, электролит и керамику. На Vin нужно подавать >7.5 Вольт, иначе нутренний стабилизатор не работает
     
    Andrey12 нравится это.
  3. vpalchik

    vpalchik Нуб

    Конденсатор на 470 мкф поставил, не помогло. Керамики нет, но тоже попробую. С питанием по vin 6v ошибся изначально, потом переделал с dc dc преобразователем и питаю плату в пин 5v, а нагрузка идет напрямую от бп 6v
     
  4. parovoZZ

    parovoZZ Гуру

    блохастого не слушай - достаточно качественной керамики на 1 uF. Электролиты цифровой технике не работают - лишком высок ESR даже у самых дорогих.
     
    vpalchik нравится это.
  5. Asper Daffy

    Asper Daffy Иксперд

    Попробуй в начале (самой первой строкой) delay поставить, ну типа на 1 сек для разминки. И скажи поменялось ли что-нить.
     
    SergeiL нравится это.
  6. vpalchik

    vpalchik Нуб

    Это первое, что я попробовал. Толку нет. Проблему решил по другому. Поставил выпрямительный диод
     
  7. vpalchik

    vpalchik Нуб

    Проблему вроде решил. Начал разбираться в чем же разница между питанием через usb, и через пин 5v. Посмотрев принципиальную схему, понял что разница только в том, что по линии питания от usb стоит предохранитель на 500 мА и диод. Решил тоже поставить диод с выхода блока питания и на вход 5в. Диод поставил какой был (выпрямительный 4007). Проблема ушла. Поставил еще два керамических конденсатора на 0,1 мкФ. Вообщем, не совсем понял почему диод помог, но он помог. На данный момент все работает. Спасибо за советы!
     
  8. DetSimen

    DetSimen Guest

    скорей всего, не диод помог, а
     
  9. vpalchik

    vpalchik Нуб

    После установки только конденсаторов ничего не изменилось. А потом уже поставил диод
     
  10. DetSimen

    DetSimen Guest

    ну, значит, блохастого больше не слушай.
     
  11. Igor68

    Igor68 Гуру

    ...диод помог потому, как не позволил кратковременно просаживать питание после Vin на входе стабилизатора при включении нагрузок на этом самом Vin, а консднсаторы просто сгладили всплески при кратковременном повышении. Тут и ёжику понятно:)
     
    Последнее редактирование: 28 окт 2019
    Onkel нравится это.
  12. SergeiL

    SergeiL Оракул Модератор

    А я бы с задержки начал разбираться.
     
  13. parovoZZ

    parovoZZ Гуру

    Не ясен ход мысли: на диоде дополнительно теряем напряжение от 600 и до 1000 мВ.
     
  14. SergeiL

    SergeiL Оракул Модератор

    Проще все данные снести в структуру, и читать всю структуру целиком:
    Код (C++):
    // -------------------------------- EEPROM Data ------------------------
    typedef struct _eeprom_data_struct     // определяем структуру для хранения данных
    {
      uint8_t     Start_Counter;
      uint8_t     MQTT_Restart_Counter;
      uint8_t     Relay_Sate;
    } EEPROM_Data_Sruct;

    EEPROM_Data_Sruct   EEMEM   EEPROM_Data = {0,0,0};    // в EEPROM
    EEPROM_Data_Sruct           EEPROM_Data_RAM;          // те же данные в RAM

    void Load_EEPROM_Val(void)                  // вызывается из setup
    {
          EEPROM.get((uint16_t) &EEPROM_Data, EEPROM_Data_RAM);
         
          EEPROM_Data_RAM.Start_Counter ++;
           
          EEPROM.put((uint16_t) &EEPROM_Data,EEPROM_Data_RAM);

    }
     
     
  15. vpalchik

    vpalchik Нуб

    За
    Я и начал с задержки. Ставил задержку и перед началом чтения из eeprom и после чтения, но толку не было. И убирал вообще все из setup и оставлял только чтениt из памяти, все без результата
     
  16. vpalchik

    vpalchik Нуб

    Согласен. Так более правильно
     
  17. Igor68

    Igor68 Гуру

    Думаю выпимшего, как и блохастого не слушать надо.
     
  18. Asper Daffy

    Asper Daffy Иксперд

    Вы не поняли смысла этой задержки. Её надо ставить не перед чтением, а первой командой в сетап - перед всем остальным
     
  19. vpalchik

    vpalchik Нуб

    Вот тут вы правы. На диоде потерялись 0,4 В. Напряжение на входе в ардуино получилось 4.6 В. И при этом все работает нормально. Поднял напряжение до 5 вольт и опять начались проблемы, опускаю до 4,6 - становится нормально
     
  20. vpalchik

    vpalchik Нуб

    Да. Действительно не так понял. Попробую поставить задержку первой строкой в setup.