можно ли заменить delay в функции void zero_cross_int()

kasun_69
Offline
Зарегистрирован: 21.02.2020

1 int AC_LOAD =3; 2 volatile int dimming =128; 3 void setup() { 4 pinMode(AC_LOAD,OUTPUT); 5 attachInterrupt(0,zero_cross_int, RISING); 6 } 7 void zero_cross_int() 8 { 9 int dimtime = (75*dimming); 10 delayMicroseconds(dimtime); 11 digitalWrite(AC_LOAD, HIGH); 12 delayMicroseconds(20); 13 digitalWrite(AC_LOAD, LOW); 14 } 15 void loop() { 16 for (int i = 1; i <=128; i++) { 17 dimming=i; 18 delay(20); 19 } 20 for (int i = 128; i >=1; i--) { 21 dimming=i; 22 delay(20); 23 } 24 }

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

Для кого это месиво запостили?

kasun_69
Offline
Зарегистрирован: 21.02.2020
 
int AC_LOAD =3;                                        // тиристор подключен к пину D3
volatile int dimming =128;
void setup() {
  pinMode(AC_LOAD,OUTPUT);
  attachInterrupt(0,zero_cross_int, RISING);   // прерывание при переходе нуля на пине D2
}
void zero_cross_int()
{
  int dimtime = (75*dimming);
   delayMicroseconds(dimtime);      //  здесь замена не работает 
   digitalWrite(AC_LOAD, HIGH); 
   delayMicroseconds(20);  
   digitalWrite(AC_LOAD, LOW);  
}
void loop() {
    for (int i = 1; i <=128; i++) {
     dimming=i;
     delay(20);                                       // здесь могу заменить
}
 for (int i = 128; i >=1; i--) {
     dimming=i;
     delay(20);
}
}// скейч рабочий,плавно вкючает и выключает лампочку тиристором управляемый от нано ,хотелось заменить другими командами  этот  delayMicroseconds
 

 

kasun_69
Offline
Зарегистрирован: 21.02.2020

навыков ещё мало в общении на форуме, пронумеровать не смог 

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

Написанное- малопредсказуемый бред

kasun_69
Offline
Зарегистрирован: 21.02.2020

она работает, только не знаю как его сюда выложить 

фото или видео 

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

какими "другими командами" вы хотите это заменить. и. главное. зачем?

Обозначьте конечную цель этого действия

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

kasun_69 пишет:

она работает, только не знаю как его сюда выложить 

фото или видео 

ни в коем случае не фото и не видео. вам в сообщении #4 дали ссылку на правильное выкладывание кода - читайте

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

Оно конечно как то даже работает, только вот совсем не так как задумано автором.

Потому как, к мнимому времени полуволны (delay(20)), прибавляется задержка внутри прерывания. И непредсказуемо количество итераций в цикле перебора for .

Тут правильнее сделать инкремент внутри прерывания.

