Переключение режимов гирлянды

Sc0rpion
Offline
Зарегистрирован: 21.12.2017

Всех приветствую. Решил под новый год гирлянду сделать, в коробках нашел только Tlc5940.

Распаял 16 диодов, подключил. Написал пару - тройку, простеньких режимов. Все работает. Но не могу придумать как сделать нормально кнопку для их переключений, что бы сразу переключались. Пробовал через прерывания, работает, но нужно ждать пока цикл режима пройдет, delay() мешает, а избавляться от него муторно и не охота))

Может подскажите, как такое можно реализовать


#include <Tlc5940.h>;
volatile byte change;
volatile int mil;

void setup() {
  Tlc.init();
  attachInterrupt(0, inter, CHANGE);
  Serial.begin(9600);
}

void loop() {

begunok();
//  plavno();
//  poocheredi();
//  vsegor();
  
}

void inter() {
  Serial.println(millis());
  Serial.println("  :");
  int chan_mil = millis() - mil;
  if (chan_mil > 500) {
    change++;
    if (change == 5) {change = 0;}
    Serial.println(change);
    mil = millis();
  }
  
 
}

void poocheredi() {
  int direction = 1;
int raz = 0 ;
  for (int channel = 0; channel < NUM_TLCS*16; channel += direction) {
raz ++ ;
    //Гасим выводы:
    Tlc.clear();
    //Устанавливаем яркость в зависимости от направления волны
    if (channel == 0) {
      direction = 1;
    } else {
      Tlc.set(channel - 1, 1000);
    }
    Tlc.set(channel, 4095);
    if (channel != NUM_TLCS * 16 - 1) {
      Tlc.set(channel + 1, 1000);
    } else {
      direction = -1;
    }
    //Применяем изменения
    Tlc.update();
    delay(300);
    
    if ((raz > 30) & (change != poocheredi)){break;}
  }
}
  void plavno() {
  Tlc.clear();
    for(int i=0;i<=4094;i+= 2)
{
  Tlc.set(0, i);
  Tlc.set(1, i);
  Tlc.set(2, i);
  Tlc.set(3, i);
  Tlc.set(4, i);
  Tlc.set(5, i);
  Tlc.set(6, i);
  Tlc.set(7, i);
  Tlc.set(8, i);
  Tlc.set(9, i);
  Tlc.set(10, i);
  Tlc.set(11, i);
  Tlc.set(12, i);
  Tlc.set(13, i);
  Tlc.set(14, i);
  Tlc.set(15, i);
  Tlc.update();
  delay(2);
}

  for(int i=4094;i>=0;i-=2)
{
  Tlc.set(0, i);
  Tlc.set(1, i);
  Tlc.set(2, i);
  Tlc.set(3, i);
  Tlc.set(4, i);
  Tlc.set(5, i);
  Tlc.set(6, i);
  Tlc.set(7, i);
  Tlc.set(8, i);
  Tlc.set(9, i);
  Tlc.set(10, i);
  Tlc.set(11, i);
  Tlc.set(12, i);
  Tlc.set(13, i);
  Tlc.set(14, i);
  Tlc.set(15, i);
  Tlc.update();
  delay(2);
}
delay(100); // ставим паузу в 0,5 секунды
  }

void begunok () {
  int del=100;
  //Зажигание светодиодов
  Tlc.clear();
  Tlc.set(0, 4094);   Tlc.update();   delay(del);
  Tlc.set(1, 4094);   Tlc.update();   delay(del);
  Tlc.set(2, 4094);   Tlc.update();   delay(del);
  Tlc.set(3, 4094);   Tlc.update();   delay(del);
  Tlc.set(4, 4094);   Tlc.update();   delay(del);
  Tlc.set(5, 4094);   Tlc.update();   delay(del);
  Tlc.set(6, 4094);   Tlc.update();   delay(del);
  Tlc.set(7, 4094);   Tlc.update();   delay(del);
  Tlc.set(8, 4094);   Tlc.update();   delay(del);
  Tlc.set(9, 4094);   Tlc.update();   delay(del);
  Tlc.set(10, 4094);  Tlc.update();   delay(del);
  Tlc.set(11, 4094);  Tlc.update();   delay(del);
  Tlc.set(12, 4094);  Tlc.update();   delay(del);
  Tlc.set(13, 4094);  Tlc.update();   delay(del);
  Tlc.set(14, 4094);  Tlc.update();   delay(del);
  Tlc.set(15, 4094);  Tlc.update();   delay(del);

 // затухание светодиода

  Tlc.set(15, 0); 	 Tlc.update();   delay(del);
  Tlc.set(14, 0); 	 Tlc.update();   delay(del);
  Tlc.set(13, 0); 	 Tlc.update();   delay(del);
  Tlc.set(12, 0); 	 Tlc.update();   delay(del);
  Tlc.set(11, 0); 	 Tlc.update();   delay(del);
  Tlc.set(10, 0); 	 Tlc.update();   delay(del);
  Tlc.set(9, 0);  	 Tlc.update();   delay(del);
  Tlc.set(8, 0);  	 Tlc.update();   delay(del);
  Tlc.set(7, 0);  	 Tlc.update();   delay(del);
  Tlc.set(6, 0);  	 Tlc.update();   delay(del);
  Tlc.set(5, 0);  	 Tlc.update();   delay(del);
  Tlc.set(4, 0);  	 Tlc.update();   delay(del);
  Tlc.set(3, 0);  	 Tlc.update();   delay(del);
  Tlc.set(2, 0);  	 Tlc.update();   delay(del);
  Tlc.set(1, 0);  	 Tlc.update();   delay(del);
  Tlc.set(0, 0);  	 Tlc.update();   delay(del);
}
  
