Salve a tutti,
vorrei costruire dei ritmi usando un percussore, a partire dall'esempio base blinkWithoutDelay.
La mia domanda è: come posso far eseguire la funzione contemporaneamente più volte ma in maniera indipendente e passando intervalli di tempo differenti? Vorrei che tutte le variabili fossero all'interno di una "istanza della funzione" senza che le variabili si confondessero tra loro.
Devo creare tante funzioni e tante variabili quante sono i diversi ritmi che voglio sommare? o c'è un'altra via?
Metto qui uno pseudo-codice per cercare di spiegarmi meglio, spero si capisca cosa intendo:
unsigned long previousMillis = 0; // will store last time LED was updated
void loop() {
blinkWithoutDelay(1000);
blinkWithoutDelay(1250);
}
void blinkWithoutDelay (int frequenza) {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= frequenza) {
// ---> fai qualcosa, tipo aziona un solenoide!
previousMillis = currentMillis;
}
}
Grazie per qualsiasi suggerimento.
Ah, sto lavorando con una MKR zero.
Se usi la stessa funzione per tutti e 3 i percussori, ogni successiva chiamata andrà a modificare di nuovo le variabili andando a interferire con la chiamata precedente.
Il modo migliore secondo me è fare una semplice classe che puoi istanziare quante volte vuoi passandogli ad esempio il pin dove è connesso il percussori e la durata del blink.
creare tante funzioni (le variabili possono essere globali, ciascuna con un nome diverso, oppure static interne alla funzione.
creare una sola funzione a cui passare un indice con cui accedere a un insieme di array, o a un array di struct, oppure passare alla funzione un puntatore a una struct (quindi gli array o le struct contengono le variabili di volta in volta in gioco)
creare una classe da cui ottenere tutte le istanze che servono, ciascuna con le sue variabili.
La prima soluzione è la più lunga, dispersiva, è facile confondersi con le variabili. L'ultima è la più compatta e con meno potenziali effetti collaterali. Quella intermedia è ciò che si farebbe in C puro dove le classi non esistono.
Ciao a tutti e grazie mille per le vostre risposte. Cerco di spiegarmi.
volendo creare diversi pattern ritmici, vorrei evitare di scrivere una funzione per ognuno, cioè è la soluzione che sto usando in questo momento perché più semplice per me che sono noob, ma mi crea molta confusione se le funzioni cominciano ad essere più di tre e lo trovo scomodo.
@ducecoder i percussori sono due, ma vorrei poter chiamare la stessa funzione anche sullo stesso percussore, in modo da ottenere ad esempio una sovrapposizione tra ritmi binari e ternari con un unico attuatore.
@Datman, scusa, non sono sicuro di capire, ma anche qui dovrei chiamare con un nome diverso ogni variabile all'interno di un case, giusto?
@Claudio_FF La seconda soluzione per me è arabo, scusate. Mi ci vorrà studio e molte prove prima di poterla prendere in considerazione.
La soluzione che "a naso" mi parrebbe giusta è quella suggerita da @cotestatnt ma prima di pronunciarmi vado a studiare l'esempio che ha postato. Credo che se ci fosse una classe dove posso specificare ad esempio la frequenza della pulsazione, il pin di riferimento e il numero di pulsazioni da eseguire sarei a posto e potrei chiamarla più volte facendo diverse prove.
@nid69ita vuoi dire che se la variabile previousMillis è static mantiene valori diversi ad ogni chiamata? Non mi è molto chiaro e non credo sia la mia soluzione (sempre "a naso") ma ci provo subito, anche perché è la più veloce.
come prima cosa devi pensare al singolo oggetto percussore e non a multi oggetti e trovare/capire/descrivere il suo funzionamento.
da quel che riporti capisco che tale percussore debba/possa avere nell'arco di un tot tempo diversi andamenti...per esempio in un tempo ciclo completo di 10 secondi farà:
1 secondo ON
1 secondo OFF
0.5 secondi ON
0,5 secondi OFF
0,5 secondi ON
0,5 secondi OFF
2 secondi ON
2 secondi OFF
1 secondo ON
1 secondo OFF
quindi un andamento del tipo, "normale", "accelerato", "lento", "normale".
ho capito giusto?
se è così la tua funzione finale di gestione percussore dovrà essere in po' più articolata...e modi per farlo sono diversi...come già hanno suggerito.
Si è esatto, ma se usi la stessa funzione con più percussori, le variabili su cui vai a lavorare DEVONO essere diverse e non basta renderle statiche altrimenti quando richiami la funzione la seconda volta per il secondo percussore vai ad interferire con quello che avevo fatto la prima volta.
Se usi l'approccio delle classi, nessuno ti vieta di creare due istanze della classe che lavorano in modo indipendente sullo stesso pin di uscita.
La stessa cosa si può fare anche con l'approccio 2 suggerito da @Claudio_FF, ma secondo me l'eleganza e la "compiutezza" della classe è imbattibile in questo contesto.
blinkWithoutDelay(1000); // un colpo ogni secondo
blinkWithoutDelay(1500); // un colpo ogni secondo e mezzo
in questo modo (ad esempio!) avrei un pattern ritmico di questo tipo:
A: x x x x x x x
B: x x x x x
________________________________________________________________
= x x x x x x x x x
Qui ci sono due livelli ritmici che danno un pattern, ma vorrei poter fare anche più livelli, passando i diversi tempi di intervallo alle funzioni senza doverne fare una per ogni tipo di ritmo.
Secondo me @cotestatnt ha capito, poi io più cerco di spiegarmi e più incasino le cose
ma i "ritmi" vengono eseguiti contemporaneamente o prima uno e poi l'altro?
altra domanda...immginando che "!" stia per stato ON... lo spazio tra due "!" è stato OFF?...quindi un "! !" vuon dire ON/OFF/ON...giusto?