millis

artmob
Offline
Зарегистрирован: 03.05.2019

Хотел сделать управление светом при помощи millis , но смог настроить только 12/12, нужно 18/6 (18 часов светит , 6 часов выключено(сделал на реле)), но к сожалению моих навыков не хватает чтобы сделать такой режим

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

а скетч?

vk007
Offline
Зарегистрирован: 16.06.2015

ua6em пишет:

а скетч?

Для вставки скетча наверное тоже навыков нет

artmob
Offline
Зарегистрирован: 03.05.2019
unsigned long previousMillis = 0;

const long interval_1 = 21600000
const long interval_2 = 64800000
int led = 13;
int interv = interval_2;

void setup()
{
  pinMode(led, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
  unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interv) {
          if (interv == interval_2) interv = interval_1;
      else interv = interval_2;
      previousMillis = currentMillis;
            Serial.println(interv);
      digitalWrite(led, !digitalRead(led));
    }
}

 

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

artmob пишет:

unsigned long previousMillis = 0;

const long interval_1 = 21600000
const long interval_2 = 64800000
int led = 13;
int interv = interval_2;

void setup()
{
  pinMode(led, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
  unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interv) {
          if (interv == interval_2) interv = interval_1;
      else interv = interval_2;
      previousMillis = currentMillis;
            Serial.println(interv);
      digitalWrite(led, !digitalRead(led));
    }
}

 

artmob - код вполне грамотный, просто все переменные времен, включая интервал ! - тоже сделайте unsigned long

vk007
Offline
Зарегистрирован: 16.06.2015

"Всё уже украдено до нас..." artmob, учитесь пользоваться поиском. Эта тема уже поднималась не раз, например, http://arduino.ru/forum/programmirovanie/eshche-raz-migaem-svetodiodom-b...

 
 
 

 

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

artmob пишет:

unsigned long previousMillis = 0;

const long interval_1 = 21600000
const long interval_2 = 64800000
int led = 13;
int interv = interval_2;

void setup()
{
  pinMode(led, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
  unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interv) {
          if (interv == interval_2) interv = interval_1;
      else interv = interval_2;
      previousMillis = currentMillis;
            Serial.println(interv);
      digitalWrite(led, !digitalRead(led));
    }
}

artmob, никогда так не делайте. Код надо копировать точно (копи-пастом) - а не так, как Вы это сделали. Что Вы нам подсунули? Оно ведь даже не компилируется!!! Как же Вы его загружаете? Это неуважение к сообществу.

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

Совсем нетрудно ведь один раз написать простые макросы:

#define SECONDS(x)	((x) * 1000UL)
#define MINUTES(x)	(SECONDS(x) * 60UL)
#define HOURS(x)	(MINUTES(x) * 60UL)
#define DAYS(x)		(HOURS(x) * 24UL)
#define WEEKS(x)	(DAYS(x) * 7UL)

А один раз их написав, всегда записывать, например

unsigned long interval = HOURS(6);
unsigned long theDay = DAYS(1);

Разве так не читабельнее?

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

да вот, а не программисты пишут в лоб, то-есть, что вижу о том и пою )))
 


#define SECONDS(x)  ((x) * 1000UL)
#define MINUTES(x)  (SECONDS(x) * 60UL)
#define HOURS(x)  (MINUTES(x) * 60UL)
#define DAYS(x)   (HOURS(x) * 24UL)
#define WEEKS(x)  (DAYS(x) * 7UL)
unsigned long interval_1 = SECONDS(6);
unsigned long interval_2 = SECONDS(18);

unsigned long previousMillis = 0;
int led = 13;
byte flag = 0;

void setup(){
  pinMode(led, OUTPUT);
  Serial.begin(9600);
  digitalWrite(led, HIGH);
  flag = 1;
  previousMillis = millis();
}

void loop(){
     if (millis() - previousMillis >= interval_2 && flag ==1) {
     digitalWrite(led, LOW);
     flag = 0;
     previousMillis = millis();
     }
     
     if (millis() - previousMillis >= interval_1 && flag ==0) {
     digitalWrite(led, HIGH);
     flag = 1;
     previousMillis = millis();
     }
 }

 

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

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

#define SECONDS(x)  ((x) * 1000UL)
#define MINUTES(x)  (SECONDS(x) * 60UL)
#define HOURS(x)  (MINUTES(x) * 60UL)
#define DAYS(x)   (HOURS(x) * 24UL)
#define WEEKS(x)  (DAYS(x) * 7UL)
unsigned long interval_1 = HOURS(0) + MINUTES(0) + SECONDS(6);
unsigned long interval_2 = HOURS(0) + MINUTES(0) + SECONDS(18);

unsigned long previousMillis = 0;
int led = 13;

void setup(){
  pinMode(led, OUTPUT);
  Serial.begin(9600);
  digitalWrite(led, HIGH);
  flag = 1;
  previousMillis = millis();
}