void vsegor() {
      Tlc.clear();
  for (int channel = 0; channel < 16; channel += 1) {
      Tlc.set(channel, 4094);
  }
  Tlc.update();
}

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

Sc0rpion пишет:

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

Может подскажите, как такое можно реализовать

при такой поставновке задачи - никак. Пока delay не уберете.

 

 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

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

vk007
Offline
Зарегистрирован: 16.06.2015

Ну не такой там и большой delay, чтобы его бояться.

Почти все эффекты у вас в виде циклов. Не понимаю, почему не загнать в цикл и остальное - типа строк 64-79, 112-127 и тому подобных.

Так вот, чтобы не ждать окончания циклов (т.е.всего эффекта целиком), внутри этих циклов надо сделать проверку на нажатие кнопки, если кнопка нажата, то выходить из цикла хоть по break, а хоть задав условие в самом for.

Sc0rpion
Offline
Зарегистрирован: 21.12.2017

Всем огромное спасибо

Знаю что тот еще говно-код наваял но он работает так как я и хотел. Надеюсь у меня будет еще время и желание переделать на что то более красивое. А пока повешаю ее уже на окошко и 

А пока вот что получилось

#include <EEPROM.h>
#include <Tlc5940.h>;
#include <avr/wdt.h>

volatile byte change;
volatile long mil;

void setup() {
	digitalWrite(8, HIGH);
	pinMode(8, OUTPUT);
  Tlc.init();
  pinMode(2, INPUT_PULLUP);
  attachInterrupt(0, inter, CHANGE);
  Serial.begin(9600);
  change = EEPROM.read(0);
  Serial.print("Rezim nomer: ");
  Serial.println(change);
}

void reboot() {
  wdt_disable();
  wdt_enable(WDTO_15MS);
  while (1) {}
}

void softReset() {
  asm volatile ("jmp 0");
}

void loop() {  

	while(change == 0){
        begunok();
        plavno();
        poocheredi();
        vsegor(); 
	}
	while(change == 1){
		plavno();
	}
	while(change == 2){
		begunok();
	}
	while(change == 3){
		poocheredi();
	}
	while(change == 4){
		vsegor(); 
	}


//  begunok();
//  plavno();
//  poocheredi();
//  vsegor();
  
}

void inter() {
  long chan_mil = millis() - mil;
  if (chan_mil > 500) {
    change++;
	if (change > 4) {change = 0;}
   Serial.println(change);
    mil = millis();
	EEPROM.write(0, change);
	reboot();
  }
 
}

