Ws2812b бегущий поворотник без delay

Gavrosh
Offline
Зарегистрирован: 28.12.2017

Всем привет. Не могу реализовать денамический повортник без delay.

       for (int il=0; il<25; il++ ) //Количество диодов которые надо зажечь
        {
        strip.setPixelColor(il+69, strip.Color(250,120,0)); //от кокого диода надо зажечь
        strip.show();
        delay(15); //скорость зажигания ленты
       }
       for (int il=0; il<25; il++ ) //Количество диодов которые надо зажечь
      {
        strip.setPixelColor(il+69, strip.Color(0,0,0)); //от кокого диода надо зажечь
        strip.show();
        delay(15);//скорость зажигания ленты
      }

Подскажите 

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014
Gavrosh
Offline
Зарегистрирован: 28.12.2017

С миллис не катит.
https://youtu.be/3cB8ddTYF1g так работает с delay
https://youtu.be/xdfV7Hd_pVA так работает с millis

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

Gavrosh пишет:
С миллис не катит.

Куда вы её воткнули, что не катит?

Gavrosh
Offline
Зарегистрирован: 28.12.2017

Пробывал по разному. Может кто пример подскажет.

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

Ну вы свой код покажите, как пробОвали, чего стесняетесь...

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

Можно через Менеджер задач. Но там специфический подход.

/* Программа Менеджер обрабочик заказов по времени
*/
unsigned long mill; // переменная под millis()
typedef void(*pDo)(void);// тип- функция-обработчик
//-----Cl_Manager---------------------------
// класс менеджер задач
typedef struct task {
  pDo Do; // функция-обработчик
  unsigned long past;// кода был заказ
  unsigned int interval;// через сколько выполнить
  struct task (*next);
} task_t, *pTask;

class Cl_Manager {
  protected:
    pTask top = NULL;
  public:
    /*работа- вставить в setup()*/
    void run() {
      pTask *head = &top;
      while ((*head) != NULL) { // пока не дошли до конца цепочки
        if (mill - (*head)->past >= (*head)->interval) { //проверить этот узел
          pTask tmp = *head;
          (*head) = tmp->next;
          tmp->Do();
          delete tmp;
        }
        else head = &((*head)->next);
      }
    }
    /*втавить новую задачу в Менеджер*/
    void Task(unsigned int interval, pDo Do) {
      pTask *head = &top;
      while ((*head) != NULL) { // найти конец цепочки
        head = &((*head)->next);
      }
      pTask tmp = new task_t;
      (*tmp).Do = Do;
      (*tmp).past = mill;
      (*tmp).interval = interval;
      (*tmp).next = NULL;
      *head = tmp;
    }
};
Cl_Manager Manager;
//---Компоновка-----------------------
void serial_1() {
  Manager.Task(/*через 0.5 сек*/ 500,/*сделать это*/&serial_2);
  Serial.println("1-one");
}
void serial_2() {
  Manager.Task(/*через 0.5 сек*/ 500,/*сделать это*/&serial_3);
  Serial.println("2-two");
}
void serial_3() {
  Manager.Task(/*через 0.5 сек*/ 500,/*сделать это*/&serial_4);
  Serial.println("3-three");
}
void serial_4() {
  Manager.Task(/*через 0.5 сек*/ 500,/*сделать это*/&serial_5);
  Serial.println("4-four");
}
void serial_5() {
  Manager.Task(/*через 0.5 сек*/ 500,/*сделать это*/&serial_1);
  Serial.println("5-five");
}
const byte ledPin =/*пин светодиода*/13;
void blink() {
  static bool led = 0;
  Manager.Task(/*через 0.5 сек*/ 500,/*сделать это*/&blink);
  digitalWrite(ledPin, led = !led);
}
//---main-----------------------------
void setup() {
  Serial.begin(9600);
  serial_1();
  pinMode(ledPin, OUTPUT);
  blink();
}

void loop() {
  mill = millis();
  Manager.run();
}
/*Скетч использует 2726 байт (8%) памяти устройства. Всего доступно 30720 байт.
  Глобальные переменные используют 237 байт (11%) динамической памяти, оставляя 1811 байт для локальных переменных. Максимум: 2048 байт.
*/

 

Gavrosh
Offline
Зарегистрирован: 28.12.2017

Код на работе, завтра выложу.

Gavrosh
Offline
Зарегистрирован: 28.12.2017

Я мега новичок если что.

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

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


void loop() {
  static boolean work_left = false;
  static byte il = 0;
  static boolean need_Off = false;
  static unsigned long prev_millis = 0;

  //...где-то тут опрос рычага поворотника

  if (work_left) { //левый поворот
    if (millis() - prev_millis > 15) {
      prev_millis = millis();
      if (il < 25) {
        if (!need_Off) {
          strip.setPixelColor(il + 69, strip.Color(250, 120, 0));
        } else {
          strip.setPixelColor(il + 69, strip.Color(0, 0, 0));
        }
        strip.show();
        il++;
      } else {
        need_Off = !need_Off;
        il = 0;
      }
    }
  } else {
    prev_millis = millis();
    need_Off = false;
    il = 0;
  }
}

 

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

.

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

Попробуйте так, я не проверял

uint32_t time;
uint8_t il = 69;
bool f_lev;
bool f_rig;

void setup(){

} 

void loop(){
 // Вот это (il+69) я вижу как for (int il=69; il<94; il++ )
  if(нажали поворот влево){ 
   if (millis() - time >= 15){
     time = millis();
     if(!f_lev)f_lev=1, il = 69, f_rig = 0;
     if (il<=94)
     {
      strip.setPixelColor(il, strip.Color(250,120,0)); //от кокого диода надо зажечь
      strip.show();
      il++;
     }
     else il=69;
   }
  }

  if(нажали поворот в право){ 
   if (millis() - time >= 15){
     time = millis();
     if(!f_rig)f_rig=1, il = 69, f_lev = 0;
     if (il<=94)
     {
      strip.setPixelColor(il, strip.Color(0,0,0)); //от кокого диода надо зажечь
      strip.show();
      il++;
     }
     else il=69;
   }
  }

} 

 

Gavrosh
Offline
Зарегистрирован: 28.12.2017

Спасибо вам огромное за помощь. Завтра буду пробовать.

Gavrosh
Offline
Зарегистрирован: 28.12.2017

ОГРОМНОЕ вам спасибо за помощь. Принцип понял. Дальше буду мудрить.

Gavrosh
Offline
Зарегистрирован: 28.12.2017

OlegK
Спасибо. В Вашем коде разобрался, но подскажите ещё пожалуйста, как сделать чтоб это код дорабатывал до конца не зависимо от того есть сигнал или нет. Тоестт маргнул поворотником они пробежали цветом и пробежали в "0"?

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

Непонятно, в чём трудности, если понятно, как оно работает. Одну строку добавить всего лишь...
При включении переключателя поворотов (ПП) в положение "левый поворот" взводите флаг work_left.
А при отключении ПП ничего делать не надо, после отработки зажигания-погасания он опрокинется в false.
 

void loop() {
  static boolean work_left = false;
  static byte il = 0;
  static boolean need_Off = false;
  static unsigned long prev_millis = 0;

  //...где-то тут опрос рычага поворотника, нужно взвести флаг work_left = true

  if (work_left) { //левый поворот
    if (millis() - prev_millis > 15) {
      prev_millis = millis();
      if (il < 25) {
        if (!need_Off) {
          strip.setPixelColor(il + 69, strip.Color(250, 120, 0));
        } else {
          strip.setPixelColor(il + 69, strip.Color(0, 0, 0));
        }
        strip.show();
        il++;
      } else {
        need_Off = !need_Off;
        if (need_off) work_left = false; // <--- тут флаг опрокинется после отработки
        il = 0;
      }
    }
  } else {
    prev_millis = millis();
    need_Off = false;
    il = 0;
  }
}

 

Gavrosh
Offline
Зарегистрирован: 28.12.2017

Беда в том что у меня ещё и стоп на всю ленту. И при таком раскладе они друг друга выключают

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

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

Gavrosh
Offline
Зарегистрирован: 28.12.2017

https://youtu.be/HLTGZ8uj7g0
Я устройство сделал, но delay все портит.
Можно убрать эффекты, но тогда потеряется идея.

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

Это точно. Надо сначало выложить ТЗ причем со всеми нюансами. А то догадаться что вы там себе придумали сложновато.

Gavrosh
Offline
Зарегистрирован: 28.12.2017

Всех с прошедшими.

С кодом еще разбираюсь.

Не сразу заметил ошибку, но потом разобрался.

OlegK пишет:
 if (need_off) work_left = false// <--- тут флаг опрокинется после отработки

Спасибо