Vai al contenuto
PLC Forum


WS2812B DA PULSANTE IN AUTOMATICO


kemosabe

Messaggi consigliati

#include <Adafruit_NeoPixel.h>

#define SWITCH 0
#define PIN 6
Adafruit_NeoPixel strip = Adafruit_NeoPixel(24, PIN, NEO_RGB + NEO_KHZ800);

void setup() {
   strip.begin();
  strip.show(); // Initialize all pixels to 'off'

  // initialize the SWITCH pin as an input.
  pinMode(SWITCH, INPUT);
  // ...with a pullup
  digitalWrite(SWITCH, HIGH);
}

void loop() {
  uint8_t mode = EEPROM.read(MODE_ADDR) % N_MODES;
  switch (mode) {
    case 0:
      singleColor(strip.Color(192, 0, 255)); // purple
      break;
    case 1:
      twinkle(strip.Color(0, 0, 255), strip.Color(255, 255, 255), 50);
      break;
    case 2:
      rainbowCycle(20);
      break;
    case 3:
      colorBlink(50);
      break;
  }
  mode = (mode + 1) % N_MODES;
  EEPROM.write(MODE_ADDR, mode);
}

bool buttonPressed() {
  bool pressed = false;
  while (! digitalRead(SWITCH))
    pressed = true;
  return pressed;
}

// Fill the dots with a color
void singleColor(uint32_t c) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
  }
  strip.show();
  while (! buttonPressed())
    ;
}

#define MAX_TWINKLE 5

void twinkle(uint32_t c1, uint32_t c2, uint8_t wait) {
  int16_t tw[MAX_TWINKLE];

  for(uint16_t i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c1);
  }
  strip.show();

  for (uint8_t i = 0; i < MAX_TWINKLE; i++) {
    tw[i] = -1;
  }

  for ( ; ; ) {
    for (uint8_t i = 0; i < MAX_TWINKLE; i++) {
      if (tw[i] >= 0)
        strip.setPixelColor(tw[i], c1);
      tw[i] = random(strip.numPixels());
      strip.setPixelColor(tw[i], c2);
      strip.show();
      delay(wait);
      if (buttonPressed())
        return;
    }
  }
}

