Interferenze con arduino - computer

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..

qualcuno sa illuminarmi?

vi ringrazio tanto

Paolo

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 :wink:

Poi ... due cose ...

  1. 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".

  1. 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 :wink:)

Guglielmo

Ehi ciao!

grazie delle info e scusa per il codice che non era inserito correttamente. Non sapevo e spero di aver provveduto ora.

Ora devo correre al lavoro, ma sta sera controllo cos'è il meccanismo di debauncing e provo ad implementarlo

grazie ancora
paolo

LordA92:
...
Ora devo correre al lavoro, ma sta sera controllo cos'è il meccanismo di debauncing e provo ad implementarlo

Il codice va bene come lo hai messo ... :slight_smile:
... oltre al debouncing ricorda anche il punto 2 ... mi raccomando :grin:

Guglielmo

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 :wink:

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 ... ]:smiley:

... 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 ???

Guglielmo

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!

Ok ... allora ...

  1. usa la funzione che hai nel IDE Tools -> Auto Formatting ... per rendere più ordinato l tuo sorgente, specie per le indentature ...

  2. la resistenza sul LED è fondamentale per limitare la corrente !!!

  3. Non vedo il debounce nel codice ...

  4. continuo a vedere nelle Serial.print() dei singoli apici invece dei doppi apici ...

... torna quando hai sistemato il tutto ]:smiley: ]:smiley: ]:smiley:

Guglielmo

Buongiorno,

resistenza messa e formattazione sistemata.

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');

grazie nid69ita :slight_smile:

sto correggendo il codice secondo tutte le varie indicazioni :slight_smile:

Buona Pasqua a tutti voi.

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!

Paolo

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.

Ciao Leo72 e ciao agli altri.

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.

Qualcuno ha idee?

Grazie
Paolo

LordA92:
Qualcuno ha idee?

SI, che ti studi il reference .... ]:smiley: ]:smiley: ]:smiley:

... 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".

Guglielmo

è vero posso concatenare più caratteri finche arrivano dati dalla usb!

grazie :smiley: