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

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

Sascha69 пишет:

qwone

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

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

не интересно, кочующая по сайтам потеря мерности )))

if ( (millis()-oldtime) > 500) {
       oldtime = millis();

 

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

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

Kakmyc спасибо. Разобрался.

#include <LiquidCrystal.h>

#include <EEPROM.h>

LiquidCrystal lcd(12, 11, 6, 9, 8, 7);
byte sensorInterrupt = 0;  // 0 = digital pin 2, 1= digital pin 3.
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);//номер прерывания pin2, функция вызова прерывания режим падающий

EEPROM.get(address,totalMilliLitres);
lcd.setCursor (10, 1);
lcd.print (totalMilliLitres, DEC);
}
void loop()
{
  if ((millis() - oldTime) > 1000)   // задержка  в 1 секунду
  {
    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 (flowMilliLitres);
    lcd.print ("mL");
    lcd.setCursor (10, 1);
    lcd.print (totalMilliLitres / 1000);
    lcd.print ("L");

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

 

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

Осталось разобраться с математикой. 

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

ua6em пишет:

не интересно, кочующая по сайтам потеря мерности )))

if ( (millis()-oldtime) > 500) {
       oldtime = millis();

Вы, так и не ответили, что же в этом страшного? Все пытаюсь придумать задачу, где это может быть критично и не могу.

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

bwn пишет:

ua6em пишет:

не интересно, кочующая по сайтам потеря мерности )))

