Помогите сделать код без delay().

Витя
Offline
Зарегистрирован: 09.06.2018
Здравствуйте.
Полгода назад сделал контролер для аквариума, где реализовано плавное включение
выключение света, открытие воздуха шаговым двигателем, управление инфракрасным пультом.
Еще планирую подключить датчик 18b20 ну и там еще чего-нибудь.
И все меня устраивает, кроме одного, что при плавном включение выключение света контролер больше нечего не делает.
Помогите избавится от delay().
В программирование ничего не понимаю, делал программу из того что находил в инете.
Здесь часть программы, где ардуино управляет светом. 
#include <RTC.h>
RTC  time;
int t1 = 10; // включение света
int m1=30;   // Минуты включения
int t2 = 23; // выключение сета
int m2=10;   // Минуты вылючения
int d;       // Переменная в которую записываются текущий показатель часов
int m;       // Переменная в которую записываются текущий показатель минут
int led = 5; //подключен к цифровому выводу 5
int i;

void setup(){
   Serial.begin(9600);
   
   pinMode(led, OUTPUT);
  
 // инициализация модуля RTC
  time.begin(RTC_DS3231);     // на базе чипа DS3231            модуль подключается к аппаратным выводам I2C
//  time.begin(RTC_DS1307);     // на базе чипа DS1307            модуль подключается к аппаратным выводам I2C
//  time.begin(RTC_DS1302,10,13,12);  // на базе чипа DS1302, вывод RST, вывод CLK, вывод DAT   доступны любые выводы

//  запись даты и времени
// time.settime(0,14,9,13,03,18,2);  // 0  сек, 17 мин, 15 час, 1, октября, 2015 года, четверг
//  time.settime(35,10,20);     // 35 сек, 10 мин, 20 час, дату оставить без изменений
//  time.settime(-1,-1,-1,31,12,15);  // 31, декабря, 2015 года, время и день недели оставить без изменений   
}

void loop(){ 
 d=time.Hours ;
 m=time.minutes;
  // Передать время
 Serial.println(time.gettime("d-m-Y, H:i:s, D"));
 
  // Плавное включение
   if ((time.Hours == 10) && (time.minutes == 00))
 {
 for (int i=0; i<=255; i++)
  {
   analogWrite(led, i);
   if (i==255)
    {
     digitalWrite(led, HIGH);
    } 
   delay(16000);
  }

 }
 /////
  // Защита от выключения эдектричества
  else{
  if (d <= t2 && d >= t1) {
                          if (d==t1 && m<m1) {goto label;}
                          if (d==t2 && m>m2) {goto label;}
   digitalWrite(led, HIGH);   // свет включен
   Serial.println(" HIGH ");
                        }
                        else
                            {  
                             label:           
                            digitalWrite(led, LOW);  // свет выключен 
                            Serial.println(" LOW "); 
                            }
  }
 /////
  // Плавное выключение
   if ((time.Hours == 22) && (time.minutes == 10))
{
 for (int i=255; i>=0; i--)
  {
   analogWrite(led, i);
   if (i==0)
    {
     digitalWrite(led, LOW);
    } 
   delay(16000);
  }
} 
 delay(1000);
}

 

 

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

Поищите так же "blink без delay" - должно подойти к вашей программе.

Витя
Offline
Зарегистрирован: 09.06.2018

"blink без delay"  у меня не получается срастить с плавным включением.

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

Витя пишет:

Помогите избавится от delay().
В программирование ничего не понимаю, делал программу из того что находил в инете.
 

С таким подходом Вы от delay не избавитесь.

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

В общем, надо хорошо понимать, что делаешь и зачем. Иначе - никак.

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

Витя пишет:

В программирование ничего не понимаю, делал программу из того что находил в инете.

У Вас четыре варианта:

1. Прокачать знания и начать что-то понимать
2. Найти в Интернете готовое решение
3. Заказать эту работу за деньги
4. Забить на это

Вариант сидеть в этой теме и ждать, что кто-то сжалится и подаст Христа ради почти бесперспективен.

Voodoo Doll
Voodoo Doll аватар
Offline
Зарегистрирован: 18.09.2016

Чтобы сделать неблокирующее гашение, надо:

1. Определиться с длительностью гашения и поделить на 256. Я тут вижу delay(1000) и цикл 255->0, так что далее считаю длительность равной 256с, из чего следует что перод (длительность шага) - одна секунда ровно. Но это вовсе необязательно, например можно погасить за 20с, тогда период 20000/256=78, за 5 минут, тогда 300000/256=1171.

2. Делается подпрограмма, которая крутит этот период. Это здесь принято называть конечным автоматом, или тем самым blink без delay(). Состоит из условия "если время минус прошлое время равно или больше периода", и внутри этого условия присвоение прошлое время=текущее, чтобы оно повторялось, каждый период.

Фсё! Далее останется только увеличивать/уменьшать нужную переменную, в вашей программе это i, в новой будет led_level. Мб с вариациями типа разрешить/запретить уменьшение/увеличение, такая переменная называется "флаг".

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

Ага. Без blink без delay() тут никак. Советую хороше разобратся с ним например на моргании светодиода типа 1сек горит одну сек нет. Показателем того, что разобрались можно считать что Вы легко и непренужденно находите место в коде, которое всегда выполняется раз в сек. В этом месте вставляете код вида i++;if(i==10){i=0;...} - код на месте в скобках будет выполнятся уже раз в 10 сек. Там можете понижать/повышать яркость или датчики опрашивать или делать любые действия которые надо делать раз в 10 сек. Аналогично формируются остальные периодические интервалы. Почему именно так советую - специфика такого кантроллера как у Вас в том, что таких интервалов надо много, а так их получать легко просто и понятно. 

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

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

Витя пишет:

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

А ты его, лодыря, загрузи, чтоб он в это время таки еще и немношко биткойны майнил. 

Efim
Offline
Зарегистрирован: 04.05.2018

Держи!

#include <RTC.h>
RTC  time;
int t1 = 10; // включение света
int m1=30;   // Минуты включения
int t2 = 23; // выключение сета
int m2=10;   // Минуты вылючения
int d;       // Переменная в которую записываются текущий показатель часов
int m;       // Переменная в которую записываются текущий показатель минут
int led = 5; //подключен к цифровому выводу 5
byte i=0;                  
boolean running = false;   
boolean stop = false;      
unsigned long timeR;       

void setup(){
   Serial.begin(9600);   
   pinMode(led, OUTPUT);
   timeR = millis();  
 // инициализация модуля RTC
  time.begin(RTC_DS3231);     // на базе чипа DS3231            модуль подключается к аппаратным выводам I2C
//  time.begin(RTC_DS1307);     // на базе чипа DS1307            модуль подключается к аппаратным выводам I2C
//  time.begin(RTC_DS1302,10,13,12);  // на базе чипа DS1302, вывод RST, вывод CLK, вывод DAT   доступны любые выводы

//  запись даты и времени
// time.settime(0,14,9,13,03,18,2);  // 0  сек, 17 мин, 15 час, 1, октября, 2015 года, четверг
//  time.settime(35,10,20);     // 35 сек, 10 мин, 20 час, дату оставить без изменений
//  time.settime(-1,-1,-1,31,12,15);  // 31, декабря, 2015 года, время и день недели оставить без изменений   
}

void loop(){ 
 d=time.Hours ;
 m=time.minutes; 
  // Передать время
 Serial.println(time.gettime("d-m-Y, H:i:s, D"));
 
  // Плавное включение
   if ((time.Hours == 10) && (time.minutes == 00)) running = true;    
   if ((running)&&(millis()-timeR>=16000))                                
   {   
   i++;                                                               
   analogWrite(led, i);
   timeR = millis();
   }
   if ((running)&&(i==255))                                           
   {
   digitalWrite(led, HIGH);                                            
   running = false;                                                   
   i = 0;                                                             
   }
   
   // Плавное выключение
   if ((time.Hours == 22) && (time.minutes == 10)) stop = true;       
   if ((stop)&&(millis()-timeR>=16000))                                
   {   
   i++;                                                               
   analogWrite(led, (255-i));
   timeR = millis();
   }
   if ((stop)&&(i==255))                                               
   {
   digitalWrite(led, LOW);                                            
   stop = false;
   i = 0;                                                              
   }
 
 /////
  // Защита от выключения эдектричества
  else{
  if (d <= t2 && d >= t1) {
                          if (d==t1 && m<m1) {goto label;}
                          if (d==t2 && m>m2) {goto label;}
   digitalWrite(led, HIGH);   // свет включен
   Serial.println(" HIGH ");
                        }
                        else
                            {  
                             label:           
                            digitalWrite(led, LOW);  // свет выключен 
                            Serial.println(" LOW "); 
                            }
  }

 delay(10);
}

 

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

Похоже встретились два "одиночества". ;))

/**/
//-----------------------------------------------
typedef struct {
  byte min;
  byte second;
} aaa;
void save(aaa &v, unsigned long mill) {
  mill /= 1000;
  v.second = mill % 60;
  mill /= 60;
  v.min = mill % 60;
}
void print(aaa &v) {
  Serial.println();
  Serial.print(v.min);
  Serial.print(":");
  Serial.print(v.second);
  Serial.print("  ");
};
int total(aaa &v) {
  return 60 * v.min + v.second;
}
/*сравнить
  вернуть 1 если v1>v2 / -1 если v1<v2 / 0 если v1==v2 */
int compare(aaa &v1, aaa &v2) {
  int a = total(v1);
  int b = total(v2);
  if (a > b) return 1;
  else if (a < b) return -1;
  else return 0;
};
//---------------------------
aaa tON  = {/*минута*/0,/*секунда*/3};
aaa tOFF = {/*минута*/0,/*секунда*/10};
//-----main()-------------------
void setup() {
  Serial.begin(9600);
}
void loop() {
  aaa tNow;
  save(tNow, millis());
  print(tNow);
  Serial.print(compare(tON, tNow));
  Serial.print("  ");
  Serial.print(compare(tOFF, tNow));
  Serial.print("  ");
  delay(1000);
}
/**/

 

Витя
Offline
Зарегистрирован: 09.06.2018

Efim пишет:

Держи!

#include <RTC.h>
RTC  time;
int t1 = 10; // включение света
int m1=30;   // Минуты включения
int t2 = 23; // выключение сета
int m2=10;   // Минуты вылючения
int d;       // Переменная в которую записываются текущий показатель часов
int m;       // Переменная в которую записываются текущий показатель минут
int led = 5; //подключен к цифровому выводу 5
byte i=0;                  
boolean running = false;   
boolean stop = false;      
unsigned long timeR;       

void setup(){
   Serial.begin(9600);   
   pinMode(led, OUTPUT);
   timeR = millis();  
 // инициализация модуля RTC
  time.begin(RTC_DS3231);     // на базе чипа DS3231            модуль подключается к аппаратным выводам I2C
//  time.begin(RTC_DS1307);     // на базе чипа DS1307            модуль подключается к аппаратным выводам I2C
//  time.begin(RTC_DS1302,10,13,12);  // на базе чипа DS1302, вывод RST, вывод CLK, вывод DAT   доступны любые выводы

//  запись даты и времени
// time.settime(0,14,9,13,03,18,2);  // 0  сек, 17 мин, 15 час, 1, октября, 2015 года, четверг
//  time.settime(35,10,20);     // 35 сек, 10 мин, 20 час, дату оставить без изменений
//  time.settime(-1,-1,-1,31,12,15);  // 31, декабря, 2015 года, время и день недели оставить без изменений   
}

