RGB лента и arduino mega

kwyjibo
Offline
Зарегистрирован: 27.01.2013

Доброго времени суток, форумчане. На форуме человек новый, еще не освоился, так что если есть решение моей проблемы - ткните носом пожалуйста "новичка".

Суть проблемы такая.. Задался соорудить такой проект - http://cxem.net/beginner/beginner61.php. Собрал, зашил код - все работает. Потом вдруг захотелось немного модернизировать это все дело и добавить несколько кнопок, чтоб можно было управлять светом (горит только красный, только синий, зеленый и кнопка выключения всего этого). Как эти кнопки подключать к ардуине нашел. Вроде непроблема. Там же и был код программы. Схему пока не собирал, не все элементы есть. Собрал кусок кода со своим и вот, что получилось.

//оглашение пинов контроллера
#define REDPIN 5     //подключение контактов ленты
#define GREENPIN 6
#define BLUEPIN 3
#define FADESPEED 5  //скорость затухания
const int FADEBTN = 7;   //кнопки
const int REDBTN = 8;
const int GREENBTN = 9;
const int BLUEBTN = 10;
const int PWRBTN = 11;
  
void setup() {
  pinMode(FADEBTN, INPUT);   //Входы
  pinMode(REDBTN, INPUT);
  pinMode(GREENBTN, INPUT);
  pinMode(BLUEBTN, INPUT);
  pinMode(PWRBTN, INPUT);
  pinMode(REDPIN, OUTPUT);  //Выходы
  pinMode(GREENPIN, OUTPUT);
  pinMode(BLUEPIN, OUTPUT);
}
  
  
void loop() {
  int r, g, b;
  int fadeButtonState = 0;    //первоначальное состояние кнопок
  int redButtonState = 0;
  int greenButtonState = 0;
  int blueButtonState = 0;
  int pwrButtonState = 0;
  fadeButtonState = digitalRead(FADEBTN);  //считываются состояния кнопок
  redButtonState = digitalRead(REDBTN);
  greenButtonState = digitalRead(GREENBTN);
  blueButtonState = digitalRead(BLUEBTN);
  pwrButtonState = digitalRead(PWRBTN);

  if (fadeButtonState == HIGH) {   //если нажата кнопка fade - режим затуханий
  
  for (r = 0; r < 256; r++) {
    analogWrite(REDPIN, r);
    delay(FADESPEED);
  }
  
  for (b = 255; b > 0; b--) {
    analogWrite(BLUEPIN, b);
    delay(FADESPEED);
  }
  
  for (g = 0; g < 256; g++) {
    analogWrite(GREENPIN, g);
    delay(FADESPEED);
  }
  
  for (r = 255; r > 0; r--) {
    analogWrite(REDPIN, r);
    delay(FADESPEED);
  }
  
  for (b = 0; b < 256; b++) {
    analogWrite(BLUEPIN, b);
    delay(FADESPEED);
  }
  
  for (g = 255; g > 0; g--) {
    analogWrite(GREENPIN, g);
    delay(FADESPEED);
  }
  }

  else if (redButtonState == HIGH) //если нажата кнопка red - красный свет
	{
    r = 256; b = 0; g = 0;
    analogWrite(REDPIN, r);	
	}

  else if (blueButtonState == HIGH) //если нажата кнопка blue - синий свет
	{
    r = 0; b = 256; g = 0;
    analogWrite(BLUEPIN, b);	
	}

  else if (greenButtonState == HIGH) //если нажата кнопка green - зеленый свет
	{
    r = 0; b = 0; g = 256;
    analogWrite(GREENPIN, g);	
	}

 else if (pwrButtonState == HIGH) //если нажата кнопка pwr - отключить
	{
    r = 0; b = 0; g = 0;
    analogWrite(GREENPIN, g);	
    analogWrite(BLUEPIN, b);	
    analogWrite(REDPIN, r);	
	}

}

 

