Arduino: Таймер включения/отключения

Cesium137
Cesium137 аватар
Offline
Зарегистрирован: 13.12.2016

Вот код про поток задач Thread из сайта  http://www.kakprosto.ru/kak-918733-kak-vypolnyat-parallelnye-zadachi-threads-v-programme-dlya-arduino. Запускал два светодиода мигающие в оджно и тоже время с одинаковым интервалом. Пока не промигает первый второй не начнет. Вывод. код не работает для моей задачи псевдопараллельности.

#include <Thread.h>//Подключение библиотеки
const int led1=2;
const int led2=4;
Thread led1Thread=Thread()//создаем поток мигания первого леда;
Thread led2Thread=Thread();//поток мигания второго леда

void setup(){
  pinMode(led1,OUTPUT);
  pinMode(led2,OUTPUT);
  
  led1Thread.onRun(funcled1);//назначаем потоку задачу тоесть функцию ты что в скобках
  led1Thread.setInterval(20);//задаем интервал срабатывания потока, мсек
  
  led2Thread.onRun(funcled2);
  led2Thread.setInterval(1000);
}
  void loop(){
    //проверим, пришло ли время переключиться светодиоду
    if (led1Thread.shouldRun())
    led1Thread.run();//запускаем поток
   
    if(led2Thread.shouldRun())
    led2Thread.run();
 }
  
  void funcled1(){
  digitalWrite(led1,HIGH);
  delay(2000);
  digitalWrite(led1,LOW);
  delay(2000);
}

 void funcled2(){
  digitalWrite(led2,HIGH);
}

 

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

Цитата от сюда: В каждой итерации цикла для каждого потока проверяем, пришло ли время его выполнения или нет. Если пришло - он запускается на исполнение с помощью метода "run()". Главное - не использовать оператор "delay()".

И что мы видим:

void funcled1(){
  digitalWrite(led1,HIGH);
  delay(2000);
  digitalWrite(led1,LOW);
  delay(2000);
}
 

Стою на асфальте в лыжи обутый, то ли лыжи не едут, то ли я долбанутый.

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

Теперь свои делеи(2секунды) переделайте на аналогичную обработку и все взлетит. Охота со всякими подобными библами извращаться. Лучше велосипед Клапауция изучите. ИМХО.

Cesium137
Cesium137 аватар
Offline
Зарегистрирован: 13.12.2016

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

