Controllare led indirizzabili con Arduino

di il
27 risposte

Controllare led indirizzabili con Arduino

Buongiorno,
sono nuovo nel forum e vorrei sottoporvi un problemino.
Vi allego uno sketch in cui vorrei far iniziare la sequenza di luci e accendere il led dell'uscita 13, appena A2 riceve la tensione, e fin qui va bene, ma vorrei che tale sequenza finisse spegnendo l'ultimo led che poi sarebbe il primo della striscia, invece la sequenza si ferma lasciando accesi 72 led, quindi si spegne il led dell'uscita 13.
Senza l' if e quello che viene dall'else in poi, i led si spengono tutti ma mentre la sequenza ricomincia

Come potrei far si che la sequenza si ferma allo spegnimento dell'ultimo led ?

Allego foto di come si ferma la sequenza

Grazie


#include <FastLED.h>
#define NUM_LEDS 250
#define InputAnalogico A2
CRGBArray<NUM_LEDS> leds;
const int led1 = 13;

void setup() {
  FastLED.addLeds<NEOPIXEL, 6>(leds, NUM_LEDS);
  pinMode(led1, OUTPUT);
}
void loop()
{ int SensoreSu = analogRead(InputAnalogico);

  if (SensoreSu > 140) {

    static uint8_t colori;
    for (int i = 230; i > NUM_LEDS - 251; i--)
    { leds.fadeToBlackBy(10);  // lo spazio spento
      leds[i] = CHSV(colori++, 255, 255);
      leds(NUM_LEDS / 1, NUM_LEDS - 1) = leds(NUM_LEDS / 5 - 1 , 0);
      FastLED.delay(30); //la velocità
      digitalWrite(led1, HIGH);
    }
  }
  else {

    static uint8_t hue;
    for (int i = 72; i > NUM_LEDS - 73; i--) 
    { leds.fadeToBlackBy(10);
      leds[i] = CHSV(hue++, 255, 255);
      leds(NUM_LEDS / 1, NUM_LEDS - 1) = leds(NUM_LEDS / 5 - 1 , 0);
      FastLED.delay(30); //la velocità
      digitalWrite(led1, LOW);
    }
  }
}

27 Risposte

  • Re: Controllare led indirizzabili con Arduino

    Purtroppo ci sono tante cose che non vanno e che rendono il codice difficile da leggere, mettile a posto:
    - uso di costanti nel codice. Definiscile all'inizio come "costanti simboliche", proprio come hai fatto con NUM_LEDS
    - non spieghi che significato abbiano i led fino al 71 e dal 230
    - forse non hai chiaro il funzionamento dello sketch: è un loop infinito. La sequenza si ripete per sempre. Devi essere tu, con degli IF a determinare come si evolve nel tempo.
    - non scrivere codice sulla stessa linea di {
    - la possibilità di dichiarare le variabili ovunque sembra una grande comodità ma espone anche ad una cattiva progettazione. Finché non sarai esperto dichiara le variabili all'inizio della funzione e commenta come intendi usarle
    - le divisioni sono una cosa complicata (soprattutto con Arduino), se puoi non usarle.
    - manca la foto!
    - un link alla libreria che stai usando è indispensabile, nessuno sa tutto e se per aiutarti ci tocca anche metterci a guuglare... andiamo male
  • Re: Controllare led indirizzabili con Arduino

    nicolap ha scritto:


    - forse non hai chiaro il funzionamento dello sketch: è un loop infinito. La sequenza si ripete per sempre. Devi essere tu, con degli IF a determinare come si evolve nel tempo.
    esatto. Io suggerirei
    
    int SensoreLettura;
    bool SensoreSu = false;
    
    void loop(){ 
        SensoreLettura = analogRead(InputAnalogico);
      
        if (!SensoreSu && SensoreLettura > 140) {
      	/*** codici led high ***/
        }
        else if (SensoreSu && SensoreLettura <= 140)  {
      	/*** codici led low ***/
        }
    
        if (SensoreLettura > 140) 
      	SensoreSu = true;  
        else 
      	SensoreSu = false;
    }
    
    ma ci sono altre soluzioni
  • Re: Controllare led indirizzabili con Arduino

    Così può funzionare ma trovo la logica contorta e difficile da seguire.
    Meglio individuare un evento che fa partire il ciclo e un'indicazione che si è NEL ciclo.
    Però la specifica non è chiara quindi...
  • Re: Controllare led indirizzabili con Arduino

    Qui sotto il codice originale senza la parte del controllo esterno ma solo la parte in cui continua a far accendere i led con vari colori, come fosse una biscia
    è un codice preso dagli esempi della libreria FastLed in cui ho leggermente modificato la riga "for" per cambiar l'effetto.
    Se riesco e vi può essere d'aiuto, vi allego la libreria, o cerco un link in cui potete vederla
    So che è un loop infinito, ma non trovo il modo di fermarlo facendogli spegnere l'ultimo led
    
    #include <FastLED.h>
    #define NUM_LEDS 230
    
    CRGBArray<NUM_LEDS> leds;
    
    void setup() {
      FastLED.addLeds<NEOPIXEL, 6>(leds, NUM_LEDS);
    }
    void loop() {
    
      static uint8_t hue;
      for (int i = 0; i < NUM_LEDS / 1; i++)  
       
      { 
        leds.fadeToBlackBy(10);// lo spazio spento 
    
        // let's set an led value
        leds[i] = CHSV(hue++, 255, 255);
    
        // now, let's first 20 leds to the top 20 leds,
        leds(NUM_LEDS / 1, NUM_LEDS - 1) = leds(NUM_LEDS / 5 - 1 , 0);
        FastLED.delay(30); // la velocità di scorrimento
      }
    }
    

    Allegati:
    la foto che non mi ha caricato stamane
    la foto che non mi ha caricato stamane
  • Re: Controllare led indirizzabili con Arduino

    bitroby ha scritto:


    Qui sotto il codice originale senza la parte del controllo esterno ma solo la parte in cui continua a far accendere i led con vari colori, come fosse una biscia
    è un codice preso dagli esempi della libreria FastLed in cui ho leggermente modificato la riga "for" per cambiar l'effetto.
    Se riesco e vi può essere d'aiuto, vi allego la libreria, o cerco un link in cui potete vederla
    So che è un loop infinito, ma non trovo il modo di fermarlo facendogli spegnere l'ultimo led
    Non ci siamo ancora:
    - manca il link, non deve essere necessario cercarlo, lo devi avere a portata di mano! Altrimenti come fai a lavorare??? La documentazione va sempre tenuta... là!
    - sbagli a togliere parti del programma. Potresti avere tolto una parte significativa, non hai le competenze per capirlo quindi non farlo.
    - manca una descrizione in italiano corrente (e corretto) di cosa vuoi ottenere. Questa è la parte più importante!!!
    - le righe vuote "a ca..o" non servono e disturbano. Un programmatore (serio) ha bisogno di ordine.
    - usa la tua lingua madre per i commenti.

    PS: se non leggi i nostri post (e parrebbe di no) è inutile che perdiamo tempo.
  • Re: Controllare led indirizzabili con Arduino

    Purtroppo la documentazione non so leggerla essendo inglese, e in italiano non so se capirei abbastanza...

    https://github.com/FastLED/FastLED/wik
    http://fastled.io/docs/3.1/index.htm

    nel secondo post, ho inserito il programma con la sola sequenza di accensione dei led, (come FastLed lo ha scritto) che è lo stesso programma di stamane, a cui ho tolto la parte di codice che ho provato a scrivere io, che dovrebbe servire a fare in modo che la sequenza si avvii quando il piedino A2 riceve una tensione, e si fermi quando l'ultimo led smettere di esser pilotato.
    Con il codice che ho postato stamane, la sequenza si avvia, ma si ferma come potete vedere nella foto, ovvero con un bel po di led ancora accesi
  • Re: Controllare led indirizzabili con Arduino

    Qui riposto il programma (scritto da FastLed) nel quale tolgo gli spazi ma i commenti in inglese son scritti da loro
    P.s. ho voluto darvi la sola parte scritta da loro, solo per potervi aiutarvi il più possibile.
    Più tardi provo quanto consigliato da Weierstrass.
    Grazie
    
    #include <FastLED.h>
    #define NUM_LEDS 230
    CRGBArray<NUM_LEDS> leds;
    
    void setup()
     {
    FastLED.addLeds<NEOPIXEL, 6>(leds, NUM_LEDS);
    }
    
    void loop() {
    static uint8_t hue;
      for (int i = 0; i < NUM_LEDS / 1; i++)  
     { 
      leds.fadeToBlackBy(10);// lo spazio spento tra la sequenza iniziale e quella finale
      leds[i] = CHSV(hue++, 255, 255); // let's set an led value
      leds(NUM_LEDS / 1, NUM_LEDS - 1) = leds(NUM_LEDS / 5 - 1 , 0); // now, let's first 20 leds to the top 20 leds
      FastLED.delay(30); //la velocità
      }
    }
    
  • Re: Controllare led indirizzabili con Arduino

    Ho letto bene il codice di Weierstrass ma mi sa che il mio primo programma vi ha confuso le idee, inserendo anche il controllo del led al piedino 13.
    Vi riposto il codice senza quel led, nella speranza che abbiate capito cosa vorrei fare.
    
    #include <FastLED.h>
    #define NUM_LEDS 230
    #define InputAnalogico A2
    CRGBArray<NUM_LEDS> leds;
    
    void setup(){
     FastLED.addLeds<NEOPIXEL, 6>(leds, NUM_LEDS);
     }
    
    void loop()
    {
     int SensoreSu = analogRead(InputAnalogico); 
     if(SensoreSu > 140)
    {
      static uint8_t hue;
      for (int i = 230; i > NUM_LEDS -231; i--) 
     {
      leds.fadeToBlackBy(10);// lo spazio spento tra la sequenza iniziale e quella finale  
      leds[i] = CHSV(hue++, 255, 255);
      leds(NUM_LEDS / 1, NUM_LEDS - 1) = leds(NUM_LEDS / 5 - 1 , 0);
        FastLED.delay(30); //la velocità
     } 
     }  
     else
     { 
      static uint8_t hue;
      for (int i = 100; i > NUM_LEDS -101; i--)  
     {
      leds.fadeToBlackBy(10);// lo spazio spento    
      leds[i] = CHSV(hue++, 255, 255);
      leds(NUM_LEDS / 1, NUM_LEDS - 1) = leds(NUM_LEDS / 5 - 1 , 0);
        FastLED.delay(30); 
      }
      }
      }
    
  • Re: Controllare led indirizzabili con Arduino

    bitroby ha scritto:


    Ho letto bene il codice di Weierstrass ma mi sa che il mio primo programma vi ha confuso le idee, inserendo anche il controllo del led al piedino 13.
    Vi riposto il codice senza quel led, nella speranza che abbiate capito cosa vorrei fare.
    SBAGLI!
    Leggere il codice, anche per un programmatore professionista, non è MEGLIO che leggere una descrizione in italiano (avevo specificato corrente e corretto, non a caso) soprattutto se chi scrive il codice non è capace!

    Descrivi il tuo problema, in maniera esaustiva, descrivendo l'oggetto che hai e cosa vuoi che faccia.
    quando il piedino A2 riceve una tensione
    Questo è decisamente confuso ma soprattutto non dici che cosa c'è collegato e perché usi un ingresso analogico (che non "riceve" un bel niente).
  • Re: Controllare led indirizzabili con Arduino

    Ok..
    devo illuminare degli scalini, tale sequenza di led, deve avviarsi quando passando davanti al sensore infrarosso, tale sensore fornisce una tensione al piedino A2 di Arduino, una volta avviata tale sequenza, deve fermarsi quando si è spento l'ultimo led della striscia.
    Il numero 230 che vedete nella seconda riga, è il numero di led con cui ora sto facendo le prove, in realtà sugli scalini ne ho installati 508, ma quest'ultimo dettaglio ha poca importanza nella risoluzione del mio problema
    La direzione della sequenza ( scritta nella riga del "for" )va al contrario, quindi ora inizia dal led numero 229 andando verso il led "0", questo perché mi è arrivato solo il sensore del primo piano e attendo quello che monterò al piano terra.
  • Re: Controllare led indirizzabili con Arduino

    Ora ho escluso la terza riga del codice in quanto già dichiarata subito dentro al loop, e modificato il "for" sotto l'else, con il for così modificato la striscia si spegne quasi tutta...rimane acceso il led 0 continuando a cambiar colore
    
    #include <FastLED.h>
    #define NUM_LEDS 230
    //#define InputAnalogico A2
    CRGBArray<NUM_LEDS> leds;
    
    void setup(){
     FastLED.addLeds<NEOPIXEL, 6>(leds, NUM_LEDS);
    }
    void loop()
    {
     int SensoreSu = analogRead(A2); 
     if(SensoreSu > 140)
    {
      static uint8_t hue;
      for (int i = 230; i > NUM_LEDS -231; i--) 
     {
      leds.fadeToBlackBy(10);// lo spazio spento tra la sequenza iniziale e quella finale  
      leds[i] = CHSV(hue++, 255, 255);
      leds(NUM_LEDS / 1, NUM_LEDS - 1) = leds(NUM_LEDS / 5 - 1 , 0);
        FastLED.delay(30); //la velocità
     } 
     }  
     else
     { 
      static uint8_t hue;
      for (int i = 0; i > NUM_LEDS -231; i--)  
     {
      leds.fadeToBlackBy(10);// lo spazio spento    
      leds[i] = CHSV(hue++, 255, 255);
      leds(NUM_LEDS / 1, NUM_LEDS - 1) = leds(NUM_LEDS / 5 - 1 , 0);
        FastLED.delay(30); 
      }
      }
      }
    
  • Re: Controllare led indirizzabili con Arduino

    bitroby ha scritto:


    devo illuminare degli scalini, tale sequenza di led, deve avviarsi quando passando davanti al sensore infrarosso, tale sensore fornisce una tensione al piedino A2 di Arduino,
    Molto meglio!
    Come scritto prima "fornire una tensione" non è una cosa molto corretta. Tra l'altro ci sono tanti tipi di sensori ad infrarossi: alcuni hanno un'uscita digitale, altri analogica. In più alcuni danno un impulso di lunghezza fissa mentre altri danno un segnale per tutta la durata del rilevamento.
    Questi "dettagli" sono importanti, e cambiano un pochino l'algoritmo della sequenza.
    una volta avviata tale sequenza, deve fermarsi quando si è spento l'ultimo led della striscia.
    Ovvero dopo un segnale da parte del sensore dovrà essere eseguito un solo ciclo. Fino al prossimo rilevamento.
    Cosa deve succedere se durante il ciclo arriva un altro segnale dal sensore? DEVI deciderlo!
    Il numero 230 che vedete nella seconda riga, è il numero di led con cui ora sto facendo le prove, in realtà sugli scalini ne ho installati 508, ma quest'ultimo dettaglio ha poca importanza nella risoluzione del mio problema
    La direzione della sequenza ( scritta nella riga del "for" )va al contrario, quindi inizia dal led numero 507 andando verso il led "0", questo perché mi è arrivato solo il sensore del primo piano e attendo quello che monterò al piano terra.
    Quindi ci saranno due sensori?
    Hai mai pensato di fare un diagramma di flusso? Anche con carta e penna!
    
     FastLED.addLeds<NEOPIXEL, 6>(leds, NUM_LEDS);
    
    Quel 6 non va bene, dichiaralo con un #define più sopra. Prendi la buonissima abitudine subito.

    
     if(SensoreSu > 140)
    
    Altra costante! Regola: si possono usare come costanti solo -1, 0, 1 ed anche 2 e 10 ma SOLO quando indicano la base numerica. Altrimenti definiscile sempre come "costanti simboliche" e dagli un nome decente (lungo, esplicativo).
    
      for (int i = 230; i > NUM_LEDS -231; i--) // prima i era = a 0 e > era <
    
    Il ciclo deve andare da NUM_LEDS fino a 0 (compreso? non è chiaro), decrementando.
    Osserva come ho scritto in ITALIANO e come puoi trasformare la frase in un costrutto for pari pari. Se ci metti un pelo di attenzione ti riesce facile e ti aiuta tantissimo.

    
      leds.fadeToBlackBy(10);// lo spazio spento tra la sequenza iniziale e quella finale  
    
    La dichiarazione della funzione è questa:
    CRGB & 	fadeToBlackBy (uint8_t fadefactor)
    fadeToBlackBy is a synonym for nscale8( ..., 255-fadefactor)   
    
    inline CRGB& nscale8 (const CRGB & scaledown )
    {
      r = ::scale8(r, scaledown.r);
      g = ::scale8(g, scaledown.g);
      b = ::scale8(b, scaledown.b);
      return *this;
    }
    
    Quindi nel tuo caso non fa niente!
    
      leds[i] = CHSV(hue++, 255, 255);
    
    Assegni un colore con tinta che cambia, facendo una sfumatura.
    Però quando hue arriva a 255 cosa succederà, secondo te?
    
      leds(NUM_LEDS / 1, NUM_LEDS - 1) = leds(NUM_LEDS / 5 - 1 , 0);
    
    Questa riga non ha senso, stai cercando di usare una delle cose più contorte del C++, lascia stare! Usa la carta a quadretti e disegna, poi scrivi del codice "normale".
    
        FastLED.delay(30); //la velocità
    
    Sbagliato: non la velocità ma la PAUSA. Che l'effetto della pausa determini la velocità è secondario! Chiama le cose col loro nome, poi puoi commentare per esteso...
    
      FastLED.show(); 
    
    Questa riga manca ed è indispensabile!


    Manca ancora la logica per fare il ciclo una sola volta.
    Ma facciamo un passo alla volta.
  • Re: Controllare led indirizzabili con Arduino

    Il sensore composto da un trasmettitore ed un ricevitore infrarossi, quando ha un'ostacolo a circa 10 cm , che fa ritornare l'infrarosso al ricevitore, fornisce circa 2,2 volt e man mano che l'ostacolo si allontana (max 80 cm) tale tensione diminuisce, il valore 140 l'ho scelto facendo delle prove.

    Dopo che Arduino legge un valore superiore a 140, deve avviarsi un ciclo per ogni led, (almeno per quello che ho capito io essendo a digiuno di programmazione in C, quindi in questo caso, 231 cicli come dichiarato in NUM_LEDS

    Se durante il ciclo, arriva un segnale da uno dei due sensori, attualmente non succede nulla in quanto il programma è occupato a svolgere il ciclo e la lettura dei sensori avviene fuori dal ciclo, ma mi va bene così in quanto questa scia, segue come velocità chi sta facendo le scale, se un'altra persona dovesse percorrere la scala, non saprei come avviare la sequenza se non accendendo tutti il led, ma è un problema che affronterò se in un futuro ne vedrò la necessità.
    Dici che il 6 posto qui...FastLED.addLeds<NEOPIXEL, 6>(leds, NUM_LEDS); non va bene e di spostarlo in un #define sopra, lho fatto ed ho modificato in vari modi quella riga, ma così mi da errore, ma posso chiederti cosa cambierebbe spostandolo ?

    Non capisco cosa intendi qui sotto... per me SensoreSu indica il sensore al piano di sopra, e scusami ma non so cosa sia una costante simbolica
    if(SensoreSu > 140)
    Altra costante! Regola: si possono usare come costanti solo -1, 0, 1 ed anche 2 e 10 ma SOLO quando indicano la base numerica. Altrimenti definiscile sempre come "costanti simboliche" e dagli un nome decente (lungo, esplicativo).

    Qui... for (int i = 230; i > NUM_LEDS -231; i--) // prima i era = a 0 e > era <

    Il ciclo deve andare da NUM_LEDS fino a 0 (compreso? non è chiaro), decrementando.
    Osserva come ho scritto in ITALIANO e come puoi trasformare la frase in un costrutto for pari pari. Se ci metti un pelo di attenzione ti riesce facile e ti aiuta tantissimo.
    Credo che sia come lo hai descritto tu ma non conoscendo il linguaggio C, non posso dirlo con certezza, per tanto non posso descriverlo per non rischiare di dire sciocchezze, in origine andava incrementando in quanto iniziava dal led "0", e l'ho modificato così per far avviare la sequenza dall'ultimo led della striscia, per apportar modifiche non posso basarmi su degli insegnamenti ma su 4 articoli scritti in italiano che trovo in internet.

    Non ho capito cosa intendi con... La dichiarazione della funzione è questa:

    CRGB & fadeToBlackBy (uint8_t fadefactor)
    fadeToBlackBy is a synonym for nscale8( ..., 255-fadefactor)

    inline CRGB& nscale8 (const CRGB & scaledown )
    {
    r = ::scale8(r, scaledown.r);
    g = ::scale8(g, scaledown.g);
    b = ::scale8(b, scaledown.b);
    return *this;
    }

    Quindi nel tuo caso non fa niente!
    Dove hai preso questo codice?

    Qui... credo che quando arriva a 255, il ciclo ricomincia
    leds = CHSV(hue++, 255, 255);

    Assegni un colore con tinta che cambia, facendo una sfumatura.
    Però quando hue arriva a 255 cosa succederà, secondo te?

    Qui sotto ...si me ne sono accorto anch'io che a differenza di altri programmi, non c'è, ma funziona ugualmente, ci sarà un motivo se la FastLed non lo ha inserito
    FastLED.show();
    Questa riga manca ed è indispensabile!

    Quindi ci saranno due sensori? ....Si, uno sullo scalino a piano terra ed uno sul gradino al primo piano

    Hai mai pensato di fare un diagramma di flusso? Anche con carta e penna!... a dirla tutta, fino a pochi mesi fa usavo Flowcode che appunto usa I diagrammi di flusso per programmare i Pic, ma non son sufficienti per comandare il led indirizzabili, se non usando un pic con molta velocità e memoria, quindi son passato ad Arduino con lo svantaggio per me, di non sapere il linguaggio, tutt'ora il diagramma non lo faccio, in quanto provo dei programmi già scritti, e li modifico fino a che il led si accendono come vorrei
  • Re: Controllare led indirizzabili con Arduino

    
    #define NUM_LEDS 230
    CRGBArray<NUM_LEDS> leds;
    
    Ok stai dichiarando un array "leds" da 230, quindi leds parte da 0 e arriva a 229
    
    for (int i = 230; i > NUM_LEDS -231; i--) 
    
    Non ha senso scrivere le macro se poi devi metterci delle operazioni con numeri fissi in mezzo. A questo punto scrivi direttamente i > -1. In ogni caso i parte da 230 e quindi...
    
    leds[i] =
    
    qui stai scrivendo fuori dall'array, con possibile comportamento indefinito del tuo codice
    
    leds(NUM_LEDS / 1, NUM_LEDS - 1) = leds(NUM_LEDS / 5 - 1 , 0);
    Ma sta roba che fa esattamente? Nel dubbio commentala un attimo
    
    static uint8_t hue;
    Per il momento queste variabili dichiarale una sola volta e fuori dalle funzioni, che già è difficile capire cosa vuoi fare...
    FastLED.delay(30);
    
    Questi delay mettili al massimo possibile che almeno si capisce che sta succedendo nel tuo codice.
Devi accedere o registrarti per scrivere nel forum
27 risposte