Плавное мигание светодиода

clem
Offline
Зарегистрирован: 27.12.2019

Здравствуйте! Имею светодиод, ардуину и пульт ДУ, мне нужно чтобы от нажатия первой кнопки на пульте начинал плавно мигать светодиод, а после нажатия второй кнопки это действие прекращалось. Чтобы светодиод включался и мигал после нажатия кнопки - я сделал, но как не смешно бы это звучало, я не знаю как остановить мигание. Я пытался на вторую кнопку просто поставить analogWrite(9, LOW), но это не сработало. Подскажите, пожалуйста, как мне обыграть эту ситуацию.

clem
Offline
Зарегистрирован: 27.12.2019
#include "IRremote.h"

IRrecv irrecv(2); // указываем вывод, к которому подключен приемник

decode_results results;



void setup() {
  irrecv.enableIRIn(); // запускаем прием
    pinMode(9, OUTPUT); 
}

void loop() {
  if ( irrecv.decode( &results )) { // если данные пришли
    switch ( results.value ) {
    case 0xFFA25D:
        for(int i=0;i<=255;i++){
    analogWrite(9, i);
    //Задержка для более плавного эффекта свечения
    delay(2);
  }
  
  for(int i=255;i>=0;i--){
    analogWrite(9, i);
    //Задержка для более плавного эффекта потухания
    delay(2);
  }
  
  case 0xFF629D:
 analogWrite(9, LOW); 
}
  }
}

 

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

Попробуйте нажать в момент полного затухания светодиода. Если повезет - сработает, не повезет - уйдет на новый круг. Потому что ваши циклы на увеличение/уменьшение яркости полностью блокируют работу МК, до опроса приемника дело не доходит ))

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

clem - забыли дать irrecv.resume() после приема первой команды

clem
Offline
Зарегистрирован: 27.12.2019

Спасибо за советы. Если нажать во время затухания - ноль реакции, много комбинаций команд попробовал, но ничего не получается... Существуют ли ещё какие-нибудь способы выключить мигание светодиода или на этом возможности ардуины заканчиваются?))

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

Заканчиваются. Если у человека мозгов не хватает, то ардуине-то куда.

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

clem пишет:

Существуют ли ещё какие-нибудь способы выключить мигание светодиода или на этом возможности ардуины заканчиваются?))

Ардуина - это тупой набор транзисторов. И умеет этот набор транзисторов ровно то, что в него вложил программист. В вашем случае светодиод мигает ровно так, как вы запрограммировали. То, что вы хотели другого, говорит не о возможностях ардуины, а о ваших возможностях, как программиста. Можно ли сделать так, как вы хотите? Можно. Но, боюсь, вы на текущем уровне с этим не справитесь )

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

имхо, тут все не так страшно. В коде нет бесконечных циклов, Если почистить данные, пришедшие с пульта - программа отработает одно мигание и заткется. Вот для этого и нужна функция resume()

clem
Offline
Зарегистрирован: 27.12.2019

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

clem
Offline
Зарегистрирован: 27.12.2019

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

AndreyD
AndreyD аватар
Offline
Зарегистрирован: 07.10.2018

Посмотрите http://arduino.ru/tutorials/BlinkWithoutDelay

1. Переделать в BlinkWithoutFor.

2. В switch только выставлять флаг, а дальше по if-у первый пункт.

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

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

Если бы ты дал себе труд почитать форум, то узнал бы, что именно такие высказывания вызывают много негатива. Это хоббийный форум, не нуждающийся в новых "кликах" ;)). Тут нет рекламы, как можно заметить. Следовательно просто ради "кармы" никто советы давать не станет, а высказыванием "не вижу смысла учиться", ты вызываешь ответ  "не вижу смысла помогать".

Мы специально для таких пассажиров завели коммерческий раздел форума. Если ты не наш коллега по хобби, то помогать тебе бесплатно ни у кого нет мотивации - вот и найди желающего дать тебе совет "за пиво". В разделе "Ищу исполнителя".

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

