inserimento subroutine

Buonasera a tutti, so che a Natale manca ancora molto ma sto ampliando la centralina fatta con arduino per il mio presepio con motori passo passo e servo per fare movimenti e sostituendo le strisce led con i led neopixel. sto incontrando alcune difficoltà per inserire le subroutine nel loop. prima mi esegue la subroutine e poi si accendono i neopixel.
Per esempio ho creato un for infinito per la ruota del mulino che dovrebbe girare tutto il giorno ma la ruota gira ma le luci non si accendono. Ho provato ad inserirle prima dell'if sia nell'if ma il risultato è lo stesso.
Per i lampioni vorrei invece che funzionassero solo nella fase mezzanotte.
ma anche là (togliendo la subroutine mulino) prima lampeggiano 200 volte poi partono le luci
Dove devo inserirle?

Sono partito come base la vecchia centralina con un contatore per ogni fase (curr) e un curr ++ fuori dall'if. considerate che senza subroutine dichiarate nel loop la centralina funziona.

grazie

mulino();
 if ( curr == 0 ) { 
     Serial.print("Fase: "); Serial.println("mezzanotte");
    for(uint16_t i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, notte); // imposti il colore del LED numero 'i'
   }
strip.show(); // invii tutti i dati alla LED-st
tremolio();
 delay (14335); 
 }
//alba.....................................................................
   if ( curr == 1 ) { 
     Serial.print("Fase: "); Serial.println("alba");
  //arancio
for(uint16_t i=0; i<5; i++) {
    strip.setPixelColor(i, arancio); // imposti il colore del LED numero 'i'
    }
strip.show(); // invii tutti i dati alla LED-strip 
delay (500);
   }
   
 if ( curr == 2) { 
     Serial.print("Fase: "); Serial.println("alba");
for(uint16_t i=0; i<10; i++) {
    strip.setPixelColor(i, arancio); // imposti il colore del LED numero 'i'
       }
strip.show(); // invii tutti i dati alla LED-strip
delay (500);
.......
.........
........
curr ++;
} //fine loop

void lampioni (){                //lampeggio lampioni
for (int j=0; j<2000; j++){   
valoreX=random(10,255); 
analogWrite(lampioni,valoreX);   
delay(50);//attendi 50 millisecondi  
 }
  
}

void mulino (){
for (int k=0; k<2000; k++){                          
  digitalWrite(motorPin1, LOW); //ROTAZIONE ORARIA
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delay(delayTime);
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delay(delayTime);
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
  delay(delayTime);
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
  delay(delayTime);
}
}

Ho visto male o è tutto sequenziale?
Cioè fai una cosa per volta e le varie cose una in fila all'altra...
Quindi se una di queste è un loop infinito ... fine dei giochi.
Devi parallelizzare tutto mi sa.

Ogni if curr fa una cosa in quanto la vecchia centralina funzionava così...
ho provato anche con cicli non infiniti ma non va.....
Che intendi per parallelizzare???
ho provato a togliere gli if e inserire la subroutine ma prima finisce il ciclo for poi parte il ciclo delle luci..
Cosa intedi per parallelizzare??

il microprcessore lavora in modo sequenziale, se gli dici, conta fino a 1000 e ad ogni numero fai questo, quando hai finito conta fino a 500 e fai quest'altro, stai facendo tutte cose in sequenza e prima tutta una e poi tutta l'altra.

Devi invece dirgli una cosa del tipo:
conta fino a 1000 e quando ci sono i numeri pari fai questo e quello mentre quando ci sono i numeri dispari fai solo questo.
In questo modo fai questo per 1000 volte e quello per 500 volta in parallelo.

Capito cosa intendo?

il concetto è chiaro-...... sarà molto difficile realizzarlo anche perchè non ho mai usato un contatore....
Pensavo sarebbe stato più facile anche perchè tutto si azionerebbe con un sensore ad ultrasuoni cioè se ti avvicini al presepe parte il ciclo giorno notte e se ti allonatani si accendo i neopixel tutti di bianco

