Il 24/08/2019 19:32, Giorgio Bibbiani ha scritto:
Esattamente questa funzione me la puoi spiegare?
Il 24/08/2019 19:32, Giorgio Bibbiani ha scritto:
Esattamente questa funzione me la puoi spiegare?
Il 24/08/2019 19.53, Drizzt do'Urden ha scritto:
L'istruzione for inizia un ciclo, all'inizio del ciclo alla variabile intera counter viene assegnato il valore 0, la condizione seguente stabilisce quando il ciclo debba terminare, fino a quando rimane vera la disuguaglianza counter < debounceDelay il ciclo prosegue, altrimenti quando counter = debounceDelay allora termina, ogni volta che il ciclo viene ripetuto la variabile counter viene incrementata di 1 (funzione ++).
Ciao
Il 24/08/2019 20:07, Giorgio Bibbiani ha scritto:
Grazie, purtroppo mi sto rendendo conto che non ci acchiappo per nulla, non mi entra in testa la logica di programmazione, se mi ci vogliono due
sono adatto a queste cose :-(
Il 24/08/2019 20.47, Drizzt do'Urden ha scritto:
Io, come dicevo, non so niente di Arduino e non saprei consigliarti un percorso di studio (sentiamo magari altri...), ma in termini generali, per capire come funziona, penso che sarebbe meglio cominciare a studiare il suo linguaggio di programmazione in modo ordinato e strutturato su qualche testo cartaceo o in formato elettronico (intendo un testo per neofiti della programmazione, che descrivesse anche la "logica della programmazione"...), piuttosto che
scritti (la qual cosa non fa male, ma da sola non basta,
Ciao
Drizzt do'Urden ha scritto:
Io non so niente di Arduino, ma quel frammento mi sembra scritto in C.
Provo a scriverti lo stesso frammento in un altro linguaggio.
c := 0; while c < d do c := c + 1;
Avrei anche da dire qualcosa sulla spiegazione di Claudio_F, un discorso tipicamente informatico.
seguente.
(approccio top-down).
significhi questa analisi.
Qui mi fermo, per stasera almeno.
preoccupare e prenditi il tempo che ti serve. Penso che qui sopra molti conoscano C/C++ e potrai sempre avere una
fare per forza.
ridondanti :D
Il 24/08/2019 21:08, Giorgio Bibbiani ha scritto:
Infatti, mi sono stampato (leggendo su carta capisco meglio e mi cavo meno gli occhi) un manuale di elementi base di programmazione di
una certa cosa, quelle righe di comando che mi hai spiegato sono incomprensibili per me nella loro logica, come dire che partendo da Roma per andare a Milano devo passare da Palermo, se non capisco la logica di come mettere assieme le varie istruzioni non posso andare avanti, e i vari manuali che mi sono scaricato non aiutano, ovvero, io non ne traggo aiuto. Chiaro che non pretendo di imparare in due giorni, ma come dici tu, se non inizio dalla parte giusta non arrivo a un risultato.
Il 24/08/2019 21:45, Archaeopteryx ha scritto:
Il 24/08/2019 21:30, Elio Fabri ha scritto:
arrivato? Devi avere la mente allenata a ragionare diversamente dal solito?
ecco, appunto :-)
Buona serata :-)
algoritmi, con pochi dei quali si fanno molte cose. Devi solo iniziare a conoscerle.
telecomando contiene un mondo; si capisce che compiti che il cervello esegue in totale automatismo, quando devi "spiegarli" a una macchina tramite il software sono in
questo fatto si scrive codice in modo automatico, pensando ad altro e ascoltando musica.
testo di elettronica: ci sono sempre circuiti classici che sono la lingua comune. Io credo che se mi chiedessero la
partendo da zero probabilmente ci metterei anni a tempo
un normalissimo timer via software che si impiega anche
usare si possono ripetere le identiche considerazioni sui ciruiti standard e relativi riutilizzi.
Il 24/08/19 19:07, Drizzt do'Urden ha scritto:
Ci sono molti modi per fare la stessa cosa. Quell'esempio in particolare lo avevo gia` visto, e` di un incasinato esemplare, basta vedere la pittoresca inversione della variabile led_state realizzata con un'operazione aritmetica...
Io lo riscriverei cosi`:
//---------------------------------------------------------------- // DEFINIZIONI COSTANTI //---------------------------------------------------------------- #define LED_PIN 13 //pin led, acceso HIGH #define BUTTON_PIN 8 //pin pulsante, LOW quando premuto #define DEB_DELAY 50 //millisecondi di debounce
//---------------------------------------------------------------- // VARIABILI DI LAVORO GLOBALI //---------------------------------------------------------------- unsigned long t; //variabile tempo per debounce byte in_prec = HIGH; //livello ultima lettura stabile byte led_state = LOW; //LED inizialmente spento
//---------------------------------------------------------------- // LETTURA PULSANTE, DEBOUNCE E RICONOSCIMENTO FRONTE PRESSIONE //---------------------------------------------------------------- boolean onPress() { byte in = digitalRead(BUTTON_PIN); //legge ingresso
if (in == in_prec) { t = millis(); } //nessuna variazione else if (millis()-t > DEB_DELAY) //se trascorsi 50ms { in_prec = in; //salva livello stabile if (in == LOW) { return true; } //se fronte di discesa }
return false; }
//---------------------------------------------------------------- // FUNZIONE SETUP ESEGUITA ALL'AVVIO //---------------------------------------------------------------- void setup() { pinMode(BUTTON_PIN, INPUT_PULLUP); pinMode(LED_PIN, OUTPUT); digitalWrite(LED_PIN, led_state); }
//---------------------------------------------------------------- // CICLO PRINCIPALE RIPETUTO CONTINUAMENTE //---------------------------------------------------------------- void loop() { if (onPress()) //se istante pressione { led_state = !led_state; //inverte stato digitalWrite(LED_PIN, led_state); } }
Il 24/08/2019 19:07, Drizzt do'Urden ha scritto:
La causa del debouncing non l'ho vista spiegare e non sono sicuro tu la conosca. Se la conosci, salta pure tutto il discorso seguente. Se leggi qui, il problema e' dato da una serie di aperture e chiusure che ogni interruttore ha prima di raggiungere lo stato stabile ON o OFF e gli spyke, sbalzi di tensione presenti sul pin controllato, dovuti a semplici interferenze, sempre presenti lavorando in elettronica digitale. Quello che occorre fare per evitare di attuare diverse volte on e off un interruttore a causa dei rimbalzi, e' controllare che per un certo periodo di tempo, quantificato per interruttori meccanici in T > 6 to 10 ms. e portato a circa 20 ms. per sicurezza, lo stato del pin sia stabile. Per questo, si inserisce una uscita dal loop, se il pin cambia stato durante il controllo temporizzato. Se il pin e' stabile per T > 20 ms. e' stato attuato! Se in questo tempo, cambia stato, esce senza attuare il cambiamento e rientrera' non appena eseguite altre istruzioni del programma per controllare che questa volta sia stato attuato veramente e non da uno spyke. Spero possa esserti utile questa spiegazione tera-tera, ma hai detto di essere un principiante e quindi spero non ti riterrai offeso se ti ho detto cose che gia' conoscevi. ciao Angelo
Rispondo qui sotto a Deh!
Ma per usi di questo tipo non basta un condensatore (o meglio una coppia) in parallelo al contatto per eliminare gli spike all'origine risparmiandosi quella routine?
Il 25/08/19 09:44, ArchiPit ha scritto:
Certo. Un passa basso all'ingresso e` sufficiente, infatti il debounce puo` essere sia software che hardware.
Qualsiasi ingresso digitale vuole tre cose:
- Un livello di riposo stabile (resistenze pull up/down di valore adeguato alla quantita` di rumore elettrico captabile, quindi tanto piu` basse quanto meno si vuole essere sensibili ai disturbi)
- Il debounce (per le cose dette sopra)
- Il disaccoppiamento (evitare il collegamento diretto dei pin a lunghe filature interponendo vicino all'ingresso almeno una resistenza in serie, il passa basso RC svolge anche questa funzione).
Ma in genere e` adeguato anche solo un semplice condensatore aggiunto tra ingresso e massa, calcolato per una costante di tempo di 20ms con la resistenza di pull.
Resta il fatto che studiare il debounce software e` comunque istruttivo, perche` nella maggior parte dei casi si tratta di una modifica irrisoria:
//----------------------------------------------------------- // RILEVA PRESSIONI E RILASCI SENZA DEBOUNCE //----------------------------------------------------------- in = digitalRead(PIN_INGRESSO) if (in != in_prec) { in_prec = in; if (in == LIVELLO_PREMUTO) { ...rilevata pressione... } else { ...rilevato rilascio.... } }
//----------------------------------------------------------- // RILEVA PRESSIONI E RILASCI CON DEBOUNCE 20ms //----------------------------------------------------------- in = digitalRead(PIN_INGRESSO) if (in == in_prec) { tdeb = millis(); } else if (millis()-tdeb > 20) { in_prec = in; if (in == LIVELLO_PREMUTO) { ...rilevata pressione... } else { ...rilevato rilascio.... } }
Il 25/08/2019 00:15, Claudio_F ha scritto:
lettura del pulsante?
memorizza lo stato"?
Niente da fare, non mi entra la logica digitale in testa, il fatto poi
Il 25/08/2019 13:20, Claudio_F ha scritto:
E quando si azzera cosa succede?
Cercando la funzione millis ho trovato questo che sembra spiegato
accende?
Ha fatto una cosa elegante che non vedo fare molto in giro. Ci sono due approcci di stile per questo problema
e nel caso di arduino, le ultime due funzioni scritte sono setup e main. Ovviamente il compilatore "sa" tutto ovvero
ciononostante te lo consiglio.
comunque buona; come fa qualsiasi artista all'inizio meglio copiare e piano piano adattare e crearsi un proprio stile.
credimi, se non devi cercare di gestire una sonda spaziale
"assemblando" pezzi di codice, tecniche e modi di scrivere. Una discreta parte del lavoro di programmazione
esterne").
giorni? Forse meno... Come tutte le cose ha la sua curva di apprendimento.
Ti consiglierei di copiare il codice e poi per esercizio aggiungere un secondo e poi un terzo pulsante, solo copincollando e cambiando ovviamente i nomi delle
dovresti procurartene uno.
Il 25/08/19 18:21, Drizzt do'Urden ha scritto:
Come detto da Archa e` un ordine mentale acquisito dal Pascal:
DEFINISCO PRIMA TUTTO QUELLO CHE USO DOPO
Non e` che in C stretto sia diverso, ma il compilatore lo nasconde permettendo di fare (quasi) come si vuole.
Quello che conta e` che sia chiaro l'ordine di esecuzione delle varie funzioni, indipendentemente da dove sono scritte.
Ni, per due motivi. Il primo e` che se hai 32 pulsanti da leggere ci metteresti piu`di mezzo secondo (e nel frattempo non potresti gestire nessun'altra cosa), il secondo motivo e` che non filtri i disturbi impulsivi, dovresti per lo meno rileggere di nuovo l'ingresso dopo quei
20ms e verificare se e` ancora come lo hai letto prima, e solo in quel caso aggiornare la variabile che rappresenta l'ultima lettura stabile:in = digitalRead(INGRESSO); delay(20); if (in == digitalRead(INGRESSO)) { lettura_stabile = in; }
Se guardi bene c'e` anche l'edge detect, cioe` non si legge solo l'ingresso applicando il debounce, ma si controlla l'esatto momento in cui viene premuto (c'e` differenza tra livello costante ed evento istantaneo).
Seconda cosa, "semplice" per il senso umano e` qualcosa che non ha senso per una macchina... e puo` valere anche il contrario :D
Il 25/08/19 18:38, Drizzt do'Urden ha scritto:
E'un contatore di millisecondi, non e` detto che sia l'esatto momento di accensione, e in effetti non e`, anche se all'accensione il contatore partisse ogni da un valore casuale funzionerebbe uguale.
Niente :) Facendo una sottrazione intera tra numeri senza segno formati da un numero finito di bit, il risultato viene sempre corretto.
Nell'esempio che hai indicato la sottrazione
millis() - previousMills
e` corretta, ma il tipo di variabile usata no, infatti per 'previousMillis' ha usato una 'long' (che ha il segno) invece della corretta 'unsigned long'.
Inoltre anche li tutto quel:
if (value == LOW) value = HIGH; else value = LOW;
poteva essere scritto:
value = !value;
Il LED viene comandato con la digitalWrite finale, lo stato acceso o spento dipende dal valore della variabile 'value' che viene invertito ogni volta che trascorrono 'interval' millisecondi dall'ultima volta che si e' caricato il tempo nella variabile 'previousMillis'.
Bell'idea, non ci avevo pensato mai e mi salvo il post :)
Nemmeno io mi potrei definire tale, e aggiungo per
sono legati alla programmazione.
Have something to add? Share your thoughts — no account required.
Ask the community — no account required