void funcled1() // сама функция таймера ее тело
{
if (fl_pause == 0 && millis() - currentPause >= 5000)  //В начале запуска Вытяжка не работает  5 секунд
    {
        digitalWrite(led1, HIGH);//по достижении 5 секунд она включается командой HIGH
        currentPause = millis();
        fl_pause = 1;
    }
    if (fl_pause == 1 && millis() - currentPause >= 5000)  //Если прошло 10 секунд то
    {
        digitalWrite(led1, LOW);// то вытяжка отключается, т.е получается она проработает 10 секунд.
        fl_pause = 0;
        currentPause = millis();

 

Cesium137
Cesium137 аватар
Offline
Зарегистрирован: 13.12.2016
Все я сделал псевдо параллельную работу двух светодиодов. Точнее не совсем я сам))))). Но разобрался наконец как и что работает
void funcled1(){
   static bool ledstatus=false;
   ledstatus=!ledstatus;
   digitalWrite(led1,ledstatus);

Отсутствие делей

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
(анекдот)
Старый шофер учит молодого:
- Запомни , салага, на машине старайся ездить вдоль дороги, а не поперек.
Молодой, удивленно:
- Почему?
-  Вдоль дорога длиная, долго можно ехать. А поперек от бордюра до бордюра даже газ не успел нажать, как вылетел.

В конечном итоге похожая картина и в программировании. Чем больше программа и чем больше устройств она обслуживает, тем больше параллельных процессов организовывается. И не важно, как это сделано: как у вас выше, при помощи костылей, или как-то иначе, но чаще всего это сделано неявно. Но в любом случае, отдельный параллельный процесс не должен заклинивать. Потому-что если заклинит где-то, то заклинит вся программа.

Cesium137
Cesium137 аватар
Offline
Зарегистрирован: 13.12.2016

Я уже об этом призадумался. и думаю как организовать в будущем. ВОт например в коде выше если поставить одну функцию на основе millis() а другую без нее то работают одновременно две (псевдопараллельно). Если же две функции на основе millis() задействованы, то одна из них не работает

#include <Thread.h>//Подключение библиотеки
const int led1=2;
const int led2=4;
Thread led1Thread=Thread();//создаем поток мигания первого леда;
Thread led2Thread=Thread();//поток мигания второго леда
unsigned long currentPause = millis();   //массив данных.
bool fl_pause;//массив данных.

void setup(){
  pinMode(led1,OUTPUT);
  pinMode(led2,OUTPUT);
  
  led1Thread.onRun(funcled1);//назначаем потоку задачу тоесть функцию ты что в скобках
  led1Thread.setInterval(1000);//задаем интервал срабатывания потока, мсек
  
 // led2Thread.onRun(funcled2);//задержки отключены, т.к. в функции выставлена интервалы работы
  //led2Thread.setInterval(1000);
}

  void loop(){
    //проверим, пришло ли время переключиться светодиоду
    if (led1Thread.shouldRun())
  led1Thread.run();//запускаем поток
    
    if (led2Thread.shouldRun())
  led2Thread.run();//запускаем поток 
    
 }
  
void funcled1(){
  
{
if (fl_pause == 0 && millis() - currentPause >= 5000)  //В начале запуска Вытяжка не работает  5 секунд
    {
        digitalWrite(led1, HIGH);//по достижении 5 секунд она включается командой HIGH
        currentPause = millis();
        fl_pause = 1;
    }
    if (fl_pause == 1 && millis() - currentPause >= 5000)  //Если прошло 10 секунд то
    {
        digitalWrite(led1, LOW);// то вытяжка отключается, т.е получается она проработает 10 секунд.
        fl_pause = 0;
        currentPause = millis();
    
}
} 
}
 

void funcled2(){
  
{
if (fl_pause == 0 && millis() - currentPause >= 5000)  //В начале запуска Вытяжка не работает  5 секунд
    {
        digitalWrite(led2, HIGH);//по достижении 5 секунд она включается командой HIGH
        currentPause = millis();
        fl_pause = 1;
    }
    if (fl_pause == 1 && millis() - currentPause >= 5000)  //Если прошло 10 секунд то
    {
        digitalWrite(led2, LOW);// то вытяжка отключается, т.е получается она проработает 10 секунд.
        fl_pause = 0;
        currentPause = millis();
    
}
} 
}

 

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

Мой "классический" код выглядит так.

/*
#1
#2
#3
*/
//#1
//#2
//#3
void setup() {
  //#1
  //#2
  //#3
}
void loop() {
  static uint32_t MILLIS ;
  MILLIS = millis() ;
  //#1 1000 миллисекунд вычислит. поток 1
  static uint32_t past_1 = 0 ;
  if (MILLIS - past_1 >= 1000) { // если прошло 1000 миллисек
    past_1 = MILLIS ;
    // сам код
    MILLIS = millis() ;
  }
  //#2  200 миллисекунд вычислит. поток 2
  static uint32_t past_2 = 0 ;
  if (MILLIS - past_2 >= 200) { // если прошло 200 миллисек
    past_2 = MILLIS ;
    // сам код
    MILLIS = millis() ;
  }
  //#3  100 миллисекунд вычислит. поток 3
  static uint32_t past_3 = 0 ;
  if (MILLIS - past_3 >= 100) { // если прошло 100 миллисек
    past_3 = MILLIS ;
    // сам код
  }
}

И да.  На основе "параллельный процессов" облегчается проектирование программы, но усложняется сам код. И еще один бонус. Если у вас есть несколько скетчей программ на основе "параллельный процессов" , то их легко поместить в одну ардуину. Чего нельзя реализовать при обычном написании. Хотя для опытных програмистов это не составит труда.

Вот мой аналог написаного выше вами скетча. Тоже 2 процесса.

/*
 //#1 5 секунд не работает 5 секунд работает и дальше
светодиод 1->2 (led1_pin) 1 вкл/0 выкл
 //#2 6 секунд не работает 6 секунд работает и дальше
светодиод 2->4 (led2_pin) 1 вкл/0 выкл
*/
//#1
const int led1_pin = 2;
bool led1; //состояние реле 1 вкл/ 0 нет
//#2
const int led2_pin = 4;
bool led2; //состояние реле 1 вкл/ 0 нет
void setup() {
  //#1
  pinMode(led1_pin, OUTPUT);
  digitalWrite(led1_pin, led1 = 0);
  //#2
  pinMode(led2_pin, OUTPUT);
  digitalWrite(led2_pin, led2 = 0);
}

void loop() {
  //#1 10сек вычислит. поток 1
  static uint32_t past_1 = 0 ;
  if (! led1 && millis() - past_1 >= 5000) // если прошло 5 сек
    digitalWrite(led1_pin, led1 = 1); // вкл вытяжку
  if (millis() - past_1 >= 10000) { // если прошло 10 секунд
    past_1 = millis() ;
    digitalWrite(led1_pin, led1 = 0); // выкл вытяжку
  }
    //#2 12 сек вычислит. поток 2
  static uint32_t past_2 = 0 ;
  if (! led2 && millis() - past_2 >= 6000) // если прошло 6 сек
    digitalWrite(led2_pin, led2 = 1); // вкл вытяжку
  if (millis() - past_2 >= 12000) { // если прошло 12 секунд
    past_2 = millis() ;
    digitalWrite(led2_pin, led2 = 0); // выкл вытяжку
  }
}

ПС: В моем посте #55 этой темы была точно такая же программа. И да я не навязываю свой стиль. Я просто показываю вариант 

Cesium137
Cesium137 аватар
Offline
Зарегистрирован: 13.12.2016

Спасибо вам огромное за ваши коды. опробую код с двумя процессами. пригодятся например для усправления двумя реле по времени или ещё для чего. ТЕм более я так понимаю и сколько угодно можно процессов запускать одновременно и с функцией миллис (заданный таймер и интервал в которой). Функциональность от этого будет хорошей при многозадачности умного дома. Хотя я ещё не совсем определился что буду автоматизировать.

ДЛя начала хочу сделать:

1)контроль утечки природного газа на базе MQ-4. Акуратно от газовой службы ради эксперимента хочу приобрести электромагнитный газовый клапан. и в случае утечуи газа (например залило водой из кипящей кастрюли пламя) клапан закрывался.

