• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Błędnie odczytywane kody [FastLED & IRremote]
#1
Witam, mam problem ze swoim kodem, chciałbym mieć kod który włącza różne funkcje ledów (na obecny moment mam 3 funkcje, w przyszłości jeśli ten problem by się rozwiązał chciałbym tych funkcji mieć więcej) po naciśnięciu przycisków na pilocie IR. Jeśli puszczę trzymanie przycisku to funkcja będzie się wykonywała dopóki nie nacisnę kolejnego przycisku. Problemem są otrzymywane wartości 0, jeśli jednak zacznę naciskać przyciski na pilocie szybko to kody zaczynają być odczytywane. Kod:
Kod:
#include <FastLED.h>
#include <IRremote.h>

#define NUM_LEDS 60
#define DATA_PIN 7
#define BRIGHTNESS 100
#define RECV_PIN 6

CRGB leds[NUM_LEDS];

uint8_t hue = 0;
int huechange = 3;
int dir = 1;
int i = 0;
int currFunct = 0;

void setup() {
  Serial.begin(9600);
  IrReceiver.begin(RECV_PIN);
  pinMode(2, OUTPUT);

  FastLED.setBrightness(BRIGHTNESS);
  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
  FastLED.clear();
  FastLED.show();
}

void red() {
  fill_solid(leds, NUM_LEDS, CRGB::Red);
  FastLED.show();
}

void green() {
  fill_solid(leds, NUM_LEDS, CRGB::Green);
  FastLED.show();
}

void rainbowEffect() {
  EVERY_N_MILLISECONDS(25) {
    if (i < NUM_LEDS && i >= 0) {
      leds[i] = CHSV(hue, 255, 255);
      FastLED.show();
      i += dir;
    } else {
      dir *= -1;
      i += dir;
    }
    hue += huechange;
    blur1d(leds, NUM_LEDS, 172);
  }
}

void black() {
  fill_solid(leds, NUM_LEDS, CRGB::Black);
  FastLED.show();
}

void checkFunct() {
  switch (IrReceiver.decodedIRData.command) {
      case 69:
        red();
        break;

      case 70:
        green();
        break;

      case 71:
        rainbowEffect();
        break;

      default:
        black();
    }
    delay(100);
}

void loop() {
  if (IrReceiver.decode()) {
    IrReceiver.resume();
    Serial.println(IrReceiver.decodedIRData.command);
    digitalWrite(2, HIGH);
  } else {
    digitalWrite(2, LOW);
    checkFunct();
  }
}

Problemem w tym kodzie jest także delay(100) które blokuje efekt tęczy w rainbowEffect() sprawiając że efekt zamiast zmieniać ledę co 25ms zmienia ją co 125ms. Jestem prawie pewien że jest możliwość usunięcia delay i jednocześnie braku otrzymywanych błędnych sygnałów. Będę bardzo wdzięczny jeśli ktoś pomoże Smile
 
Odpowiedź
#2
No to wywal delay 100, zamiast tego użyj millis i wywołuj funkcję co 100ms, skoro chcesz by nie była wywoływana częściej. Przykład masz w menu Arduino, BlinkWithOutDelay, tam jest 1000, zamień na 100, a jak już masz to wywołanie co 100ms, to możesz tam dodać zmienna++, która będzie zliczała te setki, będziesz mierzył czas, możesz zdecydować, że jak wyślesz jakiś kod pilotem, to jest ważny przez 10000ms i wyłacza sam efekt, możesz też zdecydować, że jeśli otrzymasz kod częściej niż co określony czas to go ignorujesz.
Możesz też po prostu rozbić blok otrzymania kodu IR i robienia z nim czegoś na dwa osobne, na odbiór kodu jesteś gotowy zawsze, a czy coś z nim zrobisz podejmujesz decyzję osobno.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#3
(20-11-2023, 00:48)kaczakat napisał(a): No to wywal delay 100, zamiast tego użyj millis i wywołuj funkcję co 100ms, skoro chcesz by nie była wywoływana częściej. Przykład masz w menu Arduino, BlinkWithOutDelay, tam jest 1000, zamień na 100, a jak już masz to wywołanie co 100ms, to możesz tam dodać zmienna++, która będzie zliczała te setki, będziesz mierzył czas, możesz zdecydować, że jak wyślesz jakiś kod pilotem, to jest ważny przez 10000ms i wyłacza sam efekt, możesz też zdecydować, że jeśli otrzymasz kod częściej niż co określony czas to go ignorujesz.
Możesz też po prostu rozbić blok otrzymania kodu IR i robienia z nim czegoś na dwa osobne, na odbiór kodu jesteś gotowy zawsze, a czy coś z nim zrobisz podejmujesz decyzję osobno.

