Не сохраняет в EEPROM

Sascha69
Offline
Зарегистрирован: 24.11.2019
#include <EEPROM.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 6, 9, 8, 7);
byte sensorInterrupt = 0;          // 0 = digital pin 2
byte sensorPin       = 2;
float calibrationFactor = 4.5;    //калибровочное число с паспорта датчика протока
volatile byte pulseCount;         //счетчик импульсов
float flowRate;                          //расход
unsigned int flowMilliLitres;      //поток
unsigned long totalMilliLitres;   //общее количество
unsigned long oldTime;            // время

int address = 0;
byte value;

void setup()
{
  pinMode(sensorPin, INPUT);
  digitalWrite(sensorPin, HIGH);//высокий уровень
  lcd.begin (16, 2);
  pulseCount      = 0;
  flowRate          = 0.0;
  flowMilliLitres   = 0;
  totalMilliLitres   = 0;
  oldTime            = 0;
  attachInterrupt(sensorInterrupt, pulseCounter, FALLING);       //падающий
}
void loop()
{
  if ((millis() - oldTime) > 1000)           //  счетчик обрабатывать один раз в секунду
  {
    detachInterrupt(sensorInterrupt);
    flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
    oldTime = millis();
    flowMilliLitres = (flowRate / 60) * 1000;
    totalMilliLitres += flowMilliLitres;
    unsigned int frac;//скорость потока
    frac = (flowRate - int(flowRate)) * 10;//скорость потока за эту секунду в литрах / минуту
 

    value = (totalMilliLitres/1000);
    EEPROM.update(0, value);
    value = EEPROM.read(0);     // Считываем значение байта
    delay(100);


    lcd.clear ();
    lcd.setCursor (0, 0);
    lcd.print (int(flowRate));
    lcd.print (".");
    lcd.print (frac, DEC) ;
    lcd.print ("L/min");
    lcd.setCursor (0, 1);
    lcd.print (totalMilliLitres);
    lcd.print ("mL");
    lcd.setCursor (10, 1);
    lcd.print (value, DEC);
    lcd.print ("L");
   

   
    pulseCount = 0;
    attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
  }
}
void pulseCounter()
{
  pulseCount++;
}

 

Sascha69
Offline
Зарегистрирован: 24.11.2019

Здравствуйте. Что прописал не так, прошу помощи ,не могу разобраться как сохранять в eeprom update . Это датчик протока подключен на 2-й пин, UNO, лсд 16х2, в целом все работает, кроме сохранения в eeprom. На нарекания не обижусь, это первые мои азы, буду рад всему. Спасибо.

sadman41
Offline
Зарегистрирован: 19.10.2016

Как определили, что не работает? Как ардуину зовут?

Sascha69
Offline
Зарегистрирован: 24.11.2019

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

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

наверно считать EEPROM в сетапе и вывести на лсд там же

sadman41
Offline
Зарегистрирован: 19.10.2016

Ну, подумайте чему будет равна value и связанные с ней переменные после каждого передерга питания.

Sascha69
Offline
Зарегистрирован: 24.11.2019
41     value = (totalMilliLitres/1000);
42     EEPROM.update(0, value);
43     value = EEPROM.read(0);     // Считываем значение байта
44     delay(100);

Вот как я понимаю, ст.41 присваиваем значению value показания в литрах, ст.42 записываем по адресу в нулевой ячейке значение value если оно изменилось, ст.43 считываем данные с нулевой ячейки и присваиваем value, ст.44 задержка. Ст.57 выводим значение value в литрах в лсд.

sadman41
Offline
Зарегистрирован: 19.10.2016

Дальше что... питание передернули, что в стр. 41 нарисовалось?

Sascha69
Offline
Зарегистрирован: 24.11.2019

По всей видимости "0", ответ дал интуитивно так как вижу это на лсд, думаю, что наверное должна бы при правильном написании скеча произойти запись в eeprom перед выключением.

sadman41
Offline
Зарегистрирован: 19.10.2016

