Ws2812b бегущий поворотник без delay
- Войдите на сайт для отправки комментариев
Чт, 28/12/2017 - 20:12
Всем привет. Не могу реализовать денамический повортник без 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);//скорость зажигания ленты
}
Подскажите
http://arduino.ru/tutorials/BlinkWithoutDelay
http://robocraft.ru/blog/arduino/385.html
С миллис не катит.
https://youtu.be/3cB8ddTYF1g так работает с delay
https://youtu.be/xdfV7Hd_pVA так работает с millis
Куда вы её воткнули, что не катит?
Пробывал по разному. Может кто пример подскажет.
Ну вы свой код покажите, как пробОвали, чего стесняетесь...
Можно через Менеджер задач. Но там специфический подход.
/* Программа Менеджер обрабочик заказов по времени */ 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 = ⊤ 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 = ⊤ 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 байт. */Код на работе, завтра выложу.
Я мега новичок если что.
Да ладно, не обязательно )) Просто вам бы, возможно, подсказали, что сделано не так, для вашего же понимания...
Вот, накидал, пока супчик варю -
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; } }.
Попробуйте так, я не проверял
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; } } }Спасибо вам огромное за помощь. Завтра буду пробовать.
ОГРОМНОЕ вам спасибо за помощь. Принцип понял. Дальше буду мудрить.
OlegK
Спасибо. В Вашем коде разобрался, но подскажите ещё пожалуйста, как сделать чтоб это код дорабатывал до конца не зависимо от того есть сигнал или нет. Тоестт маргнул поворотником они пробежали цветом и пробежали в "0"?
Непонятно, в чём трудности, если понятно, как оно работает. Одну строку добавить всего лишь...
При включении переключателя поворотов (ПП) в положение "левый поворот" взводите флаг 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; } }Беда в том что у меня ещё и стоп на всю ленту. И при таком раскладе они друг друга выключают
Вопрос был про убирание дилэя, про стоп-сигнал нигде не озвучивалось...
Вам, думаю, лучше сперва составить алгоритм работы всего устройства, а уж потом пытаться реализовать его программно.
https://youtu.be/HLTGZ8uj7g0
Я устройство сделал, но delay все портит.
Можно убрать эффекты, но тогда потеряется идея.
Это точно. Надо сначало выложить ТЗ причем со всеми нюансами. А то догадаться что вы там себе придумали сложновато.
Всех с прошедшими.
С кодом еще разбираюсь.
Не сразу заметил ошибку, но потом разобрался.
if(need_off) work_left =false;// <--- тут флаг опрокинется после отработкиСпасибо