Zmieniłem kod m.in użyłem millis i zmienniłem też trochę składnię w loop. Dowiedziałem się że ten problem może polegać z czytnikami IR które przerywają sygnały lub odczytują je niepoprawnie podczas działania funkcji FastLED. Spróbowałem zastosować kod gdzie jeśli sygnał otrzymany jest nieprawidłowy (0) ledy są wyłączone dopóki nie otrzymam poprawnego kodu. Tym razem otrzymywałem kody poprawne, jednak ledy są ciągle wyłączone.
Kod:
#include <FastLED.h>
#include <IRremote.h>

#define NUM_LEDS 180
#define DATA_PIN 7
#define BRIGHTNESS 100
#define RECV_PIN 6

CRGB leds[NUM_LEDS];

uint8_t hue = 0;
int huechange = 3;
int dir = 1;
int i = 0;
bool turnedOn = true;

unsigned long previousMillis = 0;
const long interval = 25;

void setup() {
  Serial.begin(9600);
  IrReceiver.begin(RECV_PIN);
  pinMode(2, OUTPUT);

  FastLED.setBrightness(BRIGHTNESS);
  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
  FastLED.clear();
  FastLED.show();
}

void red() {
  fill_solid(leds, NUM_LEDS, CRGB::Red);
  FastLED.show();
}

void green() {
  fill_solid(leds, NUM_LEDS, CRGB::Green);
  FastLED.show();
}

void rainbowEffect() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    if (i < NUM_LEDS && i >= 0) {
      leds[i] = CHSV(hue, 255, 255);
      FastLED.show();
      i += dir;
    } else {
      dir *= -1;
      i += dir;
    }
    hue += huechange;
    blur1d(leds, NUM_LEDS, 172);
  }
}

void white() {
  fill_solid(leds, NUM_LEDS, CRGB::White);
  FastLED.show();
}

void loop() {
  if (IrReceiver.decode()) {
    IrReceiver.resume();
    Serial.println(IrReceiver.decodedIRData.command);
    digitalWrite(2, HIGH);
    turnedOn = true;
   
    if (IrReceiver.decodedIRData.command == 0) {
      fill_solid(leds, NUM_LEDS, CRGB::Black);
      FastLED.show();
      turnedOn = false;
    } else if (!turnedOn) {
      switch (IrReceiver.decodedIRData.command) {
        case 69:
          red();
          break;

        case 70:
          green();
          break;

        case 71:
          rainbowEffect();
          break;

        default:
          white();
      }
    }
  } else {
      digitalWrite(2, LOW);
  }
}
 
Odpowiedź
#4
Nie wiem czy Ci to wyjdzie z tymi ledami, one mają częstotliwość nadawania w okolicach 1MHz i by to działało biblioteki powinny blokować przerwania, no ale w sumie to nie jest jakoś istotne i może tego nie robią. Ale by to faktycznie wyglądało tak jak powinno to uC musi zasuwać całym sercem tylko dla tych bitów wypisywanych na magistralę.
Tak ogolenie to powinno wyglądać tak:
loop
{
{blok wejścia - odbiór sygnału IR i podjęcie decyzji co z tym odebranym sygnałem zrobić
}
{
blok wyjścia - obsługa led, switch case, jako dafault to raczej nie white, tylko wyłączone
ten blok ma się wykonywać stale, nie chodzi by tu stać, tylko loop ma go za każdym obiegiem realizować, niezależnie co się działo w poprzednim, co najwyżej możesz tu nie zmieniać case adekwatnie
}
}
Funkcje do efektów powinny być tak napisane, by wysyłały stan wszystkich led i zwalniały na kolejne 20-50ms czas na inne funkcje, potem kolejna "klatka". W uproszczeniu jak masz 10 led to wysłanie trwa 24 bity x 1.2us = 288us, ale przy 200 ledach to już prawie 6ms. Wydaje mi się, że nie ma czasu transmitując bity by w tym czasie odbierać kody IR, nawet w przerwaniu, 1.2us to za mało, a tak właściwie to bit jest jeszcze stanem 0/1.
Coś tam zmieniali by wydłużyć czas stanu reset, to powinno pomóc obsłużyć przerwanie podczas transmisji, więc może robią blok atomic w bibliotece tylko na poszczególne bity, a można się wsunąć z przerwaniem między te bloki. W sumie millis powinny dalej działać, ciekawe czy czas się mocno rozjeżdża z tymi ledami.
Jak będę miał chwilę to przetestuję.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#5
Wczytałem bibliotekę, wybrałem przykład ColorPalette, efekty zamieniłem na case'y przypisane do kodów 0-9, w loop wywołuję sprawdzanie kodów, jak jest inny niż 0 , a często jest przy wywołaniu efektu co 100ms, to ignoruję, jak jest któryś z tych 0-9 to zmieniam efekt.
Faktycznie czasami odczytuje 0 przy ustawieniu na 10FPS, a przy 50ms (20FPS) to już same 0, coś zaczyna działać od 60ms.
Ledów mam 24 w ringu, jak miałbym to zrobić tylko na AVR to dodałbym Attiny13 by czytał mi kody IR NEC i przez soft serial wysyłał na UART sprzętowy Atmega, ma bufor, odczyta w przerwaniach, to 1 bajt, zadziała na 100%.
Jak masz więcej led to i 100ms może czkać. 
Za to ESP8266, w sumie ten sam kod tylko zmienione dwa piny dla IR i LED, bez problemu śmiga w ustawieniu na 10ms, i na 1ms, bez zająknięcia, sterować można tym wtedy również przez WIFI, z drugiego końca świata (jak masz zewnętrzne IP i umiesz przekierować porty na routerze).
Tak że możesz trochę powalczyć, albo zrobić to na tańszej płytce jak Wemos MINI.
Ewentualnie są takie ledy z SPI, jest sprzętowy w Atmega328p, to wtedy może działać 10x szybciej, a na pewno jest tu opcja użycia przerwań zamiast blokować na kilkaset us /ms uC by nadawać banglując pinem.


Kod:
/// @file    ColorPalette.ino
/// @brief   Demonstrates how to use @ref ColorPalettes
/// @example ColorPalette.ino

#include <FastLED.h>



#define LED_PIN     11 //12
#define NUM_LEDS    24
#define BRIGHTNESS  64
#define LED_TYPE    WS2811
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];

#define UPDATES_PER_SECOND 50
#include <IRremote.h>

#define RECV_PIN 2 //143

// This example shows several ways to set up and use 'palettes' of colors
// with FastLED.
//
// These compact palettes provide an easy way to re-colorize your
// animation on the fly, quickly, easily, and with low overhead.
//
// USING palettes is MUCH simpler in practice than in theory, so first just
// run this sketch, and watch the pretty lights as you then read through
// the code.  Although this sketch has eight (or more) different color schemes,
// the entire sketch compiles down to about 6.5K on AVR.
//
// FastLED provides a few pre-configured color palettes, and makes it
// extremely easy to make up your own color schemes with palettes.
//
// Some notes on the more abstract 'theory and practice' of
// FastLED compact palettes are at the bottom of this file.



CRGBPalette16 currentPalette;
TBlendType    currentBlending;

extern CRGBPalette16 myRedWhiteBluePalette;
extern const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM;

//******************************************CZAS

uint32_t czasTeraz,czasPoprzedni,tik=10, minutyDoby;
uint8_t nTik,sekundy,minuty,godziny,dni;
bool fnTik,fsekundy,fminuty,fgodziny,fdni,czasInternetowyOK;


/*
0  0X16
1  0XC
2  0X18
3  0X5E
4  0X8
5  0X1C
6  0X5A
7  0X42
8  0X52
9  0X4A
*/
// const int pilot[]={0x16,0xC,0x18,0x5E,0x8,0x1C,0x5A,0x42,0x52,0x4A};

char  napis[20] ;
uint8_t kod;
void setup() {
 
    delay( 300 ); // power-up safety delay
      IrReceiver.begin(RECV_PIN);
    FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
    FastLED.setBrightness(  BRIGHTNESS );
    Serial.begin(115200);
    currentPalette = RainbowColors_p;
    currentBlending = LINEARBLEND;
}


void loop()
{
czas();

if (IrReceiver.decode()) {
  IrReceiver.resume();
  uint8_t last;
if(last=IrReceiver.decodedIRData.command) kod=last;
 
    Serial.println(kod);
   
}
//if(fnTik)  //co 10ms
if(fnTik and nTik%10==0)  //co 100ms

  {
    ChangePalettePeriodically();
   
    static uint8_t startIndex = 0;
    startIndex = startIndex + 1; /* motion speed */
   
    FillLEDsFromPaletteColors( startIndex);
   
    FastLED.show();
//    FastLED.delay(1000 / UPDATES_PER_SECOND);
  }
if(fsekundy)
{
sprintf(napis,"%03d:%02d:%02d",godziny,minuty,sekundy);
Serial.println(napis);
}
   
}

void czas()
{
static uint32_t  czasPoprzedniS=0;
  czasTeraz=millis();
fnTik=fsekundy=fminuty=fgodziny=fdni=0;
if((uint32_t)(czasTeraz-czasPoprzedni)>=tik)
{
  czasPoprzedni=czasTeraz;
  fnTik=1;
  nTik++;
if(nTik>=(1000/tik))    nTik=0;


  if((uint32_t)(czasTeraz-czasPoprzedniS)>=1000)
  {
    czasPoprzedniS=czasTeraz;
    sekundy++;
    fsekundy=1;
     if (sekundy>=60)
    {
      sekundy=0;
      minuty++;
      fminuty=1;
      if (minuty>=60)
      {
        minuty=0;
        godziny++;
        fgodziny=1;
        if (godziny>=24)
        {
          godziny=0;
          fdni=1;
          dni++;
   
        }
      }
    }
  }
}
}




void FillLEDsFromPaletteColors( uint8_t colorIndex)
{
    uint8_t brightness = 255;
   
    for( int i = 0; i < NUM_LEDS; ++i) {
        leds[i] = ColorFromPalette( currentPalette, colorIndex, brightness, currentBlending);
        colorIndex += 3;
    }
}


// There are several different palettes of colors demonstrated here.
//
// FastLED provides several 'preset' palettes: RainbowColors_p, RainbowStripeColors_p,
// OceanColors_p, CloudColors_p, LavaColors_p, ForestColors_p, and PartyColors_p.
//
// Additionally, you can manually define your own color palettes, or you can write
// code that creates color palettes on the fly.  All are shown here.

