Помогите с прерыванием цикла

goldpistol
Offline
Зарегистрирован: 01.10.2014

Народ, всем привет.В общем как и у всех, пришло время задуматься о подарках на нг, придумал сделать светильник на ws2812.Из железа планирую использовать arduino pro(5v/16mhz),поворотный энкодер с кнопкой(для регулировки интенсивности и переключения эффекта), фоторезистор(для адаптации яркости под освещение).Уткнулся в стену уже на этапе просмотра примеров.Есть скетч из adafruit neopixel, но есть у него одно НО, он выполняет эффекты циклами по 5с.(а нужно бесконечно) и второе, он не реагирует на кнопку до тех пор пока эффект не отработает.Суть вопроса как его остановить во время работы и заставить увидеть кнопку.Ну и конечно если будут идеи или советы по данному девайсу пишите, буду рад!Код прилагаю.

#include <Adafruit_NeoPixel.h>

#define BUTTON_PIN   2    // Digital IO pin connected to the button.  This will be
                          // driven with a pull-up resistor so the switch should
                          // pull the pin to ground momentarily.  On a high -> low
                          // transition the button press logic will execute.

#define PIXEL_PIN    6    // Digital IO pin connected to the NeoPixels.

#define PIXEL_COUNT 16

// Parameter 1 = number of pixels in strip,  neopixel stick has 8
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_RGB     Pixels are wired for RGB bitstream
//   NEO_GRB     Pixels are wired for GRB bitstream, correct for neopixel stick
//   NEO_KHZ400  400 KHz bitstream (e.g. FLORA pixels)
//   NEO_KHZ800  800 KHz bitstream (e.g. High Density LED strip), correct for neopixel stick
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);

bool oldState = HIGH;
int showType = 0;

void setup() {
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void loop() {
  // Get current button state.
  bool newState = digitalRead(BUTTON_PIN);

  // Check if state changed from high to low (button press).
  if (newState == LOW && oldState == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState = digitalRead(BUTTON_PIN);
    if (newState == LOW) {
      showType++;
      if (showType > 9)
        showType=0;
      startShow(showType);
    }
  }

  // Set the last button state to the old state.
  oldState = newState;
}

void startShow(int i) {
  switch(i){
    case 0: colorWipe(strip.Color(0, 0, 0), 50);    // Black/off
            break;
    case 1: colorWipe(strip.Color(255, 0, 0), 50);  // Red
            break;
    case 2: colorWipe(strip.Color(0, 255, 0), 50);  // Green
            break;
    case 3: colorWipe(strip.Color(0, 0, 255), 50);  // Blue
            break;
    case 4: theaterChase(strip.Color(127, 127, 127), 50); // White
            break;
    case 5: theaterChase(strip.Color(127,   0,   0), 50); // Red
            break;
    case 6: theaterChase(strip.Color(  0,   0, 127), 50); // Blue
            break;
    case 7: rainbow(20);
            break;
    case 8: rainbowCycle(20);
            break;
    case 9: theaterChaseRainbow(50);
            break;
  }
}

// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}

void rainbow(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
  for (int j=0; j<10; j++) {  //do 10 cycles of chasing
    for (int q=0; q < 3; q++) {
      for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, c);    //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
  for (int j=0; j < 256; j++) {     // cycle all 256 colors in the wheel
    for (int q=0; q < 3; q++) {
      for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

 

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

goldpistol пишет:

Суть вопроса как его остановить во время работы и заставить увидеть кнопку.

Суть ответа - обратиться в профильный раздел и там Вам всё сделают.

Ну или поптыаться сделать самому, и только если не получится, обращаться сюда.

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

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

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

Ветеран форума, между прочим :((((

goldpistol
Offline
Зарегистрирован: 01.10.2014

Спасибо, пойду курить.

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

А я, сссскатина, последнюю ёлку у детей пропил.... :(   Грусна. 

arduinec
Offline
Зарегистрирован: 01.09.2015

goldpistol пишет:

он не реагирует на кнопку до тех пор пока эффект не отработает

Критичным является время выполнения strip.show() - при этом блокируются прерывания - но при 16 светодиодах оно составляет всего 0,5 мс. Остальное время скетч не видит кнопку из-за многочисленных delay() - от них надо избавляться.

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

DetSimen пишет:

А я, сссскатина, последнюю ёлку у детей пропил.... :(   Грусна. 

Береги печень, Сеня.

Впереди еще праздники - сходишь на ёлку с детями.

goldpistol
Offline
Зарегистрирован: 01.10.2014

Кажись нашел решение того что искал.

#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>
#include "QuadController.h"

#define LED 13
#define MAX_BRIGHT 200

enum MODES{
  SOLID,
  SPARKLE,
  LP_MODE
};

enum BRIGHT{
  OFF = 0,
  TEN = 20,
  TWENTY = 40,
  THIRTY = 70,
  FOURTY = 120,
  EIGHTY = 200,
};

enum COLORS{
  RED,
  GREEN,
  BLUE
};

enum SPEED{
  ZERO = 30,
  SLOW = 20,
  MEDIUM = 10,
  FAST = 3
};

BRIGHT curBright = OFF;
MODES curState = SOLID;
COLORS curColor = RED;
SPEED curSpeed = ZERO;
byte curOption = 0;

MODES lstState = SOLID;
byte numOptions = 0;
bool direction = true;

byte tmpColor[3]={0,0,0};
Adafruit_NeoPixel strip = Adafruit_NeoPixel(7, 6,  NEO_GRB + NEO_KHZ800);
QuadController control = QuadController(2,3,8,7);
unsigned long timer = 0;

void setup() {
  // put your setup code here, to run once:  
  strip.begin();
  strip.setBrightness(curBright);
  strip.show(); // Initialize all pixels to 'off'
  pinMode(LED, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  unsigned long curTime = millis();
  
  control.update();
  updateStateMachine();
  updatePixels();
  
  if((millis()%1000)>900){
    digitalWrite(LED, HIGH);
  }
  else{
    digitalWrite(LED, LOW);
  }
}

void updatePixels(){

  switch(curState){
    case LP_MODE: // next switch statement inside to control behavior based on lstState
      tmpColor[0] = MAX_BRIGHT;
      tmpColor[1] = 0;
      tmpColor[2] = 0;
      if((millis()/1000)%2){ // V
        strip.setPixelColor(0, tmpColor[0], tmpColor[1], tmpColor[2]);
        strip.setPixelColor(1, tmpColor[0], tmpColor[1], tmpColor[2]);
        strip.setPixelColor(2, tmpColor[0], tmpColor[1], tmpColor[2]);
        strip.setPixelColor(6, 0, 0, 0);
        strip.setPixelColor(12, 0, 0, 0);
      }
      else{ // H
        strip.setPixelColor(0, tmpColor[0], tmpColor[1], tmpColor[2]);
        strip.setPixelColor(6, tmpColor[0], tmpColor[1], tmpColor[2]);
        strip.setPixelColor(12, tmpColor[0], tmpColor[1], tmpColor[2]);    
        strip.setPixelColor(1, 0, 0, 0);
        strip.setPixelColor(2, 0, 0, 0);  
      }
      break;
    case SPARKLE:
      tmpColor[0] = 3*sqrt(curBright);
      tmpColor[1] = 3*sqrt(curBright);
      tmpColor[2] = 3*sqrt(curBright);
      switch(curColor){
        case RED:
          tmpColor[0] = MAX_BRIGHT;
          break;
        case GREEN:
          tmpColor[1] = MAX_BRIGHT;
          break;
        case BLUE:
          tmpColor[2] = MAX_BRIGHT;
          break;
      }  
      if(millis()>timer){
        strip.setPixelColor(random(0,18), random(0,tmpColor[0]), random(0,tmpColor[1]), random(0,tmpColor[2]));
        timer = timer + ((curSpeed*curSpeed) * 5);
      }
      break;
    case SOLID:
      tmpColor[0] = 0;
      tmpColor[1] = 0;
      tmpColor[2] = 0;
      switch(curColor){
        case RED:
          tmpColor[0] = MAX_BRIGHT;
          break;
        case GREEN:
          tmpColor[1] = MAX_BRIGHT;
          break;
        case BLUE:
          tmpColor[2] = MAX_BRIGHT;
          break;
      }
      for(int i=0;i<18;i++){
        strip.setPixelColor(i, tmpColor[0],tmpColor[1], tmpColor[2]);
      }
      break;
  }
  
  strip.show();

}

void updateStateMachine(){
  
  button_state brightState = control.getButton(0);
  if(brightState==SHORT_PRESS){
    switch(curBright){
      case OFF:
        curBright = TEN;
        break;
      case TEN:
        curBright = TWENTY;
        break;
      case TWENTY:
        curBright = THIRTY;
        break;
      case THIRTY:
        curBright = FOURTY;
        break;
      case FOURTY:
        curBright = EIGHTY;
        break;
      case EIGHTY:
        curBright = OFF;
        break;
    }
    strip.setBrightness(curBright);
    strip.show();
  }
  
  button_state modeState = control.getButton(1);
  if(curState == LP_MODE){ // if we are in LONG_PRESS mode
    if(!control.getPress(1)){ // and the button is no longer pressed
      curState = lstState; // go back to the last state
    }
  }
  else{ // if the machine is NOT in LONG_PRESS mode
    if(modeState==SHORT_PRESS){ // check for a short press, and cycle states if found
      switch(curState){
        case SOLID:
          curState = SPARKLE;
          break;
        case SPARKLE:
          curState = SOLID;
          break;
      }
    }
    else if(modeState == LONG_PRESS){ // check for a long press, and enter LONG_PRESS mode if found
      lstState = curState; // save the current state
      curState = LP_MODE; // then enter LONG_PRESS mode
    }
  }
  
  button_state colorState = control.getButton(2);
  if(colorState==SHORT_PRESS){
    switch(curColor){
      case RED:
        curColor = GREEN;
        break;
      case GREEN:
        curColor = BLUE;
        break;
      case BLUE:
        curColor = RED;
        break;
    }
    
  }
  
  button_state typeState = control.getButton(3);
  if(typeState==SHORT_PRESS){
    switch(curSpeed){
      case ZERO:
        curSpeed = SLOW;
        break;
      case SLOW:
        curSpeed = MEDIUM;
        break;
      case MEDIUM:
        curSpeed = FAST;
        break;
      case FAST:
        curSpeed = ZERO;
        break;
    }
    
  }
  
}

 

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

сильно лучше чем раньше.

недостатки:

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

- такое условие задержки в стр 83 будет давать при каждом проходе разный интервал

- переменная curTime (стр 62) - нигде не используется, что-то планировали сделать и забыли?

Lotus6202
Lotus6202 аватар
Offline
Зарегистрирован: 12.01.2018

Помогите с прериванием цикла ...  код в самом начале.. 

В планах собрать светильник с сенсорной кнопкой и пду ..Тупо управление переключать цвета и перелив цвета к цвету..   все недуги  goldpistol  описал в первом посте....    ПОМОГИТЕ,

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

А что тут помогать. Тут рефакторинг программы надо делать .:) а рефакторинг без денег , как пиво без водки. :))

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

Чё, Квон, решил эффективным менеджером заделаться?

Lotus6202
Lotus6202 аватар
Offline
Зарегистрирован: 12.01.2018

 Ребята НЕТ никаких мыслей как исправить.. этот косяк...

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

Lotus6202 пишет:

 Ребята НЕТ никаких мыслей как исправить.. этот косяк...

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

ПС: Вот Вороту нечем занятся, может и согласиться. А я пас.

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

Lotus6202 пишет:

 Ребята НЕТ никаких мыслей как исправить.. этот косяк...

конечно есть. За 3-5 тыр исправлю

Lotus6202
Lotus6202 аватар
Offline
Зарегистрирован: 12.01.2018

А харя не треснет....  

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

Обычно не трескает. 

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

Lotus6202 пишет:

А харя не треснет....  

Не, у него тренированная. Лишь бы тебя жаба не задушила. Я больше об этом беспокоюсь.

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

Lotus6202 пишет:

А харя не треснет....  

Дорого, что ли?

Ну изучи программирование, сделай сам - получится бесплатно. Заодно и что-то новое узнаешь.

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

А я бы помог, только там этих циклов ...

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

ua6em пишет:

А я бы помог, только там этих циклов ...

ну кабы там 2 строчки переставить - я бы тоже помог :)

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

qwone пишет:
Вот Вороту нечем занятся
С чего ты взял? Я тут из всех сил квонокодинг осваиваю. Вот пишу новый пример с лямбдами, но на этот раз и с классами, и с шаблонами. Скоро выложу! :)

Lotus6202
Lotus6202 аватар
Offline
Зарегистрирован: 12.01.2018

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

bwn
Offline
Зарегистрирован: 25.08.2014

Lotus6202 пишет:

Особо не дорого..  но 3- 5 тыс за перестоновку 2 -3 х строчек..   да и проблема в этом коде кроется , в куске отвечающее за кнопку ... Там всех 5 строчек...  а за 3 -5 тысяч я лучше детям чо нить куплю....   а за  подсказку спосибо уже сам этим разберусь... 

А это верно. Ритчи с Керниганом всего 800 рублей стоят.

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Уважаемый, Вам уже говорили, что изменение программы для Вашей задачи не получится. Тут надо полностью менять концепцию и алгоритм. Перевести ХОРОШИЙ алгоритм на любой язык программирования - это чисто техническая задача.

То, что у Вас написано в программе, будет работать так, как написано. Косметика здесь не поможет... 

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

Lotus6202 пишет:

Особо не дорого..  но 3- 5 тыс за перестоновку 2 -3 х строчек..   да и проблема в этом коде кроется , в куске отвечающее за кнопку ... Там всех 5 строчек...

нет, изменением только строчек про кнопку проблемы не решить. Надо полностью переписывать код. Кстати, в этой ветке и пример есть - это код в сообщении №9. Возьмите его и поправьте под свою задачу.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Lotus6202 пишет:

А харя не треснет....  

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

Lotus6202
Lotus6202 аватар
Offline
Зарегистрирован: 12.01.2018

В том дело что этот код я и поправляю под свою задачу.и  почти закончил.. только не могу справится с циклом свечения нео светиков.....

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Уважаемый, как бы Вам попонятнее объяснить. В этой программе во время "цикла свечения" не опрашиваются кнопки. У Вас 2 варианта:

1) Опрашивать кнопки в цикле (в каждом) и при изменении состояния прерывать цикл и вываливаться из подпрограммы.

2) То же самое по сути, но используя прерывания на кнопки.

Lotus6202
Lotus6202 аватар
Offline
Зарегистрирован: 12.01.2018

mykaida пишет:

Уважаемый, как бы Вам попонятнее объяснить. В этой программе во время "цикла свечения" не опрашиваются кнопки. У Вас 2 варианта:

1) Опрашивать кнопки в цикле (в каждом) и при изменении состояния прерывать цикл и вываливаться из подпрограммы.

2) То же самое по сути, но используя прерывания на кнопки.

Так это понятно... вариант  1  ...   всё дело в опросе кнопки... Без кнопки код работает идеально....

 

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

Так ото ж!

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

Lotus6202 пишет:

только не могу справится с циклом свечения нео светиков.....

Т.е. Вы полагаете, что за решение задачи, с которой (вероятно, в сиду ее сложности) Вы не можете справиться, 3-5 тысяч рублей - это слишком много?

Вот интересно, 3-5 тысяч - это стоимость какого объема Вашей работы:

- часа?

- дня?

- недели?

- месяца?

- года?

- до конца жизни?

Lotus6202
Lotus6202 аватар
Offline
Зарегистрирован: 12.01.2018

andriano пишет:

Lotus6202 пишет:

только не могу справится с циклом свечения нео светиков.....

Т.е. Вы полагаете, что за решение задачи, с которой (вероятно, в сиду ее сложности) Вы не можете справиться, 3-5 тысяч рублей - это слишком много?

Вот интересно, 3-5 тысяч - это стоимость какого объема Вашей работы:

- часа?

- дня?

- недели?

- месяца?

- года?

- до конца жизни?

до конца жизни   :)