2)температурный контроль- Даллас плюс включение или отключение кондиционера.

3) Отключение света в комнатах при отсутствии человека на основе PIR инфракрасного датчика. ПРавда не разобрался как соединить провода чтобы основной выключатель работал также. Т.к вкл и выкл света будет осуществлять реле.

4)Сигнализатор задымленности на основе MQ2.

5 автополив маминого цветка на основе датчика влажности почвы и помпы от аквариума (управление помпы через реле).

Если все это сделаю путем упрного труда в программировании на С , то в перспективе хочу управлять домом и следить за показаниями через WEB на смартфоне когда бду отсутствовать дома.

НЕдавно читал чо выла (правда недоработанная) ОС Arduino MEga Server. можно будет создавать полнофункциональный веб интерфейс для управление и мониторинга ардуино

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

qwone пишет:

Мой "классический" код выглядит так.

/*
#1
#2
#3
*/
//#1
//#2
//#3
void setup() {
  //#1
  //#2
  //#3
}
void loop() {
  static uint32_t MILLIS ;
  MILLIS = millis() ;
  //#1 1000 миллисекунд вычислит. поток 1
  static uint32_t past_1 = 0 ;
  if (MILLIS - past_1 >= 1000) { // если прошло 1000 миллисек
    past_1 = MILLIS ;
    // сам код
    MILLIS = millis() ;
  }
  //#2  200 миллисекунд вычислит. поток 2
  static uint32_t past_2 = 0 ;
  if (MILLIS - past_2 >= 200) { // если прошло 200 миллисек
    past_2 = MILLIS ;
    // сам код
    MILLIS = millis() ;
  }
  //#3  100 миллисекунд вычислит. поток 3
  static uint32_t past_3 = 0 ;
  if (MILLIS - past_3 >= 100) { // если прошло 100 миллисек
    past_3 = MILLIS ;
    // сам код
  }
}