se invece lo faccio con 2 arduino??!!!
cioè uno gestisce le luci e un'altro la parte meccanica!!! anche se credo di risolvere il problema a metà cioè il mulino funziona sempre mentre i lampioni solo di notte e altri servo che devo aggiungere solo di giorno...

Ti servirebbe un arduino per ogni funzione che può essere attivata assieme ad un'altra.
Secondo me ti conviene investire un po' di tempo per ragionare sul come parallelizzare.
Di fatto lo facciamo continuamente nella vita quotidiana ma forse non ce ne rendiamo conto.

E qui mi azzardo a citare Datman (senza permesso :() perchè il suo esempio è troppo chiaro per lasciarlo inutilizzato :wink:

Datman:
Devi studiare un po' le tecniche di temporizzazione che usano millis(): il loop gira sempre, senza fermarsi. È come se tu facessi molte cose guardando l'orologio. Non hai un cronometro con cui aspetti 40 minuti per la cottura della torta, poi aspetti 5 minuti per il caffè: hai un orologio che indica le 13: alle 13.05 tolgo il caffè dal fuoco; alle 13.40 sforno la torta.

:smiley:

Ho letto un po' di informazioni sui millis praticamente (se considero che ogni fase del giorno dura 10000 ms)
Se il tempo è minore di 10000
Accendi le luci notte
Se il tempo è minore di 10000
Fai il tremolio ai lampioni
Se il tempo è maggiore di 10000 e minore di 20000
Accendi luce giorno
E alla fine azzero il contatore millis

Corretto???

armandinok:
Corretto???

Non proprio, millis() è una funzione che restituisce un valore in millisecondi dall'accensione, non la puoi azzerare (in verità potresti ma non ha senso farlo), per capire le basi con cui si usa millis() consiglio prima la lettura di QUESTO post esplicativo, dopo di che lo studio di come si usa la funzione millis(), prima QUI, poi QUI e QUI e QUI e tutti gli articoli che sono in QUESTA pagina ... alla fine il tutto dovrebbe essere più chiaro :slight_smile:

armandinok:
Ho letto un po' di informazioni sui millis praticamente (se considero che ogni fase del giorno dura 10000 ms)
Se il tempo è minore di 10000
Accendi le luci notte
....
E alla fine azzero il contatore millis

E' una possibilità. Ma normalmente il contatore millis non si azzera mai esplicitamente. Ci si annota il tempo attuale nel momento da cui cui si vuole misurare il tempo:

inizio = millis();

e si calcola il tempo trascorso da quel momento:

trascorso = millis() - inizio;

Quando è trascorso si fa quello che serve (ed eventualmente se c'è bisogno ci si annota di nuovo il tempo attuale).

Se serve tenere conto di più tempi indipendenti si usano diverse variabili "inizio".

NOTA: tutte le variabili che coinvolgono millis e i tempi calcolati sono normalmente di tipo unsigned long (o uint32_t), che permettono di gestire tempi fino a circa 1192 ore.

accendo tutto e assumo di far partire il ciclo di mattina (la mattina rappresentata nel presepe), che ora è? mi salvo su una variabile il valore di millis.
poi ad ogni ciclo mi domando, dal millis che mi sono salvato, sono passati 10.000 millisecondi (facendo la differenza tra il nuovo millis e quello salvato)?
NO => non faccio nulla
SI => avvio la procedura che mi fa scendere la notte e mi salvo il millis di inizio sera.
ora sono im modalità SERA e quindi ogni X millisecondi abbasso la luminosità di un pelino fino a quando trascorso un certo tempo entro in modalità notte e mi salvo il millis di inizio notte.
Qui ora mi chiedo se è trascorso abbastanza tempo e capisco quando far partira l'alba e poi il giorno.
Avviato il giorno mi salvo il millis di avvio del nuovo giorno sopra quello precedente.
E via così.

Questo come schema concettuale, poi sul software puoi ragionare sul modo migliore per te di tenere traccia di queste cose.

Grazie ci lavorerò su!!!!!

Claudio_FF:
...circa 1192 ore.

Spero che un intero ciclo alba tramonto duri un po' meno altrimenti per guardare il suo presepe tocca prendere aspettativa dal lavoro :smiley: :smiley: :smiley:

fabpolli:
Spero che un intero ciclo alba tramonto duri un po' meno altrimenti per guardare il suo presepe tocca prendere aspettativa dal lavoro :smiley: :smiley: :smiley:

Ho visto persone spazientirsi e bisognava aspettare un minuto per 1 giorno!!!! Quest'anno spero di "invogliare" un po' di più le persone con dei personaggi meccanizzati... Purtroppo la centralina (comprata ormai 25 anni fa) funzionava tutto a 220v e utilizzavo motoriduttori sempre a 220v e lampadine ad incandesceza, non era il caso di utilizzarla visto che ho esposto il presepe ad una mostra... quest'anno utilizzerò neopixel e servo che sono molto più versatili e piccoli. Infatti prima faccio la centralina poi mi dedico al presepe...

Qualcuno trova la luce LED troppo poco "realistica" e preferisce usare comunque lampadinette ad incandescenza da 12V, basta pilotarle in PWM con dei transistor e si regola anche la luminosità.

Per il futuro presepe di un collega si pensava a cinque secondi massimo l'alba e tramonto, e dieci secondi le fasi giorno e notte. Ovviamente fuocherello tremolante sempre con PWM.

Vero, io me ne sono fregato e ho usato led ad alta luminosità regolati in pwm.
Ho provato con led gialli ma sono troppo gialli.
L'ideale sarebbe led rgb su cui impostare il colore preferito ma alla fine hai più cavi che pecore.
Però con gli rgb si potrebbe anche far tremolare le luci per renderle ancora più realistiche non un accendi spegni ma un varia colore in modo tremulo.
Ho usato led normali ad alta luminosità ma al prossimo giro li sostituirò con led a luce diffusa e magari altero la luce bianca mascherando con dei trasparenti colorati.

Ho fatto anche il fuoco, in realtà un braciere, con due led uno rosso e uno giallo che si accendevano e spegnevano con temporizzazione casuale con tempi sempre diversi, se non ricordo male l'accensione era 10 volte più lunga dello spegnimento random(X) e random(10X)

Il problema è regolare correttamente la luminosità per non avere le foto con macchie totalmente sovraesposte e zone completamente scure. Bisognerebbe tarare bene il tutto per avere una certa uniformità e qui il pwm aiuta.

Non ho gestito effetti alba/tramonto, per cui mi sono limitato a led da 20mA per le sole case e lanterne.

Ci ho messo anche una fotoresistenza per rilevare la luminosità ambientale, di giorno accendevo solo alcune luci, di notte anche altre, così in base alla luminosità della stanza avevo effetti differenti.

Adesso devi fare le luci delle case che si accendono in successione pseudo casuale :slight_smile:
Ci stavo pensando: la soluzione più semplice è un vecchio, classico NE555 in ogni casa che accende le luci con un ritardo (regolabile tramite un trimmer) dal momento in cui vengono forniti i 12V.

Già fatto, però non accendo o spengo ma vario la luminosità in modo casuale (valore pwm random tra zero e 1023), così non sono mai totalmente accese o totalmente spente.
Da movimento in modo molto discreto e lascia sempre intravvedere gli interni.

Arduino mi pilotava questo e così avevo 16 uscite PWM per pilotare i led.
Le uscite finivano in base a 16 transistor e ogni transistor era dimensionato per pilotare fino a 3 led, ognuno con la sua resistenza e alimentazione separata a 9V. Non separata completamente ma dai 9V alimentavo da un lato arduino e dall'altro i led via transistor.

Scusate non sono meglio i neopixel almeno con un solo pin comandi tutte le luci e le fai del colore che vuoi!!!

si