if ( (millis()-oldtime) > 500) {
       oldtime = millis();

Вы, так и не ответили, что же в этом страшного? Все пытаюсь придумать задачу, где это может быть критично и не могу.

Немного не понял о каком страшном речь, если Вы об операторе if, millis,  так это на сколько я разобрался, воплощена задержка, в данном примере пол секунды, которая лучше чем delay, так как не останавливает всю программу.

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

Sascha69 пишет:

К Вам, вопрос совершенно не относился, он исключительно к тому, кому задан. Но походу, опять без ответу.(((

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

Всем доброго вечера. Не знаю как было бы правильно, но попробую продолжить здесь, выложу законченный скеч , хотелось бы узнать мнение профи все ли правильно ,а особо по поводу очистки eeprom стр.42 - 54. Спасибо.

#include <LiquidCrystal.h>

#include <EEPROM.h>

LiquidCrystal lcd(12, 11, 6, 9, 8, 7);
byte sensorInterrupt = 0;        // INT0 = digital pin 2, INT1= digital pin 3.
byte sensorPin       = 2;        // pin датчика.
const int buttonPin  = 3;        // pin кнопки.
float calibrationFactor = 4.5;   // калибровочное число с паспорта датчика.
volatile byte pulseCount;        // счетчик импульсов.
float flowRate;                  // расход.
unsigned int flowMilliLitres;    // поток.
unsigned long totalMilliLitres;  // общее количество.
unsigned long oldTime;           // старое время (время запуска программы).
int address = 0;                 // переменная адреса ЭН памяти.
int buttonState = 0;             // переменная статуса кнопки.
int analoginput = 0 ;            //аналоговый вход А0.
float vout ;                     //значение аналогового входа А0.
float volt ;                     //результат измерения напряжения.

void setup()
{
  pinMode(sensorPin, INPUT);      // pin датчика на вход.
  digitalWrite(sensorPin, HIGH);  // высокий уровень.
  pinMode(buttonPin, INPUT);      // pin кнопки на вход.

  lcd.begin (16, 2);
  pulseCount        = 0;
  flowRate          = 0.0;
  flowMilliLitres   = 0;
  totalMilliLitres  = 0;
  oldTime           = 0;
  attachInterrupt(sensorInterrupt, pulseCounter, FALLING);  //номер прерывания pin2, функция вызова прерывания, режим падающий

  EEPROM.get(address, totalMilliLitres);  // считываем по адресу в ЭН памяти общее количество.
  lcd.setCursor (6, 1);
  lcd.print (totalMilliLitres, DEC);      // выводим на экран строку.
}

void loop()
{
  buttonState = digitalRead(buttonPin);          // проверяем статус кнопки.
  if (buttonState == HIGH)                       // если кнопка нажата.
  {
    for (int i = 0 ; i < EEPROM.length() ; i++)  // в цикле инициализируем, проверяем условие, приращиваем.
    {
      EEPROM.write(i, 0);                        // пишим в ЭН нули.
      delay(1000);                               // задержка.
      (address, totalMilliLitres = 0);           // по адресу присваеваем значение ноль.
      lcd.setCursor (6, 1);
      lcd.print (totalMilliLitres, DEC);         // выводим на экран строку.
      break;//
    }
  }
  if ((millis() - oldTime) > 1000)                                                  // от текущего времени отнимаем старое, проверяем.
  {
    detachInterrupt(sensorInterrupt);                                               // отключаем внешнее прерывание с датчика.
    flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;  // вычисляем расход.
    oldTime = millis();                                                             // задержка  в 1 секунду.
    flowMilliLitres = (flowRate / 60) * 1000;                                       // вычисляем поток.
    totalMilliLitres += flowMilliLitres;                                            // к общему прибавляем мгновенный.
    unsigned int frac;                                                              // переменная скорости потока.
    frac = (flowRate - int(flowRate)) * 10;                                         // скорость потоказа эту секунду в литрах / минуту.

    EEPROM.put(address, totalMilliLitres);  // пишем в ЭН общий.
    delay(100);
    
    vout = analogRead(analoginput);      //читаем значение входа А0.
    volt = vout * 5.0 / 1024.0 / 0.152;  // вычисляем результат напряжения.
    
    lcd.clear ();
    lcd.setCursor (0, 0);
    lcd.print (int(flowRate));            // выводим расход.
    lcd.print (".");
    lcd.print (frac, DEC) ;               // выводим скорость потока.
    lcd.print ("L/min");
    lcd.setCursor (10, 0);
    lcd.print (pulseCount, DEC);          // выводим импульсы с датчика.
    lcd.setCursor (0, 1);
    lcd.print (flowMilliLitres);          // выводим мгновенный расход.
    lcd.print ("mL");
    lcd.setCursor (6, 1);
    lcd.print (totalMilliLitres / 1000);  // выводим общий в литрах.
    lcd.print ("L");
    lcd.setCursor (10, 1);
    lcd.print (volt);                     // выводим результат измерения напряжения.
    lcd.print ("V");
    delay (500);
    
    pulseCount = 0;                                           // присваиваем переменной импульсов ноль.
    attachInterrupt(sensorInterrupt, pulseCounter, FALLING);  // запускаем прерывание.
  }
}

void pulseCounter()  // функция подсчета импульсов.
{
  pulseCount++;      // к импульсу прибавляем один.
}

 

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

Не мое, конечно дело, но зачем так сложно накапливать миллилитры - через несколько преобразований? У Вас счётчик импульс на что выдает, на какую единицу учёта?

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

Sascha69 пишет:

хотелось бы узнать мнение профи все ли правильно ,а особо по поводу очистки eeprom стр.42 - 54.

На профи не претендую, но мнением могу поделится. Мнеие такое - в куске кода, посвещенном очистке ЕЕПРОМ стр.42 - 54 правильный только заголовок и первая строчка цикла - стр 47

А далее начинаются одни вопросы...

В строке 48 идет задержка на секунду - вы действительно понимаете, что делаете? - эта задержка будет вызываться после очистки каждой ячейки, соответственно очистка ЕЕПРОМ на Уно займет 16 минут - вы этого хотели?

Строка 49 - абсолютная бессмыслица. Обьясните, что вы хотели тут написать?

Строки 50-51 - формально правильные, но совершенно бестолковые. Зачем сотни раз выводить на экран одно и тоже число?

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

bwn пишет:

ua6em пишет:

не интересно, кочующая по сайтам потеря мерности )))

if ( (millis()-oldtime) > 500) {
       oldtime = millis();

Вы, так и не ответили, что же в этом страшного? Все пытаюсь придумать задачу, где это может быть критично и не могу.

часы на миллис

PS "...какою мерою мерите, такою же отмерится и вам..." Евангелие от Луки

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

ua6em пишет:

часы на миллис

Но ведь это бред? А для какого-нибудь кухонного таймера, ошибка абсолютно некритична. ИМХО.

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

sadman41

pulseCount он же счетчик импульсов, это основная переменная, как только начинает вращаться крыльчатка датчика срабатывает прерывание и вызывает функцию подсчета импульсов. А имея импульсы делаем расчет расхода, мгновенного расхода и т.д.

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

b707 пишет:

Sascha69 пишет:

хотелось бы узнать мнение профи все ли правильно ,а особо по поводу очистки eeprom стр.42 - 54.

На профи не претендую, но мнением могу поделится. Мнеие такое - в куске кода, посвещенном очистке ЕЕПРОМ стр.42 - 54 правильный только заголовок и первая строчка цикла - стр 47

А далее начинаются одни вопросы...

В строке 48 идет задержка на секунду - вы действительно понимаете, что делаете? - эта задержка будет вызываться после очистки каждой ячейки, соответственно очистка ЕЕПРОМ на Уно займет 16 минут - вы этого хотели?

Строка 49 - абсолютная бессмыслица. Обьясните, что вы хотели тут написать?

Строки 50-51 - формально правильные, но совершенно бестолковые. Зачем сотни раз выводить на экран одно и тоже число?

Я не знаю почему Вы считаете 16 минут, на самом деле все происходит мгновенно, хотя уменьшил до 50 мсек, не чего не изменилось, без 49 стр. при нажатии на кнопку сброса не выводится ноль на экране, с 50-51 стр. согласен лишние. 

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

Хотелось бы услышать есть другие методы сброса (очистки) eeprom. Спасибо всем.

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

Зачем его чистить, тем более весь?
Тут через строку написано то, что обычному программисту способно взорвать мозг.

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

Sascha69 пишет:

Я не знаю почему Вы считаете 16 минут, на самом деле все происходит мгновенно, хотя уменьшил до 50 мсек, не чего не изменилось, без 49 стр. при нажатии на кнопку сброса не выводится ноль на экране, с 50-51 стр. согласен лишние. 


если все "происходит мгновенно" - значит реально вы ничего не чистите. Поставьте вместо вашего дэлей 1000 вывод в Сериал переменной i и покажите, что ваш код напечает в мониторе

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

Sascha69 пишет:

Хотелось бы услышать есть другие методы сброса (очистки) eeprom. Спасибо всем.


а зачем это надо? Я никогда его не чищу и как-то все работает:)

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

Sascha69 пишет:

Хотелось бы услышать есть другие методы сброса (очистки) eeprom. Спасибо всем.

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

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

bwn пишет:

ua6em пишет:

часы на миллис

Но ведь это бред? А для какого-нибудь кухонного таймера, ошибка абсолютно некритична. ИМХО.

это не бред, оперируем размерностью, в данном случает - секунда (и её производные), если программа написана правильно, то в алгоритме сравнения при применении >= будет находится в пределах 1 миллисекунды, отсчитывая оперируемой размерностью получается примитивнейший механизм компенсации, в противном случае при каждом цикле получим накапливаемую погрешность, здесь миллисекунда, бог с ней, но вы же переносите эти методы и на измерение расстояний, если бы я не сталкивался по работе с подобным ПО, вообще бы разговора не было, речь о том, что если оперируем размерностью, ей и надо оперировать, а не сферическими конями в вакууме...

PS один раз выяснение ситуации, почему набегающая погрешность улетала в сотни микрон заняло почти неделю, оказалось, всё потому, что один из НЬЮ программистов, приплюсовывал текущее положение счётчика, WDRAKULA прямо сказал, что всегда так делает и, иных задач у него по жизни не попадалось...то-есть прошёл по контуру, в ноль не пришёл - И ТАК СОЙДЁТ - КИНО )))

 

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