void loop(){ 
 d=time.Hours ;
 m=time.minutes; 
  // Передать время
 Serial.println(time.gettime("d-m-Y, H:i:s, D"));
 
  // Плавное включение
   if ((time.Hours == 10) && (time.minutes == 00)) running = true;    
   if ((running)&&(millis()-timeR>=16000))                                
   {   
   i++;                                                               
   analogWrite(led, i);
   timeR = millis();
   }
   if ((running)&&(i==255))                                           
   {
   digitalWrite(led, HIGH);                                            
   running = false;                                                   
   i = 0;                                                             
   }
   
   // Плавное выключение
   if ((time.Hours == 22) && (time.minutes == 10)) stop = true;       
   if ((stop)&&(millis()-timeR>=16000))                                
   {   
   i++;                                                               
   analogWrite(led, (255-i));
   timeR = millis();
   }
   if ((stop)&&(i==255))                                               
   {
   digitalWrite(led, LOW);                                            
   stop = false;
   i = 0;                                                              
   }
 
 /////
  // Защита от выключения эдектричества
  else{
  if (d <= t2 && d >= t1) {
                          if (d==t1 && m<m1) {goto label;}
                          if (d==t2 && m>m2) {goto label;}
   digitalWrite(led, HIGH);   // свет включен
   Serial.println(" HIGH ");
                        }
                        else
                            {  
                             label:           
                            digitalWrite(led, LOW);  // свет выключен 
                            Serial.println(" LOW "); 
                            }
  }

 delay(10);
}

 

Код компилируется, но свет не зажигается. 

Efim
Offline
Зарегистрирован: 04.05.2018

Давайте разбираться. Забыл убрать некую защиту от выключения электричества.


#define PinLed 5  //подключен к цифровому выводу 5
#include <RTC.h>

RTC  time;
byte tON  = 10;    // включение света
byte mON  = 30;    // Минуты включения
byte tOFF = 23;    // выключение сета
byte mOFF = 10;    // Минуты вылючения
byte d;            // Переменная в которую записываются текущий показатель часов
byte m;            // Переменная в которую записываются текущий показатель минут 
byte iPwm = 0;                  
boolean running = false;   
boolean stop = false;      
unsigned long timeR;       

void setup(){
   Serial.begin(9600);   
   pinMode(PinLed, OUTPUT);
   timeR = millis();  
 // инициализация модуля RTC
  time.begin(RTC_DS3231);     // на базе чипа DS3231            модуль подключается к аппаратным выводам I2C
//  time.begin(RTC_DS1307);     // на базе чипа DS1307            модуль подключается к аппаратным выводам I2C
//  time.begin(RTC_DS1302,10,13,12);  // на базе чипа DS1302, вывод RST, вывод CLK, вывод DAT   доступны любые выводы

//  запись даты и времени
// time.settime(0,14,9,13,03,18,2);  // 0  сек, 17 мин, 15 час, 1, октября, 2015 года, четверг
//  time.settime(35,10,20);     // 35 сек, 10 мин, 20 час, дату оставить без изменений
//  time.settime(-1,-1,-1,31,12,15);  // 31, декабря, 2015 года, время и день недели оставить без изменений   
}

void loop(){ 
 d=time.Hours ;
 m=time.minutes; 
  // Передать время
 Serial.println(time.gettime("d-m-Y, H:i:s, D"));
 
  // Плавное включение
   if ((time.Hours == tON) && (time.minutes == mON)) running = true;    
   if ((running)&&(millis()-timeR>=16000))                                
   {   
   iPwm++;                                                               
   analogWrite(PinLed, iPwm);
   timeR = millis();
   }
   if ((running)&&(iPwm==255))                                           
   {
   digitalWrite(PinLed, HIGH);                                            
   running = false;                                                   
   iPwm = 0;                                                             
   }
   
   // Плавное выключение
   if ((time.Hours == tOFF) && (time.minutes == mOFF)) stop = true;       
   if ((stop)&&(millis()-timeR>=16000))                                
   {   
   iPwm++;                                                               
   analogWrite(PinLed, (255-iPwm));
   timeR = millis();
   }
   if ((stop)&&(iPwm==255))                                               
   {
   digitalWrite(PinLed, LOW);                                            
   stop = false;
   iPwm = 0;                                                              
   }
 
}

