Salve a tutti, premetto che sono un nuovo utente del forum e come tale mi presento.
Sono un ragazzo di 19 anni che frequenta una scuola di programmazione e da qualche mesetto mi sono avvicinato alla piattaforma Arduino dopo averne visti alcuni navigando su internet.
Ho consultato molte volte il forum per cercare aiuto leggendo i topic di altri utenti ma non sono riuscito a trovare risposta a questo mio problema e non riesco a venirne a capo.
In pratica voglio leggere i giri di un motore magnetico attraverso un ingresso analogico di Arduino(e fin qui nessun problema).
Per leggere i valori non faccio altro che utilizzare questo piccolo sketch:
#define Motore 5 //dichiaro "Motore" nell'ingresso digitale 5
boolean State=true; // dichiaro "State" come stato del motore in cui si strova
int Conteggio=0; //dichiaro la variabile "Conteggio" a 0
void setup(){
pinMode(Motore,INPUT); //associo all'ingresso digitale 5 che si chiama "Motore" di tipo INPUT
Serial.begin(9600); //inizializzo la porta seriale per stampare i valori a video
}
void loop(){
if(digitalRead(Motore)==LOW && State==0){ //controllo che il segnale che proviene dal Motore sia LOW e lo "State" a 0
State++; //setto la variabile "State" a 1
Conteggio++; //incremento la variabile conteggio di 1
}
if(digitalRead(Motore)==HIGH && State==1){ //controllo analogo a quello precedente con Motore HIGH e "State" a 1
State--; //setto "State" a 0
}
Serial.println(Conteggio);
}
Il problema sta nel fatto che Arduino non mi riesce a leggere tutti i giri del motore ma ne perdi alcuni.
Voglio precisare che utilizzo un Arduino Mega.
Allora mi sono detto :utilizzo gli INTERRUPT che sono molto più veloci.
Nonostante mi sono letto tutta la documentazione di Arduino riguardanti gli interrupt e visti vari sketch non riesco proprio ad utilizzarli questi bene amati interrupt dandomi errori nella verifica del codice.
Non soffermiamoci solo su questo problema un ulteriore problema è che se il cavo che invia i segnali ad Arduino si interrompesse per alcuni micro secondi io non sarei in grado di capirlo allora volevo fare un controllo.
Ma non riesco proprio a capire come potrei fare.
In sintesi le domande che mi pongo sono:
-Come essere in grado di leggere tutti i giri del motore.
-Come eseguire un controllo nel caso il cavo si interrompesse.
Ciao,
essendo il tuo primo post, ti chiederei di presentartinell'apposito thread (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con attenzione il REGOLAMENTO ... Grazie.
gpb01:
Ciao,
essendo il tuo primo post, ti chiederei di presentartinell'apposito thread (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con attenzione il REGOLAMENTO ... Grazie.
Guglielmo
Ciao Guglielmo,scusami ancora per la mia barbaria.
Appena letto il tuo post sono andato nel thread apposta,mi scuso ancora.
uwefed:
non so da dove prendi il segnale dei giri.
non sti leggendo un valore analogico ma un valore digitale con quel sketch.
Ciao Uwe
Ciao Uwe,
1)il segnale dei giri mi viene inviato tramite un Encoder di fatto è questo il motivo per cui leggo HIGH e LOW, in pratica quando la calamita si trova in un determinato punto leggo LOW e quando in un altro HIGH.
2)Il motivo per cui uso un ingresso digitale credo che si capisca.
Se hai un encoder che ti genera praticamente un'onda quadra ... collega ad un pin di interrupt (su Arduino UNO i pin 2 e 3) e decidi se vuoi far scattare il conteggio sul fronte di salita o di discesa.
gpb01:
Se hai un encoder che ti genera praticamente un'onda quadra ... collega ad un pin di interrupt (su Arduino UNO i pin 2 e 3) e decidi se vuoi far scattare il conteggio sul fronte di salita o di discesa.
Ancora una volta ti ringrazio davvero tanto Guglielmo, domani appena sveglio incomincierò a leggere la guida che mi hai mandato anche se ci ho già dato una sbirciatina .
uwefed:
allora perché scrivi nel primo post:
Ciao Uwe
Ciao Uwe scusa la mia distrazione ero convinto di aver scritto digitale e invece ho scritto analogico e l'ho pure riletto due volte ,ancora scusa per la distrazione.
gpb01:
Se hai un encoder che ti genera praticamente un'onda quadra ... collega ad un pin di interrupt (su Arduino UNO i pin 2 e 3) e decidi se vuoi far scattare il conteggio sul fronte di salita o di discesa.
Grazie a tutti,ora ho implementato gli interrupt nel mio codice,ma sono fermo a due problemi che non riesco a capire.
1)facendo compiere 10 giri al motore con una tensione di 10V leggo per esempio 10000 impulsi(attraverso il pin interrupt 18), se lo faccio girare a 15V e compie sempre 10 giri leggo un valore nettamente superiore.
Non riesco a capire il motivo di tale risultato dato che, il motore giustamente girando più veloce mi da più impulsi, ma impiegherà meno tempo a compiere i 10 giri(ho pensato io).
Invece non sembra essere la cosa corretta,ho cercato anche in internet e dicevano di costruire un partitore.
L'ho fatto come era riportato ma sembra che Arduino non gliene fregasse nulla.
2)dato che devo pilotare diversi motori, mi servono più pin interrupt di quanti ne disponga Arduino Mega 2560.
In internet ho trovato che si possono abilitare diversi gruppi di interrupt agendo direttamente su registro di PCICR.
Dato che voglio utilizzare il pin digitale 10 secondo quello che ho capito dovrò utilizzare il seguente codice:
//D8-D13 = PCINT 0-5 = PCIR0 = PB = PCIE0 = pcmsk0.
PCICR |= (1<<PCICR0);
PCMSK2 =(1<<PCINT2) // pin 10
// ISR-funzione che incrementerà i miei impulsi contati
ISR(PCINT0_vect){ //PCINT0_vect perchè gruppo dei piedini da D8-D13
cont++; // variabile fittizzia per rendere l'idea dell'incremento
}
Mi sono detto, va bene prendiamo in questione un altro esempio da me fatto
void pciSetup(byte pin){
*digitalPinToPCMSK(pin) |= bit(digitalPinToPCMSK(pin));
PCIFR |= bit(digitalPinToPCICRbit(pin));
PCICR |= bit(digitalPinToPCICRbit(pin));
}
ISR(PCINT0_vect){ //PCINT0_vect perchè gruppo dei piedini da D8-D13
cont++; // variabile fittizzia per rendere l'idea dell'incremento
}
void setup(){
pciSetup(10); // passo alla funzione pciSetup() il pin 10
}
Di entrambi gli esempi fatti e implementati nessuno dei due mi funziona,cioè non ci sono errori di compilazione o sintassi ma come se l'interrupt non venisse abilitato.
Ormai ci ho perso praticamente una giornata per risolvere questo problema ma non riesco proprio a venirne a capo.
Plutoleo96:
1)facendo compiere 10 giri al motore con una tensione di 10V leggo per esempio 10000 impulsi(attraverso il pin interrupt 18), se lo faccio girare a 15V e compie sempre 10 giri leggo un valore nettamente superiore.
Spero bene tu NON stia mandando impulsi a 10V o 15V sui pin di Arduino :o :o :o ... perché, se è così, probabilmente lo hai già danneggiato !!!
Mai e poi mai mandare su un pin di Arduino meno di GND e più di Vcc ... pena il bruciare la MCU e, probabilmente, anche altro.
Devi costruire un circuito che limita la tensione che arriva sui pin di Arduino a massimo 5V !!!
Plutoleo96:
2)dato che devo pilotare diversi motori, mi servono più pin interrupt di quanti ne disponga Arduino Mega 2560.
In internet ho trovato che si possono abilitare diversi gruppi di interrupt agendo direttamente su registro di PCICR.
Perdona, NON è cattiveria, ma non mi sembra tu abbia ancora l'esperienza per giocare direttamente con registri della MCU e quant'altro ...
Quelli che tu vuoi usare sono gli interrupt classificati "Pin Change Interrupt". Esistono delle ottime librerie per gestire detti interrupt e una delle più complete è QUESTA ... studiati bene gli esempi e vedrai che ti sarà tutto più chiaro
gpb01:
Spero bene tu NON stia mandando impulsi a 10V o 15V sui pin di Arduino :o :o :o ... perché, se è così, probabilmente lo hai già danneggiato !!!
Mai e poi mai mandare su un pin di Arduino meno di GND e più di Vcc ... pena il bruciare la MCU e, probabilmente, anche altro.
Devi costruire un circuito che limita la tensione che arriva sui pin di Arduino a massimo 5V !!!
Perdona, NON è cattiveria, ma non mi sembra tu abbia ancora l'esperienza per giocare direttamente con registri della MCU e quant'altro ...
Quelli che tu vuoi usare sono gli interrupt classificati "Pin Change Interrupt". Esistono delle ottime librerie per gestire detti interrupt e una delle più complete è QUESTA ... studiati bene gli esempi e vedrai che ti sarà tutto più chiaro
Guglielmo
Grazie ancora Guglielmo,
la tensione che arriva a Arduino è sempre 5V ma la tensione del motore varia,su questo stai sicuro .
Adesso incomincierò a leggermi bene la guida che mi hai mandato, comunque è da qualche giorno che leggevo come accedere e modifica i registri della MCU e avevo trovato anche qualche esempio spiegato molto bene.
Solo che non ci avevo capito molto .
Grazie ancora.
Plutoleo96:
la tensione che arriva a Arduino è sempre 5V ma la tensione del motore varia,su questo stai sicuro
ok, l'importante che, comunque vari in ingresso, in uscita tu abbia sempre un segnale con livelli TTL ovvero, se l'oscillazione è ampia, al partitore resistivo che usi per abbassarla, metti in parallelo un diodo zener che la tagli ad un valore prefissato (es. 4.7V)
Plutoleo96:
Adesso incomincierò a leggermi bene la guida che mi hai mandato ...
Più che una guida è una libreria pronta con tutti gli esempi ed adatta a varie MCU, incluso l'ATmega328P di Arduino