Luci presepe ennesimo progetto

Salve a tutti, premetto che sono nuovo del mondo di Arduino e totalmente zero sia in elettronica che in programmazione, ma nella vita c’è sempre tempo per imparare :slight_smile:
Bando alle ciance, il dilemma è il seguente, volevo sfruttare Arduino nella seguente maniera, LED su uscite PWM con valore di accensione randomico in maniera tale da avere un effetto tremolante continuo (stelle) e LED su uscite digitali con accensione anch’essa randomica, ma intervalli lunghi, per l’illuminazione delle case.
Leggi a destra, leggi a sinistra, un po di Ardublock alla fine sono riuscito ad avere i due eventi separati, ma non riesco a combinarli in maniera tale che funzionino in contemporanea.
Allego il listato che sono riuscito a creare e accetto tutti i suggerimenti, compreso quello di comprare un buon libro di programmazione!

unsigned long prevTime = 0, interval = 10; // in millisecondi
int _ABVAR_1_caso = 0 ;
void offoff();
void onon();

void setup() //dichiarazioni varie
{
  digitalWrite(1, HIGH);
  randomSeed(analogRead(A0) + analogRead(A1) + analogRead(A2));
  pinMode( 1, INPUT);
  pinMode( 2, OUTPUT);
  pinMode( 3, OUTPUT);
  pinMode( 4, OUTPUT);
  pinMode( 5, OUTPUT);
  pinMode( 6, OUTPUT);
  pinMode( 7, OUTPUT);
  pinMode( 8, OUTPUT);
  pinMode( 9, OUTPUT);
  pinMode( 10, OUTPUT);
  pinMode( 11, OUTPUT);
  pinMode( 12, OUTPUT);
  pinMode( 13, OUTPUT);

}

void loop(){

  if(millis() - prevTime > interval)
  {
     prevTime = millis();
 
  analogWrite(3 , random( 200 ));  //led tremolanti per le stelle
  analogWrite(5 , random( 220 ));
  analogWrite(6 , random( 180 ));
  analogWrite(9 , random( 240 ));
  analogWrite(10 , random( 160 ));
  analogWrite(11 , random( 140 )); 
} 
 _ABVAR_1_caso =   random( 100 , 500 ) ;
  delay( _ABVAR_1_caso );
  digitalWrite( 2 , HIGH );   //led fissi ad accensione casuale per le case
  delay( _ABVAR_1_caso );
  digitalWrite( 4 , LOW );
  delay( _ABVAR_1_caso );
  digitalWrite( 7 , LOW );
  delay( _ABVAR_1_caso );
  digitalWrite( 8 , HIGH );
  delay( _ABVAR_1_caso );
  digitalWrite( 12 , LOW );
  delay( _ABVAR_1_caso );
  digitalWrite( 13 , LOW );
  delay( _ABVAR_1_caso );
  digitalWrite( 2 , HIGH );
  delay( _ABVAR_1_caso );
  digitalWrite( 4 , LOW );
  delay( _ABVAR_1_caso );
  digitalWrite( 7 , LOW );
  delay( _ABVAR_1_caso );
  digitalWrite( 8 , HIGH );
  delay( _ABVAR_1_caso );
  digitalWrite( 12 , LOW );
  delay( _ABVAR_1_caso );
  digitalWrite( 13 , LOW ); 
  }
  1. devi usare i CODE TAG per lo sketch (icona </>) Correggilo per favore
  2. Non usare il pin 1 come entrata; é collegato l’ adattatore USB. puoi usare le entrate analogica come pin digitali coi numeri da 14 a 19.

Non usare delay() per l’ accensione e spegnimenti. Usa anche lí millis()

Vuoi far lampeggiare 6 LED ogni 10 mS ma l’ accensione degli altri led dura dai 1,2 ai 6 secondi. Percui le stelle lampeggiano con la frequenza di 0,833 a 0,166 Hz

Se vuoi accender le luci a random selezioni un led a caso ogni 10 secondi e lo accendi / spegni a secondo dello stato precedente.

Ciao Uwe

Uwe ti ringrazio innanzitutto per la risposta e ho provveduto immediatamente ad effettuare la correzione del post.