void loop(){
     if (millis() - previousMillis >= interval_2 && digitalRead(led)== HIGH) {
     digitalWrite(led, LOW);
     previousMillis = millis();
     }
     
     if (millis() - previousMillis >= interval_1 && digitalRead(led)== LOW) {
     digitalWrite(led, HIGH);
     previousMillis = millis();
     }
 }

 

Pyotr
Offline
Зарегистрирован: 12.03.2014

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

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

Pyotr пишет:
Смею предположить, что ТС нужен не просто таймер, а суточный таймер. (привязка к началу суток). А тут уж без RTC не обойтись.

Не обязательно. Пусть сам встаёт и ровно в полночь  нажимает Reset

SLKH
Offline
Зарегистрирован: 17.08.2015

DetSimen пишет:

Pyotr пишет:
Смею предположить, что ТС нужен не просто таймер, а суточный таймер. (привязка к началу суток). А тут уж без RTC не обойтись.

Не обязательно. Пусть сам встаёт и ровно в полночь  нажимает Reset

Да.

А для вставания в 23:55 и нажимания спаять устройство на ардуине с RTC.

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

DetSimen пишет:

Пусть сам встаёт и ровно в полночь  нажимает Reset

Не обязательно самому, можно нанять кого-нибудь.

ratman
Offline
Зарегистрирован: 11.10.2015

https://www.arduinolibraries.info/libraries/sw-rtc можно обойтись без толкового майора.

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

ratman пишет:

https://www.arduinolibraries.info/libraries/sw-rtc можно обойтись без толкового майора.

Проследите цепочку постов от #9 до #12. Вы её просто зациклили и вернулись в исходную точку :)

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

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

DetSimen пишет:

Пусть сам встаёт и ровно в полночь  нажимает Reset

Не обязательно самому, можно нанять кого-нибудь.

зачем нанимать? у некоторых...
для этой самой штуки есть своя законная жена )))

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

Дороже выйдет.

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

а вот если применить битовые оперции, хотя бы на чтение, то экономим не только ОЗУ но и память программ )))
 

#define SECONDS(x)  ((x) * 1000UL)
#define MINUTES(x)  (SECONDS(x) * 60UL)
#define HOURS(x)  (MINUTES(x) * 60UL)
#define DAYS(x)   (HOURS(x) * 24UL)
#define WEEKS(x)  (DAYS(x) * 7UL)
unsigned long interval_1 = HOURS(0) + MINUTES(0) + SECONDS(6);
unsigned long interval_2 = HOURS(0) + MINUTES(0) + SECONDS(18);
#define port PORTB
#define pin 5

unsigned long previousMillis = 0;
int led = 13;

void setup(){
  pinMode(led, OUTPUT);
  Serial.begin(9600);
  digitalWrite(led, HIGH);
  previousMillis = millis();
}

void loop(){
    // if (millis() - previousMillis >= interval_2 && digitalRead(led)== HIGH) {
    // if (millis() - previousMillis >= interval_2 && bitRead(PORTB,5) == HIGH) {
     if (millis() - previousMillis >= interval_2 && bitRead(port,pin) == HIGH) { 
     digitalWrite(led, LOW);
     previousMillis = millis();
     }
     
    // if (millis() - previousMillis >= interval_1 && digitalRead(led)== LOW) {
    // if (millis() - previousMillis >= interval_1 && bitRead(PORTB,5) == LOW) { 
     if (millis() - previousMillis >= interval_1 && bitRead(port,pin) == LOW) { 
     digitalWrite(led, HIGH);
     previousMillis = millis();
     }
 }

 

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

а если воспользоваться битовыми операциями и для записи в порт, то экономия места под программу составит еще пару сотен байт )))
 

#define SECONDS(x)  ((x) * 1000UL)
#define MINUTES(x)  (SECONDS(x) * 60UL)
#define HOURS(x)  (MINUTES(x) * 60UL)
#define DAYS(x)   (HOURS(x) * 24UL)
#define WEEKS(x)  (DAYS(x) * 7UL)
unsigned long interval_1 = HOURS(0) + MINUTES(0) + SECONDS(6);
unsigned long interval_2 = HOURS(0) + MINUTES(0) + SECONDS(18);
#define port PORTB
#define pin 5

unsigned long previousMillis = 0;
int led = 13;

void setup(){
  pinMode(led, OUTPUT);
  Serial.begin(9600);
  bitWrite(port,pin,HIGH);
 // digitalWrite(led, HIGH);
  previousMillis = millis();
}

void loop(){
    // if (millis() - previousMillis >= interval_2 && digitalRead(led)== HIGH) {
    // if (millis() - previousMillis >= interval_2 && bitRead(PORTB,5) == HIGH) {
     if (millis() - previousMillis >= interval_2 && bitRead(port,pin) == HIGH) { 
     bitWrite(port,pin,LOW);
     //digitalWrite(led, LOW);
     previousMillis = millis();
     }
     
    // if (millis() - previousMillis >= interval_1 && digitalRead(led)== LOW) {
    // if (millis() - previousMillis >= interval_1 && bitRead(PORTB,5) == LOW) { 
     if (millis() - previousMillis >= interval_1 && bitRead(port,pin) == LOW) { 
     bitWrite(port,pin,HIGH); 
    // digitalWrite(led, HIGH);
     previousMillis = millis();
     }
 }

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

#define SECONDS(x)  ((x) * 1000UL)
#define MINUTES(x)  (SECONDS(x) * 60UL)
#define HOURS(x)  (MINUTES(x) * 60UL)
#define DAYS(x)   (HOURS(x) * 24UL)
#define WEEKS(x)  (DAYS(x) * 7UL)
#define port PORTB
#define pin 5

PROGMEM const unsigned long interval[2] = {HOURS(0) + MINUTES(0) + SECONDS(1), HOURS(0) + MINUTES(0) + SECONDS(2)};

unsigned long previousMillis;

void setup(){
  port = DDRB = 1 << pin;
}

void loop(){
  bool b = bitRead(port,pin);
  unsigned long Millis = millis();
  if (Millis - previousMillis >= pgm_read_dword_near(&interval[b])) { 
    bitWrite(port,pin,!b);
    previousMillis = Millis;
  }
 }
ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

andriano пишет:


#define SECONDS(x)  ((x) * 1000UL)
#define MINUTES(x)  (SECONDS(x) * 60UL)
#define HOURS(x)  (MINUTES(x) * 60UL)
#define DAYS(x)   (HOURS(x) * 24UL)
#define WEEKS(x)  (DAYS(x) * 7UL)
#define port PORTB
#define pin 5

PROGMEM const unsigned long interval[2] = {HOURS(0) + MINUTES(0) + SECONDS(1), HOURS(0) + MINUTES(0) + SECONDS(2)};

unsigned long previousMillis;

void setup(){
  port = DDRB = 1 << pin;
}

void loop(){
  bool b = bitRead(port,pin);
  unsigned long Millis = millis();
  if (Millis - previousMillis >= pgm_read_dword_near(&interval[b])) { 
    bitWrite(port,pin,!b);
    previousMillis = Millis;
  }
 }

красиво!!!

не совсем понимаю 14 строку, DDRB это настройка на выход?

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

ua6em пишет:

не совсем понимаю 14 строку, DDRB это настройка на выход?

Запись единицы в пятый бит регистра Data Direction Register порта B, т.е. запись единицы для пина PB5. Запись единицы в регистр DDRx настраивает пин на выход.

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

Jeka_M пишет:

ua6em пишет:

не совсем понимаю 14 строку, DDRB это настройка на выход?

Запись единицы в пятый бит регистра Data Direction Register порта B, т.е. запись единицы в PB5. Запись единицы настраивает пин на выход.

это понятно, там же не только настраивает на выход я так понимаю и устанавливает на нём 1?

То-есть выполнение программы идёт по арабско-армянски, справо налево

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Нет, только настраивает на выход. Чтобы установить на пине высокий уровень, нужно PORTB |= 1 << pin;

UPD: Ой, извиняюсь. Не заметил выше дефайн #define port PORTB. Таки да, сразу настраивает на выход и устанавливает высокий уовень, Вы правы.

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

Jeka_M пишет:

Нет, только настраивает на выход. Чтобы установить на пине высокий уровень, нужно PORTB |= 1 << pin;

UPD: Ой, извиняюсь. Не заметил выше дефайн #define port PORTB. Таки да, сразу настраивает на выход и устанавливает высокий уовень.


Вывел в сериал, при первом вхождении в порту 1 однако

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

ua6em пишет:

То-есть выполнение программы идёт по арабско-армянски, справо налево

Можно сначала записать единицу в PORTx, а потом в DDRx. В таком случае сразу включится внутренняя подтяжка, а потом пин переведётся на выход. В принципе без разницы, куда сначала писать единицу - в DDRx или в PORTx.

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

а если булеву заменить на байт, то еще 8 байт экономим в блоке программного кода )))

#define SECONDS(x)  ((x) * 1000UL)
#define MINUTES(x)  (SECONDS(x) * 60UL)
#define HOURS(x)  (MINUTES(x) * 60UL)
#define DAYS(x)   (HOURS(x) * 24UL)
#define WEEKS(x)  (DAYS(x) * 7UL)
#define port PORTB
#define pin 5

PROGMEM const unsigned long interval[2] = {HOURS(0) + MINUTES(0) + SECONDS(1), HOURS(0) + MINUTES(0) + SECONDS(2)};

unsigned long previousMillis;

void setup(){
  //Serial.begin(9600);
  port = DDRB = 1 << pin;
}

void loop(){
 // bool b = bitRead(port,pin);
   byte b = bitRead(port,pin);
  unsigned long Millis = millis();
  if (Millis - previousMillis >= pgm_read_dword_near(&interval[b])) { 
 //   Serial.println(b);
    bitWrite(port,pin,!b);
    previousMillis = Millis;
  }
 }