void colorBlink(uint8_t wait) {
  uint16_t i;
  uint8_t hue;
  uint32_t c;
  while (! buttonPressed()) {
    i = random(strip.numPixels());
    hue = random(256);
    c = Wheel(hue);
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;

  for ( ; ; ) {
    for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
      for(i=0; i< strip.numPixels(); i++) {
        strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
      }
      strip.show();
      delay(wait);
      if (buttonPressed())
        return;
    }
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

OK , non avevo ancora guardato gli ingressi, mi stavo concentrando su quel bool del pulsante, anche perchè poi dovrà sparire lo switch

grazie

Link al commento
Condividi su altri siti


tornando a quello che mi chiedevate, oltre che a fare la descrizione del mio intento, non capisco cosa debba fare.

perchè secondo me risolto il problema del bool del pulsante e di capire a cosa servono i return, credo che si possa risolvere.

 

grazie

 

Link al commento
Condividi su altri siti

 

risolto il problema del bool del pulsante

 

Questo non è unproblema, visto che l'ingresso del pulsante può assumere solo 2 valori: LOW o HIG (FALSE o TRUE), la variabile non può che essere dichiarata "bool", che significa booleana richiamando le regole dell'algebra di bool.

 

 

capire a cosa servono i return

 

Te lo avevo già spiegato.

Servono a tornare al punto in cui è stata chiamata la funzione.

 

Se nel "loop()" richiami, ad esempiola funzione

rainbowCycle(20);

Questa sarà eseguita ed al termine il programma tornerà alla riga immediatamente seguente quella della chiamata.

Questa funzione è dichiarata void, quindi non renderà alcun valore.

 

Quando invece il programma incotra

if (buttonPressed()

Al ternine della funzione sarà ritornata una variabile bool con lo stato TRUE o FALSE che indica se il pulsante è stato premuto.

 

Se elimini la chiamata a questa funzione il programma evolverà senza attendere che venga pigiato il pulsante.

 

 

 

Link al commento
Condividi su altri siti

 

secondo voi, sarebbe meglio, lasciare o eliminare lo switch case, e lasciare solo la chiamata ai sotto programmi?

Se ti va bene una sequenza fissa puoi eliminarlo, ed elimina quelle chiamate alla EEPROM. Poi ti conviene lavorare sulle singole funzioni per eliminare il buttonPressed(), visto che non c'è uniformità nella gestione del pulsante.

 

Ciao, Ale.

Link al commento
Condividi su altri siti

Buongiorno, non capisco, in questo programma, tre cose:

1: rainbowCycle(20); a cosa serve quel 20

2: void colorBlink(uint8_t wait) {
  uint16_t i;
  uint8_t hue;
  uint32_t c;
 // while (! buttonPressed()) {
    i = random(strip.numPixels());
    hue = random(256);
    c = Wheel(hue);
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  //}
}

non capisco a cosa serva dichiarare una variabile all'interno di una funzione, quindi quel  delay(wait); quanto aspetta

 

 

3: visto che alcune volte per proseguire con il programma bisogna avere il pulsante premuto e altre no, come faccio a decidere quando devo farlo risultare premuto o no.

 

grazie

Link al commento
Condividi su altri siti

 

: rainbowCycle(20); a cosa serve quel 20

 

Guarda la funzione che viene chiamata

 

void rainbowCycle(uint8_t wait)

ti dice che una funzione che non ritorna alcun valore, ma che ha necessità di un parametr, byte senza segno che corrisponde al tempo di attesa (wait) suppongo.

 

 

non capisco a cosa serva dichiarare una variabile all'interno di una funzione, quindi quel  delay(wait); quanto aspetta

 

Dovresti studiarti un po' di programamzione, non si può tenere un corso di "C" a puntate con dei messaggi di una discussione.

Comunque se dichiari una variabile all'interno di una funzione, l'area di memoria riservata è occupata solo durante lo svolgimento della funzione, fuori dalla funzone può essere riassegnata.

 

 

visto che alcune volte per proseguire con il programma bisogna avere il pulsante premuto e altre no, come faccio a decidere quando devo farlo risultare premuto o no.

 

Lo vedi dal programma, qunado viene chiamata la funzione

 

buttonPressed()

 

Link al commento
Condividi su altri siti

Io ti consiglio il padre di tutti i libri che insegnano "C" e suoi derivati:"Linguaggio C" di Kernighan e Ritcie, colloquialmente detto "il ritcikernigam".

Ce l'ho da circa 50 anni e ogni tanto mi serve consultarlo, C'è tutto quello che serve come fondamento dellinguaggio Ai tempi costava 21.000Lire, oggi penso si trovi attorno ai 20€

Link al commento
Condividi su altri siti

E molto più recente della mia edizione che, probabilmente, è più scarna, però il testo è quello.

In pratica è "il verbo" per chi programma in "C" e suoi derivati.

Link al commento
Condividi su altri siti

 

ok ma in definitiva, quel wait all'interno della funzione, quanto tempo aspetta???

Quello che gli passi quando chiami la funzioni. Essendo il parametro dichiarato come uint8_t, cioè unsigned int 8 bit, può assumere valori tra 0 e 255. Nel loop hanno usato 50 o 20, ricordati che parliamo di millisecondi.

 

Ciao, Ale.

Link al commento
Condividi su altri siti

quindi questo rainbowCycle(20); passa 20 al wait che c'è nella funzione giusto?

se allora capisco bene, ogni volta che chiamo una funzione con questo rainbowCycle(20);, se imposto degli interi all'interno della funzione acquisiscono il dato impostato prima

 

giusto???

 

grazie

 

Link al commento
Condividi su altri siti

 

quindi questo rainbowCycle(20); passa 20 al wait che c'è nella funzione giusto?

Si, il dato che passi diventa una variabile locale della funzione e assume il nome che hai impostato nella definizione della funzione, in questo caso "wait".

 

se allora capisco bene, ogni volta che chiamo una funzione con questo rainbowCycle(20);, se imposto degli interi all'interno della funzione acquisiscono il dato impostato prima

Non proprio, vedi sopra, ci sono delle regole da seguire. Nella funzione puoi dichiarare e definire delle variabili, che saranno anch'esse variabili locali della funzione, cioè saranno visibili ed utilizzabili solo all'interno della funzione stessa. Una variabile che invece definisci/dichiari all'esterno delle funzioni (tipo "strip" nell'esempio sopra) è una variabile globale, cioè può essere usata da tutte le funzioni. Questo meccanismo si chiama visibilità delle variabili, ed è spiegato nel libro che leggerai.

 

Ciao, Ale.

Link al commento
Condividi su altri siti

ok, almeno adesso comincio a comprendere qualcosa di piu.

torniamo a noi, mi serve un consiglio per quel pulsante, non capisco che procedura fare per farlo vedere una volta premuto e poi altre volte no.

 

grazie

Link al commento
Condividi su altri siti

Te lo ripeto, cerca nelle funzioni dove viene chiamata la funzione

buttonPressed()

 

Se richiami questa funzione devi poi premere il pulsante per far proseguire il programma.

 

Fai una prova: commenta le rige che chiamano questa funzione e osserva quello che accada.

Link al commento
Condividi su altri siti

bool buttonPressed() {           //variabile di stato 
  bool pressed = false;          //variabile di default = false
  while (! digitalRead(SWITCH))  // finchè il pulsante non è premuto
    pressed = true;               // la variabile è true
  return pressed;                 //  ritorna lo stato della variabile
}

// Fill the dots with a color
void singleColor(uint32_t c) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
  }
  strip.show();
  while (! buttonPressed())     // finchè la variabile bool è true
    ;

ve ne mando un pezzo alla volta cosi' è piu' chiaro

 

grazie

Modificato: da kemosabe
Link al commento
Condividi su altri siti

void twinkle(uint32_t c1, uint32_t c2, uint8_t wait) {
  int16_t tw[MAX_TWINKLE];

  for(uint16_t i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c1);
  }
  strip.show();

  for (uint8_t i = 0; i < MAX_TWINKLE; i++) {
    tw[i] = -1;
  }

  for ( ; ; ) {
    for (uint8_t i = 0; i < MAX_TWINKLE; i++) {
      if (tw[i] >= 0)
        strip.setPixelColor(tw[i], c1);
      tw[i] = random(strip.numPixels());
      strip.setPixelColor(tw[i], c2);
      strip.show();
      delay(wait);
      if (buttonPressed())   // se la variabile bool è false
        return;              // ritorna alla chiamata della funzione  twinkle
    }

 

void rainbowCycle(uint8_t wait) {
  uint16_t i, j;

  for ( ; ; ) {
    for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
      for(i=0; i< strip.numPixels(); i++) {
        strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
      }
      strip.show();
      delay(wait);
      if (buttonPressed())    // bool è false ritorna alla funzione rainbowCycle
        return;

 

ok ditemi cosa sbaglio?????

 

grazie

Link al commento
Condividi su altri siti

void colorBlink(uint8_t wait) {
  uint16_t i;
  uint8_t hue;
  uint32_t c;
  while (! buttonPressed()) {     // finchè bool è true
    i = random(strip.numPixels());
    hue = random(256);
    c = Wheel(hue);
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }

ce ne era ancora uno......

Link al commento
Condividi su altri siti

secondo me dovrei impostare due variabili, una per selezionare i case dello switch case, e una per impostare il bool

 

dico bene o dico giusto????

 

hahahaha scherzo

 

grazie

Link al commento
Condividi su altri siti

Questa è una possibile soluzione, vedi se ti va bene :


#include <Adafruit_NeoPixel.h>

#define PIN 6
Adafruit_NeoPixel strip = Adafruit_NeoPixel(24, PIN, NEO_RGB + NEO_KHZ800);

void setup() {
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void loop() {
    singleColor(strip.Color(192, 0, 255)); // purple
    //singleColor(strip.Color(random(255),random(255), random(255))); // casuale
    twinkle(strip.Color(0, 0, 255), strip.Color(255, 255, 255), 50);
    rainbowCycle(20);
    colorBlink(50);
}

// Fill the dots with a color
void singleColor(uint32_t c) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
  }
  strip.show();
  delay(1000); // tempo per cui l'effetto verrà visualizzato (in ms)
}

#define MAX_TWINKLE 5

void twinkle(uint32_t c1, uint32_t c2, uint8_t wait) {
  int16_t tw[MAX_TWINKLE];

  for(uint16_t i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c1);
  }
  strip.show();

  for (uint8_t i = 0; i < MAX_TWINKLE; i++) {
    tw[i] = -1;
  }

  //for ( ; ; ) {
  for (uint8_t n=0; n < 5 ; n++ ) {  // ripete l'effetto n volte
    for (uint8_t i = 0; i < MAX_TWINKLE; i++) {
      if (tw[i] >= 0)
        strip.setPixelColor(tw[i], c1);
      tw[i] = random(strip.numPixels());
      strip.setPixelColor(tw[i], c2);
      strip.show();
      delay(wait);
    }
  }
}

void colorBlink(uint8_t wait) {
  uint16_t i;
  uint8_t hue;
  uint32_t c;
  //while (! buttonPressed()) {
    //i = random(strip.numPixels());
  for(uint8_t i=0;i<strip.numPixels();i++){
    hue = random(256);
    c = Wheel(hue);
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;

  for (uint8_t n=0 ;n < 5 ; n++ ) {  // ripete l'effetto n volte
    for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
      for(i=0; i< strip.numPixels(); i++) {
        strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
      }
      strip.show();
      delay(wait);
    }
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

Non ho la libreria e non ho voglia di scaricarla, per cui non ho provato la compilazione, ma dovrebbe funzionare.

 

Ciao, Ale.

 

Edit: ci siamo sovrapposti, mi spiace, comunque leggi e facci sapere.

Modificato: da ilguargua
edit
Link al commento
Condividi su altri siti

kemosabe, giusto per la cronaca, queste 2 sono le uniche che hai azzeccato :

 

pressed = true; // la variabile è true

return pressed; // ritorna lo stato della variabile

 

Leggi il libro e poi ritenta, per ora Auguri di buon Natale.

 

Ciao, Ale.

Link al commento
Condividi su altri siti

arriva a rainbowCycle e si blocca.

ma il problema non è questo, il fatto di togliere lo switch case, lo avevo gia provato, e sapevo che in un punto o in un'altro si sarebbe bloccato.

oltre a non capire perchè si blocca, vorrei vedere se riesco a farlo funzionare sostituendo il pulsante, perchè da quel poco che capisco, mi sa che i bool del pulsante servano per far avanzare il programma.

Sto guardando come funziona il programma che mi hai dato, in effetti non si blocca, ma procede in modo strano, nel senso che alcuni passaggi li fagirare una sola volta e quindi con un tempo di esecuzione quasi nullo, altri passaggi, tipo il rainbow cycle, li svolge anche per piu di un minuto.

Per esempio potremmo fare come l'esempio della striscia rgb , mettendo dei while(millis), ma prima vorrei vedere di provare a farlo funzionare modificando solo il consenso del pulsante.

 

grazie

tanti auguri anche a te e grazie di tutto

 

Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...