Riguardo l’utilizzo del pin1 è parte di uno dei “furti” dal altri sketch, e da quello che ho capito serve solo ad inizializzare la variabile , giusto? Posso comunque sostituirlo con uno degli altri pin che mi hai indicato?

L’effetto che vorrei ottenere dovrebbe essere la combinazione di

void loop() {
  analogWrite(3 ,   random( 200 ));  
  analogWrite(5 ,   random( 220 ));
  analogWrite(6 ,   random( 180 ));
  analogWrite(9 ,   random( 240 ));
  analogWrite(10 ,  random( 160 ));
  analogWrite(11 ,  random( 140 ));   

}

perciò un tremolio veloce ed evidente, con una sorta di quest’altro

void setup() {
    pinMode( 15, INPUT); 
    pinMode( 2 , OUTPUT)
    pinMode( 4, OUTPUT);
    pinMode( 7, OUTPUT);
    pinMode( 8 , OUTPUT)
    pinMode( 12, OUTPUT);
    pinMode( 13, OUTPUT);
    digitalWrite(15, HIGH);
  randomSeed(analogRead(A0) + analogRead(A1) + analogRead(A2));
  ;
  
}

void loop() {
  delay(random(5000,15000));
  digitalWrite( 2 , HIGH );
  delay(random(5000,15000));
  digitalWrite( 4 , LOW );
  delay(random(5000,15000));
  digitalWrite( 7 , LOW );
  delay(random(5000,15000));
  digitalWrite( 8 , HIGH );
  delay(random(5000,15000));
  digitalWrite( 12 , LOW );
  delay(random(5000,15000));
  digitalWrite( 13 , LOW );
  delay(random(5000,15000));
  digitalWrite( 2, LOW );
  delay(random(5000,15000));
  digitalWrite( 4 , HIGH );
  delay(random(5000,15000));
  digitalWrite( 7 , HIGH );
  delay(random(5000,15000));
  digitalWrite( 8 , LOW );
  delay(random(5000,15000));
  digitalWrite( 12 , HIGH );
  delay(random(5000,15000));
  digitalWrite( 13 , HIGH );

}

dove però i singoli led si dovrebbero accendere e spegnere in sequenza casuale e con durata casuale per ognuno di loro.

Immagino che per le mie nulle conoscenze di programmazione mi sono imbarcato in uno sketch non semplicissimo e ho il dubbio che non possa essere realizzabile con Arduino.

PS ho provato a sostituire brutalmente delay con millis, ma mi restituisce un errore. Devo dedicarmi per capirne il funzionamento :confused:

Essendo il tuo primo post Ti invitiamo a presentarti QUI
(dicci quali conoscenze hai di elettronica e di programmazione) e a leggere il regolamento QUI
se non lo hai già fatto.

Comunque benvenuto sul forum.

Attilio

Ciao Attilio, chiedo scusa ma il topic di presentazione mo era sfuggito, ma ho provveduto anche a quello.

Per lo sketch credo di aver risolto

  const byte ledPin2 =  2;                          // the number of the LED pin
const byte ledPin3 =  3;
const byte ledPin4 =  4;
const byte ledPin5 =  5;
const byte ledPin6 =  6;
const byte ledPin7 =  7;
const byte ledPin8 =  8;                       
const byte ledPin9 =  9;
const byte ledPin10 =  10;
const byte ledPin11 =  11;
const byte ledPin12 =  12;
const byte ledPin13 =  13;


byte ledState = 0;                                  // ledState used to set the LED
                                                    //will store last time LED was updated

unsigned long previousMillis = 0;                   // flikering led timer
unsigned long interval = 1;
unsigned long previousMillis2 = 0;                  // blink led timer
unsigned long interval2 = 8413;                
unsigned long previousMillis4 = 0;
unsigned long interval4 = 5728;
unsigned long previousMillis7 = 0;
unsigned long interval7 = 7415;
unsigned long previousMillis8 = 0;             
unsigned long interval8 = 6842;                
unsigned long previousMillis12 = 0;
unsigned long interval12 = 5946;
unsigned long previousMillis13 = 0;
unsigned long interval13 = 6495;
unsigned int counter = 0;