Ua6em - вы что-то так прилипли к этому случаю, будто это какое-то тайное знание, один раз повторили, другой, третий... Успокойтесь, тут никакой тайны. Еще когда вы первый раз задали эту загадку - вам же сказали, что это известная вещь. Если нужен интервал "не менее хх секунд" - каждый новый цикл стартуем от текущего момента. Если нужны точные моменты старта и финиша - используем компенсацию. И все. И нечего это тыкать в каждую тему - возникает впечатление, что вы сами в этом не уверены :)

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

да я бы и не тыкал, если бы не видел постоянно одни и те же грабли...Вы же начинающих учите...

 

 

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

ua6em пишет:

да я бы и не тыкал, если бы не видел постоянно одни и те же грабли...Вы же начинающих учите...

И что, неправильно учим? Счего вы взяли, что начинающим нужна именно компенсация? Ведь вроде все в той ветке разобрали - среди этих двух вариантов нет "правильного" и "неправильного", каждый из них для своего применения. И в ардуине в 90% процентов случаев нужны интервалы, а не точные отрезки, так что Дракула-то прав

 

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

ua6em пишет:
да я бы и не тыкал, если бы не видел постоянно одни и те же грабли...Вы же начинающих учите...
Горе от ума. Вы еще граблей не видели. Почему здесь отсутствуют  профессиональные программисты. Их код не читается нами. А наш код коробит их.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