void ChangePalettePeriodically()
{
//    uint8_t secondHand = (millis() / 1000) % 60;
//    static uint8_t lastSecond = 99;
    switch (kod)
{     case 0x16:
       { currentPalette = RainbowColors_p;         currentBlending = LINEARBLEND; }
      break;
      case 0xC:
      { currentPalette = RainbowStripeColors_p;   currentBlending = NOBLEND;  }
      break;
      case 0x18:
      { currentPalette = RainbowStripeColors_p;   currentBlending = LINEARBLEND; }
      break;
      case 0x5E:
       { SetupPurpleAndGreenPalette();             currentBlending = LINEARBLEND; }
      break;
      case 0x8:
       { SetupTotallyRandomPalette();              currentBlending = LINEARBLEND; }
      break;
      case 0x1C:
       { SetupBlackAndWhiteStripedPalette();       currentBlending = NOBLEND; }
      break;
      case 0x5A:
      { SetupBlackAndWhiteStripedPalette();       currentBlending = LINEARBLEND; }
      break;
      case 0x42:
      { currentPalette = CloudColors_p;           currentBlending = LINEARBLEND; }
      break;
      case 0x52:
      { currentPalette = PartyColors_p;           currentBlending = LINEARBLEND; }
      break;
      case 0x4A:
      { currentPalette = myRedWhiteBluePalette_p; currentBlending = NOBLEND;  }
      break;
default:
//leds[whiteLed] = CRGB::White;
break;
}

   
//    if( lastSecond != secondHand) {
//        lastSecond = secondHand;
//        if( secondHand ==  0)  { currentPalette = RainbowColors_p;         currentBlending = LINEARBLEND; }
//        if( secondHand == 10)  { currentPalette = RainbowStripeColors_p;   currentBlending = NOBLEND;  }
//        if( secondHand == 15)  { currentPalette = RainbowStripeColors_p;   currentBlending = LINEARBLEND; }
//        if( secondHand == 20)  { SetupPurpleAndGreenPalette();             currentBlending = LINEARBLEND; }
//        if( secondHand == 25)  { SetupTotallyRandomPalette();              currentBlending = LINEARBLEND; }
//        if( secondHand == 30)  { SetupBlackAndWhiteStripedPalette();       currentBlending = NOBLEND; }
//        if( secondHand == 35)  { SetupBlackAndWhiteStripedPalette();       currentBlending = LINEARBLEND; }
//        if( secondHand == 40)  { currentPalette = CloudColors_p;           currentBlending = LINEARBLEND; }
//        if( secondHand == 45)  { currentPalette = PartyColors_p;           currentBlending = LINEARBLEND; }
//        if( secondHand == 50)  { currentPalette = myRedWhiteBluePalette_p; currentBlending = NOBLEND;  }
//        if( secondHand == 55)  { currentPalette = myRedWhiteBluePalette_p; currentBlending = LINEARBLEND; }
//    }
}

// This function fills the palette with totally random colors.
void SetupTotallyRandomPalette()
{
    for( int i = 0; i < 16; ++i) {
        currentPalette[i] = CHSV( random8(), 255, random8());
    }
}

// This function sets up a palette of black and white stripes,
// using code.  Since the palette is effectively an array of
// sixteen CRGB colors, the various fill_* functions can be used
// to set them up.
void SetupBlackAndWhiteStripedPalette()
{
    // 'black out' all 16 palette entries...
    fill_solid( currentPalette, 16, CRGB::Black);
    // and set every fourth one to white.
    currentPalette[0] = CRGB::White;
    currentPalette[4] = CRGB::White;
    currentPalette[8] = CRGB::White;
    currentPalette[12] = CRGB::White;
   
}

// This function sets up a palette of purple and green stripes.
void SetupPurpleAndGreenPalette()
{
    CRGB purple = CHSV( HUE_PURPLE, 255, 255);
    CRGB green  = CHSV( HUE_GREEN, 255, 255);
    CRGB black  = CRGB::Black;
   
    currentPalette = CRGBPalette16(
                                   green,  green,  black,  black,
                                   purple, purple, black,  black,
                                   green,  green,  black,  black,
                                   purple, purple, black,  black );
}