Зайдем с другой стороны. У Вас есть яблоко, которое Вы держали в руке и, затем, положили в корзину. Каким образом это яблоко может снова оказаться в руке?

Sascha69
Offline
Зарегистрирован: 24.11.2019

Мне нужно снова взять яблоко с корзины, но ведь мы производим считывание с присвоением, я могу ошибаться, но что то мне подсказывает ,что нужно сначала сделать запись типа так, EEPROM.put (0,value); и так как это нам нужно сделать всего лишь один раз , пишим в setup.

sadman41
Offline
Зарегистрирован: 19.10.2016

Продолжаем с яблоками. Яблоко остается Вашим, пока за ним следите или в запертой корзине. Ночью за яблоком никто не следит и его ворует, положим, Клапауций. Задача: держать утром в руке "вечернее" яблоко. Справитесь?

Если да, то вот аналогия: яблоко - ваши литры, корзина - ееprom, утро - setup(), вечер - loop(), ночь - отключение питания микроконтроллера.

Sascha69
Offline
Зарегистрирован: 24.11.2019

Не справился, перепробовал все не догоняю....

на сколько понял ,нужно считать, присвоить, записать и потом update, но ...

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

пост 4

Sascha69
Offline
Зарегистрирован: 24.11.2019

пробовал не ...

я думаю нужно правильно понять алгоритм и приоритет действий, но вот здесь и проблема. 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Sascha69 пишет:

пробовал не ...

не может быть

value = EEPROM.read(0);  
lcd.setCursor (10, 1);
lcd.print (value, DEC);

последними строчками в setup
и что показывает?

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Это ничего не даст, не та переменная.

Sascha69
Offline
Зарегистрирован: 24.11.2019

при  начале перезагрузке показание остается, а при включении сбрасывается на ноль.  

Sascha69
Offline
Зарегистрирован: 24.11.2019

sadman41

Если еще есть силы, продолжим ребусы с яблоком, прошу подсказку.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

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

sadman41
Offline
Зарегистрирован: 19.10.2016

Это не ребус.

Я не знаю, на чем еще объяснять. Лучше Вы мне объясните, зачем считываете сразу после записи.

Sascha69
Offline
Зарегистрирован: 24.11.2019

Не нужно покупать новую тетрадь, нужно взять ту в которую писал вечером. Извините не успеваю и скечь править и отписываться 

Sascha69
Offline
Зарегистрирован: 24.11.2019

sadman41 пишет:

Это не ребус.

Я не знаю, на чем еще объяснять. Лучше Вы мне объясните, зачем считываете сразу после записи.

пост 12 считать , присвоить , записать, заменить. Как бы так, но не получается .

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
#include <EEPROM.h>// купил терадь
const int adr = 0;
void setup() {
  Serial.begin(9600);
  int value = EEPROM.read(adr);// посмотрел запись
  Serial.println(value);
  for (int i = 0; i < 255; i++) {
    EEPROM.write(adr, i); //записал новую запись
    delay(500);// подождал пол секунды
    int value = EEPROM.read(adr);
    Serial.println(value);// посмотрел запись
  }

}

void loop() {

}

запусти и посмотри. 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Sascha69 пишет:

sadman41 пишет:

Это не ребус.

Я не знаю, на чем еще объяснять. Лучше Вы мне объясните, зачем считываете сразу после записи.

пост 12 считать , присвоить , записать, заменить. Как бы так, но не получается .

считать из епром - вывести - считать из датчика, записать в епром и далее по кругу не получается?

Sascha69
Offline
Зарегистрирован: 24.11.2019

qwone пишет:

#include <EEPROM.h>// купил терадь
const int adr = 0;
void setup() {
  Serial.begin(9600);
  int value = EEPROM.read(adr);// посмотрел запись
  Serial.println(value);
  for (int i = 0; i < 255; i++) {
    EEPROM.write(adr, i); //записал новую запись
    delay(500);// подождал пол секунды
    int value = EEPROM.read(adr);
    Serial.println(value);// посмотрел запись
  }

}

void loop() {

}

запусти и посмотри. 

в сериале работает, нужно теперь подумать к моему примеру, спасибо за урок.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

А ни хера не получится. 1- Вы не знаете как правильно организовать структуру программы. 2- у millis есть нелюбимые числа. Так что 1 секунда будет не очень точная.http://arduino.ru/forum/otvlechennye-temy/bespoleznaya-arifmeticheskaya-krasivost

Sascha69
Offline
Зарегистрирован: 24.11.2019

qwone пишет:

А ни хера не получится. 1- Вы не знаете как правильно организовать структуру программы. 2- у millis есть нелюбимые числа. Так что 1 секунда будет не очень точная.http://arduino.ru/forum/otvlechennye-temy/bespoleznaya-arifmeticheskaya-krasivost

Забавно, но мне до таких понятий ох как далеко.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

qwone пишет:

А ни хера не получится. 1- Вы не знаете как правильно организовать структуру программы. 2- у millis есть нелюбимые числа. Так что 1 секунда будет не очень точная.http://arduino.ru/forum/otvlechennye-temy/bespoleznaya-arifmeticheskaya-krasivost

надо над собой работать, добрее надо быть к людяяям, добрееееее )))

Sascha69
Offline
Зарегистрирован: 24.11.2019

Sascha69 пишет:

qwone пишет:

#include <EEPROM.h>// купил терадь
const int adr = 0;
void setup() {
  Serial.begin(9600);
  int value = EEPROM.read(adr);// посмотрел запись
  Serial.println(value);
  for (int i = 0; i < 255; i++) {
    EEPROM.write(adr, i); //записал новую запись
    delay(500);// подождал пол секунды
    int value = EEPROM.read(adr);
    Serial.println(value);// посмотрел запись
  }

}

void loop() {

}

запусти и посмотри. 

в сериале работает, нужно теперь подумать к моему примеру, спасибо за урок.

Здравствуйте. Прошу пояснить, почему применяется цикл for . Много встречал примеров с применением этого цикла при сохранении в eeprom. Спасибо.

b707
Offline
Зарегистрирован: 26.05.2017

Sascha69 пишет:

Здравствуйте. Прошу пояснить, почему применяется цикл for . Много встречал примеров с применением этого цикла при сохранении в eeprom. Спасибо.

ну в данном случае, похоже,  цикл на 255 повторов использован, чтоб вы наконец отстали. Видимо вы задолбали qwone своими вопросами :)

Это примерно как диалог:

- Ах, тебе ложку? Держи! (швыряет ложку в обидчика) Еще хочешь? - держи еще!! и еще! и еще! А вот еще вилки есть! и ножи!!! 255 ножей!!

Аналогия вполне подходящая, потому что для записи в ЕЕПРОМ вполне достаточно одной строчки 8, и повторять это в цикле 255 раз абсолютно бессмысленно :)

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

ну да . так и есть. А если прервать на середине программы то строка 5 и 6 покажет что в ЕЕроме число отличное от 0 или 255. Для этого и делей повешен. Надеюсь понятно почему делей в программе. Для записи и чтения он точно не нужен.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Разберитесь для начала с тем , что вы все таки собираетесь хранить в энергонезависимой памяти.
Интуитивно понимаю, что это должен быть параметр totalMililitres.
Но в литрах, те /1000.
Так вот вы его сохранять то сохраняете, но при старте не читаете из ЕЕПРОМ вообще.
И с математикой фигня какая то у вас.

Алгоритм должен быть такой:
При старте, один раз считываем значение в переменную
EEPROM.get(address,totalMililitres);
Используем ее для вывода и переписываем в памяти при каждом изменении.
totalMillilitres+=flowMililitres;
EEEPROM.put(address,totalMililitres);

Не обязательно использовать переменную для вывода, можно вывести и результат формулы.
Serial.println(totalMillilitres/1000);

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Добавлю, если ви таки позволите

Алгоритм должен быть такой:
При старте, один раз считываем значение в переменную

EEPROM.get(address,totalMililitres);

if (totalMililitres == 0xFFFF) {
 totalMililitres = 0;
EEPOM.put(address, totalMililitres);
}