б707! Оставь дурака в покое. Чудо не понимает, что при его подходе, если система, например занятая прерыванием, пропустила три события, она их добросовестно три подряд и исполнит, как только освободится.... никакого приложения, кроме часов, для которого это не было бы вредным, я не знаю.
Нет таких задач, ну почти нет, в которых важно сделать ровно пять ударов по морде в минуту, неважно с какими промежутками. Гораздо важнее правильные промежутки.

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

И я о том же, основное использование - интервалы смены экранов, опроса датчиков (по интервалу)...... Нужна точность - прерывания, таймеры, но не миллис. ИМХО.
Отсюда и повторяющийся, назойливый вопрос, так что это ua6em, мне отвечал. Пока не убедил.))))
Мне, это, за Лешака, обидно стало.))))

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

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

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

bwn пишет:

И я о том же, основное использование - интервалы смены экранов, опроса датчиков (по интервалу)...... Нужна точность - прерывания, таймеры, но не миллис. ИМХО.
Отсюда и повторяющийся, назойливый вопрос, так что это ua6em, мне отвечал. Пока не убедил.))))
Мне, это, за Лешака, обидно стало.))))

да ладно, ситуация простая, получили новые эрозионные станки, режут твердосплав латунной проволокой диаметром где-то 0,2мм, точно не помню, инженер программист пишет программу, режет "утюг", естественно пишет как вы учили, изделие в габаритах 200х200, ноль не сошёлся на 10 миллиметров где-то, может чуток больше...понятно, вы же не знаете задач, где это важно...для вас их не существует...еще раз для тех кому метрология пустой звук, при оперировании мерностью, оперировать надо мерностями, а не лаптями щи хлебать...

Резюме "...Знают и ведают, что творят, но стригут с этого купоны..." В.Высоцкий

PS у Ленина "Детская болезнь левизны в коммунизме"...это не о политоте еже что )))

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

sadman41 пишет:

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

C какого это бодуна millis() останавливает прерывания??? Эта функция просто возвращает значение счетчика.
А счетчик обновляется по прерыванию таймера, которое случается примерно раз в миллисекунду. Пользоваться миллис в прерывании абсолютно безопасно. Просто надо учитывать, что если прерывания запрещены (как это обычно бывает в обработчиеке прерываний), то миллис не будет обновляться.

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

asam пишет:

sadman41 пишет:

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

C какого это бодуна millis() останавливает прерывания???

unsigned long millis() {
unsigned long m;
uint8_t oldSREG = SREG;

// disable interrupts while we read timer0_millis or we might get an
// inconsistent value (e.g. in the middle of a write to timer0_millis)
cli();
m = timer0_millis;
SREG = oldSREG;

return m;
}

 

asam пишет:

Эта функция просто возвращает значение счетчика.

 

Основным функционалом - да. Но, есть и побочка.

asam пишет:

А счетчик обновляется по прерыванию таймера, которое случается примерно раз в миллисекунду. 

Ну, счётчик там неровно идёт, хоть и с корректировками периодическими. Так что в применении к микронам - никуда не годится )) А на ардуинах, как известно, обычно Stratum1 строят.
 
bwn
Offline
Зарегистрирован: 25.08.2014

ua6em пишет:

да ладно, ситуация простая, получили новые эрозионные станки, режут твердосплав латунной проволокой диаметром где-то 0,2мм, точно не помню, инженер программист пишет программу, режет "утюг", естественно пишет как вы учили, изделие в габаритах 200х200, ноль не сошёлся на 10 миллиметров где-то, может чуток больше...понятно, вы же не знаете задач, где это важно...для вас их не существует...еще раз для тех кому метрология пустой звук, при оперировании мерностью, оперировать надо мерностями, а не лаптями щи хлебать...

