Per chi non avesse voglia di leggere tutta sta pappardella ecco un indice col quale potrete passare direttamente alla parte che vi interessa:
- Che cos'è
- Come funziona (sensore infrarosso generico)
- Come funziona (encoder ottico)
- Come collegarlo al
microcontrollore (Arduino)
- Pin interrupt (cos'è e perché usarlo)
La tanta amata Wikipedia da
questa definizione: "Il trasduttore di
posizione angolare, comunemente noto in ingegneria
elettronica come encoder,
è un dispositivo elettromeccanico che converte la posizione angolare del suo
asso rotante in segnali elettrici numerici digitali", nel
caso di Explò servirà a dare indicazioni sulla rotazione delle ruote, in modo
da poter fare una stima della distanza percorsa dal robot.
L'encoder
che vogliamo utilizzare è molto semplice (e soprattutto molto poco costoso), ma
richiede qualche piccola accortezza per funzionare al meglio, per cui
cominciamo col parlare di come è fatto e del funzionamento vero e proprio.
L'encoder
ottico che useremo, come già accennato in un precedente post, è
sostanzialmente costituito da soli due componenti, due led infrarossi (più tardi vedremo come mai proprio infrarossi): uno
detto emettitore e l'altro detto ricevitore.
L’emettitore svolge la tipica funzione di
un qualsiasi LED (Light Emitting
Diode, diodo ad emissione luminosa): emettere
luce se ai due poli è applicata una differenza di potenziale.
Al contrario il ricevitore sfrutta una proprietà poco conosciuta dei led; infatti non
solo possono emettere luce, ma sono anche in grado di fare l'esatto opposto: generare corrente elettrica se colpiti da una radiazione
luminosa, proprio come fanno le celle fotovoltaiche quando colpite dai raggi solari.
Ma
in che modo funziona? Con le
premesse appena fatte il funzionamento è molto semplice e intuitivo.
Questi
due led, posti l'uno di fronte l'altro, agiscono esattamente come le
fotocellule dei cancelli o dei portoni. Il led emettitore produce costantemente
una radiazione luminosa: se vi è un ostacolo tra i due diodi il led ricevitore non
viene investito dalla luce e non succederà nulla; al contrario, in assenza di
ostacoli, la radiazione arriverà a colpire il ricevitore, che quindi, come
detto sopra, produrrà una corrente.
Proprio
per evitare che il ricevitore reagisca a qualsiasi radiazione luminosa estranea
(ad esempio la luce del sole), per queste applicazioni vengono utilizzati dei led IR (infrarossi): infatti ogni led
reagisce solo alle radiazioni di lunghezza d’onda che sono in grado di produrre.
Nel nostro caso il ricevitore reagirà soltanto ad una luce nel campo
dell’infrarosso, e l’unica fonte di questo tipo di radiazione sarà l'emettitore,
quindi il sensore non subirà sostanziali disturbi dalle altre radiazioni
presenti nell'ambiente (nel nostro caso useremo led con lunghezza d’onda di 840
nm, ma qualsiasi tipo di led IR dovrebbe andare bene).
Se
ve lo foste mai chiesto questo è praticamente lo stesso metodo utilizzato per
la comunicazione tra telecomando e televisore, che infatti hanno
rispettivamente un emettitore ed un ricevitore infrarosso.
Fin
qua dovrebbe essere tutto chiaro (o almeno spero), però abbiamo parlato solo di raggi solari e tetti, cancelli e portoni, televisori e telecomandi: tutto
questo cosa c'entra con l'encoder ottico?
Intanto
grazie per la domanda azzeccatissima, cade giusto a fagiolo per introdurre il
prossimo capitolo: come usare il sensore appena descritto per realizzare un encoder ottico.
Posizioniamo
i due led sul telaio, o comunque fissi alla struttura portante, in modo tale
che si trovino ai lati della ruota del nostro robot, il più vicino possibile
alla circonferenza esterna e rivolti l’uno verso l’altro. Ora facciamo sulla
ruota stessa un piccolo foro (diametro almeno 2-3mm per garantire un buon passaggio di luce), sempre vicino al bordo
esterno, in linea con i led: in questo modo, con il robot è in movimento, il
ricevitore produrrà un segnale elettrico quando la fessura si troverà all'altezza
del sensore, e solo in quel istante. Il microcontrollore sarà allora in grado
di capire quando il foro passa di fronte ai led e quindi, ad ogni impulso
elettrico in arrivo dal ricevitore, saprà che la ruota avrà compiuto un giro
completo sul proprio asse.
La soluzione c’è ed è anche molto semplice: usando termini tecnici, basta fare più buchi.
Tracciamo
quindi una circonferenza sulla ruota, con centro nell'asse della ruota e passante
per il foro già fatto: lungo questa curva facciamo gli altri fori ad egual
distanza l’uno dall'altro, con l’aiuto di un goniometro. Avendo fatto il primo
vicino al bordo esterno dovrebbe esserci spazio per almeno 20 fori, facendo
salire la precisione a 18°, quindi, nel nostro caso, avremo informazioni
praticamente ad ogni centimetro percorso da Explò. Ovviamente aumentando i fori
aumenta la precisione del sensore, però se facciamo i fori troppo piccoli per
risparmiare spazio, c’è il rischio, come già detto prima, che non facciano passare abbastanza luce: fate
qualche prova, magari con ruote di cartone per trovare il giusto equilibrio tra
quantità e larghezza dei fori.
A
questo punto abbiamo pronto il nostro encoder, manca soltanto renderlo
operativo attaccandolo ad un microcontrollore,
nel nostro caso un Arduino UNO (le
stesse considerazioni possono essere applicate a qualunque altro microcontrollore).
Come abbiamo detto il sensore è formato solo da due led IR: vediamo come vanno
collegati, cominciando con il led emettitore.
Per chi fosse proprio
alle primissime armi nel mondo dell’elettronica ecco come riconoscere in un led
quale dei due poli è il negativo (catodo) e quale il positivo (anodo).
Negativo: gamba corta
e circonferenza tagliata (come si vede nella foto il bordo del led sul “lato negativo” non è tondo ma smussato)
Positivo: gamba lunga
Ricordiamo che il led emettitore deve solo emettere (scusate, ma proprio non mi veniva in mente nessun altro verbo) costantemente un raggio di luce, non ha bisogno di alcun controllo o non deve fornire alcun dato: ha semplicemente bisogno di essere alimentato nel modo adatto (se sapete già come alimentare un led cliccate qua per andare al collegamento del ricevitore).
Per
farlo basta collegare il polo negativo alla massa (ground in inglese e GND su Arduino) e quello
positivo ad una resistenza che a sua volta è collegata all'alimentazione (Vcc
sui microcontrollori e 5V su Arduino).
Il
valore della resistenza (espresso in ohm,
simbolo Ω) viene calcolata in base
alla tensione di alimentazione, alla tensione di lavoro del led e alla corrente
assorbita dallo stesso tramite questa formula: R = (Val – Vled)
/ Iled. Nel nostro caso abbiamo una tensione di
alimentazione di 5 V (volt), una
tensione di lavoro del led di circa 1,5 V e il led assorbe circa 16 mA (milliampere): la resistenza adatta è
quindi di 218.75 ohm. Le resistenze che si trovano in commercio vengono
prodotte solo in alcuni valori standard, quindi, per rimanere nella sicurezza,
bisogna sempre arrotondare per eccesso e usare una resistenza con un valore maggiore, il più vicino possibile a quella richiesta. Noi useremo delle resistenze da 220 ohm.
Il valore di ogni resistenza viene identificato dalle bande colorate impresse
sulla superficie: ci sono un sacco di siti o di tabelle o di app per
identificare il valore dal colore delle bande e/o viceversa, google vi sarà di
aiuto.
Il
collegamento del ricevitore può sembrare ancora più semplice: il polo negativo
di nuovo attaccato alla massa (sempre GND su Arduino), mentre il polo positivo collegato direttamente
ad uno dei pin digitali del microcontrollore in modo da ricevere il potenziale
prodotto dal ricevitore quando non vi sono ostacoli tra i due led.
Questo
è stato il nostro primo tentativo, risultato: all'Arduino non arrivava
assolutamente nulla.
Dopo
qualche attimo di disperazione abbiamo preso il fidato multimetro e trovato la
magagna. Per capire cosa non andava serve prima un po’ di teoria (se non vi
interessa e volete andare subito alla soluzione pigiate qui).
I
pin di un microcontrollore (nel caso di Arduino quelli digitali) sono in grado
di identificare e produrre solo due tipi di segnale: HIGH (alto, attivo, vero,
1 in codice binario) e LOW (basso, non attivo, falso, 0 in codice binario).
Lo
stato LOW si ha quando non vi è passaggio di corrente, o meglio quando la
tensione sul pin è di circa 0 volt. Per attivare lo stato HIGH deve essere
invece presente sul pin una certa tensione specifica per ogni tipo di
microcontrollore. Se andiamo a controllare il datasheet del micro di Arduino (ATmega328),
esattamente a pagina 313 troviamo questo:
Vcc
è la tensione di funzionamento del microcontrollore, nel caso di Arduino 5V: lo
stato HIGH viene quindi raggiunto oltre la tensione di circa 3 volt.
Dopo
questa piccola premessa, torniamo alla pratica. Proviamo a misurare la tensione
presente sul pin, in assenza di ostacoli tra i led: ricordiamo che in questa
situazione il microcontrollore dovrebbe essere in grado di ricevere una
“impulso” elettrico e, quindi, di leggere uno stato HIGH sul pin; però, con la nostra
misurazione, abbiamo ottenuto una tensione di 900 mV (millivolt): confrontandola
con i dati nella tabella qua sopra, vediamo che si trova ancora nel range dello
stato LOW, ecco il problema!
Dobbiamo
quindi amplificare il segnale in arrivo dal ricevitore, e per farlo basta un
semplice componente: un transistor, per la precisione un transistor NPN; ma
come funziona un transistor?
Per
farla veloce il transistor NPN ha 3 poli, base, collettore ed emettitore: la
corrente che va dal collettore all'emettitore è proporzionale alla corrente che
arriva sulla base, e quindi se non c’è corrente sulla base, non passa corrente
tra il collettore e l’emettitore. L’ho fatta un po’ semplice, ma è
sostanzialmente quello che ci serve sapere. Se volete saperne di più in rete ci
sono un mare di informazioni a riguardo, per ora torniamo al nostro problema
pratico.