Используем ее для вывода и переписываем в памяти при каждом изменении.
totalMillilitres+=flowMililitres;
EEEPROM.put(address,totalMililitres);

 

bwn
Offline
Зарегистрирован: 25.08.2014

Программеры, а чем плох EEPROM.update? Почему .put?

sadman41
Offline
Зарегистрирован: 19.10.2016

Для байта put() плох даже, а для остального - лучше. Ибо сохраняет все байтики любой заданной структуры.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

bwn пишет:

Программеры, а чем плох EEPROM.update? Почему .put?

put() шаблонный метод, и внутри сиравно дергает update()

bwn
Offline
Зарегистрирован: 25.08.2014

DetSimen пишет:

put() шаблонный метод, и внутри сиравно дергает update()

ОК, пасибки, думал, что он обязательно обновляет.

Sascha69
Offline
Зарегистрирован: 24.11.2019

DetSimen пишет:

Добавлю, если ви таки позволите

Алгоритм должен быть такой:
При старте, один раз считываем значение в переменную

EEPROM.get(address,totalMililitres);

if (totalMililitres == 0xFFFF) {
 totalMililitres = 0;
EEPOM.put(address, totalMililitres);
}

Используем ее для вывода и переписываем в памяти при каждом изменении.
totalMillilitres+=flowMililitres;
EEEPROM.put(address,totalMililitres);

 

Здравствуйте. Всем огромное спасибо и мои плюсы. Вот этот пример очень интересен, если можно подскажите какая строка в EEPROM начала сохранять и flowMililitres.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Никакая .
Сохраняется только значение totalMillilitres.

Sascha69
Offline
Зарегистрирован: 24.11.2019

Kakmyc пишет:
Никакая . Сохраняется только значение totalMillilitres.

Я тоже так думал, но на самом деле сохраняет и flowMilliLitres. Вот скеч.

#include <LiquidCrystal.h>

#include <EEPROM.h>

LiquidCrystal lcd(12, 11, 6, 9, 8, 7);
byte sensorInterrupt = 0;  // 0 = digital pin 2
byte sensorPin       = 2;
float calibrationFactor = 4.5;
volatile byte pulseCount;//счетчик импульсов
float flowRate;//rashod
unsigned int flowMilliLitres;//поток
unsigned long totalMilliLitres;//общее количество
unsigned long oldTime;//старое время

int address = 0;
byte value;

void setup()
{
pinMode(sensorPin, INPUT);
  digitalWrite(sensorPin, HIGH);//высокий уровень
  lcd.begin (16, 2);
  pulseCount        = 0;
  flowRate          = 0.0;
  flowMilliLitres   = 0;
  totalMilliLitres  = 0;
  oldTime           = 0;
  attachInterrupt(sensorInterrupt, pulseCounter, FALLING);//падающий

EEPROM.get(address,totalMilliLitres);
lcd.setCursor (10, 1);
lcd.print (value, DEC);

void loop()
{
  if ((millis() - oldTime) > 1000)   // Только счетчики обрабатывать один раз в секунду
  {
    detachInterrupt(sensorInterrupt);
    flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
    oldTime = millis();
    flowMilliLitres = (flowRate / 60) * 1000;
    totalMilliLitres += flowMilliLitres;
    unsigned int frac;//скорость потока
    frac = (flowRate - int(flowRate)) * 10;//скорость потоказа эту секунду в литрах / минуту

EEPROM.put(address,totalMilliLitres);
delay(100);

lcd.clear ();
    lcd.setCursor (0, 0);
    lcd.print (int(flowRate));
    lcd.print (".");
    lcd.print (frac, DEC) ;
    lcd.print ("L/min");
    lcd.setCursor (0, 1);
    lcd.print (totalMilliLitres);
    lcd.print ("mL");
    lcd.setCursor (10, 1);
    lcd.print (totalMilliLitres / 1000);
    lcd.print ("L");

 pulseCount = 0;
    attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
  }
}
void pulseCounter()
{
  pulseCount++;
}
  }