Если кто-то взял на работу программиста, закончившего только курсы "Ардуины.ру" и не имеющего мозгов осознать сей факт, уволить нужно обоих. Также уволить метролога, который вздумает рулеткой ловить микронные допуски, а заодно и архитектора, которому придет в голову размечать резы у шестиметровых брусьев микрометром. Каждый инструмент предназначен для своей задачи. 
А попытка установки более жестких допусков, чем требуются для решения поставленной задачи, есть непрофессионализм технолога, ведущий к удлинению производственного цикла и удорожанию конечной продукции, что мы и наблюдаем повсеместно.
В качестве одного из примеров - рассверловка канала труб после центробежного литья: длина 6м, требуемый диаметр (установленный умным технологом -100+-0,1мм), при этом на другом предприятии будет дальнейшая расточка еще ~ на 25мм. Из-за раковин, регулярный провал в плюс, гора переписки на согласование и вопли при раздаче слонов - там вообще сплошной брак делают, поэтому мы сорвали. Лечение - турнули главного технолога, поставили вменяемого, который согласовал 2мм в плюс и брак чудесным образом исчез. Рецепт, для конкретного, описанного случая, неприменимый к чистовой обработке.
Так и с миллисом, в подавляющем числе случаев компенсация не требуется, от слова - совсем, а сам миллис, не есть мерительный инструмент, т.к. не обеспечивает безоговорочную повторяемость результата. ИМХО.
 

Logik
Offline
Зарегистрирован: 05.08.2014

Без паники! millis() приостанавливает прерывания в строке 7 и возвращает как было в строке 09. Было разрешено - будет разрешено и далее. Это сделано из за не атомарности строки 8. Но она отрабатывает быстро, быстрей мксек. Если в каком то коде это критично - ардуино не для вас. Хотяб потому что обработчики аппаратных прерываний того ж таймера или Serial создадут приостановки на 1-2 порядка больше.

Про точность формирования 1мсек - везде выше где это упоминалось надо понимать что так будет если цикл проверки, как правило loop, прокручивается существенно быстрей 1мсек. Это далеко не всегда так. И обычно точность равна максимальному времени прохождения цикла (если уж совсем дотошно - надо суммировать погрешности и учитывать др. особенности, например возможно или нет два раза подряд пройти с максимальным временем). Из за этого все любимые и не любимые числа не значат вобще ничего.

Logik
Offline
Зарегистрирован: 05.08.2014

// нет, в которых важно сделать ровно пять ударов по морде в минуту, неважно с какими промежутками. Гораздо важнее правильные промежутки.

Пример задачи - вращаем насос-дозатор для подачи реагента с постоянной средней скоростью.

Есть разные задачи. Это спор уровня что лучше - вилка или ложка. В защиту "ровно пять ударов по морде в минуту". Он точней в среднем. Если метод этот вызвать 1000 раз то получим 1000 минут и 5000 ударов, погрешность симметричная, не накапливается, все просто. Метод с правильными промежутками выдаст неизвестное кол-во ударов за 1000 минут т.к. погрешность не симметричная (в плюс все время) и она вырастит в 1000 раз после чего станет куда более значимой.

 

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

Если придерживаться точных формулировок, то да - приостанавливает. По SREG-у видно, что разрешает их после чтения переменной.

Тем не менее: гражданин утверждает, что линейкой можно измерить всё точно, как у них на предприятии (где программисты - говно, как и тут) - достаточно только её прикладывать правильной стороной. А то, что цена деления у этой линейки может гулять туда-сюда, а погрешность накапливаться в интервале - это ему не особо важно.

Да, я прекрасно понимаю, что в масштабе вселенной никакого значения не имеет временной сдвиг на несколько десятков-сотен (а это ещё и зависит от степени оптимизации компилятором, как следует полагать) тиков от исполнения функции по TIMER0_OVF_vect, иных обработчиков прерываний и постоянных вызовов millis() в лупе для проверки условия и пр. и др. 

И я бы прошёл даже мимо, если бы данный гражданин писал свой пост под катушкой, а не пытался с серьёзным лицом вычерпать море ситом, утверждая, что все, кто не черпает - должны сдать дипломы по месту получения.

