Ви не увійшли.
Сторінки 1
Всім привіт, допоможіть виправити код, програма зупиняється на першому ефекті який було включено з пульта так і зависає, не йде подальша обробка запитів з пульта, і неможливо переключити режим. Пробував і бібліотеку IRremote.
#include <FastLED.h>
#include <NecDecoder.h>
NecDecoder ir;
#define IR_1 0xA2
#define IR_2 0x62
#define IR_3 0xE2
#define IR_4 0x22
#define IR_5 0x2
#define IR_6 0xC2
#define IR_7 0xE0
#define IR_8 0xA8
#define IR_9 0x90
#define IR_STAR 0x68
#define IR_0 0x98
#define IR_HASH 0xB0
#define IR_UP 0x18
#define IR_LEFT 0x10
#define IR_OK 0x38
#define IR_RIGHT 0x5A
#define IR_DOWN 0x4A
#define NUM_LEDS 144 // Number of LEDs in your strip
#define LED_PIN 12 // Pin to which the data line is connected
#define LED_TYPE WS2812B // LED type
#define BRIGHTNESS 255 // Maximum brightness value
#define CYCLE_DELAY 50 // Delay between cycles
#define MAX_SIMULTANEOUS_LEDS 20 // Maximum number of LEDs turned on simultaneously
CRGB leds[NUM_LEDS];
enum Modes { RANDOM_LEDS, POLICE_FLASHING, WHITE_LIGHT, STATIC };
byte mode = RANDOM_LEDS;
unsigned long int prev_code;
void setup() {
Serial.begin(9600);
attachInterrupt(0, irIsr, FALLING);
FastLED.addLeds<LED_TYPE, LED_PIN, GRB>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
randomSeed(analogRead(A0)); // Seed the random number generator with an analog reading
}
void irIsr() {
ir.tick();
}
void loop() {
if (ir.available()) {
// вывести команду (8 бит)
Serial.print("0x");
int command = ir.readCommand();
Serial.println(command, HEX);
handleIRCommand(command);
}
runCurrentEffect();
}
void handleIRCommand(unsigned long irValue) {
if (irValue == IR_1) {
mode = RANDOM_LEDS;
} else if (irValue == IR_2) {
mode = POLICE_FLASHING;
}
else if (irValue == IR_3) {
mode = WHITE_LIGHT;
}
}
void runCurrentEffect() {
FastLED.clear();
switch (mode) {
case RANDOM_LEDS:
randomLEDs();
break;
case POLICE_FLASHING:
policeFlashing();
break;
case WHITE_LIGHT:
whiteLightTicTac();
break;
case STATIC:
staticEffect();
break;
}
}
Неактивний
Поставте runCurrentEffect(); перед }
Поставте runCurrentEffect(); перед }
Тоді ефект виконається тільки лдин раз, а мені потрібне циклічне відтворення допоки я не нажму іншу кнопку на пульті
Тоді передавайте у runCurrentEffect() значення mode
Всім привіт, допоможіть виправити код, програма зупиняється на першому ефекті який було включено з пульта так і зависає, не йде подальша обробка запитів з пульта, і неможливо переключити режим. Пробував і бібліотеку IRremote.
А коды кнопок правильно определены?
derix пише:Всім привіт, допоможіть виправити код, програма зупиняється на першому ефекті який було включено з пульта так і зависає, не йде подальша обробка запитів з пульта, і неможливо переключити режим. Пробував і бібліотеку IRremote.
А коды кнопок правильно определены?
Так
Тоді передавайте у runCurrentEffect() значення mode
Воно знову чекає першого натискання на кнопку, включає відповідний ефект і більше не зчитує сигнали з прийомника, можливо потрібно якось ефекти переписати?
можливо потрібно якось ефекти переписати?
Хто ж його знає. Ви їх не виклали. Код працює, принаймні в симуляторі з деякими правками, режими перемикаються
Васятко пише:можливо потрібно якось ефекти переписати?
Хто ж його знає. Ви їх не виклали. Код працює, принаймні в симуляторі з деякими правками, режими перемикаються
Ці два найбільше цікавлять.
void randomLEDs(){
int indices[NUM_LEDS];
int numSimultaneous = random(1, MAX_SIMULTANEOUS_LEDS + 1);
for (int i = 0; i < NUM_LEDS; i++) {
indices[i] = i;
}
// Shuffle the indices array
for (int i = NUM_LEDS - 1; i > 0; i--) {
int j = random(i + 1);
int temp = indices[i];
indices[i] = indices[j];
indices[j] = temp;
}
for (int i = 0; i < NUM_LEDS; i++) {
if (i < numSimultaneous) {
leds[indices[i]] = CRGB::White; // Turn on LEDs
} else {
leds[indices[i]] = CRGB::Black; // Turn off LEDs
}
}
delay(CYCLE_DELAY);
FastLED.show();
}
void policeFlashing() {
for (int i = 0; i < NUM_LEDS; i++) {
if (i < NUM_LEDS / 2) {
leds[i] = CRGB::Blue; // First half is blue
} else {
leds[i] = CRGB::Black; // Second half is dark
}
}
FastLED.show();
delay(100); // Adjust flashing speed
for (int i = 0; i < NUM_LEDS; i++) {
if (i < NUM_LEDS / 2) {
leds[i] = CRGB::Black; // First half becomes dark
} else {
leds[i] = CRGB::Red; // Second half becomes red
}
}
FastLED.show();
delay(100); // Adjust flashing speed
}
Вот та же проблема хоть и используется друга библиотека
https://qna.habr.com/q/1258298
Вот та же проблема хоть и используется друга библиотека
https://qna.habr.com/q/1258298
Дякую, но оскільки мені потрібно виводити анімації циклічно до наступного натискання, це не допоможе мені
Те, що ви хочете, (майже) неможливо реалізувати на одному AVR мікроконтролері.
IR приймач може видавати фронти з мінімальним інтервалом 562.5мкс, їх близько 30 на одне натиснення.
Стрічці потрібно передати один цілий нерозривний потік бітів, "відстань" між якими 1.25мкс, кількість бітів пропорційна довжині стрічки.
При 16MHz це відповідно 9000 і 20 тактів процесора. Якщо дуже гарно постаратися, то в цих 20 тактах можна якось обробляти дані з IR приймача, але це потрібно реалізовувати на ASM.
У вашому випадку краще взяти два мікроконтролери, один буде обробляти сигнали з IR приймача і відправляти в UART один символ на одне натиснення. Інший буде працювати по вашому алгоритму, але читатиме символи з UART, апаратний UART дозволить прийняти один символ під час запису на стрічку.
Неактивний
мені потрібно виводити анімації циклічно
А количество светодиодов принципиально 144?
мені потрібно виводити анімації циклічно
А количество светодиодов принципиально 144?
А від цього щось залежить?
Є ідея реалізації:
Ініціалізуємо 16-бітний таймер з дільником частоти 128, це дискретність 8мкс, переповнення через півсекунди.
В PCINT від IR приймача тупо записуєм в рінгбуфер значення таймера.
Під час вигрузки бітів в стрічку, коли переривання заборонені, цю ж функцію виконує код між вигрузкою бітів.
Коли вільні, вичитуєм з рінгбуфера і декодуємо.
Нажаль, програмування цього всього буде коштувати в рази дорожче, ніж ще одна ардуіна)
Неактивний
А від цього щось залежить?
Ну з меншою кількістю код запрацював, принаймні в симуляторі.
А від цього щось залежить?
Ну з меншою кількістю код запрацював, принаймні в симуляторі.
144 можливо навіть і замало
144 можливо навіть і замало
А тут уже можно напороться на другую проблему - нехватку памяти
int command = ir.readCommand();
...
void handleIRCommand(unsigned long irValue) {
Заменить на:
uint8_t command = ir.readCommand();
...
void handleIRCommand(uint8_t irValue) {
А вообще, откажитесь от библиотеки FstLed и напишите свое управление лентой. Там не так уж и сложно.
Сторінки 1