это фото после передергивания питания.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Ппц ну зачем ты тупишь ?
Это одна и та же переменная
totalMillilitres.
Просто в одном случае выводится она:
lcd.print(totalMillilitres);
А в другом результат ее деления на 1000
lcd.print(totalMillilitres/1000);

Sascha69
Offline
Зарегистрирован: 24.11.2019

Kakmyc пишет:
Ппц ну зачем ты тупишь ? Это одна и та же переменная totalMillilitres. Просто в одном случае выводится она: lcd.print(totalMillilitres); А в другом результат ее деления на 1000 lcd.print(totalMillilitres/1000);

Пускай будет по Вашему, но я пытаюсь разобраться. 

В get считываем totalMilliLitres, print выводим totalMilliLitres, не важно с делением или нет, в put пишем totalMilliLitres, выводим снова print totalMilliLitres, почему на дисплее выводит и flowMilliLitres сохранённое ?

Если я чего то не понимаю, можно как то изменить код ,что бы flowMilliLitres не сохраняло. Спасибо.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Ты меня не слышишь совсем ?
Не сохраняется оно.
И даже никуда не выводится.
Ты хочешь видеть на экране одно а выводишь другое

Sascha69
Offline
Зарегистрирован: 24.11.2019

Kakmyc пишет:
Ты меня не слышишь совсем ?
Не сохраняется оно.
И даже никуда не выводится.
Ты хочешь видеть на экране одно а выводишь другое

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

Гриша
Offline
Зарегистрирован: 27.04.2014

Sascha69 пишет:
Kakmyc пишет:
Ты меня не слышишь совсем ? Не сохраняется оно. И даже никуда не выводится. Ты хочешь видеть на экране одно а выводишь другое
Я понимаю, что по правилам не могу указывать ветеранам, но уважаемые форумчани в первом посту я писал, что это моё первое ознакомление, форум это свободная платформа общения хочешь помоги, не хочешь не помогай, никто не принуждает, я же писал хочу понять, что бы на будущее было меньше вопросов. Не кого не хотел и не хочу грубить. Спасибо.

 1) и чего так "с обидой" вам конкретно предложили разобраться с тем, что ваше "хочу" и "по факту" не совпадают.

2)пост 40 строка 35 - где фигурная скобка закрывается??? или я не вижу или у вас LOOP в SETUP угодил (и не только )? 

3) после разберитесь со строкой 16 и 32 - чего оно по факту делает?

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Читать научили в школе ?
Почему тогда не читаем , что тебе пишут ?

У тебя сейчас ситуация , как в том видео : "в третьем бочонке 24 огурца".

Покажи мне, вот прям можешь носом ткнуть в ту строку , где ты на экран выводишь flowMillilitres.

bwn
Offline
Зарегистрирован: 25.08.2014

Sascha69 пишет:
Kakmyc пишет:
Ты меня не слышишь совсем ? Не сохраняется оно. И даже никуда не выводится. Ты хочешь видеть на экране одно а выводишь другое
Я понимаю, что по правилам не могу указывать ветеранам, но уважаемые форумчани в первом посту я писал, что это моё первое ознакомление, форум это свободная платформа общения хочешь помоги, не хочешь не помогай, никто не принуждает, я же писал хочу понять, что бы на будущее было меньше вопросов. Не кого не хотел и не хочу грубить. Спасибо.

Вывод на экран осуществляет команда Serial.print(), где по вашей версии происходит указываемый, вами, вывод?

И 38378/1000 = 38.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Все же не "Serial.print()", а object_name.print()
Конкретно в этом случае
lcd.print()

bwn
Offline
Зарегистрирован: 25.08.2014

Kakmyc пишет:
Все же не "Serial.print()", а object_name.print() Конкретно в этом случае lcd.print()

ОК. Поторопился.

Sascha69
Offline
Зарегистрирован: 24.11.2019

qwone

Может будет интересно. (здесь есть и о нелюбимых числах)

https://www.best-microcontroller-projects.com/arduino-millis.html