Logik
Offline
Зарегистрирован: 05.08.2014

Море ситом - почему бы и нет! Если ставку платят, гранды пилят, бюджет осваивают а фонды финансируют )) У людей пол трубы - в опилки, зато план есть и точность соответствует!

На вещи смотреть ширше, с людьми мягше ;)

А по сути с Вами согласен.

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

А ить еще тока вторник....

Logik
Offline
Зарегистрирован: 05.08.2014

Так среда - маленькая пятница, вот и разминаемся.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Logik пишет:

// нет, в которых важно сделать ровно пять ударов по морде в минуту, неважно с какими промежутками. Гораздо важнее правильные промежутки.

Пример задачи - вращаем насос-дозатор для подачи реагента с постоянной средней скоростью.

Есть разные задачи. Это спор уровня что лучше - вилка или ложка. В защиту "ровно пять ударов по морде в минуту". Он точней в среднем. Если метод этот вызвать 1000 раз то получим 1000 минут и 5000 ударов, погрешность симметричная, не накапливается, все просто. Метод с правильными промежутками выдаст неизвестное кол-во ударов за 1000 минут т.к. погрешность не симметричная (в плюс все время) и она вырастит в 1000 раз после чего станет куда более значимой.

 

Я не стал сокращать при цитировании. Сорри.

Да, ты совершенно прав! И я уже ночью понял причину того, что у нашего "радиста" подрывает пукан. Он, как и в этом примере, имеет в мыслях управление каким-то прибором или станком, где важна синхронизация процессов. Синхронизация по времени. Отсюда и желание убрать накапливающуюся ошибку.

Получился смешной спор "стрижено - брито". Спор програмиста с ....кем-то другим (я не про тебя, Логик). Я - програмист и мне в голову не придет управлять чем-то в реальном времени пользуясь обсуждаемой конструкцией на миллис(). Для меня миллис - исключительно для определения интервалов "не менее чем...". Конструкции реального времени программируют совершенно иначе. И решают как поступать с пропущенными событиями - игнор или изменение частоты на время и так далее - это вообще другая тема для разговора.

====================

Пример с насосом, или что-то-там про резку у радиста - следует делать на таймере. И контроллер лучше взять другой, с приоритетами прерываний, иначе все равно накладки полезут. Для насоса - достаточно просто таймера, даже в АВР-ке. Для точной резки чего-то - STM32 минимум, поскольку можно сделать аппаратно движение, без прерываний, а следовательно без неизбежных пропусков.

------------------------------

Еще раз - попытка сделать синхронную обработку чего-либо с использованием миллис() неизбежно влечет исполнение нескольких обработок подряд, в случае пропуска. Не всякий исполнительный механизм сумеет такое выполнить.

Logik
Offline
Зарегистрирован: 05.08.2014

wdrakula пишет:

 Я - програмист и мне в голову не придет управлять чем-то в реальном времени пользуясь обсуждаемой конструкцией на миллис(). 

А что такое РВ - это время за которое гарантируется отклик. И подход к решению зависит от его абсолютной величины. Если управляем к примеру солнечным коллектором - так там минуты будут, чем там миллис плох? Или интерфейс юзера- 100мсек самое РВ, тоже миллис годен.

Я когда-то писал свои прикидки, по которым я работаю на 328р. Шото типа.

Интервалы >10мсек - просто миллис.

1-10мсек - миллис с оптимизацией лупа.

200мксек-1мсек - самый противный, избегать, если не получается - группа прерываний. Если можно аппаратно - делать.

10-20мксек - 200мксек - прерывания и/или аппаратно.

еще быстрей - аппаратно или запрет прерываний и фигачить просто в цикле.

Если в этом тексте заменить РВ на "требуемая точность" то тоже будет верно.

 

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

я вообще-то не о миллисе, а о глобальном, о подходе к  программированию как таковому, о решении ЛЮБЫХ задач с максимально возможной точностью...а если в задаче важна точность конкретного отрезка, то естественно делать на прерываниях, с максимально доступным приоритетом...
А по миллису уже давно протестировали, что ардуина на хорошем кварце не уступает по точности DS1307 (если не ошибаюсь), при должном программировании - это в частности...
Да, а станки те были на 16 битных процессорах из серии 18xx и, после эрозионной обработки изделие просто собиралось, то-есть на выходе должно было быть в допусках, о зазорах на рубочно-гибочные  штампы под материал о,3-0,5 видимо имеете представление, как приблизительный образец - ножевой контакт на ардуино, только штамп бьёт их сразу сотнями  )))
 

 

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