// This example shows how to set up a static color palette
// which is stored in PROGMEM (flash), which is almost always more
// plentiful than RAM.  A static PROGMEM palette like this
// takes up 64 bytes of flash.
const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM =
{
    CRGB::Red,
    CRGB::Gray, // 'white' is too bright compared to red and blue
    CRGB::Blue,
    CRGB::Black,
   
    CRGB::Red,
    CRGB::Gray,
    CRGB::Blue,
    CRGB::Black,
   
    CRGB::Red,
    CRGB::Red,
    CRGB::Gray,
    CRGB::Gray,
    CRGB::Blue,
    CRGB::Blue,
    CRGB::Black,
    CRGB::Black
};



// Additional notes on FastLED compact palettes:
//
// Normally, in computer graphics, the palette (or "color lookup table")
// has 256 entries, each containing a specific 24-bit RGB color.  You can then
// index into the color palette using a simple 8-bit (one byte) value.
// A 256-entry color palette takes up 768 bytes of RAM, which on Arduino
// is quite possibly "too many" bytes.
//
// FastLED does offer traditional 256-element palettes, for setups that
// can afford the 768-byte cost in RAM.
//
// However, FastLED also offers a compact alternative.  FastLED offers
// palettes that store 16 distinct entries, but can be accessed AS IF
// they actually have 256 entries; this is accomplished by interpolating
// between the 16 explicit entries to create fifteen intermediate palette
// entries between each pair.
//
// So for example, if you set the first two explicit entries of a compact
// palette to Green (0,255,0) and Blue (0,0,255), and then retrieved
// the first sixteen entries from the virtual palette (of 256), you'd get
// Green, followed by a smooth gradient from green-to-blue, and then Blue.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#6
Dziękuję za wcześniejsze odpowiedzi! Wypróbowałem twój kod i widzę że funkcje zmieniają się także u mnie pod niektórymi przyciskami, jednak jak mam być szczery jeszcze nie jestem w C++ wystarczająco długo aby zrozumieć całkowite działanie ColorPalette. Zrobiłem z kodu prostotę w loop i dzięki temu otrzymałem najlepszy póki co dla mnie efekt. Usunąłem także switch bo z jakiegoś powodu nie działała, jakbyś wiedział jak zastąpić w moim kodzie if else na switch to byłbym wdzięczny. Próbowałem IrReceiver.available() ponieważ znalazłem posty mówiące że dzięki temu sposobowi otrzymują 80% odczytywań poprawnych, jednak w moim przypadku jeśli go użyję to dostaję tylko niepoprawne. Gdy nacisnę na przycisk na pilocie pierwszy kod otrzymuję poprawny, jednak jeśli go przytrzymam to wszystkie po kolei podczas trzymania otrzymuję niepoprawne, i przez trzymanie nazywam ok. 200ms, gdy otrzymam poprawny kod to działa tak jak chciałbym, jednak gdy otrzyma kod niepoprawny to ledy zatrzymują się w miejscu. Mógłbyś doradzić jak zapobiec tym błędnym kodom, jak je ignorować?
Kod:
#include <FastLED.h>
#include <IRremote.h>

#define NUM_LEDS 180
#define DATA_PIN 7
#define BRIGHTNESS 60
#define RECV_PIN 6

CRGB leds[NUM_LEDS];

uint8_t hue = 0;
int huechange = 3;
int dir = 1;
int i = 0;
bool turnedOn = true;
int o = 0;

unsigned long previousMillis = 0;
const long interval = 25;

void setup() {
  Serial.begin(9600);
  IrReceiver.begin(RECV_PIN);
  pinMode(2, OUTPUT);

  FastLED.setBrightness(BRIGHTNESS);
  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
  FastLED.clear();
  FastLED.show();
}

// FUNKCJA RED
void red() {
  fill_solid(leds, NUM_LEDS, CRGB::Red);
  FastLED.show();
}

// FUNKCJA GREEN
void green() {
  fill_solid(leds, NUM_LEDS, CRGB::Green);
  FastLED.show();
}

// FUNKCJA RAINBOWEFFECT
void rainbowEffect() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    if (i < NUM_LEDS && i >= 0) {
      leds[i] = CHSV(hue, 255, 255);
      FastLED.show();
      i += dir;
    } else {
      dir *= -1;
      i += dir;
    }
    hue += huechange;
    blur1d(leds, NUM_LEDS, 172);
  }
}