Colleghiamo
il polo negativo del led e l’emettitore del transistor al ground, il collettore
alla tensione di alimentazione (+5V di Arduino) tramite una resistenza da
10Kohm (10'000 ohm) e infine il pin digitale di Arduino al collettore (N.B. MOLTO IMPORTANTE: è da scegliere
un pin così detto interrupt, nel
caso di Arduino UNO il 2 o il 3; più tardi vi spiego cos'è e perché è da
preferire agli altri pin). Se le parole non vi bastano ecco una piccola illustrazione e la foto del risultato finale.
Vediamo
come si comporta nei due casi di funzionamento:
Ostacolo
tra i led NO
La
corrente in arrivo dall'emettitore va a finire sulla base, consentendo il passaggio
di corrente tra collettore e emettitore. In questo caso è come se il collettore
fosse direttamente collegato al ground: sappiamo che al ground (se facciamo
tutto giusto) c’è una tensione di 0V, di conseguenza sia sul collettore che sul
pin di Arduino la tensione sarà di 0V.
Riassumendo
se non ci sono ostacoli tra i led lo stato del pin digitale sarà LOW (o 0 o
basso).
Ostacolo
tra i led SI
Sulla
base non vi è corrente, quindi è come se il transistor non ci fosse: in pratica
il pin dell’Arduino risulta essere collegato direttamente all'alimentazione
tramite la resistenza, quindi ci sarà una tensione di circa 5V (un po’ meno a
causa di una piccola dissipazione dovuta alla resistenza).
Quindi
se ci sono ostacoli tra i led lo stato del pin digitale sarà HIGH (o 1 o alto).
Perfetto,
l'encoder è pronto! Ecco lo schema elettronico definitivo e una foto del nostro encoder
ottico! (Nella foto il cavo rosso porta il segnale all'Arduino)


Per ultima cosa diamo un’occhiata a come far interagire il microcontrollore con il sensore.
Come vi abbiamo detto poco sopra, è meglio, se non addirittura necessario, scegliere un pin interrupt per collegare l’encoder all'Arduino, ma perché?
A noi non serve semplicemente leggere lo stato in cui si trova il pin (alto o basso) in un determinato momento, ma ci interessa sapere quando avviene il cambiamento dello stato da alto a basso e viceversa, cioè, quando lo spazio tra i due led passa dall'essere libero all'essere ostruito da un ostacolo e viceversa; quindi il programma deve verificare che ci sia il cambiamento di stato e dunque lanciare una funzione specifica. Vediamo allora cosa cambia utilizzando i pin normali e gli interrupt.
Pin digitali (normali)
Prima di tutto bisogna scrivere, in un punto preciso del programma, una funzione di lettura dello stato del pin; poi bisogna controllare la lettura precedente e verificare che effettivamente è avvenuto il cambiamento di stato, ed infine, se c’è stato cambiamento di stato, lanciare la funzione: insomma molte righe per lanciare una singola funzione.
Tutto ciò, inoltre, è inserito in mezzo ad altre decine se non centinaia di righe di programma, sorge quindi un altro problema: e se il cambiamento di stato avviene mentre il microprocessore sta facendo qualcos'altro? Beh, se il programma è particolarmente complesso è possibile che uno o più cambiamenti di stato vengano saltati, quindi tutto il sistema perde notevolmente in precisione ed affidabilità. Insomma, non è un gran che, non resta che sperare nell'interrupt.
Pin interrupt
Spendiamo prima due parole per spiegare di cosa si tratta.
L’interrupt è una funzione che permette letteralmente di interrompere il programma in qualsiasi momento per avviare un funzione specifica; una volta terminata la funzione, il programma riprende da dove è stato fermato. Questo interrupt deve essere lanciato da un qualche tipo di comando: il pin interrupt ha proprio questo scopo, ed esegue il suo compito in modo completamente diverso da ogni altro pin. In pratica il microcontrollore lancia un interrupt quando un particolare evento, deciso dall'utente, accade sul pin interrupt; non c’è più bisogno di specificare un punto del programma in cui effettuare la lettura dello stato del pin: non appena l’evento specifico avviene, il microcontrollore lancia l’interrupt e la funzione collegata può essere svolta.
Tra gli eventi che si possono specificare c’è CHANGE che fa proprio al caso nostro: ogni volta che lo stato del pin cambia da alto a basso o viceversa, l’interrupt viene lanciato.
Come si può vedere i vantaggi nell'usare questo tipo di pin sono multipli e risolvono tutti i problemi dell’usarne uno qualsiasi. L’intero funzionamento dell’interrupt è racchiuso in una sola riga di programma: infatti con un singolo comando si specifica il pin interrupt che si vuol usare, la funzione da lanciare e l’evento scatenante l’interrupt (qua trovate come dichiarare e far funzionare un interrupt con Arduino). Altro vantaggio nell'uso dell'interrupt, è che, come abbiamo già detto più volte, può essere lanciato in qualsiasi momento, sia con il microcontrollore inattivo, sia durante altre operazioni: diventa quindi praticamente impossibile perdere il passaggio da presenza di ostacolo ad assenza (e viceversa) tra i led dell’encoder. Inoltre, utilizzando l'evento change, con un solo foro potremo lanciare l'interrupt due volte: infatti verrà lanciato al passaggio da ruota a foro e di nuovo al passaggio da foro a ruota. In questo modo avremo raddoppiato la precisione del sensore senza modificare la ruota o il sensore stesso, e senza aggiungere alcuna riga di programma.
Ci siamo, ogni problema dovrebbe essere risolto e le nostre prove lo dimostrano: questo encoder ottico funziona davvero!
Se volete testare il vostro encoder, o comunque volete farvi un’idea di come richiamare un interrupt con Arduino, qua sotto vi alleghiamo un piccolo programma di controllo: come potrete notare una volta caricato il file sulla scheda, anche mettendo il microcontrollore in pausa (con la funzione delay), l’interrupt è comunque in grado di interagire con il processore, facendogli lanciare la funzione di nostra scelta (nel nostro caso un semplice contatore).
volatile long contatore = 0; // dichiarando la variabile come volatile, il suo valore viene salvato anche quando il loop ricomincia void setup(){ Serial.begin(9600); attachInterrupt(0, conta, CHANGE); // dichiaro il pin interrupt, la funzione da lanciare e l'evento scatenante } // nella dichiarazione 0 corrisponde al pin 2 su Arduino, 1 al pin 3 void loop(){ // il programma continua a girare per conto suo delay(1000); // il microcontrollore viene messo in pausa per un secondo (1000 millisecondi) Serial.print("passato un secondo"); // questo comando serve per verificare che effettivamente il loop continua a funzionare } void conta(){ // non appena l'evento dichiarato in setup avviene sul pin scelto, parte questa funzione contatore++; Serial.println(contatore); } |
Bene, direi che finalmente arrivati alla conclusione: il post è davvero lungo, ma spero lo troviate utile e completo.
Come sempre per ogni domanda, dubbio, insulto, complimento o qualsiasi altra cosa scriveteci un commento qua sotto.
Alla prossima da io e ancheio.
Ti faccio una domanda da ignorantone...ma come fa ad arrivare corrente sulla base del transistor se questa non è collegata a Vcc?
RispondiEliminaScusa l'ingnoranza ma non capisco proprio...
Cioè mi spiego meglio...Se l'anodo del LED ricevente non è connesso a Vcc come può funzionare lo stesso LED? e poi soprattutto come fa ad arrivare corrente sulla base del transistor se non è collegata a Vcc?
EliminaIn realtà non è niente di complicato: per capire lo schema devi ricordarti che i LED, oltre ad emettere luce, hanno anche la proprietà di generare un impulso elettrico se colpiti dalla luce, proprio come fa una cella fotovoltaica (vedi paragrafo Com'è fatto). In pratica quando il LED emettitore è acceso, la luce che emana colpisce il LED ricevente, che non deve illuminarsi (quindi non deve essere collegato alla Vcc), ma deve trasformare la luce che lo colpisce in corrente elettrica. Questa corrente, generata dal LED ricevente, arriva tramite il catodo (quindi il positivo del led) alla base del transistor, che può quindi funzionare senza ricevere corrente dalla Vcc, ma solo con quella generata dal LED.
EliminaSpero sia un po' più chiaro, comunque se c'è qualcosa che non ti torna scrivi pure. Ciao, alla prossima
Intanto grazie mille per avermi risposto!!!
EliminaCioè intendevi dire, arriva all'anodo(che è il positivo del LED) vero?
Ma il discorso che il led genera corrente vale solo per i LED riceventi? Non c'è bisogno di mettere una resistenza limitatrice? Quanta corrente genera?
Scusa se ti assalto dalle domande ma sono alle prime armi e sono affamato di chiarimenti!!!
Grazie ancora!
Comunque ti faccio i miei complimenti per la chiarezza con cui spieghi...è dote di pochi!!!
EliminaSi, intendevo l'anodo, mi confondo ogni volta... (avevo pure sbagliato sul blog, ho corretto grazie mille!)
EliminaQUALSIASI LED ha proprietà fotovoltaiche, cioè appunto trasformare luce in impulsi elettrici, e può essere utilizzato sia come ricevitore che come emettitore, dipende solo da come lo colleghi al resto del circuito: se lo colleghi ad una tensione esterna (come può essere Vcc) sarà un emettitore di luce (che è l'utilizzo classico), se invece non lo alimenti in nessun modo genererà un tensione proporzionale all'intensità della luce che lo colpisce e sarà un led ricevente. Non è una gran risposta, ma volevo essere conciso: se non ti convince del tutto proverò a fare un mini articolo sul blog per spiegarlo meglio.
Per quanto riguarda la corrente che genera non c'è bisogno di limitarla in alcun modo perché è davvero minuscola, meno di 10 microAmpere (10^-6 Ampere). Una corrente così bassa non può fare del male a niente o nessuno, quindi non servono ne resistenze ne circuiti di sicurezza o cose simili: attacca e via.
Grazie a te per i complimenti! Continua pure a fare domande e soprattutto prova con mano e fai esperimenti, è il modo migliore per imparare! Prima o poi tornerò a scrivere un articolo qua sopra, quindi ogni tanto dacci un occhio e magari ritroverai qualcosa di interessante. Alla prossima, ciao
Grazie mille di avermi chiarito le idee!!! Comunque mi farebbe molto piacere se potessi scrivere un articolo a riguardo di queste proprietà dei LED...
RispondiEliminaCiao alla prossima e grazie ancora!
Ciao mi potreste aiutare per un esperimento simile? avrei bisogno di un contatore di passaggio e direyione a ir. Cioè mi spiego vorrei creare un tubo nel quale passano insetti, e calcolare quanti escono e quanti entrano. Se tutto cio fosse possibile qualcuno potrebbe aiutarmi? graie mille
RispondiEliminaCiao, direi che il sensore sopra si può tranquillamente adattare al tuo progetto, però ci vorrebbe qualche informazione in più. Comunque come contatore questo encoder va benissimo e per capire in che direzione vanno si potrebbe metterne due uno in fila all'altro e a seconda di quale dei due scatta prima si può capire da che parte vanno. Se comunque hai bisogno scrivi pure qua. Ciao
EliminaCiao, grazie mille ho studiato un sistema con dei integrati NTE74LS86 in poche parole facendo dei comandi logici e come risultato mi da 1 impulso per direzione. Grazie mille di tutto..
EliminaDi niente, alla prossima!
EliminaCiao scusa avrei bisogno ancora di aiuto...sto impazzendo con un modulo gsm.. qualsiasi sketch che carico mi da sempre errore char. ecco un esempio.
RispondiElimina/*
http://www.plexishop.it/it/arduino-gsm-shield-con-antenna-integrata.html
Plexishop.it (Global Engineering Network srl) investe tempo e risorse per produrre tutorial ed esempi di programmazione, vi preghiamo di supportarci acquistando i prodotti dal nostro sito. Questo sketch è rilasciato sotto licenza BSD (vedi file di licenza allegato). La licenza impone che tutto il testo qua sopra sia lasciato integro in ogni redistribuzione del file, anche se il codice viene modificato.
*/
// ITA: Si includono le librerie GSM
// ENG: Include the GSM library
#include
// ITA: Inizializzazione delle librerie
// ENG: Initialize the library instances
GSM gsmAccess;
GSM_SMS sms;
//ITA: Numero di telefono
//ENG: Telephone number
char telefono[14]="+3932xxxxxxxx";
// ITA: Assegno i pin ai led
int pulsante=10;
int ledVerde=12;
void setup()
{
// ENG: Setup pins for OUTPUT
// ITA: Imposto i pin come OUTPUT
pinMode(pulsante, INPUT);
pinMode(ledVerde, OUTPUT);
boolean connessione = true;
// ITA: Attivo la connessione GSM
// ENG: Start GSM connection
while(connessione)
{
if(gsmAccess.begin()==GSM_READY)
connessione = false;
}
// ENG: GSM initialized
// ITA: Il GSM è pronto per ricevere messaggi
digitalWrite(ledVerde,HIGH);
}
//ENG: Variable declaration
//ITA: Dichiarazione variabili
float valoreSensore=0;
float tensioneLetta=0;
float valoreAcquisito=0;
void loop()
{
if(digitalRead(pulsante))
{
// ITA: Invia il messaggio
// ENG: Send the message
sms.beginSMS(telefono);
sms.print(leggiTemp());
sms.endSMS();
}
}
//ITA: Leggi la temperatura
//ENG: Acquire temperature
float leggiTemp()
{
valoreSensore=analogRead(A0);
tensioneLetta=(valoreSensore/1024.0)*5.0;
return (tensioneLetta-0.5)*100;
}
pure anche con quelli originali di arduino mi fa sempre lo stesso scherzo..Ti ringrazio aticipatamente
Saluti Ricky
Ciao, un problema sicuramente presente nel tuo codice è che non hai caricato la libreria: con la funzione #include dichiari quali libreria vuoi utilizzare, e per farlo devi dire ad arduino come si chiama questa libreria. Nel tuo caso non hai messo nessun nome e quindi non carica nulla e le funzioni successive vengono date come errori perché non le riconosce. Prova semplicemente a scrivere dopo #include, nelle prime righe: provando a compilarlo con questa piccola aggiunta sul mio pc non ha dato nessun errore.
EliminaHo visto che la roba tra le parentesi < non le pubblica nei commenti, quindi forse anche te hai già scritto GSM.h dopo #include. Che versione del software Arduino stai usando? Lo vedi in alto nella finestra principale
EliminaCiao, io uso arduino 1.0.6 per progrmmare. Scusa ma non ho capito cosa dici di scrivere dopo a #include?? cioè sapresti dirmi corretto come sarebbe lo sketch scritto sopra? grazie mile
EliminaHai Skype cosi possiamo sentirci e capirci meglio ok? grazi mille per gli aiuti :)
EliminaPer skype ora non ci posso essere, comunque per lo sketch deve esserci scritto #include < GSM.h > senza spazi tra < > e GSM.h. Se il codice ti da ancora errore scrivimi esattamente cosa dice in basso
EliminaCiao si è incluso GSM.h.. il problema è il seguente:
RispondiEliminaC:\Users\Ricky\Downloads\arduino-1.0.6-windows\arduino-1.0.6\libraries\GSM\GSM3ShieldV1ModemVerification.cpp: In member function 'String GSM3ShieldV1ModemVerification::getIMEI()':
C:\Users\Ricky\Downloads\arduino-1.0.6-windows\arduino-1.0.6\libraries\GSM\GSM3ShieldV1ModemVerification.cpp:72: error: conversion from 'int' to 'String' is ambiguous
C:\Users\Ricky\Downloads\arduino-1.0.6-windows\arduino-1.0.6\hardware\arduino\cores\arduino/WString.h:61: note: candidates are: String::String(const __FlashStringHelper*)
C:\Users\Ricky\Downloads\arduino-1.0.6-windows\arduino-1.0.6\hardware\arduino\cores\arduino/WString.h:59: note: String::String(const char*)
Mi spiace ma veramente non so più cosa fare.. e mi spiace aver speso soldi senza usarli. Ti ringrazio veramente tanto per il tuo aiuto.
Ciao, a quanto pare il problema è della versione di Arduino, ci deve essere qualche bug nella libreria GSM. In effetti come ti dicevo prima a me non dava nessun problema, ma io usavo Arduino 1.0.5: ho provato a scaricare 1.0.6 e il problema è spuntato anche a me. Una semplice soluzione è usare la libreria di un'altra versione, puoi scaricarla da qua http://downloads.arduino.cc/GSM-Arduino-1.0.7-afc368b.zip che è quella della versione 1.0.7 che dovrebbe uscire tra poco.
EliminaPer sostituire la libreria per prima cosa estrai dal file zip del link sopra la cartella GSM e quindi copiala in ...\arduino-1.0.6\libraries\.
Fammi sapere se il fix funziona
Ciao grayie mille, ora funziona.. amche se non capisco perché invia 8 sms alla volta ;(.. per il resto e tutto ok.. ti ringrazio veramente tanto.. era un po' che stavo impazzendo..
EliminaTranquillo, anche io sto usando un modulo gsm per un altro progetto e anche a me non mancano i mal di testa. Per il fatto che mandi molti sms con un solo click di tasto prova a vedere il debouncing del bottone: in pratica non essendo perfetto i contatti del pulsante ad un singolo click i segnali inviati sono multipli. Per risolvere puoi fare per via software (Debounce Arduino) oppure via hardware, comunque su internet si trova molto.
EliminaCiao alla prossima
Ciao scusa ma mi sto perdendo in un semplicissimo comando e non capisco perché.. cosa sbaglio secondo te? dovrebb essere una semplice variabile che cambia i led ma nulla.. ;(
RispondiEliminasaluti Ricky
const int ledVerde = 2;
const int ledRosso = 7;
const int pulsante = A0;
void setup(){
pinMode(ledVerde, OUTPUT);
pinMode(ledRosso, OUTPUT);
pinMode(pulsante, INPUT);
}
void loop (){
if (pulsante == HIGH){
digitalWrite(ledRosso,HIGH);
digitalWrite(ledVerde,LOW);
}
else {
digitalWrite(ledVerde,HIGH);
digitalWrite(ledRosso,LOW);
}
delay(100);
}
Ciao, il problema è molto semplice. All'inizio hai dichiarato che pulsante = A0, quindi quando nell'if dici pulsante == HIGH questo non si verificherà mai perché alla variabile "pulsante" hai dato il valore A0, e quel valore rimane fisso. Quello che devi fare è chiedere esplicitamente ad Arduino qual'è il valore del segnale sul pin "pulsante", cioè A0: per fare ciò ti basta la funzione digitalRead, quindi nel tuo programma al posto di if(pulsante == HIGH) devi mettere if (digitalRead(pulsante) == HIGH). Guardati questo esempio se non ti torna qualcosa. Fammi sapere se funziona, alla prossima, ciao
EliminaCiao si grazie... funziona ora.. sbagliavo. non davo digitalRead. grazie mille buona serata e scusa il disturbo
EliminaCiao scusate avrei bisogno di un aiuto, ho scaricato un codice per la scheda gsm una scheda relé, lo sketch non mi da errore ma non vanno i comandi che dovrebbero essere "accendi" e "spegni" . che poi dovro modificare per la mia scheda relé a 8. se qualcuno potrebbe darmi una mano lo ringrazio.....
RispondiElimina#include
const int heaterControlPin = 12;
// initialize the library instances
GSM gsmAccess;
GSM_SMS sms;
// Array to hold the number a SMS is retreived from
char senderNumber[20];
// String to hold the incoming message
String message = "";
// String that will contain the parsed values from the message
String commandID, deviceID;
void setup()
{
// set the pin connected to the relay that control the heater as output
pinMode(heaterControlPin, OUTPUT);
// initialize serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
// connection state
boolean notConnected = true;
// Start GSM connection
while(notConnected)
{
if(gsmAccess.begin()==GSM_READY)
notConnected = false;
else
{
Serial.println("Not connected");
delay(1000);
}
}
Serial.println("GSM initialized");
}
void loop()
{
char c;
// If there are any SMS available
if (sms.available())
{
Serial.println("Message received from:");
// Get remote number
sms.remoteNumber(senderNumber, 20);
Serial.println(senderNumber);
// An example of message disposal
// Any messages starting with # should be discarded
// usually anonymous messages starts with #
if(sms.peek()=='#')
{
Serial.println("Discarded SMS");
sms.flush();
}
// Read message bytes and print them
while(c = sms.read())
message += c;
// cancella message ricevuto
sms.flush();
Serial.println("MESSAGE DELETED");
}
// if there is a new message start to parse the command and the device to control
if(message != "") {
// put the incoming characters that compose the message to lower case
message.toLowerCase();
int i=0;
// deviceID and commandID are separated by a space
// find it and store the position in two strings
while(message.charAt(i) != ' ') i++;
commandID = message.substring(0,i);
deviceID = message.substring(i+1, message.length());
// check the device to control
if(deviceID == "stufetta")
{
//check the command to execute
if(commandID == "accendi") {
sendFeedbackSMS(senderNumber, deviceID, "ON"); // send the feedback to the sender
digitalWrite(heaterControlPin, HIGH);
}
if(commandID == "spegni") {
sendFeedbackSMS(senderNumber, deviceID, "OFF"); // send the feedback to the sender
digitalWrite(heaterControlPin, LOW);
}
}
// clear the message that has just been processed
message = "";
}
delay(1000);
}
// this function, given a phone number and two strings representing the device and
// its state send a feedback text message to the phone number
void sendFeedbackSMS(char remoteNum[], String devString, String devState) {
String txtMsg = devString + " " + devState;
Serial.println(txtMsg);
Serial.println(remoteNum);
sms.beginSMS(remoteNum);
sms.print(txtMsg);
sms.endSMS();
}
Grazie a tutti Loris
lo sketch inizzia con , #include non solo, #Include
RispondiEliminaciao loris
Ciao, sinceramente così su due piedi non saprei, puoi essere un po' più specifico sul sistema che stai usando e sul problema che riscontri.
Eliminaciao, io ho una scheda gsm che uso come recive sms, ed una scheda a 8 relé. vorrei che con un comando tramite sms mi apra o chiuda i relé.
RispondiEliminaho scaricato questo sketch ma non funziona il comando che dovrebbe essere "accendi" e "spegni", se mi potete aiutare perché io non ho trovato il problema, ringrazio a tutti ciao Loris
ciao, ho una scheda gsm che uso come recive sms, ed una scheda relé. vorrei che con un comando tramite sms possa aprire o chiudere il relé,ho scaricato questo sketch ma non mi funziona, i comandi dovrebbero essere "accendi" o "spegni", io non sono riuscito a trovare il problema....... ringrazio tantissimo saluti Loris
RispondiEliminaCiao pure io ho quel problema... lo Sketch e copiato da arduino http://playground.arduino.cc/Italiano/TutorialWired#SMSHeather però pure a me non funziona e non riesco a capire il motivo ;( anche modificando i "dati" accendi e spegni con numeri non mi funziona...
RispondiEliminaMi spiace perché era una cosa molto utile per me, ore e ore per nulla..
grazie a tutti
Ciao, vorrei provare a fare un circuito come al tuo ma a 24vcc mi puoi aiutare? Grazie
RispondiElimina