void setup() {
  
  pinMode(ledPin2, OUTPUT);                           //set the digital pin as output
  pinMode(ledPin3, OUTPUT);
  pinMode(ledPin4, OUTPUT);
  pinMode(ledPin5, OUTPUT);                  
  pinMode(ledPin6, OUTPUT);
  pinMode(ledPin7, OUTPUT);
  pinMode(ledPin8, OUTPUT);                  
  pinMode(ledPin9, OUTPUT);
  pinMode(ledPin10, OUTPUT);
  pinMode(ledPin11, OUTPUT);                  
  pinMode(ledPin12, OUTPUT);
  pinMode(ledPin13, OUTPUT);
}



void loop() {                                         //main loop
 
  blinkLed2();                                        //blink led subroutine 
  blinkLed4();
  blinkLed7();
  blinkLed8();
  blinkLed12();
  blinkLed13();
  
 
   if (millis() - previousMillis > interval) {
    previousMillis = millis();
  analogWrite (ledPin3, random (150));                //flicker led as star 
  analogWrite (ledPin5, random (150));
  analogWrite (ledPin6, random (150));
  analogWrite (ledPin9, random (150));
  analogWrite (ledPin10, random (150));
  analogWrite (ledPin11, random (150));  
  
} 
}



void blinkLed2() {                                    //blink the led 2
                                                      //check if it's time to blink the led
  if (millis() - previousMillis2 > interval2) {
    previousMillis2 = millis();                       //save the last time I blinked the LED
    ledState ^= 1;
    digitalWrite(ledPin2, ledState);                  // if the LED is off turn it on and vice-versa:
     }
}

void blinkLed4() {                                    //blink the led 4
                                                      //check if it's time to blink the led
  if (millis() - previousMillis4 > interval4) {
    previousMillis4 = millis();                       //save the last time I blinked the LED
    ledState ^= 1;
    digitalWrite(ledPin4, ledState);                  // if the LED is off turn it on and vice-versa:
     }
}
  
void blinkLed7() {                                    //blink the led 7
                                                      //check if it's time to blink the led
  if (millis() - previousMillis7 > interval7) {
    previousMillis7 = millis();                       //save the last time I blinked the LED
    ledState ^= 1;
    digitalWrite(ledPin7, ledState);                  // if the LED is off turn it on and vice-versa:
     }
}

void blinkLed8() {                                    //blink the led 8
                                                      //check if it's time to blink the led
  if (millis() - previousMillis8 > interval8) {
    previousMillis8 = millis();                       //save the last time I blinked the LED
    ledState ^= 1;
    digitalWrite(ledPin8, ledState);                  // if the LED is off turn it on and vice-versa:
     }
}

void blinkLed12() {                                   //blink the led 12
                                                      //check if it's time to blink the led
  if (millis() - previousMillis12 > interval12) {
    previousMillis12 = millis();                      //save the last time I blinked the LED
    ledState ^= 1;
    digitalWrite(ledPin12, ledState);                 // if the LED is off turn it on and vice-versa:
     }
}
  
  void blinkLed13() {                                 //blink the led 13
                                                      //check if it's time to blink the led
  if (millis() - previousMillis13 > interval13) {
    previousMillis13 = millis();                      //save the last time I blinked the LED
    ledState ^= 1;
    digitalWrite(ledPin13, ledState);                 // if the LED is off turn it on and vice-versa:
     }
     
}

Sicuramente il tutto potrebbe essere ripulito, accorciato, ottimizzato, ma come primo esperimento ritengo sia passabile

delay(random(5000,15000));

digitalWrite( 2 , HIGH );
  delay(random(5000,15000));
  digitalWrite( 4 , LOW );
  ....



dove però i singoli led si dovrebbero accendere e spegnere in sequenza casuale e con durata casuale per ognuno di loro.

No, la sequenza é sempre la stessa la durata cara da 5 secondi a 15 secondi.

Se vuoi avere una sequenza casuale allora devi generarti sia una variabile casuale per il led da accendere/spegnere. il tempo puó anche essere costante ma se vuoi puoi metterlo anche casuale

  1. metti il nr pin digitale in un array per esempio uno da 6 elementi
  2. usa per il ritardo il millis()
byte LED[] = {2,4,7,8,12,13};
...

loop{(){

if (millis() - previousMillis > interval) {
    previousMillis = millis();                      //save the last time I blinked the LED
    interval = random(2000,5000);        // da controllare i limiti
    nrLED = random(0,6)
    digitalWrite(LED[nrLED], !digitalRead(LED[nrLED]);                 // if the LED is off turn it on and vice-versa:
     }
...
}

Ciao Uwe

Allora UWE, il meglio che sono riuscito a fare seguendo i tuoi consigli è questo:

byte LED[] = {2,4,7,8,12,13};
unsigned long previousMillis = 0;
unsigned long interval= random(1000,2000);
byte ledState;
byte nrLED;


void setup () {
  pinMode (2,OUTPUT);
  pinMode (4,OUTPUT);
  pinMode (7,OUTPUT);
  pinMode (8,OUTPUT);
  pinMode (12,OUTPUT);
  pinMode (13,OUTPUT);
}

void loop () {                                    //blink the led 2
                                                      //check if it's time to blink the led
  if (millis() - previousMillis > interval) {
    previousMillis = millis();                       //save the last time I blinked the LED
    ledState ^= 1;   
    nrLED = random(0,6);
   digitalWrite (LED[nrLED],ledState);                 // if the LED is off turn it on and vice-versa:
     
}
}

ci sono un paio (magari) di cose che mi sfuggono

  • se nel setup dichiaro pinMode (LED[nrLED]) i led si accendono in maniera ridotta, come se fosse inserita una resistenza, eppure la sintassi dovrebbe essere corretta;
  • se nell'ultima riga di codice inserisco il !digitalRead(LED[nrLED]); i led si accendono, ma non si spengono più.
    Sorvolo su tutta la serie di altri problemi che mi sono venuti fuori durante i vari tentativi ma che, bene o male, sono riuscito ad ovviare

Il Tuo codice accende e spegne in alternanza i LED casualmente indipendentemente se sono accesi o meno.

pinMode (LED[nrLED]) manca se li vuoi fare entrata o uscita. Comunque devi usare un for per definire tutti i 6 LED.

!digitalRead(LED[nrLED]); dovrebbe funzionare (anche se non ho provato). Forse non funzionava perché non hai definiti i pin dove sono attacati i LED come uscite. Cosí leggi se il LED in quel momento é acceso o spento e lo inverti col !.

Sorvolo su tutta la serie di altri problemi che mi sono venuti fuori durante i vari tentativi ma che, bene o male, sono riuscito ad ovviare

Voglio darti la via non il Sketch finito perché cosí impari meglio. Puoi chiedere quello che non capisci e Te lo spiegheremo.

Ciao Uwe

compiti fatti

byte LEDF[] = {3,5,6,9,10,11};                       // blinking LED pin
byte LEDB[] = {2,4,7,8,12,13};                       // flikering LED pin
byte ledState;
byte nrLED;

unsigned long previousMillis = 0;                    // blinking LED timer
unsigned long interval = 0;
unsigned long previousMillis1[code]

byte LEDF[] = {3,5,6,9,10,11};                       // flikering LED pin
byte LEDB[] = {2,4,7,8,12,13};                       // blinking LED pin
byte ledState = 1;
byte nrLED;

unsigned long previousMillis = 0;                    // flikering LED timer
unsigned long interval = 0;
unsigned long previousMillis1 = 0;                   // blinking LED timer
unsigned long interval1= random(500,850);



void setup() {

  for (byte LEDF = 0; LEDF<14;LEDF++){               //set the analog pin as output
 pinMode (LEDF,OUTPUT);}
  for (byte LEDB = 0; LEDB<14;LEDB++){               //set the digital pin as output
 pinMode (LEDB,OUTPUT);}
 
}

void loop() {                                         
 
   if (millis() - previousMillis > interval) {       //flicker LED as star 
    previousMillis = millis();
    nrLED = random(0,6);
  analogWrite (LEDF[nrLED], random (20));                
   
  
} 
if (millis() - previousMillis1 > interval1) {       //blinking LED
    previousMillis1 = millis();                     
    ledState ^= 1; 
    nrLED = random(0,6);
   digitalWrite (LEDB[nrLED],ledState), !digitalRead(LEDB[nrLED]);  // if the LED is off turn it on and vice-versa:
}
}

In un unico sketch mi hai fatto studiare millis, array e for, riducendo, in effetti, di molto il codice.

Altri consigli o come prima volta posso ritenermi soddisfatto?

Già che c’ero ho aggiunto la lettura di una fotoresistenza e accendere il tutto solo al calar delle tenebre, ed evitando di dover inserire un timer nell’alimentazione

int FRes = A0;
int SV;
byte LEDF[] = {3,5,6,9,10,11};                       // flikering LED pin
byte LEDB[] = {2,4,7,8,12,13};                       // blinking LED pin
byte ledState = 1;
byte nrLED;
unsigned long previousMillis = 0;                    // flikering LED timer
unsigned long interval = 0;
unsigned long previousMillis1 = 0;                   // blinking LED timer
unsigned long interval1= random(5000,15000);



void setup() {

  for (byte LEDF = 0; LEDF<14;LEDF++){               //set the analog pin as output
 pinMode (LEDF,OUTPUT);}
  for (byte LEDB = 0; LEDB<14;LEDB++){               //set the digital pin as output
 pinMode (LEDB,OUTPUT);}
 
}

void loop() {                                         
 SV  = analogRead(FRes); 
  
 if (SV<500) {
 
  
                                              // salvo il valore fotoresistenza dentro alla variabile SV
                             
    
      if (millis() - previousMillis > interval) {       //flicker LED as star 
      previousMillis = millis();
      nrLED = random(0,6);
      analogWrite (LEDF[nrLED], random (20));                
      } 
   
     if (millis() - previousMillis1 > interval1) {       //blinking LED
      previousMillis1 = millis();                     
      ledState ^= 1; 
      nrLED = random(0,6);
      digitalWrite (LEDB[nrLED],ledState), !digitalRead(LEDB[nrLED]);  // if the LED is off turn it on and vice-versa:
      }
  }  
  else{
for (byte LEDF = 0; LEDF<14;LEDF++){               //set the analog pin low
analogWrite (LEDF,OUTPUT);}
for (byte LEDB = 0; LEDB<14;LEDB++){               //set the digital pin low
digitalWrite (LEDB,LOW);} 
 
    }
  
}

Ora mi tocca aspettare il prossimo Natale per mettere tutto in funzione

Uhm ... se lo fai come progetto "didattico" per esercitarti, oppure se le luci devono eseguire specifiche sequenze in base all'attivazione di ingressi o altri eventi, allora una MCU ci sta anche bene ... ma se tutto quello che vuoi e' un sistema che ti accenda e spenga a caso, anche con intervalli variabili, dei led o altre luci, allora personalmente mi limiterei a qualche 40106 o 4093 ed un po di altri componenti discreti ... :wink:

Come ho scritto nel primo post sono totalmente digiuno sia di elettronica che di programmazione, quindi non ho nessun problema a considerarlo un progetto didattico. Fino ad oggi ho utilizzato per le le stesse funzioni un circuito basato su un PIC che, tra integrato, componenti discreti millefori e quant'altro, è costato più dell'Arduino, con molte meno possibilità di sviluppo e di riutilzzo (da qui al prossimo Natale l'Arduino sarà impiegato in molti altri progetti).
Poi, si sa, l'appetito vien mangiando!

mi inserisco visto il tema..

quest'anno mio padre mi ha commissionato l'illuminazione (statica) di un piccolo presepe messo dentro ad una cassettina da uccelli e appeso ad un alberello.

L'obbiettivo era usare una batteria per non avere cavi in giro e rendere tutto più piacevole alla vista. Ho usato due pile AA, un led rgb, un attiny85, una fotoresistenza come crepuscolare e ho fatto lavorare l'attiny in sleep con watchdog.

La domanda per @Etem è: potevo fare anche con componenti discreti, garantendo comunque la durata della batteria? Il consumo di un attiny85 in sleep con watchdog attivo è di circa 4.7uA.

Potevi farlo con un transistor e qualche resistenza, o meglio ancora un darlington (se l'attiny e' usato solo per l'ON/OFF in presenza di luce) ... forse avrebbe consumato leggermente di piu, ma non ne sono sicuro, con un darlington anche le resistenze di base per il partitore fotoresistivo avrebbero potuto essere abbastanza alte ...

capito, grazie :slight_smile: