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

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

astwo пишет:
millis это программный клей для склеивания кучи программы компонентов в единое целое. Но этот компонент имеет кучу недостатков. Вот к примеру есть на улице автомобиль. Так никому в голову не придёт собирать его на клею. Точнее собрать то можно, но опасно на этот ездить. Конечно можно жевать тему что надо поверхности обезжиривать, потом сушить. Но все равно это не достаточно безопасно. Вот так и millis

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

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

Доброй ночи. Прошу помощи. Снова не могу сохранить в EEPROM, точнее сохраняет но после перезагрузки все стирает. 

#include "LiquidCrystal.h"
#include <EEPROM.h>
LiquidCrystal lcd(12, 11, 6, 9, 8, 7); // пины под LCD shield

#define FLOWSENSORPIN 2 // пин для датчика расхода

volatile uint16_t pulses = 0; // считает сколько импульсов
volatile uint8_t lastflowpinstate; // отслеживает состояние пина FLOWSENSORPIN
volatile uint32_t lastflowratetimer = 0; // отсчитывает время между импульсами
volatile float flowrate; // и использует это, чтобы вычислить скорость потока
int address = 0;                 // переменная адреса ЭН памяти.
const int buttonPin  = 3;        // pin кнопки.
int buttonState = 0;             // переменная статуса кнопки.
int liters = 0 ;
// Прерывание вызывается один раз в миллисекунду, ищет любые импульсы от датчика!
SIGNAL(TIMER0_COMPA_vect) {
  uint8_t x = digitalRead(FLOWSENSORPIN);
  
  if (x == lastflowpinstate) {
    lastflowratetimer++;
    return; // nothing changed!
  }
  
  if (x == HIGH) {
    //low to high transition!
    pulses++;
  }
  lastflowpinstate = x;
  flowrate = 1000.0;
  flowrate /= lastflowratetimer;  // в герцах
  lastflowratetimer = 0;
}

void useInterrupt(boolean v) {
  if (v) {
    // Timer0 уже используется для millis() - просто прерываем
    // в середине и вызываю "Compare A" функция выше
    OCR0A = 0xAF;
    TIMSK0 |= _BV(OCIE0A);
  } else {
    // не вызывать функцию прерывания больше
    TIMSK0 &= ~_BV(OCIE0A);
  }
}

void setup() {
  
   lcd.begin(16, 2);
  
   pinMode(FLOWSENSORPIN, INPUT);
   digitalWrite(FLOWSENSORPIN, HIGH);
   lastflowpinstate = digitalRead(FLOWSENSORPIN);
   useInterrupt(true);
  EEPROM.get(address, liters);
  lcd.setCursor (0, 1);
  lcd.print (liters); 
}

void loop()                     
{ 
  lcd.setCursor(0, 0);
  lcd.print("Pulses:"); lcd.print(pulses, DEC);
  lcd.print(" Hz:");
  lcd.print(flowrate);
  
  
  
 
  float liters = pulses;
  liters /= 7.5;
  liters /= 60.0;
EEPROM.put(address, liters);

  
  lcd.setCursor(0, 1);
  lcd.print(liters); lcd.print(" Liters        ");

  delay(100);
}

 

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

Sascha69 пишет:

Доброй ночи. Прошу помощи. Снова не могу сохранить в EEPROM, точнее сохраняет но после перезагрузки все стирает. 

#include "LiquidCrystal.h"
#include <EEPROM.h>
LiquidCrystal lcd(12, 11, 6, 9, 8, 7); // пины под LCD shield

#define FLOWSENSORPIN 2 // пин для датчика расхода

volatile uint16_t pulses = 0; // считает сколько импульсов
volatile uint8_t lastflowpinstate; // отслеживает состояние пина FLOWSENSORPIN
volatile uint32_t lastflowratetimer = 0; // отсчитывает время между импульсами
volatile float flowrate; // и использует это, чтобы вычислить скорость потока
int address = 0;                 // переменная адреса ЭН памяти.
const int buttonPin  = 3;        // pin кнопки.
int buttonState = 0;             // переменная статуса кнопки.
int liters = 0 ;
// Прерывание вызывается один раз в миллисекунду, ищет любые импульсы от датчика!
SIGNAL(TIMER0_COMPA_vect) {
  uint8_t x = digitalRead(FLOWSENSORPIN);
  
  if (x == lastflowpinstate) {
    lastflowratetimer++;
    return; // nothing changed!
  }
  
  if (x == HIGH) {
    //low to high transition!
    pulses++;
  }
  lastflowpinstate = x;
  flowrate = 1000.0;
  flowrate /= lastflowratetimer;  // в герцах
  lastflowratetimer = 0;
}

void useInterrupt(boolean v) {
  if (v) {
    // Timer0 уже используется для millis() - просто прерываем
    // в середине и вызываю "Compare A" функция выше
    OCR0A = 0xAF;
    TIMSK0 |= _BV(OCIE0A);
  } else {
    // не вызывать функцию прерывания больше
    TIMSK0 &= ~_BV(OCIE0A);
  }
}

void setup() {
  
   lcd.begin(16, 2);
  
   pinMode(FLOWSENSORPIN, INPUT);
   digitalWrite(FLOWSENSORPIN, HIGH);
   lastflowpinstate = digitalRead(FLOWSENSORPIN);
   useInterrupt(true);
  EEPROM.get(address, liters);
  lcd.setCursor (0, 1);
  lcd.print (liters); 
}

void loop()                     
{ 
  lcd.setCursor(0, 0);
  lcd.print("Pulses:"); lcd.print(pulses, DEC);
  lcd.print(" Hz:");
  lcd.print(flowrate);
  
  
  
 
  float liters = pulses;
  liters /= 7.5;
  liters /= 60.0;
EEPROM.put(address, liters);

  
  lcd.setCursor(0, 1);
  lcd.print(liters); lcd.print(" Liters        ");

  delay(100);
}

 

когда ж вы Си выучите? переменная, из которой вы записываете в ЕЕПРОМ. и в которую вы читаете - две разные переменные.

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

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

#include "LiquidCrystal.h"
#include <EEPROM.h>
LiquidCrystal lcd(12, 11, 6, 9, 8, 7); // пины под LCD shield

#define FLOWSENSORPIN 2 // пин для датчика расхода

volatile uint16_t pulses = 0; // считает сколько импульсов
volatile uint8_t lastflowpinstate; // отслеживает состояние пина FLOWSENSORPIN
volatile uint32_t lastflowratetimer = 0; // отсчитывает время между импульсами
volatile float flowrate; // и использует это, чтобы вычислить скорость потока
int address = 0;                 // переменная адреса ЭН памяти.
const int buttonPin  = 3;        // pin кнопки.
int buttonState = 0;             // переменная статуса кнопки.
int liters = 0 ;
// Прерывание вызывается один раз в миллисекунду, ищет любые импульсы от датчика!
SIGNAL(TIMER0_COMPA_vect) {
  uint8_t x = digitalRead(FLOWSENSORPIN);
  
  if (x == lastflowpinstate) {
    lastflowratetimer++;
    return; // nothing changed!
  }
  
  if (x == HIGH) {
    //low to high transition!
    pulses++;
  }
  lastflowpinstate = x;
  flowrate = 1000.0;
  flowrate /= lastflowratetimer;  // в герцах
  lastflowratetimer = 0;
}

void useInterrupt(boolean v) {
  if (v) {
    // Timer0 уже используется для millis() - просто прерываем
    // в середине и вызываю "Compare A" функция выше
    OCR0A = 0xAF;
    TIMSK0 |= _BV(OCIE0A);
  } else {
    // не вызывать функцию прерывания больше
    TIMSK0 &= ~_BV(OCIE0A);
  }
}

void setup() {
  
   lcd.begin(16, 2);
  
   pinMode(FLOWSENSORPIN, INPUT);
   digitalWrite(FLOWSENSORPIN, HIGH);
   lastflowpinstate = digitalRead(FLOWSENSORPIN);
   useInterrupt(true);
  EEPROM.get(address, liters);
  lcd.setCursor (0, 1);
  lcd.print (liters); 
}

void loop()                     
{ 
  lcd.setCursor(0, 0);
  lcd.print("Pulses:"); lcd.print(pulses, DEC);
  lcd.print(" Hz:");
  lcd.print(flowrate);
  
  
  
 
  int liters = pulses;
  liters /= 7.5;
  liters /= 60.0;
EEPROM.put(address, liters);

  
  lcd.setCursor(0, 1);
  lcd.print(liters); lcd.print(" Liters        ");

  delay(100);
}

 

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Sascha69 пишет:

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

А толку? Почитайте про глобальные и локальные переменные в С или С++

Вот, например - http://cppstudio.com/post/415/

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

Sascha69 пишет:

Исправил но не работает как надо.

что вы исправили? float на int переписали? - а смысл? как было две разных переменных - так и осталось.

Нельзя программировать методом тыка - а то не только по сто, а по тыще раз будете переписывать - и все равно не заработает.Прочитайте, наконец, учебник,

Sascha69
Offline
Зарегистрирован: 24.11.2019
#include "LiquidCrystal.h"
#include <EEPROM.h>
LiquidCrystal lcd(12, 11, 6, 9, 8, 7); // пины под LCD shield

#define FLOWSENSORPIN 2 // пин для датчика расхода

volatile uint16_t pulses = 0; // считает сколько импульсов
volatile uint8_t lastflowpinstate; // отслеживает состояние пина FLOWSENSORPIN
volatile uint32_t lastflowratetimer = 0; // отсчитывает время между импульсами
volatile float flowrate; // и использует это, чтобы вычислить скорость потока
int address = 0;                 // переменная адреса ЭН памяти.
const int buttonPin  = 3;        // pin кнопки.
int buttonState = 0;             // переменная статуса кнопки.
int liters = 0 ;                  // глобальная переменная.
// Прерывание вызывается один раз в миллисекунду, ищет любые импульсы от датчика!
SIGNAL(TIMER0_COMPA_vect) {
  uint8_t x = digitalRead(FLOWSENSORPIN);
  
  if (x == lastflowpinstate) {
    lastflowratetimer++;
    return; // nothing changed!
  }
  
  if (x == HIGH) {
    //low to high transition!
    pulses++;
  }
  lastflowpinstate = x;
  flowrate = 1000.0;
  flowrate /= lastflowratetimer;  // в герцах
  lastflowratetimer = 0;
}

void useInterrupt(boolean v) {
  if (v) {
    // Timer0 уже используется для millis() - просто прерываем
    // в середине и вызываю "Compare A" функция выше
    OCR0A = 0xAF;
    TIMSK0 |= _BV(OCIE0A);
  } else {
    // не вызывать функцию прерывания больше
    TIMSK0 &= ~_BV(OCIE0A);
  }
}

void setup() {
  
   lcd.begin(16, 2);
  
   pinMode(FLOWSENSORPIN, INPUT);
   digitalWrite(FLOWSENSORPIN, HIGH);
   lastflowpinstate = digitalRead(FLOWSENSORPIN);
   useInterrupt(true);
  
  EEPROM.get(address, liters);
  lcd.setCursor (0, 1);
  lcd.print (liters); 
}

void loop()                     
{ 
  lcd.setCursor(0, 0);
  lcd.print("Pulses:"); lcd.print(pulses, DEC);
  lcd.print(" Hz:");
  lcd.print(flowrate);
  
  liters = pulses;
  liters /= 7.5;
  liters /= 60.0;

  EEPROM.put(address, liters);

  lcd.setCursor(0, 1);
  lcd.print(liters); lcd.print(" Liters        ");

  delay(100);
}

В 14 строке глобальная переменная, видна по всему коду. Надеюсь это имели в виду. Не работает.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Sascha69 пишет:

В 14 строке глобальная переменная, видна по всему коду. Надеюсь это имели в виду. Не работает.

Ну потому что это была не единственная твоя ошибка. Поставь delay на пару секунд после строки 57

И ты увидешь, что все перекрасно сохраняется. Просто потом, в строке 67, ты немедленно это сохраненное значение затираешь.

PS А еще раз литры у тебя сейчас в int, то делить на 7.5 бессмысленно. Совет - пересчитай в сетапе литры в импульсы или храни импульсы, а не литры. Но записывай их не каждый раз, а через каждые 450 импульсов например.

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

asam пишет:

 Совет - пересчитай в сетапе литры в импульсы или храни импульсы, а не литры. 

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