void poocheredi() {
  int direction = 1;
int raz = 0 ;
  for (int channel = 0; channel < NUM_TLCS*16; channel += direction) {
raz ++ ;
    //Гасим выводы:
    Tlc.clear();
    //Устанавливаем яркость в зависимости от направления волны
    if (channel == 0) {
      direction = 1;
    } else {
      Tlc.set(channel - 1, 1000);
    }
    Tlc.set(channel, 4095);
    if (channel != NUM_TLCS * 16 - 1) {
      Tlc.set(channel + 1, 1000);
    } else {
      direction = -1;
    }
    //Применяем изменения
    Tlc.update();
    delay(300);
    
    if ((raz > 30) & (change != poocheredi)){break;}
  }
}
  void plavno() {
  Tlc.clear();
    for(int i=0;i<=4094;i+= 2)
{
  Tlc.set(0, i);
  Tlc.set(1, i);
  Tlc.set(2, i);
  Tlc.set(3, i);
  Tlc.set(4, i);
  Tlc.set(5, i);
  Tlc.set(6, i);
  Tlc.set(7, i);
  Tlc.set(8, i);
  Tlc.set(9, i);
  Tlc.set(10, i);
  Tlc.set(11, i);
  Tlc.set(12, i);
  Tlc.set(13, i);
  Tlc.set(14, i);
  Tlc.set(15, i);
  Tlc.update();
  delay(2);
}

  for(int i=4094;i>=0;i-=2)
{
  Tlc.set(0, i);
  Tlc.set(1, i);
  Tlc.set(2, i);
  Tlc.set(3, i);
  Tlc.set(4, i);
  Tlc.set(5, i);
  Tlc.set(6, i);
  Tlc.set(7, i);
  Tlc.set(8, i);
  Tlc.set(9, i);
  Tlc.set(10, i);
  Tlc.set(11, i);
  Tlc.set(12, i);
  Tlc.set(13, i);
  Tlc.set(14, i);
  Tlc.set(15, i);
  Tlc.update();
  delay(2);
}
delay(100); // ставим паузу в 0,5 секунды
  }

  void begunok () {
    int i=100;
  //Зажигание светодиодов
  Tlc.clear();
  Tlc.set(0, 4094);   Tlc.update();   delay(i);
  Tlc.set(1, 4094);   Tlc.update();   delay(i);
  Tlc.set(2, 4094);   Tlc.update();   delay(i);
  Tlc.set(3, 4094);   Tlc.update();   delay(i);
  Tlc.set(4, 4094);   Tlc.update();   delay(i);
  Tlc.set(5, 4094);   Tlc.update();   delay(i);
  Tlc.set(6, 4094);   Tlc.update();   delay(i);
  Tlc.set(7, 4094);   Tlc.update();   delay(i);
  Tlc.set(8, 4094);   Tlc.update();   delay(i);
  Tlc.set(9, 4094);   Tlc.update();   delay(i);
  Tlc.set(10, 4094);  Tlc.update();   delay(i);
  Tlc.set(11, 4094);  Tlc.update();   delay(i);
  Tlc.set(12, 4094);  Tlc.update();   delay(i);
  Tlc.set(13, 4094);  Tlc.update();   delay(i);
  Tlc.set(14, 4094);  Tlc.update();   delay(i);
  Tlc.set(15, 4094);  Tlc.update();
   delay(i);

 // затухание светодиода

  Tlc.set(15, 0);  Tlc.update();   delay(i);
  Tlc.set(14, 0);  Tlc.update();   delay(i);
  Tlc.set(13, 0);  Tlc.update();   delay(i);
  Tlc.set(12, 0);  Tlc.update();   delay(i);
  Tlc.set(11, 0);  Tlc.update();   delay(i);
  Tlc.set(10, 0);  Tlc.update();   delay(i);
  Tlc.set(9, 0);   Tlc.update();   delay(i);
  Tlc.set(8, 0);   Tlc.update();   delay(i);
  Tlc.set(7, 0);   Tlc.update();   delay(i);
  Tlc.set(6, 0);   Tlc.update();   delay(i);
  Tlc.set(5, 0);   Tlc.update();   delay(i);
  Tlc.set(4, 0);   Tlc.update();   delay(i);
  Tlc.set(3, 0);   Tlc.update();   delay(i);
  Tlc.set(2, 0);   Tlc.update();   delay(i);
  Tlc.set(1, 0);   Tlc.update();   delay(i);
  Tlc.set(0, 0);   Tlc.update();   delay(i);

delay(100); // ставим паузу в 0,5 секунды
  }

  void vsegor() {
      Tlc.clear();
  for (int channel = 0; channel < 16; channel += 1) {
      Tlc.set(channel, 4094);
  }
  Tlc.update();
  }

 

vk007
Offline
Зарегистрирован: 16.06.2015

Вот все-равно, объясните, почему, например, вот эту конструкцию:

Tlc.set(15, 0);  Tlc.update();   delay(i);
Tlc.set(14, 0);  Tlc.update();   delay(i);
Tlc.set(13, 0);  Tlc.update();   delay(i);
Tlc.set(12, 0);  Tlc.update();   delay(i);
Tlc.set(11, 0);  Tlc.update();   delay(i);
Tlc.set(10, 0);  Tlc.update();   delay(i);
Tlc.set(9, 0);   Tlc.update();   delay(i);
Tlc.set(8, 0);   Tlc.update();   delay(i);
Tlc.set(7, 0);   Tlc.update();   delay(i);
Tlc.set(6, 0);   Tlc.update();   delay(i);
Tlc.set(5, 0);   Tlc.update();   delay(i);
Tlc.set(4, 0);   Tlc.update();   delay(i);
Tlc.set(3, 0);   Tlc.update();   delay(i);
Tlc.set(2, 0);   Tlc.update();   delay(i);
Tlc.set(1, 0);   Tlc.update();   delay(i);
Tlc.set(0, 0);   Tlc.update();   delay(i);

не завернуть в цикл:

for(char j = 15; j >= 0; j--)
{
  Tlc.set(j, 0); Tlc.update(); delay(i);
} 

? Ведь у вас надцать раз подряд повторяется одна и та же операция с единственным изменяемым (при том изменяемым по очевидной арифметической прогрессии) параметром.

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

vk007 пишет:

Вот все-равно, объясните, почему, например, вот эту конструкцию:

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