Buongiorno a tutti.
Sono un novello, quindi vi prego di scusarmi per eventuali castronerie.
Sto usando un arduino UNO rev 3
collego alla porta usb il mio arduino al pc, ed in visual basic con l'apposito controllo seriale mi collego ad esso.
Il programma è abbastanza semplice: il computer ogni secondo invia una richiesta di presenza ad Arduino: ci sei? (in realtà il pc apre la com (se è chiusa) e trasmette il carattere "1"). Se arduino è connesso ed acceso risponde ci sono (risponde con un 1 sulla seriale).
quello che desidero fare ora è che arduino segnali al computer quando io chiudo il contatto con un tasto. In pratica vorrei che quando il pin digitale 8 venisse chiuso, arduino lo dicesse al pc, inviando una stringa. Per fare questo uso il codice che posto sotto. E ripeto, scusate la grezzezza del codice ma sono nuovo di arduino e di C++
void setup() {
Serial.begin(9600);
pinMode(8, INPUT); //serve per simulare la presenza di un interruttore
}
void loop () {
delay(150); //intervallo di tempo
if (Serial.available()) { //se arrivano dati dal computer
byte DatiArrivo = Serial.read();
if (DatiArrivo =='1') { //il computer mi sta chiedendo se sono connesso. devo rispondere di si inviando un 1
delay (150); //aspetto 150milli secondi per non mandare in pappa il sistema
Serial.write('1'); //rispondo al computer che sono acceso e connesso
}
// ora controllo se viene premuto il tasto. se viene premuto lo comunico al pc. Uso il pin 8
if (digitalRead(8) ==HIGH){ //se viene premuto il pulsante
Serial.write('premuto');
delay (50);
}
if (digitalRead(8) ==LOW){ //se rilascio il pulsante
Serial.write('non premuto');
delay (50);
}
}
Il problema che mi si presenta è strano. il programma, cosi com'è funziona, ma accadono cose strane. Se controllo le stringhe che arduino passa al pc, si presentano valori senza alcun senso. Visual basic mi evidenzia che passano stringhe tipo 1000 oppure 10 oppure 100000 ed altri numeri che non capisco da dove escano. Inoltre secondo il pc molto spesso arduino è disconnesso. Cioè credo non risponda correttamente alla stringa 1 che il computer gli passa.
inoltre mi basta collegare un cavo o qualsiasi altra cosa ad arduino e questo impazisce. Sto pensando a dei campi magnetici che lo influenzino o cose del genere.
Vi è capitato? Non credo sia il collegamento via usb perche se tolgo l'usb e lo collego con alimentatore i problemi sono gli stessi. mi accorgo di questo collegando un diodo ad una porta digitale che dovrebbe accendersi solo al ricevere di una determinata stringa dal pc. Ma il led si accende e si spegne quando gli pare a lui, anche a pc scollegato..
Ciao,
prima di tutto il codice va racchiuso tra i tag CODE che, in fase di edit, ti inserisce il bottone # ... terzultimo della seconda fila
Poi ... due cose ...
stai trascurando i rimbalzi ! Quando un pulsante viene premuto o rilasciato, succede qualche cosa come :
... che il tuo codice legge come tantissime pressioni e rilasci. DEVI implementare un meccanismo di "debouncing".
per le stringhe di caratteri DEVI usare i doppi apici, altrimenti, con un singolo apice, il C considera un singolo carattere ... quindi, ad esempio, devi scrivere :
Serial.write("premuto");
Correggi, prova e ripubblica se hai ancora problemi (intanto però correggi il tuo primo post per il codice )
Grazie, si anche il secondo punto è fondamentale..
Forse nel mio caso più importante del primo. Sto riflettendo (dal lavoro..) sul fatto della pressione del pulsante.
Il mio circuito in realtà non è proprio un pulsante ma è il relè di un altro apparecchio, ed è sempre aperto o sempre chiuso. Quindi, in questo caso, non dovrei avere il problema che tu mi sottoponi. Ovviamente per altri tipi di circuito dovrò tenerne conto, ma in questo caso è aperto o chiuso e ci resta per un bel po, nel senso che non è un pulsante che premo. Mi ero spiegato male pensando che non sarebbe cambiato nulla.
Invece quello che piu mi preoccupa è che arduino sembra fare quello che gli pare. Come dicevo nell'esempio sopra ho collegato un led tra porta digitale 12 e massa. il led è normalmente spento e si accende solamente quando io passo una stringa (o un carattere.. correggerò sta sera) da arduino a pc quindi con il comando serial.write. Ma questo led, ogni tanto, anche senza collegamento usb, si accende e si spegne.
per questo sto pensando a delle interferenze radio. ma anche spegnendo monitor, wireless, pc ecc non cambia nulla. Tocco arduino ed il led si accende. Quando arduino è collegato al pc mi trasmette dati a caso, quando vuole lui e cosa vuole lui.
questo credo sia il problema piu annoso, uff. E' mai capitato?
LordA92:
Il mio circuito in realtà non è proprio un pulsante ma è il relè di un altro apparecchio ...
... è esattamente la stessa cosa ... ogni volta che si chiude o si apre il contatto del relè ... hai quello che ti ho mostrato
LordA92:
... Invece quello che piu mi preoccupa è che arduino sembra fare quello che gli pare. Come dicevo nell'esempio sopra ho collegato un led tra porta digitale 12 e massa. il led è normalmente spento e si accende solamente
No, Arduino non fa come gli pare, stai sicuramente sbagliando TU ... ]
... e il primo sbaglio è collegare un LED direttamente ad un piedino e massa senza interporre la dovuta resistenza di limitazione della corrente !!! Così non solo rischi di bruciare il LED, ma anche il piedino di Arduino.
poi ... nel codice NON vedo riferimenti a pin in output (per il LED) ... devi postare il codice esatto che stai usando ... altrimenti come si fa a capire dove sbagli ???
Se non ha impostato il pinmode ha attivato la pull'up interna. E' stato fortunato di non avere bruciato il pin dell'Arduino.
Poi il pin 12... addio programmazione ISP, connessione Ethernet e SD, ecc ecc.
Scusa PaoloP ma non ho capito minimamente di cosa parli.
Che cosa non ho impostato?
in ogni caso ecco il codice completo che, giustamente, mi chiede Guglielmo:
byte SeConnesso = 0; //specifica se arduino è connesso al pc
void setup() {
Serial.begin(9600);
pinMode(12, OUTPUT); //diodo per ricezione dati dal pc
pinMode(8, INPUT); //serve per controllare l'apertura o la chiusura di un interruttore o relè esterno ad arduino
}
void loop () {
delay(150); //intervallo di 150 milli second
if (Serial.available()) { //se arrivano dati dal computer sulla usb-com3
byte DatiArrivo = Serial.read();
if (DatiArrivo =='1') { //il computer mi sta chiedendo se sono connesso. devo rispondere di si inviando un 1
delay (150); //aspetto 150milli secondi per non mandare in pappa il sistema
Serial.write('1'); //rispondo al computer che sono acceso
}
if (DatiArrivo =='2') {
digitalWrite(12,HIGH); //si accende il diodo di conferma dati ricevuti dal pc
delay (100);
}
if (DatiArrivo =='3') {
digitalWrite(12,LOW); // si spenge di diodo di segnalazione dati pc
delay (100);
}
}
// ora controllo che il relè esterno ad arduino non chiuda il circuito
if (digitalRead(8) ==HIGH){ //se il relè/pulsante chiude il circuito
Serial.write('chiuso'); //scrivo al pc che il relè ha chiuso il circuito
delay (50);
}
if (digitalRead(8) ==LOW){ //il relè ha aperto il circuito. condizione normale
Serial.write('aperto');
delay (50);
}
}
le modifiche fatte rispetto all'originale sull'arduino sono solo i commenti e di forma.
scusate la nabbaggine... sono nuovo di arduino, ed anche di c++ ma l'argomento è troppo interessante.
Ora provo a correggere il collegamento con la resistenza al led.
grazie ancora!
Scrivo quando ho novità sul debounce; ci sto studiando. Io e l'inglese siamo un po' il giornalismo e la verità, o i politici e l'onestà...
intanto grazie
@Loard, appunto:
In C, a differenza del Basic, è importante differenziare l'uso di apice singolo e apice doppio.
Apice singolo si usa per il singolo carattere:
if( myChar=='A')
Apice doppio per le stringhe o frasi:
Serial.println("Ciao");
Purtroppo il C accetta questa sintassi Serial.println('Ciao'); ma equivale a questo: Serial.println('C');
vi ringrazio per le info. Ora che ho aggiunto il ritardo per la pressione del pulsante, ma piu che altro (credo) corretto il circuito elettrico secondo quanto dice il sito ufficiale, non ci sono più interferenze strane, ed i dati passati tra pc ed arduino (e viceversa) vengono interpretati correttamente.
Devo ancora approfondire la questione buffer (credo), nel senso che se invio da arduino al pc una stringa tipo : "sono acceso", il computer riceve tre differenti trasmissioni divise in qualcosa come "son", "o ac" e "ceso".
Quindi immagino ci sia da controllare il buffer.
In ogni caso per ora vi ringrazio molto ed ancora buone feste!
LordA92:
Devo ancora approfondire la questione buffer (credo), nel senso che se invio da arduino al pc una stringa tipo : "sono acceso", il computer riceve tre differenti trasmissioni divise in qualcosa come "son", "o ac" e "ceso".
Quindi immagino ci sia da controllare il buffer.
Il buffer consideralo come una memoria temporanea in cui i dati vengono appoggiati per il transito. Sono alcune decine di byte sia in RX che in TX, lato Arduino intendo. Difficilmente lo saturi con una stringa come "sono acceso".
Casomai dovresti controllare sia come i dati vengono spediti sia come vengono ricevuti.
Il codice secondo le correzioni che ho fatte funziona. Sembra stabile.
Mi rimane sempre il problema di ricezione ed invio di stringhe di testo da - verso arduino - pc via usb
Mi spiego. Se invio un carattere arriva correttamente, sia da arduino al pc che viceversa.
Se però invio: Serial.print ("Ciao") al computer quello che arriverà saranno 4 trasmissioni di un carattere ciascuno-
Anche se dal pc invio ad arduino: com.Output = ("Ciao") ricevo solamente una "C"
lato arduino io creo una cosa del genere:
int DatiArrivo=Serial.read();
String MiaStringa;
MiaStringa = String(DatiArrivo);
Praticamente cerco di imbrogliare trasformando i caratteri che arrivano in stringa, ma evidentemente non è giusto fare cosi, perché il codice interpreta i dati sempre come un singolo carattere che arriva e non come una stringa, cioè una concatenazione di più caratteri.
... l'avremo detto e ripetuto non so quante volte ... Serial.read() legge UN SOLO CARATTERE e che per ricevere più caratteri occorre fare dei loop di ricezione fino a quando Serial.available() !!!
Inoltre, usare il tipo String ... serve solo per andarsi a cercare guai ... impara a usare il tipo string nel senso di "char array".