clem пишет:
Многие напишут, мол иди учись, но я не вижу смысла в этом, потому что тратить время на обучение тому, чем я не буду пользоваться, ну или раз за год написать какой-нибудь пустяшный скетч.

тогда "давай до свиданья"

AndreyD
AndreyD аватар
Offline
Зарегистрирован: 07.10.2018

Может под не хочу учиться clem имел ввиду обучение на курсах или ВО по программированию?

Я у себя набросал код, который должен у ТС заработать, но ему же самому не интересно будет готовый код получить. Хотя и мой код не проверенный до конца у меня ИК приёмника нет.

Alexey_Rem
Offline
Зарегистрирован: 09.09.2019

Я бы сделал так:


#include "IRremote.h"

IRrecv irrecv(2); // указываем вывод, к которому подключен приемник

decode_results results;
boolean blnk=false;

void _blink()
{
  for(int i=0;i<=255;i+=10)
  {
    if(blnk)
  {
    analogWrite(9, i);
    delay(20);
  }
  else
  {
  digitalWrite(9,LOW);
  return;
  }
    
  }
  
  for(int i=255;i>=0;i-=10){
      if(blnk)
  {
    analogWrite(9, i);
    delay(20);
  }
  else
  {
  digitalWrite(9,LOW);
  return;
  }
  }  

blnk=false;

} 
void setup() 
{ irrecv.enableIRIn(); // запускаем прием 
pinMode(9, OUTPUT); } 
void loop() { 
if ( irrecv.decode( &results )) 
{ // если данные пришли 
switch ( results.value ) { case 0xFFA25D: if(!blnk) { blnk=true; _blink(); } case 0xFF629D: blnk=false; //analogWrite(9, LOW); } } }

Но если в вашем коде заменит в строке 31 analogWrite() на digitalWrite(9, LOW) может начнет выключаться

AndreyD
AndreyD аватар
Offline
Зарегистрирован: 07.10.2018

Alexey_Rem

ТС-у нужно, чтобы постоянно моргал, пока вторая кнопка не будет нажата.

blnk в строках 12 и 26 всегда будут true.

clem
Offline
Зарегистрирован: 27.12.2019

AndreyD пишет:

Может под не хочу учиться clem имел ввиду обучение на курсах или ВО по программированию?

Я у себя набросал код, который должен у ТС заработать, но ему же самому не интересно будет готовый код получить. Хотя и мой код не проверенный до конца у меня ИК приёмника нет.

Да, Андрей правильно подметил. Извиняюсь, не так выразился. Посыл мой был в том, что я не вижу смысла учится этому за деньги и большое количество времени, потому что я не буду тупо пользоваться этими знаниями. Согласен с вышенаписанными сообщениями, но я не прошу написать мне скетч полностью, за какую-то сумму денег... Хоть я новичок прям нулёвый, но я в инете нашёл вот этот самый главный элемент программы, которая работает так, как мне и нужно, но проблема в том, что мне нужно прям чуть-ли одной строчки кода))) как мне кажется, потому что я не думал, что, чтобы отменить уже запушенную команду, нужно еще 150 строчек написать)) Ещё раз, извиняюсь, что задел чувства программистов. 

AndreyD
AndreyD аватар
Offline
Зарегистрирован: 07.10.2018

clem

Добавлением одной строчки это как b707 предложил. Ну да будет гаснуть после одного моргания.

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

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

clem пишет:

я не думал, что, чтобы отменить уже запушенную команду, нужно еще 150 строчек написать))

вы можете не верить. но в данном случае это так - чтобы добавить в ваш код отмену мигания по кнопке - этот код надо переписать ПОЛНОСТЬЮ

clem
Offline
Зарегистрирован: 27.12.2019

b707 пишет:

clem пишет:

я не думал, что, чтобы отменить уже запушенную команду, нужно еще 150 строчек написать))

вы можете не верить. но в данном случае это так - чтобы добавить в ваш код отмену мигания по кнопке - этот код надо переписать ПОЛНОСТЬЮ