Импульсы пробовал, все хорошо и кнопка работает но как Вы выше и говорили, после перезагрузки при новом импульсе сбрасывает на 0. 

Не подскажите в какой программе скетч можно симулировать, типа как в Атмел студио? Спасибо.

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

Sascha69 пишет:

Не подскажите в какой программе скетч можно симулировать, типа как в Атмел студио? Спасибо.

что тут симулировать - тут и так видно. что код не рабочий. Тут не симулятор нужен - вам нужно продумать логику кода, а вы этого не сделали. Саша, обьясните, зачем вы вообще пишете литры в ЕЕПРОМ? - вы же потом эту цифру никак не используете. В вашем коде что есть запись в ЕЕПРОМ. что нет

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Sascha69 пишет:

asam пишет:

 Совет - пересчитай в сетапе литры в импульсы или храни импульсы, а не литры. 

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

Ну попробуйте помедитировать над строками 14,55 и 67. Может станет понятнее.

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

b707 пишет:

что тут симулировать - тут и так видно. что код не рабочий. Тут не симулятор нужен - вам нужно продумать логику кода, а вы этого не сделали. Саша, обьясните, зачем вы вообще пишете литры в ЕЕПРОМ? - вы же потом эту цифру никак не используете. В вашем коде что есть запись в ЕЕПРОМ. что нет

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

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

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

Sascha69 пишет:

Литры заносятся в EEPROM для того что бы видеть расход, например топлива

чтобы видеть расход, надо заносить в ЕЕПРОМ не последнее считанное значение, а например, сумму... или среднее. А иначе в занесении в ЕЕПРОМ смысла ровно ноль - проще после старта вообще не считать из ЕЕПРОМ старые значения, а сразу взять с датчика новые.

Подумайте над разницей, к примеру, скорости и пробега. Запоминать скорость в ЕЕПРОМ совершенно незачем, завтра эта вчерашняя скорость никому не будет интересна...

Саша, я вам еще раз повторяю - у вас логика кода не продумана. Пока выэтого не сделаете - у вас будет не программа, а какие-то бесполезные обрывки

Цитата:
Но с записью в EEPROM разобраться не могу.

в вашем коде нет никаких проблем с записью в ЕЕПРОМ - все нормально пишется и читается. проблема в том, что вы не знаете, как эти значения использовать

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

asam пишет:

Ну попробуйте помедитировать над строками 14,55 и 67. Может станет понятнее.

Стр.14 объявлена целочисленная глобальная переменная liters, стр.55 в сетапе считываем  в EEPROM по адресу данные liters и выводим на экран, так было объяснено при разборке первого поста,  стр. 67 переменной liters присваивается переменная pulses, здесь я уже понял что при каждом новом импульсе будет сбрасываться в 0 и как реализовать либо обход, либо по новому прописать код не знаю. С Вашей мыслей сохранять pulses согласен, но опять же при его изменении будет сброс в 0. Пока у меня тупик.  

 

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

b707 пишет:

в вашем коде нет никаких проблем с записью в ЕЕПРОМ - все нормально пишется и читается. проблема в том, что вы не знаете, как эти значения использовать

Извините но я действительно не могу Вас понять. Мне не нужно эти значения где то использовать, мне нужно видеть общий расход и при обновлении бака сбросить в 0 кнопкой. То что пишется и читается я вижу, но при поступлении нового импульса сбрасывается, с этим и пытаюсь разобраться.

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

ты реально деревянный? 

Ты сохраняешь litres, а считаешь pulses. При старте программы pulses у тебя равен 0, и ты его тут же присваиваешь litres, в 67 строке, независимо от того, что ты в нее считал. 

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

DetSimen пишет:

ты реально деревянный? 

А что - ещё есть сомнения?

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

DIYMan пишет:

А что - ещё есть сомнения?

Да бесит уже, б-ть!  :)    Три страницы ниачём. 

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

Уважаемые DetSimen, а так же DIYMan попрошу Вас соблюдать правила форума. Не нужно заниматься гнусным хамством. Тема создана о сохранении данных в EEPROM о чем я и пытаюсь разобраться, из трех станиц люди пообщались о проблемах с milliss, хотя на эту тему можно было создать отдельную тему. О том что чему присваивается уже обговаривалось, да Вы правы я еще многого не понимаю, но и тема создана в рубрике для начинающих, а не профи. Давайте будем оставаться людьми, кого что то сильно раздражает, не кто сюда силком не тянет, для того и существуют форумы. Без обид.

По теме, как  можно по другому сделать расчет литров, если у кого есть сылочки о полезных примерах, книгах, буду благодарен. Спасибо.

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

Sascha69 пишет:

 Тема создана о сохранении данных в EEPROM о чем я и пытаюсь разобраться

с чем вы пытаетесь разобраться? -  в вашей программе нет проблем с сохранением данных в ЕЕПРОМ , сколько еще повторять?

Цитата:
По теме, как  можно по другому сделать расчет литров, если у кого есть сылочки о полезных примерах, книгах, буду благодарен. Спасибо.

Вы задачу сформулируйте четким понятным языком - причем не для нас, а для себя в первую очередь. Проблема в том, что вы сами не понимаете, что вы хотите с этими литрами делать.

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

Sascha69 пишет:

Уважаемые DetSimen, а так же DIYMan попрошу Вас соблюдать правила форума. Не нужно заниматься гнусным хамством. 

Где я нахамил - ткни пальцем, пж. Не нужно заниматься гнусной клеветой.

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

Админы, предлагаю тему закрыть.

Сейчас почитал - автору ответили на его вопрос на первой странице раз восемь.... и даже - небывалое для этого форума - как минимум четверо написали пример готового кода. С тех пор ТС только удаляется от правильного решения.

Ситуация, похоже, совершенно безнадежная.

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

b707 пишет:

Ситуация, похоже, совершенно безнадежная.

А что - до этого поста ещё были сомнения? :)))

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

DIYMan пишет:

А что - до этого поста ещё были сомнения? :)))

да я просто забыл, что там на первой странице было :) А сейчас глянул - и вижу, что обсуждение ходит по кругу - причем оборот уже не первый и не второй :)

Человек МЕСЯЦ! не может допетрить, что в каком порядке делать - борщ сначала сварить а потом съесть или наоборот :))))

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

b707 пишет:

Вы задачу сформулируйте четким понятным языком - причем не для нас, а для себя в первую очередь. Проблема в том, что вы сами не понимаете, что вы хотите с этими литрами делать.

Если взят этот скетч без сохранения в память, он работает изумительно, при проливе через датчик расхода одного литра воды точно показывает один литр. Суть заключается в том чтобы видеть общее количество прошедшее через датчик до следующей заправки. Сейчас пытаюсь сохранять переменную pulses, только с пересчетом раз в 450 импульсов. Как то так.

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

b707 пишет:

да я просто забыл, что там на первой странице было :) А сейчас глянул - и вижу, что обсуждение ходит по кругу - причем оборот уже не первый и не второй :

На первой странице скетч по внешнему прерыванию, там я все разобрался все работает сохраняет очищает, здесь прерывание по сравнению таймер счетчика.

 

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

Sascha69 пишет:

На первой странице скетч по внешнему прерыванию, там я все разобрался все работает сохраняет очищает, здесь прерывание по сравнению таймер счетчика.

 

а что, для сохранения литров в ЕЕПРОм есть хоть какая-то разница, чтоу вас  за прерывание?

Слушайте, заканчивайте этот балаган - если вы говорите, что "там все сохраняет очищает" - скопируйте оттуда код и закроем тему.

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

Саша, сто двадцать восемь постов, о ни о чем. Вам уже не раз сказали: возьмите рулон туалетной бумаги и нарисуйте на нем, хоть ромбиками, хоть русским по белому, в какой момент, при каких условиях что то должно произойти, чтобы результат вас удовлетворил. Вы же как слепой кутенок тычетесь во все стороны. ИМХО.

P/S Уже сто тридцать.((((

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

bwn пишет:

P/S Уже сто тридцать.((((

не вижу... или ТС пишет - а админы чистят? :)

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

а что Вы хотели, 69 цифра эзотерическая )))

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

b707 пишет:

не вижу... или ТС пишет - а админы чистят? :)

Виноват, кто-то уже пытался накал снять.))))