И да.  На основе "параллельный процессов" облегчается проектирование программы, но усложняется сам код. И еще один бонус. Если у вас есть несколько скетчей программ на основе "параллельный процессов" , то их легко поместить в одну ардуину. Чего нельзя реализовать при обычном написании. Хотя для опытных програмистов это не составит труда.

Вот мой аналог написаного выше вами скетча. Тоже 2 процесса.

/*
 //#1 5 секунд не работает 5 секунд работает и дальше
светодиод 1->2 (led1_pin) 1 вкл/0 выкл
 //#2 6 секунд не работает 6 секунд работает и дальше
светодиод 2->4 (led2_pin) 1 вкл/0 выкл
*/
//#1
const int led1_pin = 2;
bool led1; //состояние реле 1 вкл/ 0 нет
//#2
const int led2_pin = 4;
bool led2; //состояние реле 1 вкл/ 0 нет
void setup() {
  //#1
  pinMode(led1_pin, OUTPUT);
  digitalWrite(led1_pin, led1 = 0);
  //#2
  pinMode(led2_pin, OUTPUT);
  digitalWrite(led2_pin, led2 = 0);
}

void loop() {
  //#1 10сек вычислит. поток 1
  static uint32_t past_1 = 0 ;
  if (! led1 && millis() - past_1 >= 5000) // если прошло 5 сек
    digitalWrite(led1_pin, led1 = 1); // вкл вытяжку
  if (millis() - past_1 >= 10000) { // если прошло 10 секунд
    past_1 = millis() ;
    digitalWrite(led1_pin, led1 = 0); // выкл вытяжку
  }
    //#2 12 сек вычислит. поток 2
  static uint32_t past_2 = 0 ;
  if (! led2 && millis() - past_2 >= 6000) // если прошло 6 сек
    digitalWrite(led2_pin, led2 = 1); // вкл вытяжку
  if (millis() - past_2 >= 12000) { // если прошло 12 секунд
    past_2 = millis() ;
    digitalWrite(led2_pin, led2 = 0); // выкл вытяжку
  }
}

ПС: В моем посте #55 этой темы была точно такая же программа. И да я не навязываю свой стиль. Я просто показываю вариант 

А если миллис переполнится?

Nosferatu
Offline
Зарегистрирован: 04.11.2012

knack пишет:

А если миллис переполнится?

Я раньше тоже делал ненужные корректировки переполнения millis.

Там всё учтено.  (Unsigned long) 0 - 1 ==  4294967295

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

Cesium137 пишет:

Я уже об этом призадумался. и думаю как организовать в будущем. ВОт например в коде выше если поставить одну функцию на основе millis() а другую без нее то работают одновременно две (псевдопараллельно). Если же две функции на основе millis() задействованы, то одна из них не работает

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

UPD, кстати о граблях, чтобы потом не было мучительно больно, на функции  действуют правила переменных (должна быть объявлена до использования). Соответственно их лучше размещать до первого вызова. На некоторых версиях IDE можете столкнуться с непонятной ошибкой.

Cesium137
Cesium137 аватар
Offline
Зарегистрирован: 13.12.2016

Нашел ошибки. У меня переменные в обеих функциях одинаковые переменные (их имена). Попробую запустить код в разными пеменными

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

Cesium137 пишет:

Нашел ошибки. У меня переменные в обеих функциях одинаковые переменные (их имена). Попробую запустить код в разными пеменными

У них тоже одинаковые переменные.

P/S Пардон, виноват. У qwone они разные, если вывести эти блоки в отдельные функции, то можно использовать одно имя переменной для всех функций.

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

knack пишет:

А если миллис переполнится?

В каком месте? Я может невнимательно посмотрел, но вроде там с этим нормально всё.

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

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

knack пишет:

А если миллис переполнится?

В каком месте? Я может невнимательно посмотрел, но вроде там с этим нормально всё.

Очередной холивар на тему сбрендившей бабушки Миллис.

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

bwn пишет:

холивар на тему сбрендившей бабушки Миллис.

Нет, я на эту тему давно не холиварю. Просто, думаю, мож пропустил чего. Покажет, что я пропустил - спасибо. Не покажет - и Бог с ним.

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

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

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