volatile boolean rise_fall;
void zero_cross_int()
{
  int dimtime = (75*dimming);
   delayMicroseconds(dimtime);      //  здесь замена не работает 
   digitalWrite(AC_LOAD, HIGH); 
   delayMicroseconds(20);  
   digitalWrite(AC_LOAD, LOW); 
switch(rise_fall){
case 0:
dimming++;
if(dimming==128){rise_fall=1;}
break;
case 1:
dimming--;
if(dimming==0){rise_fall=0;}
break;
}

 

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

kasun_69 пишет:
хотелось заменить другими командами  этот  delayMicroseconds
Кто или что мешает? Заменяйте, раз "хотелось бы".

nik182
Offline
Зарегистрирован: 04.05.2015

Как бы в прерывании делей не работает. Только отдаёт последнее полученное перед прерыванием значение.  

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

nik182 пишет:

Как бы в прерывании делей не работает. Только отдаёт последнее полученное перед прерыванием значение.  


Как бы delayMicroseconds() вполне себе работает

nik182
Offline
Зарегистрирован: 04.05.2015

Серьёзно? Механизм можете объяснить? Как не выходя из прерывания попасть в другое? У ардуины нет приоритетных прерываний. Чтение регистра таймера при переходе через ноль может дать очень интересный результат.

rkit
Offline
Зарегистрирован: 23.11.2016

Нету там никаких прерываний.

nik182
Offline
Зарегистрирован: 04.05.2015

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

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

nik182 пишет:

Серьёзно? Механизм можете объяснить? Как не выходя из прерывания попасть в другое? 

delay() на миллисах с прерываниями, delayMicroseconds() раскладывается в nop-ы

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

nik182 пишет:

Серьёзно? Механизм можете объяснить? Как не выходя из прерывания попасть в другое? У ардуины нет приоритетных прерываний. Чтение регистра таймера при переходе через ноль может дать очень интересный результат.

Ник182, ты с делей перепутал. ДелейМикросекондс к прерывниям не обращается.

Я стер, для читаемости все от частот кроме 16МГц

void delayMicroseconds(unsigned int us)
{
    if (us <= 1) return; //  = 3 cycles, (4 when true)

	us <<= 2; // x4 us, = 4 cycles

	us -= 5; // = 2 cycles,


	__asm__ __volatile__ (
		"1: sbiw %0,1" "\n\t" // 2 cycles
		"brne 1b" : "=w" (us) : "0" (us) // 2 cycles
	);
}

 

nik182
Offline
Зарегистрирован: 04.05.2015

Спасибо! Я попутал делаумикросеконд с микросеконд. Если использовать микросеконд по принципу блинк без делэй то есть грабли.  

kasun_69
Offline
Зарегистрирован: 21.02.2020


__asm__ __volatile__ (
11         "1: sbiw %0,1" "\n\t" // 2 cycles
12         "brne 1b" "=w" (us) : "0" (us) // 2 cycles 

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

kasun_69
Offline
Зарегистрирован: 21.02.2020

согласен,не так сформулировал задачу

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

изменил код так

bool tim[3];
unsigned long tamer=0;
int AC_LOAD =3;                 
volatile int dimming =128;
const int Pin_5 =5;
const int Pin_6 =6;
int K=0;
void setup() {
   Serial.begin(9600);
  pinMode(AC_LOAD,OUTPUT);
   pinMode(Pin_5, INPUT_PULLUP);
    pinMode(Pin_6, INPUT_PULLUP);
  attachInterrupt(0,zero_cross_int, RISING);
}
void zero_cross_int()
{ if (K ==1){                        //   здесь разрешаю димирование с помощю кнопки подключенную к пину Pin_6 
  int dimtime = (75*dimming);
   delayMicroseconds(dimtime);  
   digitalWrite(AC_LOAD, HIGH); 
   delayMicroseconds(20);  
   digitalWrite(AC_LOAD, LOW);}  
}
void loop() {
 int V= digitalRead(Pin_5);    //   здесь уменньшение увеличение с помощю кнопки подключенную к пину Pin_5
  K= digitalRead(Pin_6);
     if (dimming>1&&tim[0]==0&&V==0) {
  if (tim[1] ==0) {
    dimming--;
    tamer= millis();}
  if ((millis() - tamer) > 10) {     //   здесь увеличение яркости с изменением значения 10

    tim[1] =0; 
    }else {tim[1] =1;}
    }else {tim[1] =0;
    tim[0] =1;}
if (dimming<128&&tim[0]==1&&V==1) {
  if (tim[2] ==0) {
    dimming++;
    tamer= millis();}
  if ((millis() - tamer) > 10) {   //   здесь уменьшение яркости с изменением значения 10

    tim[2] =0;
    }else {tim[2] =1;}
    }else {tim[2] =0;
    tim[0] =0;}             Serial.println (dimming);
}
  
заменил delay на задержку с millis() (других способов пока не знаю) при значениях dimming близких к 128 замедляется работа,
 по наблюдениям в сериале значений dimming , возможно будет нестабильно работать.
если в void zero_cross_int() заменить таким же способом , не работает
​хочу реализовать плавное включение и выключение нагрузки по сигналу датчика

 

 

 

 

 

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

Попробуйте использовать волшебное сочетание Ctrl+T и увидите, что Ваши проверки miilis стоят внутри условий. Не знаю, так ли задумывалось, но думаю, что нет. Писали бы код сразу аккуратно, такого бы не было.

kasun_69
Offline
Зарегистрирован: 21.02.2020
вот пример с светодиодом
нужно пока нажата кнопка через 2 секунды включить светодиод на 3 секунды и выключить
на delay получается так
const int Pin_3 = 3;               // кнопка подключена к пину Pin_3
const int Pin_5 = 5;               // светодиод подключен к пину Pin_5

void setup() {
  pinMode(Pin_3, INPUT_PULLUP);
  pinMode(Pin_5, OUTPUT);
}
void loop() {
  int V = digitalRead(Pin_3);
  if (V == 1) {                      // если кнопка включена
    delay(2000);                       // задержка на 2 секунды
    digitalWrite(Pin_5, HIGH);         // включаем светодиод
    delay(3000);                       // задержка на 3 секунды
    digitalWrite(Pin_5, LOW);          // выключаем светодиод
  }
}
на millis() получаеся так
const int Pin_3 = 3;               // кнопка подключена к пину Pin_3
const int Pin_5 = 5;               // светодиод подключен к пину Pin_5
bool tim[2];
unsigned long tamer[2];
void setup() {
  pinMode(Pin_3, INPUT_PULLUP);
  pinMode(Pin_5, OUTPUT);
}
void loop() {
  int V = digitalRead(Pin_3);
  if (V == 1) {                            // если кнопка включена
    if (tim[0] == 0) {
      tamer[0] = millis();
    }
    if ((millis() - tamer[0]) > 2000) {    // задержка на 2 секунды
      if (tim[1] == 0) {
        digitalWrite(Pin_5, HIGH);         // включаем светодиод
        tamer[1] = millis();
      }
      if ((millis() - tamer[1]) > 3000) {   // задержка на 3 секунды
        digitalWrite(Pin_5, LOW);          // выключаем светодиод
        tim[0] = 0;
        tim[1] = 0;
      } else {
        tim[1] = 1;
      }
    } else {
      tim[0] = 1;
    }
  }
}

 может есть другие более оптимальные способы 

 

 

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

Проверки по-прежнему под условием из строки №12. Что они там делают? Вы читаете, что Вам пишут?

kasun_69
Offline
Зарегистрирован: 21.02.2020
если задержка запускается через 2 сек после нажатия кнопки,вне условия разве будет работать?
при не нажатой кнопке светодиод не включается, при нажатии мигает

 

 

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

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

kasun_69 пишет:

вот пример с светодиодом
нужно пока нажата кнопка через 2 секунды включить светодиод на 3 секунды и выключить
на delay получается так
const int Pin_3 = 3;               // кнопка подключена к пину Pin_3
const int Pin_5 = 5;               // светодиод подключен к пину Pin_5

void setup() {
  pinMode(Pin_3, INPUT_PULLUP);
  pinMode(Pin_5, OUTPUT);
}
void loop() {
  int V = digitalRead(Pin_3);
  if (V == 1) {                      // если кнопка включена
    delay(2000);                       // задержка на 2 секунды
    digitalWrite(Pin_5, HIGH);         // включаем светодиод
    delay(3000);                       // задержка на 3 секунды
    digitalWrite(Pin_5, LOW);          // выключаем светодиод
  }
}

Но это же не так! В смысле Ваши слова ни разу не соответствуют коду! Что значит "пока нажата кнопка через 2 секунды"? А если я нажал и через полсекунды отпустил, то что? Уже не надо ничего делать? А в Вашем коде почему-то делается! Вашему коду вообще плевать когда я отпускаю кнопку и отпускаю ли вообще.

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

У Вас же пока в голове нет никакой логики, а есть только не вполне осознанная идея, детализировать которую Вы не можете. А, как говорил граф Калиостро, «Материализация чувственных идей есть труднейшая задача научной магии» и Вам с этой задачей не справиться. Так что работайте сначала над формулированием чёткой логики процесса. И только потом пытайтесь программировать, но не раньше.

kasun_69
Offline
Зарегистрирован: 21.02.2020
const int Pin_3 = 3;               // кнопка подключена к пину Pin_3
const int Pin_5 = 5;               // светодиод подключен к пину Pin_5

void setup() {
  pinMode(Pin_3, INPUT_PULLUP);   // подтянут к +5в резистором,при нажатии V=0
  pinMode(Pin_5, OUTPUT);
}
void loop() {
  int V = digitalRead(Pin_3);
  if (V == 0) {                      // если кнопка включена
    delay(2000);                       // задержка на 2 секунды
    digitalWrite(Pin_5, HIGH);         // включаем светодиод
    delay(3000);                       // задержка на 3 секунды
    digitalWrite(Pin_5, LOW);          // выключаем светодиод
  }else{ digitalWrite(Pin_5, LOW);}    // при отпускании кнопки раньше 2 сек светодиод не включится,а если отпустить через 3,5 сек после нажатия то включиться через 2 сек и выключится через 1,5 сек 
}
согласен,до конца не сформулировал свои мысли
до конца ещё не разобрался в операторах,как задать задержку,если нельзя внутри условий?

 

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

kasun_69 пишет:
согласен,до конца не сформулировал свои мысли до конца ещё не разобрался в операторах,как задать задержку,если нельзя внутри условий?

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

Ваш вопрос сейчас не "как", а "что" нужно делать. Пока не знаете "что", не нужно делать "никак".