Сейчас должен включатся и выключатся в заданное время. Защиту придется писать заново.

Витя
Offline
Зарегистрирован: 09.06.2018

Efim пишет:

Давайте разбираться. Забыл убрать некую защиту от выключения электричества.


#define PinLed 5  //подключен к цифровому выводу 5
#include <RTC.h>

RTC  time;
byte tON  = 10;    // включение света
byte mON  = 30;    // Минуты включения
byte tOFF = 23;    // выключение сета
byte mOFF = 10;    // Минуты вылючения
byte d;            // Переменная в которую записываются текущий показатель часов
byte m;            // Переменная в которую записываются текущий показатель минут 
byte iPwm = 0;                  
boolean running = false;   
boolean stop = false;      
unsigned long timeR;       

void setup(){
   Serial.begin(9600);   
   pinMode(PinLed, OUTPUT);
   timeR = millis();  
 // инициализация модуля RTC
  time.begin(RTC_DS3231);     // на базе чипа DS3231            модуль подключается к аппаратным выводам I2C
//  time.begin(RTC_DS1307);     // на базе чипа DS1307            модуль подключается к аппаратным выводам I2C
//  time.begin(RTC_DS1302,10,13,12);  // на базе чипа DS1302, вывод RST, вывод CLK, вывод DAT   доступны любые выводы

//  запись даты и времени
// time.settime(0,14,9,13,03,18,2);  // 0  сек, 17 мин, 15 час, 1, октября, 2015 года, четверг
//  time.settime(35,10,20);     // 35 сек, 10 мин, 20 час, дату оставить без изменений
//  time.settime(-1,-1,-1,31,12,15);  // 31, декабря, 2015 года, время и день недели оставить без изменений   
}

void loop(){ 
 d=time.Hours ;
 m=time.minutes; 
  // Передать время
 Serial.println(time.gettime("d-m-Y, H:i:s, D"));
 
  // Плавное включение
   if ((time.Hours == tON) && (time.minutes == mON)) running = true;    
   if ((running)&&(millis()-timeR>=16000))                                
   {   
   iPwm++;                                                               
   analogWrite(PinLed, iPwm);
   timeR = millis();
   }
   if ((running)&&(iPwm==255))                                           
   {
   digitalWrite(PinLed, HIGH);                                            
   running = false;                                                   
   iPwm = 0;                                                             
   }
   
   // Плавное выключение
   if ((time.Hours == tOFF) && (time.minutes == mOFF)) stop = true;       
   if ((stop)&&(millis()-timeR>=16000))                                
   {   
   iPwm++;                                                               
   analogWrite(PinLed, (255-iPwm));
   timeR = millis();
   }
   if ((stop)&&(iPwm==255))                                               
   {
   digitalWrite(PinLed, LOW);                                            
   stop = false;
   iPwm = 0;                                                              
   }
 
}

Сейчас должен включатся и выключатся в заданное время. Защиту придется писать заново.

БОЛЬШОЕ СПАСИБО, добрейший души человек.
А то многие только осуждать могут, что кто то просит у знающих людей помощи.
Всё работает, буду дальше делать свой аквапроект. 
Efim
Offline
Зарегистрирован: 04.05.2018

Витя пишет:

А то многие только осуждать могут, что кто то просит у знающих людей помощи.
Всё работает, буду дальше делать свой аквапроект. 

Да не осуждают они вас, а пытаются наоборот научить. Я просто дал вам возможность это сделать на примере.