Хотел бы уточнить, все ли правильно написал?

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

>>Хотел бы уточнить, все ли правильно написал?<<

Если работает , то правильно. Насколько я понял ваша программа проходит по спектру циклично ?

kwyjibo
Offline
Зарегистрирован: 27.01.2013

В режиме fade - Да. Просто реализовать схему с кнопками нет возможности (нет под рукой всех элементов), буду пробовать вечером... Сам код загонял в отладчик - ошибок не обнаружилось. Думал может есть возможность сократить его и кто-то эту возможность подскажет. Скажем так, с программированием не силен, делал все на логике уже готовых кодов...

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Я бы оставил одну кнопку. И управлял бы посредством переключения режимов.

kwyjibo
Offline
Зарегистрирован: 27.01.2013

То есть, если я правильно Вас понял, управление реализовать как в гирлянде китайской, по нажатию кнопки переключать по порядку режими? =)

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Именно так. Ну максимум две-три кнопки. Не вижу смысла разводит клавиатуру.

kwyjibo
Offline
Зарегистрирован: 27.01.2013

хм... думал про это... попробую... осталось додумать как это все реализовать в коде...  спасибо за подсказки =)

kwyjibo
Offline
Зарегистрирован: 27.01.2013

nestandart, не могли бы проглядеть модернизированный код под "одну" кнопку - не "зациклюсь" ли я в нем?

//оглашение пинов контроллера
#define REDPIN 5     //подключение контактов ленты
#define GREENPIN 6
#define BLUEPIN 3
#define FADESPEED 5  //скорость затухания
const int BTN = 7;   //кнопки

void setup() {
  pinMode(BTN, INPUT);   //Входы
  pinMode(REDPIN, OUTPUT);  //Выходы
  pinMode(GREENPIN, OUTPUT);
  pinMode(BLUEPIN, OUTPUT);
}

void loop() {
  int r, g, b, с;
  int c = 1; //первоначальное состояние счетчика
  int ButtonState = 0;    //первоначальное состояние кнопки
  ButtonState = digitalRead(BTN);  //считываются состояния кнопки

  if (ButtonState == HIGH && c == 1) {   //если нажата кнопка - режим затуханий
  c++;
  for (r = 0; r < 256; r++) {
    analogWrite(REDPIN, r);
    delay(FADESPEED);
  }
  for (b = 255; b > 0; b--) {
    analogWrite(BLUEPIN, b);
    delay(FADESPEED);
  }
  for (g = 0; g < 256; g++) {
    analogWrite(GREENPIN, g);
    delay(FADESPEED);
  }
  for (r = 255; r > 0; r--) {
    analogWrite(REDPIN, r);
    delay(FADESPEED);
  }
  for (b = 0; b < 256; b++) {
    analogWrite(BLUEPIN, b);
    delay(FADESPEED);
  }
  for (g = 255; g > 0; g--) {
    analogWrite(GREENPIN, g);
    delay(FADESPEED);
  }
  }

  else if (ButtonState == HIGH && c == 2) //красный свет
	{
    c++;
    r = 256; b = 0; g = 0;
    analogWrite(REDPIN, r);	
	}

  else if (ButtonState == HIGH && c == 3) //синий свет
	{
    c++;
    r = 0; b = 256; g = 0;
    analogWrite(BLUEPIN, b);	
	}

  else if (ButtonState == HIGH && c==4) //зеленый свет
	{
    c++;
    r = 0; b = 0; g = 256;
    analogWrite(GREENPIN, g);	
	}

  else if (ButtonState == HIGH && c==5) //отключить
	{
    c = 1;
    r = 0; b = 0; g = 0;
    analogWrite(GREENPIN, g);	
    analogWrite(BLUEPIN, b);	
    analogWrite(REDPIN, r);	
	}
}

 

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

В принципе работать должно.

Но я бы сделал так.



int regim=0;
int flag=0;

void setup() 
{                
 
}

void loop() 
{
  if(digitalRead(7)&&!flag)
  {
    regim++;
    flag=1;
    if(regim>5)
    {
      regim=0;
    }
  }
  if(!digitalRead(7)&&flag)flag=0;
  
  switch (regim)
  {
   case 1:
     //действие1
   break;
   case 2:
     //действие2
   break;
   case 3:
     //действие3
   break;
   case 4:
     //действие4
   break;
    case 5:
     //действие5
   break;
  }
}

Не зудьте про подтяжки.

 

kwyjibo
Offline
Зарегистрирован: 27.01.2013

О, я тоже думал все на оператор switch повесить... про подтягивающий резистор помню.... а вот такой еще вопрос... я питаю кусок светодиодной ленты от внешнего источника питания в 12V через вывод ардуины VIN. Если я добавлю кнопку, то ее надо запитать от 5V, вот вопрос - можно ли одновременно питать ардуино сразу от двух источников питания - внешнего и от USB?

uscr
Offline
Зарегистрирован: 17.08.2012

kwyjibo пишет:

О, я тоже думал все на оператор switch повесить... про подтягивающий резистор помню.... а вот такой еще вопрос... я питаю кусок светодиодной ленты от внешнего источника питания в 12V через вывод ардуины VIN. Если я добавлю кнопку, то ее надо запитать от 5V, вот вопрос - можно ли одновременно питать ардуино сразу от двух источников питания - внешнего и от USB?

Если вы питаете плату внешним источником на 12V, то 5В для кнопки можно взять с пина +5V. В ардуине есть стабилизатор напряжения.

kwyjibo
Offline
Зарегистрирован: 27.01.2013

uscr пишет:

Если вы питаете плату внешним источником на 12V, то 5В для кнопки можно взять с пина +5V. В ардуине есть стабилизатор напряжения.

Спасибо. Буду знать. =)

kwyjibo
Offline
Зарегистрирован: 27.01.2013

Эээх. Собрал схему. Видоизменил код под оператор switch, но происходит так, что при одном нажатии кнопки запускается режим мигания (то бишь case 1), а дальше на нажатия кнопки не реагирует...=(( Что сделал не так, не пойму...

//оглашение пинов контроллера
#define REDPIN 5     //подключение контактов ленты
#define GREENPIN 6
#define BLUEPIN 3
#define FADESPEED 5  //скорость затухания
const int BTN = 7;   //кнопки
int REGIM=0;
int FLAG=0;

void setup() {
  pinMode(BTN, INPUT);   //Входы
  pinMode(REDPIN, OUTPUT);  //Выходы
  pinMode(GREENPIN, OUTPUT);
  pinMode(BLUEPIN, OUTPUT);
}
void loop() {
  int r = 0;
  int g = 0;
  int b = 0;
  if(digitalRead(BTN)&&!FLAG)
  {
    REGIM++;
    FLAG=1;
    if(REGIM>5)
    {
      REGIM=0;
    }
  }
  if(!digitalRead(BTN)&&FLAG)FLAG=0;
  
  switch (REGIM)
  {
   case 1:
  for (r = 0; r < 256; r++) {
    analogWrite(REDPIN, r);
    delay(FADESPEED);
  }
  for (b = 255; b > 0; b--) {
    analogWrite(BLUEPIN, b);
    delay(FADESPEED);
  }
  for (g = 0; g < 256; g++) {
    analogWrite(GREENPIN, g);
    delay(FADESPEED);
  }
  for (r = 255; r > 0; r--) {
    analogWrite(REDPIN, r);
    delay(FADESPEED);
  }
  for (b = 0; b < 256; b++) {
    analogWrite(BLUEPIN, b);
    delay(FADESPEED);
  }
  for (g = 255; g > 0; g--) {
    analogWrite(GREENPIN, g);
    delay(FADESPEED);
  }
   break;

   case 2:
   r = 256; b = 0; g = 0;
   analogWrite(REDPIN, r);	
   break;

   case 3:
   r = 0; b = 0; g = 256;
   analogWrite(GREENPIN, g);	
   break;

   case 4:
   r = 0; b = 256; g = 0;
   analogWrite(BLUEPIN, b);	
   break;

   case 5:
   r = 0; b = 0; g = 0;
   analogWrite(GREENPIN, g);	
   analogWrite(BLUEPIN, b);	
   analogWrite(REDPIN, r);	
   break;
  }
}

 

uscr
Offline
Зарегистрирован: 17.08.2012

kwyjibo пишет:

Эээх. Собрал схему. Видоизменил код под оператор switch, но происходит так, что при одном нажатии кнопки запускается режим мигания (то бишь case 1), а дальше на нажатия кнопки не реагирует...=(( Что сделал не так, не пойму...

А как долго держите кнопку? Может быть, вам посчастливилось нажатием попадать именно в исполнение кода "режим 1"? Попробуйте кнопку повесить на прерывание. Ну или сделайте:

if(digitalRead(BTN)&&!FLAG)
  {
    Serial.println("Button pressed");
    REGIM++;
    FLAG=1;
    if(REGIM>5)
    {
      REGIM=0;
    }
  }

Что бы видеть, распозналось ли нажатие кнопки.

kwyjibo
Offline
Зарегистрирован: 27.01.2013

Нажатие короткое. Нажал - бросил. Чуть позже попробую добавить строку вывода сообщения.

uscr
Offline
Зарегистрирован: 17.08.2012

kwyjibo пишет:

Нажатие короткое. Нажал - бросил. Чуть позже попробую добавить строку вывода сообщения.

 

Подержите её, пока цикл режима 1 не закончится. Он у вас, если я не ошибся в подсчётах - чуть больше 7 секунд длиться. Код, считывающий состояние кнопки - мгновение по сравнению с этим, скорее всего действительно не попадаете.

kwyjibo
Offline
Зарегистрирован: 27.01.2013

uscr пишет:

Подержите её, пока цикл режима 1 не закончится. Он у вас, если я не ошибся в подсчётах - чуть больше 7 секунд длиться. Код, считывающий состояние кнопки - мгновение по сравнению с этим, скорее всего действительно не попадаете.

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

uscr
Offline
Зарегистрирован: 17.08.2012

kwyjibo пишет:

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

У меня под дебианом, убунтой и федорой всё выводится. Может быть, порт не тот выбран?

kwyjibo
Offline
Зарегистрирован: 27.01.2013

uscr пишет:

У меня под дебианом, убунтой и федорой всё выводится. Может быть, порт не тот выбран?

Возможно. У меня выбран порт Tools->Serial Port-> /dev/ttyUSB0. Программа заливается на ура... может что-то недонастроил?

Еще вопросик, чтоб увидеть вывод сообщения это ж ардуина должна быть подключена юсб кабелем. Одновременно у меня она питается от внешних 12В. Это ж не смертельно для дуины??

uscr
Offline
Зарегистрирован: 17.08.2012

kwyjibo пишет:

Еще вопросик, чтоб увидеть вывод сообщения это ж ардуина должна быть подключена юсб кабелем. Одновременно у меня она питается от внешних 12В. Это ж не смертельно для дуины??

Если прошивка заливается, и дым не идёт, значит не смертельно.

Собственно, я понял, в чём проблема. Нужно же ещё в setup() написать:

Serial.begin(9600);

 

kwyjibo
Offline
Зарегистрирован: 27.01.2013

uscr пишет:

Если прошивка заливается, и дым не идёт, значит не смертельно.

Собственно, я понял, в чём проблема. Нужно же ещё в setup() написать:

Serial.begin(9600);

Про дым улыбнуло =) Страшно по незнанию спалить довольно-таки недешевый контроллер. Спасибо за поправку. Я тоже как то пропустил строку инициализации порта и монитора. Запустил. Результат такой, что не всегда срабатывает кнопка - т.е. нажимаю первый раз - мигание, нажимаю через 7 сек. второй раз - в мониторе ничего не пишет. Нажимаю сразу третий раз - включился почему то 4-й case. Видимо что-то не так в программе... ((

uscr
Offline
Зарегистрирован: 17.08.2012

kwyjibo пишет:

uscr пишет:

Если прошивка заливается, и дым не идёт, значит не смертельно.

Собственно, я понял, в чём проблема. Нужно же ещё в setup() написать:

Serial.begin(9600);

Про дым улыбнуло =) Страшно по незнанию спалить довольно-таки недешевый контроллер. Спасибо за поправку. Я тоже как то пропустил строку инициализации порта и монитора. Запустил. Результат такой, что не всегда срабатывает кнопка - т.е. нажимаю первый раз - мигание, нажимаю через 7 сек. второй раз - в мониторе ничего не пишет. Нажимаю сразу третий раз - включился почему то 4-й case. Видимо что-то не так в программе... ((

На самом деле, микросхемы работают на дыме. Когда дым выходит, микросхема перестаёт работать. Ничего страшного не будет при таком подключении. Разве что компьютер может отказаться определять ардуину потому, что она по USB не потребляет ток.

В коде вроде всё верно. Попробуйте сделать режимы "попроще". Например. Режим 1 - просто постоянно горит красный, 2 - синий, 3 - зелёный, 4 - все сразу. И на простом коде отлаживайте.

 

kwyjibo
Offline
Зарегистрирован: 27.01.2013

Да, была у меня мысль попробовать с одноцветными режимами. Ну что ж, буду пробовать отлаживать. Спасибо за подсказки и помощь. Постараюсь отписаться если все получится...

 

Отчитаюсь. Сделал все по простому... одноцветные режими. Все работает, но только наблюдается "дребезг" кнопки, т.е. нажимаю один раз, а в мониторе отображается два нажатия, соответственно режими перескакивают. =((

uscr
Offline
Зарегистрирован: 17.08.2012

kwyjibo пишет:

Отчитаюсь. Сделал все по простому... одноцветные режими. Все работает, но только наблюдается "дребезг" кнопки, т.е. нажимаю один раз, а в мониторе отображается два нажатия, соответственно режими перескакивают. =((

Ну дык... Можно "по хардкору" добавить delay(150); после считывания состояния кнопки. Можно по умному. "Умных" вариантов несколько. Библиотека Bounce, засекание времени от момента последнего изменения состояния кнопки, конструкция с RC-цепью и компаратором... Подробности в гугле.

 

Собственно, мне пока всегда delay(150); хватало.

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

150 много. delay(10); после того как изменили regim. 

kwyjibo
Offline
Зарегистрирован: 27.01.2013

Спасибо всем откликнувшимся... буду экспериментировать... 

kwyjibo
Offline
Зарегистрирован: 27.01.2013

Как бы отчет. Все заработало с delay(50). Добавил его сразу перед увеличением переменной Regim. Когда ставил его после увеличения, то все равно присутствовал "дребезг". 

Еще раз спасибо откликнувшимся. На вашем форуме можно узнать много интересного и полезного...

uscr
Offline
Зарегистрирован: 17.08.2012

А "сложный" алгоритм теперь работает нормально?

kwyjibo
Offline
Зарегистрирован: 27.01.2013

К сожалению нет. =( С этим пока не разобрался. Сделал так, что "сложный" алгоритм вставил в конец подпрограммы. 

//оглашение пинов контроллера
#define REDPIN 5     //подключение контактов ленты
#define GREENPIN 6
#define BLUEPIN 3
#define FADESPEED 5  //скорость затухания
const int BTN = 7;   //кнопки
int REGIM=0;
int FLAG=0;

void setup() {
  pinMode(BTN, INPUT);   //Входы
  pinMode(REDPIN, OUTPUT);  //Выходы
  pinMode(GREENPIN, OUTPUT);
  pinMode(BLUEPIN, OUTPUT);
  Serial.begin(9600);
}
void loop() {
  int r = 0;
  int g = 0;
  int b = 0;
  if(digitalRead(BTN)&&!FLAG)
  {
    delay(550);
    Serial.println("Button pressed");
    REGIM++;
    FLAG=1;
    if(REGIM>=6)
    {
      REGIM=0;
      FLAG=0;
      r=0;
      b=0;
      g=0;
      analogWrite(GREENPIN, g);	
      analogWrite(BLUEPIN, b);	
      analogWrite(REDPIN, r);
    }
  }
  if(!digitalRead(BTN)&&FLAG)FLAG=0;
  
  switch (REGIM)
  {
   case 1:
   r = 255; b = 0; g = 0;
   analogWrite(GREENPIN, g);	
   analogWrite(BLUEPIN, b);	
   analogWrite(REDPIN, r);	
   break;
   case 2:
   r = 0; b = 0; g = 255;
   analogWrite(GREENPIN, g);	
   analogWrite(BLUEPIN, b);	
   analogWrite(REDPIN, r);	
   break;
   case 3:
   r = 0; b = 255; g = 0;
   analogWrite(GREENPIN, g);	
   analogWrite(BLUEPIN, b);	
   analogWrite(REDPIN, r);	
   break;
   case 4:
   r = 255; b = 255; g = 255;
   analogWrite(GREENPIN, g);	
   analogWrite(BLUEPIN, b);	
   analogWrite(REDPIN, r);	
   break;
   case 5:
   r = 0; b = 0; g = 0;
   for (r = 0; r < 256; r++) {
    analogWrite(REDPIN, r);
    delay(FADESPEED);
  }
  for (b = 255; b > 0; b--) {
    analogWrite(BLUEPIN, b);
    delay(FADESPEED);
  }
  for (g = 0; g < 256; g++) {
    analogWrite(GREENPIN, g);
    delay(FADESPEED);
  }
  for (r = 255; r > 0; r--) {
    analogWrite(REDPIN, r);
    delay(FADESPEED);
  }
  for (b = 0; b < 256; b++) {
    analogWrite(BLUEPIN, b);
    delay(FADESPEED);
  }
  for (g = 255; g > 0; g--) {
    analogWrite(GREENPIN, g);
    delay(FADESPEED);
  }
   
   analogWrite(GREENPIN, g);	
   analogWrite(BLUEPIN, b);	
   analogWrite(REDPIN, r);	
   break;

  }
}

Как только нажимаю 5-й раз кнопку режим мигания включается и "зацикливается", т.е. на нажатия кнопок не реагирует (монитор показывает что кнопка не нажимается)... еще не понял как сделать прерывание этого алгоритма по нажатию кнопки... но думаю, что я "победю" =))) его!

uscr
Offline
Зарегистрирован: 17.08.2012

kwyjibo пишет:

Как только нажимаю 5-й раз кнопку режим мигания включается и "зацикливается", т.е. на нажатия кнопок не реагирует (монитор показывает что кнопка не нажимается)... еще не понял как сделать прерывание этого алгоритма по нажатию кнопки... но думаю, что я "победю" =))) его!

Тоже сначала пугался прерываний. А всё просто же. Примерно так:

 

//Вешаем вызов функции regim_rotate, когда состояния вывода 2 меняется на HIGH
attachInterrupt(0, regin_rotate, RISING);

//обработчик прерывания:

void regim_rotate() {
REGIM++;
if (REGIM >= 6) 
{
//блаблабла
}
}

Теперь нажатие кнопки (которая теперь должна "висеть" на втором пине обработаются в любом случае. Но режим не изменится мгновенно. Что бы режим мгновенно менялся, после нажатия кнопки, нужно сделать так (выглядит плохо, но ничего умнее я не придумал): "маленькие" режимы и так отрабатывают быстро (это с первого по четвёртый), а для пятого, во все циклы for нужно написать так:

if ( ! REGIM == 5 ) {break;} это заставит цикл мгновенно завершиться, если режим изменился. Что бы не городить такой "костыль" я бы значение ШИМ для каждого цвета хранил в глобальных переменных (rPWM, gPWM, bPWM), а внутри case просто выводил бы значение на пины и инкрементировал переменные. Примерно так:
 

case 5:

  rPWM++;
  if ( ! rPWM>=256) { rPWM++; }
  if ( rPWM == 256 and ! bPWM >= 256 ) { bPWM++; }
  if ( rPWM == 256 and bPWM == 256 and ! gPWM >= 256) {gPWM++;}

  analogWrite(REDPIN, r);
  analogWrite(BLUEPIN, b);
  analogWrite(GREENPIN, g);
  break;

  }
}

Этот код раскрывает мою идею и не работает так, как нужно вам. Нужна ещё туча условий и дополнительные переменные. Так что непонятно, какой из вариантов на самом деле "костыль" :)

Плюс. Переменную REGIM нужно обьявить как volatile ( volatile int REGIM=0;).

И теперь снова вернётся проблема дребезга, но в нутри обработчика прерываний не работает delay(). Так что придётся завести отдельную переменную unsigned long timestamp=0; В которую писать время последнего вызова прерывания. и проверять её значение во время обработки прерывания. Примерно таким должен стать обработчик:

 

void regim_rotate() {
//Проверили, что прошло больше 50 миллисекунд:
if ( millis() - timestamp < 50) { return; }
REGIM++;
if (REGIM >= 6) 
{
//блаблабла
}
//Запомнили время последнего вызова:
timestamp = millis();
}

P.S.

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

kwyjibo
Offline
Зарегистрирован: 27.01.2013

Преклоняюсь перед Вашим знанием программирования, но я ввиду своей "лени" решил пойти может и неправильным, но более простым путем. Изучив как следует принцип работы сложного алгоритма, я просто-напросто добавил в каждый цикл перебора цветового спектра проверку "нажатия кнопки", тем самым у меня получилось прерывание по нажатию. Вот кусок "сложного" case'a:

  case 5:
   r = 0; b = 0; g = 0;
   for (r = 0; r < 256; r++) {
   analogWrite(REDPIN, r);
   delay(FADESPEED);
     if(digitalRead(BTN))
       {
         REGIM = 0;
         break;
       }
   }
   for (b = 255; b > 0; b--) {
   analogWrite(BLUEPIN, b);
   delay(FADESPEED);
     if(digitalRead(BTN))
       {
         REGIM = 0;
         break;
       }
    }
   for (g = 0; g < 256; g++) {
   analogWrite(GREENPIN, g);
   delay(FADESPEED);
     if(digitalRead(BTN))
       {
         REGIM = 0;
         break;
       }
   }
   for (r = 255; r > 0; r--) {
   analogWrite(REDPIN, r);
   delay(FADESPEED);
     if(digitalRead(BTN))
       {
         REGIM = 0;
         break;
       }
   }
   for (b = 0; b < 256; b++) {
   analogWrite(BLUEPIN, b);
   delay(FADESPEED);
     if(digitalRead(BTN))
       {
         REGIM = 0;
         break;
       }
   }
   for (g = 255; g > 0; g--) {
   analogWrite(GREENPIN, g);
   delay(FADESPEED);
     if(digitalRead(BTN))
       {
         REGIM = 0;
         break;
       }
   }
   analogWrite(GREENPIN, g);	
   analogWrite(BLUEPIN, b);	
   analogWrite(REDPIN, r);	
   break;

Возможно код не получился компактным, но он работает! Спасибо огромное за подсказки и ликбез всех участников. =)