Logik пишет:

Так среда - маленькая пятница, вот и разминаемся.

Так ить и не среда даже.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Logik пишет:

wdrakula пишет:

 Я - програмист и мне в голову не придет управлять чем-то в реальном времени пользуясь обсуждаемой конструкцией на миллис(). 

А что такое РВ - это время за которое гарантируется отклик. И подход к решению зависит от его абсолютной величины. Если управляем к примеру солнечным коллектором - так там минуты будут, чем там миллис плох? Или интерфейс юзера- 100мсек самое РВ, тоже миллис годен.

Я когда-то писал свои прикидки, по которым я работаю на 328р. Шото типа.

Интервалы >10мсек - просто миллис.

1-10мсек - миллис с оптимизацией лупа.

200мксек-1мсек - самый противный, избегать, если не получается - группа прерываний. Если можно аппаратно - делать.

10-20мксек - 200мксек - прерывания и/или аппаратно.

еще быстрей - аппаратно или запрет прерываний и фигачить просто в цикле.

Если в этом тексте заменить РВ на "требуемая точность" то тоже будет верно.

 

Вот вообще не спорю, хоть это и необычно. Согласен полностью.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

ua6em пишет:

я вообще-то не о миллисе, а о глобальном, о подходе к  программированию как таковому,

Слушай, душа моя. Я же СтоПицот раз повторил, почему НЕЛЬЗЯ просто так применять конструкцию: ОЛД_МИЛЛИС += ИНТЕРВАЛ.

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

Если тебя метролог укусил, то примочку приложи, штоле. Не всегда события привязывают к реальному времени. К примеру при опросе DS1820 важно исключительно время МЕЖДУ запросами.

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

От я молодец, оказывается не только нечисть, в виде аллегира, вызывать умею. А еще и предпятничные разминки.))))

from Araris: не поминайте всуе ))))

astwo
Offline
Зарегистрирован: 10.07.2019

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

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

b707

Здравствуйте. После вывода в монитор переменной "i" при нажатии на кнопку сброс печатает нули. Вы спрашиваете для чего это нужно, идет сохранение в eeprom, все хорошо, емкость опустошилась, делаем новую заправку делаем сброс и все считаем снова. Вот только не знаю правильно ли воплотил очистку eeprom так как других примеров не нашел. Знаете подскажите где почитать.

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

Зачем тебе очищать весь eeprom , если у тебя значения сохраненные занимают 4байта ?
Их и очищай. А точнее записывай в них 0.

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

Sascha69 пишет:

b707

Здравствуйте. После вывода в монитор переменной "i" при нажатии на кнопку сброс печатает нули.

сколько раз печатает переменную i ? - если вы очищаете ВЕСЬ ЕЕПРОМ, то должно напечатать столько строк, сколько в ЕЕПРОМ ячеек. На Уно, например - 1024. А если у вас печатает переменную i один раз - значит вы только одну ячейку и очищаете...

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

Так и есть от 0 до 1023, немного подправил оставил только 4 ячейки. 

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

Sascha69 пишет:

Так и есть от 0 до 1023

ну тогда подумайте, как мог этот код исполнятся "мгновенно", если на этом месте стояло delay(1000) ?

1000 мс - это 1 секунда, 1024 раза по 1 секунде - это 17 минут

Значит у вас прошлый код реально по всем ячейкам не проходил и ничего не чистил, как я вам и писал.

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

wdrakula пишет:

Слушай, душа моя. Я же СтоПицот раз повторил, почему НЕЛЬЗЯ просто так применять конструкцию: ОЛД_МИЛЛИС += ИНТЕРВАЛ.

Потому что после пропуска события следующие два выполнятся подряд

послушал...ты так плохо пишешь код, что у тебя разброс в loop бывает более 1 миллисекунды?

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

да, кстати 1 миллисекунда на 1000 это точность 0,1% ежели что