bwn пишет:

холивар на тему сбрендившей бабушки Миллис.

Нет, я на эту тему давно не холиварю. Просто, думаю, мож пропустил чего. Покажет, что я пропустил - спасибо. Не покажет - и Бог с ним.

Я не про Вас. Человек с двенадцатого года зарегистрирован и вдруг, вопрос.

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012
if (millis() - past_2 >= 12000) { // если прошло 12 секунд
    past_2 = millis() ;

Никакого холивара, если past_2 == 4,294,955,295, a millis() == 0 то ваш цикл сработает только через 50 дней.

if (millis() < past_2)past_2=0; //или 
if (millis() < past_2)past_2=millis(); // как душе угодно

 

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

Nosferatu пишет:

knack пишет:

А если миллис переполнится?

Я раньше тоже делал ненужные корректировки переполнения millis.

Там всё учтено.  (Unsigned long) 0 - 1 ==  4294967295

где?

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

p19cc0r31d3ig1gb1c5unv8v0i.gif

Nosferatu
Offline
Зарегистрирован: 04.11.2012

knack пишет:

Nosferatu пишет:

knack пишет:

А если миллис переполнится?

Я раньше тоже делал ненужные корректировки переполнения millis.

Там всё учтено.  (Unsigned long) 0 - 1 ==  4294967295

где?

Проврете

void setup() {
  Serial.begin(9600);
}

void loop() {
static uint32_t past_1 = 4294955295;
Serial.println(0ul - past_1);
}

 

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

Клапауций 234 пишет:

p19cc0r31d3ig1gb1c5unv8v0i.gif

не показывает, расскажи хоть, что там было?

Nosferatu
Offline
Зарегистрирован: 04.11.2012
knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

Nosferatu пишет:

knack пишет:

Nosferatu пишет:

knack пишет:

А если миллис переполнится?

Я раньше тоже делал ненужные корректировки переполнения millis.

Там всё учтено.  (Unsigned long) 0 - 1 ==  4294967295

где?

Проврете

void setup() {
  Serial.begin(9600);
}

void loop() {
static uint32_t past_1 = 4294955295;
Serial.println(0ul - past_1);
}

 

Вечером, щас арбайтен.

0ul - это шо?

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

Nosferatu пишет:

Музыкальная пауза.

неосилил, есть, что по энергичнее?

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

Хорошо, Клапауций отвали пока, миллис при переполнении на ноль сбрасывается?

 

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

knack пишет:

Nosferatu пишет:

Музыкальная пауза.

неосилил, есть, что по энергичнее?

https://youtu.be/IUcPa3Twm5A

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

knack пишет:

if (millis() - past_2 >= 12000) { // если прошло 12 секунд
    past_2 = millis() ;

Никакого холивара, если past_2 == 4,294,955,295, a millis() == 0 то ваш цикл сработает только через 50 дней.

Нормально там всё будет.

Эта тема здесь столько раз холиварилась, что я больше не буду. Сами разберётесь. Самая простая проверка - в файле wiring.c найдите определение переменной timer0_millis и проинициализируйте её не 0, а чем-нибудь типа 2^32 - "минуту-две". Запустите тест. Через минуту миллис благополучно переполнится и Вы увидите как повела себя программа.

Только, пожалуйста, не задавайте мне на эту тему вопросов - проверьте, убедитесь, а захотите понять почему так, "поиск" в правом верхнем углу - найдёте с полсотни холиваров - разбирайтесь.

Nosferatu
Offline
Зарегистрирован: 04.11.2012

Клапауций 234 пишет:

knack пишет:

Nosferatu пишет:

Музыкальная пауза.

неосилил, есть, что по энергичнее?

https://youtu.be/IUcPa3Twm5A

Motörhead

Nosferatu
Offline
Зарегистрирован: 04.11.2012

knack пишет:

0ul - это шо?

Указание, что 0 это unsigned long.

LITTLE BIG - HATEFUL LOVE

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

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

 

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

Nosferatu пишет:

Motörhead

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

https://youtu.be/D2I_ElE8c8A

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012
LITTLE BIG - HATEFUL LOVE

Зачёт!

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

Значит, у Вас было не

if (millis() - past_2 >= 12000) { // если прошло 12 секунд
    past_2 = millis() ;

а

if (millis() >= 12000 + past_2) { // если прошло 12 секунд
    past_2 = millis() ;

А это две большие разницы.

Умоляю, прекратим. Я Вам сказал, как проверить - проверьте, убедитесь, а объяснений здесь в холиварах вагон. Захотите - найдёте и разберётесь.

Я прекращаю любые ответы и комментарии на эту тему.

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

knack пишет:

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

как-то так - всё работает вечно

// 4294967294 - 4294967284 = 10
// 4294967295 - 4294967285 = 10
// 0          - 4294967286 = 10
// 1          - 4294967287 = 10
// 2          - 4294967288 = 10
// 3          - 4294967289 = 10
// 4          - 4294967290 = 10
// 5          - 4294967291 = 10
// 6          - 4294967292 = 10
// 7          - 4294967293 = 10
// 8          - 4294967294 = 10
// 9          - 4294967295 = 10
// 10         - 0          = 10
// 11         - 1          = 10

 

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

Nosferatu пишет:

Клапауций 234 пишет:

knack пишет:

Nosferatu пишет:

Музыкальная пауза.

неосилил, есть, что по энергичнее?

https://youtu.be/IUcPa3Twm5A

Motörhead

SEPULTURA

https://www.youtube.com/watch?v=Q_WHGV5bejk

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

Клапауций 234 пишет:

knack пишет:

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

как-то так - всё работает вечно

// 4294967294 - 4294967284 = 10
// 4294967295 - 4294967285 = 10
// 0          - 4294967286 = 10
// 1          - 4294967287 = 10
// 2          - 4294967288 = 10
// 3          - 4294967289 = 10
// 4          - 4294967290 = 10
// 5          - 4294967291 = 10
// 6          - 4294967292 = 10
// 7          - 4294967293 = 10
// 8          - 4294967294 = 10
// 9          - 4294967295 = 10
// 10         - 0          = 10
// 11         - 1          = 10

 

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

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

0 - 4,294,955,295 > 12000

Всё, завис, лан вечером покурю.

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

knack пишет:

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

ну, как бы поэтому:

Unsigned long используется для хранения положительных целых чисел в диапазоне от 0 до 4,294,967,295 (2^32 - 1) изанимает 32 бита (4 байта) в памяти.

http://arduino.ru/Reference/UnsignedLong

примерно так, как на круглом циферблате часов 0 - 12 часов или 0 - 60 минут, но время идёт вечно и конца света не случается.

сделай принт Unsigned long а = 4294967296;

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

это я понимаю, я про то что условие не выполняется при котором присвется переменной значения функции миллис, переменной придётся ждать пока миллис не догонит переменную до второго круга, т.е. 50 дней, если usigned long 0 - 400000000 =? что на выходе, нет железки проверить, если там не 0 а 4000000000, то я затыкаюсь. Я так понимаю 400000000! т.е. 0 - 400000000 =  -400000000 но т.к. это ul то будет 400000000 так?

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

knack пишет:

это я понимаю, я про то что условие не выполняется при котором присвется переменной значения функции миллис, переменной придётся ждать пока миллис не догонит переменную до второго круга, т.е. 50 дней, если usigned long 0 - 400000000 =? что на выходе, нет железки проверить, если там не 0 а 4000000000, то я затыкаюсь. Я так понимаю 400000000! т.е. 0 - 400000000 =  -400000000 но т.к. это ul то будет 400000000 так?

ок. если от 00:00 вычесть 20 часов, сколько будет? 20:00 или 04:00 ? О_О

т.к. 24 - 20 = 4

если циферблат у тебя не 24, а 4294967296, то 

4294967296 - что-то, т.к. 4294967296 - это 4294967296 или 0, по аналогии циферблата часов - где там 0 и почему только 12?

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

Клапауций 234 пишет:

knack пишет:

это я понимаю, я про то что условие не выполняется при котором присвется переменной значения функции миллис, переменной придётся ждать пока миллис не догонит переменную до второго круга, т.е. 50 дней, если usigned long 0 - 400000000 =? что на выходе, нет железки проверить, если там не 0 а 4000000000, то я затыкаюсь. Я так понимаю 400000000! т.е. 0 - 400000000 =  -400000000 но т.к. это ul то будет 400000000 так?

ок. если от 00:00 вычесть 20 часов, сколько будет? 20:00 или 04:00 ? О_О

т.к. 24 - 20 = 4

если циферблат у тебя не 24, а 4294967296, то 

4294967296 - что-то, т.к. 4294967296 - это 4294967296 или 0, по аналогии циферблата часов - где там 0 и почему только 12?

Клапауций 234 ты, сука гена!!! я понять!!! чо, сразу так не обьяснил.

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

bwn пишет:

У них тоже одинаковые переменные.

P/S Пардон, виноват. У qwone они разные, если вывести эти блоки в отдельные функции, то можно использовать одно имя переменной для всех функций.

Дальнейшее развитие, запихнуть все это хозяйство в класс.

/*
 //#1 5 секунд не работает 5 секунд работает и дальше
светодиод 1->2 (led1_pin) 1 вкл/0 выкл
 //#2 6 секунд не работает 6 секунд работает и дальше
светодиод 2->4 (led2_pin) 1 вкл/0 выкл
*/
class cl_Cesium {
  public:
    cl_Cesium(int pin, int Time_OFF, int Time_ON);
    void in_setup();
    void in_loop();
  private:
    int _pin; // нога реле
    int _Time_OFF; // время выключения
    int _Time_ON; // время включения
    bool _led; //состояние реле 1 вкл/ 0 нет
    uint32_t past_1 = 0 ;// время последнего обращения

};
cl_Cesium::cl_Cesium(int pin, int Time_OFF, int Time_ON) {
  _pin = pin;
  _Time_OFF = Time_OFF;
  _Time_ON = Time_ON;
}
void cl_Cesium::in_setup() {
  pinMode(_pin, OUTPUT);
  digitalWrite(_pin, _led = 0);
}
void cl_Cesium::in_loop() {
  if (! _led && millis() - past_1 >= _Time_OFF) // если прошло _Time_OFF
    digitalWrite(_pin, _led = 1); // вкл вытяжку
  if (millis() - past_1 >= _Time_OFF + _Time_ON) { // если прошло _Time_OFF+_Time_ON
    past_1 = millis() ;
    digitalWrite(_pin, _led = 0); // выкл вытяжку
  }
}

//#1
const int led1_pin = 2;
cl_Cesium Cesium_1(led1_pin, 5000, 5000); // 5 сек выкл - 5 сек вкл
//#2
const int led2_pin = 4;
cl_Cesium Cesium_2(led2_pin, 6000, 6000); // 6 сек выкл - 6 сек вкл

void setup() {
  //#1
  Cesium_1.in_setup();
  //#2
  Cesium_2.in_setup();
}

void loop() {
  //#1 вычислит. поток 1
  Cesium_1.in_loop();
  //#2 вычислит. поток 2
  Cesium_2.in_loop();
}

А затем весь класс засунуть в свою библиотеку. 

/*
 //#1 5 секунд не работает 5 секунд работает и дальше
светодиод 1->2 (led1_pin) 1 вкл/0 выкл
 //#2 6 секунд не работает 6 секунд работает и дальше
светодиод 2->4 (led2_pin) 1 вкл/0 выкл
*/
#include "cl_Cesium.h"
//#1
const int led1_pin = 2;
cl_Cesium Cesium_1(led1_pin, 5000, 5000); // 5 сек выкл - 5 сек вкл
//#2
const int led2_pin = 4;
cl_Cesium Cesium_2(led2_pin, 6000, 6000); // 6 сек выкл - 6 сек вкл

void setup() {
  //#1
  Cesium_1.in_setup();
  //#2
  Cesium_2.in_setup();
}

void loop() {
  //#1 вычислит. поток 1
  Cesium_1.in_loop();
  //#2 вычислит. поток 2
  Cesium_2.in_loop();
}

А теперь дополнительные файлы.

//cl_Cesium.h
#ifndef cl_Cesium_h
#define cl_Cesium_h
 
#include "Arduino.h"

class cl_Cesium {
  public:
    cl_Cesium(int pin, int Time_OFF, int Time_ON);
    void in_setup();
    void in_loop();
  private:
    int _pin; // нога реле
    int _Time_OFF; // время выключения
    int _Time_ON; // время включения
    bool _led; //состояние реле 1 вкл/ 0 нет
    uint32_t past_1 = 0 ;// время последнего обращения

};
#endif

И второй

//cl_Cesium.cpp
#include "Arduino.h"
#include "cl_Cesium.h"

cl_Cesium::cl_Cesium(int pin, int Time_OFF, int Time_ON) {
  _pin = pin;
  _Time_OFF = Time_OFF;
  _Time_ON = Time_ON;
}
void cl_Cesium::in_setup() {
  pinMode(_pin, OUTPUT);
  digitalWrite(_pin, _led = 0);
}
void cl_Cesium::in_loop() {
  if (! _led && millis() - past_1 >= _Time_OFF) // если прошло _Time_OFF
    digitalWrite(_pin, _led = 1); // вкл вытяжку
  if (millis() - past_1 >= _Time_OFF + _Time_ON) { // если прошло _Time_OFF+_Time_ON
    past_1 = millis() ;
    digitalWrite(_pin, _led = 0); // выкл вытяжку
  }
}

 

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

qwone пишет:

Дальнейшее развитие, запихнуть все это хозяйство в класс.

Не, я пока так не умею.((((

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

qwone пишет:

И второй

//cl_Cesium.cpp
#include "Arduino.h"
#include "cl_Cesium.h"

cl_Cesium::cl_Cesium(int pin, int Time_OFF, int Time_ON) {
  _pin = pin;
  _Time_OFF = Time_OFF;
  _Time_ON = Time_ON;
}
void cl_Cesium::in_setup() {
  pinMode(_pin, OUTPUT);
  digitalWrite(_pin, _led = 0);
}
void cl_Cesium::in_loop() {
  if (! _led && millis() - past_1 >= _Time_OFF) // если прошло _Time_OFF
    digitalWrite(_pin, _led = 1); // вкл вытяжку
  if (millis() - past_1 >= _Time_OFF + _Time_ON) { // если прошло _Time_OFF+_Time_ON
    past_1 = millis() ;
    digitalWrite(_pin, _led = 0); // выкл вытяжку
  }
}

_Time_ON используется только в одном месте - в строке 17. В таком случае правильнее хранить не его, а готовую сумму _Time_OFF + _Time_ON, чтобы каждый раз не складывать. По памяти также, а сложение одно - в конструкторе.

abaza
Offline
Зарегистрирован: 23.04.2015

так какой скетч на второй странице в итоге рабочий? Который можно использовать? Имеется ввиду работы таймера

Bivis Net
Offline
Зарегистрирован: 11.04.2019

Привет знатоки.

Помогите мне плиз решить задачу, включение вытяжки на 10 минут по нажатию кнопки.

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Bivis Net пишет:

Привет знатоки.

Помогите мне плиз решить задачу, включение вытяжки на 10 минут по нажатию кнопки.

Даю алгоритм:

Ждем нажатия кнопки, после нажатия кнопки повышаем уровень на выбраном пине, ждем 10 минут (delay(10*60*1000)), понижаем уровень на выбраном пине и так по кругу. 

Bivis Net
Offline
Зарегистрирован: 11.04.2019

mykaida пишет:

Bivis Net пишет:

Привет знатоки.

Помогите мне плиз решить задачу, включение вытяжки на 10 минут по нажатию кнопки.

Даю алгоритм:

Ждем нажатия кнопки, после нажатия кнопки повышаем уровень на выбраном пине, ждем 10 минут (delay(10*60*1000)), понижаем уровень на выбраном пине и так по кругу. 

Спасибо за участие!

Мне бы чайнику в готовом виде)

нашел вот такой код, как думаете рабочий?



int button = 2; 
int led = 13; // назначаем константы 

void setup() 
{ 
pinMode(led, OUTPUT); 
pinMode(button, INPUT); // инициализируем что вход, что выход 
} 
void loop(){ if (digitalRead(button) == HIGH) 
{ 
digitalWrite(led, HIGH); 
delay(10*60*1000); 
} else {
 digitalWrite(led, LOW); 
} }