Запись изменившихся значений переменной в энергонезаависимую память.

Samiels
Samiels аватар
Offline
Зарегистрирован: 11.02.2020

Здравствуйте. Подскажите, пожалйста, решение задачки.
Имеется плата Digispark со скетчем:int pin1 = 1; //номер пина

unsigned long freq1=1440;    //периодичность включения в минутах
unsigned long dlit1=600;    //длительность работы в минутах
unsigned long freq_last_time1;

#define adc_disable() (ADCSRA &= ~(1<<ADEN))

void setup(void){
    adc_disable();
    // все пины как выходы
  for (byte i = 0; i < 6; i++) {
pinMode(i, OUTPUT);
digitalWrite(i , HIGH);
  }
}

void loop(void){
stDelo();
}

void stDelo(){
if(  (millis()-freq_last_time1)>(freq1*60000)){
     digitalWrite(pin1 , LOW);
     freq_last_time1=millis();
}
if(  (millis()-freq_last_time1)>(dlit1*60000)){
     digitalWrite(pin1 , HIGH);
  }
}

Нужно, чтобы при прохождении цикла значение dlit1 увеличивалось на 10, пока не достигнет значения 1080, а затем уменьшалось на 10, до достижения значения 600... И так по кругу, при этом необходимо при изменении значения записывать его в память вместо начального 600(это на случай внезапного отключения питания платы).
Как это реализовать в коде.
Спасибо.

b707
Онлайн
Зарегистрирован: 26.05.2017

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

Да и сама работа с длительностью написана неправильно - у вас нагрузка включается раз 1440 минут, а выключается КАЖДЫЕ 600 минут, а вовсе не через 600 минут после включения...

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А как Вы пробовали? Что именно у Вас не получается?

Samiels
Samiels аватар
Offline
Зарегистрирован: 11.02.2020

Здесь всё верно, интервал срабатывания 1440 минут на время 600 минут и с каждым интервалом необходимо увеличивать время работы на 10 до достижения 1080, а затем уменьшать до возврата в значение 600.

А насчёт цикла - здесь я и сам "зациклился".

for (;dlit1 <= 1080; dlit1 = dlit1+10) {
  if(dlit1 == 1080) break;
}

но при этом он будет прибавлять без устали и не смотря на 1440. А может просто в начале цикла написать dlit1 = dlit1+10 и потом что-то вроде:

void EEPROM_ulong_write(int addr, unsigned long dlit1) {
	  byte raw[4];
	  (unsigned long&)raw = dlit1;
	  for(byte i = 0; i < 4; i++) EEPROM.write(addr+i, raw[i]);
	}

, а затем читать её:

unsigned long EEPROM_ulong_read(int addr) { 
	  byte raw[4];
	  for(byte i = 0; i < 4; i++) raw[i] = EEPROM.read(addr+i);
	  unsigned long &dlit1 = (unsigned long&)raw;
	  return dlit1;
	}

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

В общем совсем уже запутался, да ещё и переход с php 5.4 на 7.4 из колеи выбивает, коды путаются, котелок кипит...

b707
Онлайн
Зарегистрирован: 26.05.2017

Samiels пишет:

Здесь всё верно, интервал срабатывания 1440 минут на время 600 минут

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

Цитата:
А насчёт цикла - здесь я и сам "зациклился".

for (;dlit1 <= 1080; dlit1 = dlit1+10) {
  if(dlit1 == 1080) break;
}

но при этом он будет прибавлять без устали и не смотря на 1440. А может просто в начале цикла написать dlit1 = dlit1+10 и потом что-то вроде....

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

Samiels
Samiels аватар
Offline
Зарегистрирован: 11.02.2020

Да что тут не понять. Не знаю куда копать, вот и прошу помощи. По поводу спора в памяти Digispark шесть таких таймеров с разными интервалами и временем работы на все его шесть портов, на что хватило памяти, и всё работает как надо уже полтора года. Куски кода... их надо как-то связать и желательно правильно - а как? Знал бы - не просил помощи.

b707
Онлайн
Зарегистрирован: 26.05.2017

Samiels пишет:

 Куски кода... их надо как-то связать и желательно правильно - а как? Знал бы - не просил помощи.

вы предлагаете чтобы это кто-то сделал за вас?

Переформулируйте задачу иначе. Вместо того чтоб писать, что интервал надо менять в цикле - что заводит вас в тупик с циклом for... напишите так:

После каждого срабатывания нагрузки следующий интервал должен быть на 10 больше. Когда интервал достигнет 1080 - после каждого срабатывания делаем интервал на 10 меньше.

Ну а теперь попробуйте выразить это в коде, думаю, это будет проще, чем ваш вариант

 

Samiels
Samiels аватар
Offline
Зарегистрирован: 11.02.2020

b707 пишет:

вы предлагаете чтобы это кто-то сделал за вас?

Переформулируйте задачу иначе. Вместо того чтоб писать, что интервал надо менять в цикле - что заводит вас в тупик с циклом for... напишите так:

После каждого срабатывания нагрузки следующий интервал должен быть на 10 больше. Когда интервал достигнет 1080 - после каждого срабатывания делаем интервал на 10 меньше.

Ну а теперь попробуйте выразить это в коде, думаю, это будет проще, чем ваш вариант

Уважаемый, сколько конструктивного в ваших комментариях?... Исходя из написанного вами - вам всё прекрасно понятно. Следовательно - можете - сделайте, не хотите делать - подскажите дельным советом, научите. А воду лить здесь и толочь в ступе не надо. "После каждого срабатывания нагрузки..." а разве это не есть цикл, или у вас с пониманием значений слов неувязочка?...

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Samiels пишет:

Уважаемый, сколько конструктивного в ваших комментариях?

А в Ваших?

Я Вас спросил

ЕвгенийП пишет:

А как Вы пробовали? Что именно у Вас не получается?

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

Попробую повторить свой вопрос.

Вы пытались сделать это сами? Да или нет? Если "да", выкладывайте скетч с Вашей попыткой и объясняйте что именно в его работе Вас не устраивает.

b707
Онлайн
Зарегистрирован: 26.05.2017

Samiels пишет:

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

Конечно мне все понятно, задачка-то элементарная. Но делать я за вас ничего не собираюсь - а подсказать могу. Если вы не поняли - то что вы процитировали выше и есть мой "дельный совет", как можно решить вашу проблему. Это, говоря иначе - алгоритм, пользуясь которым, любой, немного разбираюзийся в программировании - уже написал бы код.

Если же вы ждете, чтобы кто-то написал готовую программу за вас - обратитесь в отдел "Изу исполнителя"

b707
Онлайн
Зарегистрирован: 26.05.2017

опять "неправильно помогаем"....

Samiels
Samiels аватар
Offline
Зарегистрирован: 11.02.2020

ЕвгенийП пишет:

... и увидел куски кода для записи и чтения в eeprom повышенной бредовости....

Взято отсюда http://arduino.ru/forum/programmirovanie/zapis-i-chtenie-eeprom-peremennykh-tipa-float-unsigned-long-long-unsigned-int

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Samiels пишет:

Взято отсюда

Вы правда думаете, что мне интересно на каком именно заборе это написано? :-)))

Запись (как и чтение) значения типа long в eeprom делается одной строкой - штатной функцией библиотеки eeprom.

Samiels
Samiels аватар
Offline
Зарегистрирован: 11.02.2020

Спасибо за помощь - тема закрыта