:(

Alexey_Rem
Offline
Зарегистрирован: 09.09.2019

Вполне возможно, не проверял

clem
Offline
Зарегистрирован: 27.12.2019

AndreyD пишет:

clem

Добавлением одной строчки это как b707 предложил. Ну да будет гаснуть после одного моргания.

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

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

clem
Offline
Зарегистрирован: 27.12.2019

Alexey_Rem пишет:

Я бы сделал так:


#include "IRremote.h"

IRrecv irrecv(2); // указываем вывод, к которому подключен приемник

decode_results results;
boolean blnk=false;

void _blink()
{
  for(int i=0;i<=255;i+=10)
  {
    if(blnk)
  {
    analogWrite(9, i);
    delay(20);
  }
  else
  {
  digitalWrite(9,LOW);
  return;
  }
    
  }
  
  for(int i=255;i>=0;i-=10){
      if(blnk)
  {
    analogWrite(9, i);
    delay(20);
  }
  else
  {
  digitalWrite(9,LOW);
  return;
  }
  }  

blnk=false;

} 
void setup() 
{ irrecv.enableIRIn(); // запускаем прием 
pinMode(9, OUTPUT); } 
void loop() { 
if ( irrecv.decode( &results )) 
{ // если данные пришли 
switch ( results.value ) { case 0xFFA25D: if(!blnk) { blnk=true; _blink(); } case 0xFF629D: blnk=false; //analogWrite(9, LOW); } } }

Но если в вашем коде заменит в строке 31 analogWrite() на digitalWrite(9, LOW) может начнет выключаться

Сейчас подключил, попробовал, к сожалению, ноль реакции...

clem
Offline
Зарегистрирован: 27.12.2019

И digitalWrite пробовал и analogWrite

clem
Offline
Зарегистрирован: 27.12.2019

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

Alexey_Rem
Offline
Зарегистрирован: 09.09.2019

 Я, к сожалению, проверить не могу я предложил свое видение проблемы, добавлю только что где-то на этом форуме писали что делей в лупе совсем не айс.

Alexey_Rem
Offline
Зарегистрирован: 09.09.2019

Еще

switch (var) {
    case 1:
      //выполняется, когда var равно 1
      break;
    case 2:
      //выполняется когда  var равно 2
      break;
    default: 
      // выполняется, если не выбрана ни одна альтернатива 
      // default необязателен 
  Сравните с вашим кодом и найдите два отличия
AndreyD
AndreyD аватар
Offline
Зарегистрирован: 07.10.2018

Alexey_Rem пишет:

Еще

switch (var) {
    case 1:
      //выполняется, когда var равно 1
      break;
    case 2:
      //выполняется когда  var равно 2
      break;
    default: 
      // выполняется, если не выбрана ни одна альтернатива 
      // default необязателен 
  Сравните с вашим кодом и найдите два отличия

Вы спросили сами у себя?

AndreyD
AndreyD аватар
Offline
Зарегистрирован: 07.10.2018

Во, интересно, а по аппаратному прерыванию можно ИК сигнал принять. Блин, у меня ИК приёмника нет. :(

Alexey_Rem
Offline
Зарегистрирован: 09.09.2019

И у себя и у вопрошающего (по секрету: не хватает break;)

AndreyD
AndreyD аватар
Offline
Зарегистрирован: 07.10.2018

В моём коде вот так, ну минус пару строк внутри второго case. :) break; там не было.

	if (irrecv.decode(&results)) { // если данные пришли
		switch (results.value) {
		case 0xFFA25D: {
			ledBlink = 1;
			break;
		}
		case 0xFF629D: {
			ledBlink = 0;
			analogWrite(ledPin, 0);

		}
		}
		irrecv.resume();
	}

 

AndreyD
AndreyD аватар
Offline
Зарегистрирован: 07.10.2018

Alexey_Rem пишет:

 Я, к сожалению, проверить не могу я предложил свое видение проблемы, добавлю только что где-то на этом форуме писали что делей в лупе совсем не айс.

Можете проверить свой код, заменив ИК приёмник обычной кнопкой.

Alexey_Rem
Offline
Зарегистрирован: 09.09.2019

Мне, если честно облом, думаю что  код вполне рабочий если куда надо вставить break;. чем он лучше кода вопрошающего? особо ничем кpоме некоторой оптимизации мигания и изьятия делея из лупа-не знаю правда ли но где-то здесь писали что это не хорошо когда делей в лупе, вообще считаю делей злом даже когда первый раз мигал диодом обошелся без делея, 

Feofan
Offline
Зарегистрирован: 28.05.2017
Alexey_Rem пишет:
где-то здесь писали что это не хорошо когда делей в лупе
Если delay используется, то он в любом случае окажется или в setup'e или в loop'е.
Alexey_Rem пишет:
вообще считаю делей злом
На костёр его.
 
Alexey_Rem
Offline
Зарегистрирован: 09.09.2019

Делей может быть и в свободной функции

Feofan
Offline
Зарегистрирован: 28.05.2017

Вызов функции будет произведён прямо или косвенно из setup или loop. Т.е. во время выполнения отработает delay не расположенный непосредственно в loop. Не?

void f0() {f1();}
void f1() {delay(1000);}

void setup() {f1();}
void loop() {f0();}

В loop'е delay нет, а он есть.

Alexey_Rem
Offline
Зарегистрирован: 09.09.2019

Совершенно верно

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

Feofan пишет:

Вызов функции будет произведён прямо или косвенно из setup или loop. Т.е. во время выполнения отработает delay не расположенный непосредственно в loop. Не?

Не обязательно. Кто-нибудь одаренный может сунуть дилэй в конструктор

AndreyD
AndreyD аватар
Offline
Зарегистрирован: 07.10.2018

clem пишет:

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

Интересно, что получилось.

clem
Offline
Зарегистрирован: 27.12.2019

В общем только сегодня руки дошли до ардуины. Попробовал много всяких вариантов, и delay убрал из loop, и вообще убрал delay, заменив на millis, и добавлял break, не хочет выключаться... У меня в одном скетче есть переключение режимов кнопкой, там все режимы идут один за другим, я попытался его изменить под пульт, но даже на вид получается заведомо не рабочая фигня, а главное нужно изменить так, чтобы режимы включались свободно и отдельно друг от друга. В общем, я в замешательстве...

clem
Offline
Зарегистрирован: 27.12.2019

Сейчас имею вот такой нерабочий скетч)

#include "IRremote.h"
IRrecv irrecv(2);
decode_results results; 
unsigned long lastturn;


//============================================================

void setup() {
 pinMode(9, OUTPUT); 
 irrecv.enableIRIn(); 
}
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
void loop() {

 
if ( irrecv.decode( &results )){ 
     switch ( results.value ) {
    case 0xFFA25D: 
        turn();   
    break;
    
   case 0xFF629D: 
        digitalWrite(9, LOW);
    break;

   }
 }
}

//==========================================================================
void turn()
{
if (millis() - lastturn > 1300  && millis()-lastturn < 1400 )
  {
    digitalWrite(9, HIGH);       
  }
  else
 {
    digitalWrite(9, LOW);
 }
 
 
  if (millis()-lastturn > 1400) 
  {
     lastturn=millis();  
  }
}

 

AndreyD
AndreyD аватар
Offline
Зарегистрирован: 07.10.2018

А во второй case по нажатию второй кнопки входит? Можно какую-нибудь метку в монитор порта там попробовать вывести, между строками 24 и 25.

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

clem пишет:

Сейчас имею вот такой нерабочий скетч)

нет уже сил смотреть на этот тупизм. Нате, пользуйтесь, добавил всего пару строк.

#include "IRremote.h"
IRrecv irrecv(2);
decode_results results; 
unsigned long lastturn;
boolean turn = false;


//============================================================

void setup() {
 pinMode(9, OUTPUT); 
 irrecv.enableIRIn(); 
}
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
void loop() {

 
if ( irrecv.decode( &results )){ 
     switch ( results.value ) {
    case 0xFFA25D: 
        turn = true;   
    break;
    
   case 0xFF629D: 
        digitalWrite(9, LOW);
        turn = false;
    break;

   }
 }
if (turn) turn_func();
}

//==========================================================================
void turn_func()
{
if (millis() - lastturn > 1300  && millis()-lastturn < 1400 )
  {
    digitalWrite(9, HIGH);       
  }
  else
 {
    digitalWrite(9, LOW);
 }
 
 
  if (millis()-lastturn > 1400) 
  {
     lastturn=millis();  
  }
}

 

AndreyD
AndreyD аватар
Offline
Зарегистрирован: 07.10.2018

А после switch не должно разве быть irrecv.resume(); ?

И т.к. режимов несколько, то вместо флага нужно будет использовать переменную для хранения режимов моргания.

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

AndreyD пишет:

А после switch не должно разве быть irrecv.resume(); ?

И т.к. режимов несколько, то вместо флага нужно будет использовать переменную для хранения режимов моргания.

с первым замечанием,  наверно, соглашусь, со вторым нет. Я правил скетч. в котором один режим. Если ТС захочет добавить другие режимы - это уже его дело.

AndreyD
AndreyD аватар
Offline
Зарегистрирован: 07.10.2018

clem

Попробуйте вот этот код в loop вставить вместо своего. Должен просто включать и выключать светодиод.

if (irrecv.decode(&results)) { 
		switch (results.value) {
		case 0xFF629D: 
			analogWrite(9, 0);
			break;
		case 0xFFA25D: 
			analogWrite(9, 255);
			break;
		}
		irrecv.resume();
	}

 

clem
Offline
Зарегистрирован: 27.12.2019

b707 пишет:

clem пишет:

Сейчас имею вот такой нерабочий скетч)

нет уже сил смотреть на этот тупизм. Нате, пользуйтесь, добавил всего пару строк.

#include "IRremote.h"
IRrecv irrecv(2);
decode_results results; 
unsigned long lastturn;
boolean turn = false;


//============================================================

void setup() {
 pinMode(9, OUTPUT); 
 irrecv.enableIRIn(); 
}
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
void loop() {

 
if ( irrecv.decode( &results )){ 
     switch ( results.value ) {
    case 0xFFA25D: 
        turn = true;   
    break;
    
   case 0xFF629D: 
        digitalWrite(9, LOW);
        turn = false;
    break;

   }
 }
if (turn) turn_func();
}

//==========================================================================
void turn_func()
{
if (millis() - lastturn > 1300  && millis()-lastturn < 1400 )
  {
    digitalWrite(9, HIGH);       
  }
  else
 {
    digitalWrite(9, LOW);
 }
 
 
  if (millis()-lastturn > 1400) 
  {
     lastturn=millis();  
  }
}

 

Тупизм тупизмом, но Ваша программа тоже не работает... Вот что происходит в мониторе порта каждое мгновение в вашей программе:

clem
Offline
Зарегистрирован: 27.12.2019

AndreyD пишет:

clem

Попробуйте вот этот код в loop вставить вместо своего. Должен просто включать и выключать светодиод.

if (irrecv.decode(&results)) { 
		switch (results.value) {
		case 0xFF629D: 
			analogWrite(9, 0);
			break;
		case 0xFFA25D: 
			analogWrite(9, 255);
			break;
		}
		irrecv.resume();
	}

 

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

clem
Offline
Зарегистрирован: 27.12.2019

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

AndreyD
AndreyD аватар
Offline
Зарегистрирован: 07.10.2018

Даже со строчкой 10 из моего последнего кода?

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

clem пишет:

Тупизм тупизмом, но Ваша программа тоже не работает... Вот что происходит в мониторе порта каждое мгновение в вашей программе:

покажите мне в моей программе хоть какой-то вывод в монитор - там такого нет. Отсюда вывод - это не моя программа, вы ее изменили. Тогда выкладывайте полный код, иначе вы просто врете.