void loop() {
  // ODEBRANIE KODU
  if (IrReceiver.decode()) {
    Serial.println(IrReceiver.decodedIRData.command);
    IrReceiver.resume();
  }
  // FUNKCJE W ZALEŻNOŚCI OD KODU
  if (IrReceiver.decodedIRData.command == 69) {
    red();
  } else if (IrReceiver.decodedIRData.command == 70) {
    green();
  } else if (IrReceiver.decodedIRData.command == 71) {
    rainbowEffect();
  }
}
Sygnały z pilota podczas działania tego kodu, jeśli to ma pomóc (0, 64, 132 błędne)
W trzech przypadkach: podczas trzymania przycisku przez ok. 1 sekundę (kod poprawny 69), pół sekundy (kod poprawny 70) oraz 1/3 - 1/4 (kod poprawny 71)
Kod:
64
64
69
64
64
69
64
64
69
64
Kod:
70
0
70
64
70
64
70
64
70
64
Kod:
0
71
0
71
0
71
0
71
0
71
0
71
0
71
132
71
0
71
71
 
Odpowiedź
#7
Nie wiem jaki masz pilot, ale to może być normalne, wywal wszystko i pobaw się samym pilotem, naucz się go obsługiwać i dowiedz się jak działa - jest też komenda "powtórz", wgraj jakiś szkic do sczytywania kodów. Jak ogarnąć 0 czy błędne kody też masz. Zatrzymanie led, jak otrzymujesz kod to go wtedy masz zweryfikować, poprawny przekazać do zmiennej sterującej, inne zignorować, ja używam tylko 0 by ignorować, bo innych nie odczytałem, ale jak masz ich więcej to wybierasz te 5-10, które zmieniają wartość zmiennej sterującej i resztę wywalasz do śmieci, ignorujesz ich otrzymanie.
Dlatego masz mieć podziała na bloki programu, wszystko co robi biblioteka IR ja zamknąłem w jednym bloku, z niego wychodzi już moja zmienna "kod" po weryfikacji i używam jej w innych blokach.
Nie ważne czy switch case czy if else if, działają podobnie, switch jest dla mnie bardziej czytelny, ale nie mogłem użyć tablicy stałych do wybierania caseów.

Przecież dałem Ci przykład, masz swoją funkcję red(); to wstaw ją w miejsce {}
case 0x16:
{ currentPalette = RainbowColors_p; currentBlending = LINEARBLEND; }

Funkcja Rainbow effect jest napisana źle, masz ją zrobioną tak, że musisz pokazać wszystkie kroki z pętli for(), a powinna być tak napisana, że ją wywołujesz co określony interwał, wykonujesz krok zapamiętywany w zmiennej static, wraca do loop, po kolejnym wywołaniu wykonuje kolejny krok. Wtedy między krokami możesz ją zakończyć, właściwie zmienić nowym kodem, tak są napisane funkcje w szkicu Color palet.
Przyjrzyj się funkcji czas() w moim przykładzie, używam millis tylko raz na początku loop, robię sobie flagi i proste operacje logiczne by wyznaczać interwały 1, 20, 50, 100ms i co tyle wywołuję funkcje, w między czasie program jest gotowy na inne zadania, odebrać kod, odczytać przycisk, wydrukować co się w nim dzieje i zmierzony upływ czasu.
Po krótkim zastanowieniu ograniczenia są tylko w mojej głowie, wystarczy, że nauczysz się mierzyć upływ czasu z tą funkcją czas() w przykładzie, a wtedy po odebraniu błędnego kodu IR można wstrzymać na np. 500ms wykonywanie programu, nie wywoływać funkcji FastLED.show(); i masz te 500ms na spokojne odebranie prawidłowego kodu, a jak nic nie przyleci to wracasz tam gdzie przerwałeś.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości