Go Down

Topic: Rilevare porta seriale (Read 4180 times) previous topic - next topic

staffani

Buona domenica a tutti.
Vorrei interfacciare un Arduino Mega con un software per pc.
Il firmware è già autonomo di suo ma all'occorrenza si può interfacciare con il pc per essere controllato da quest'ultimo.
Avrei, quindi, la necessità di far rilevare alla scheda Arduino Mega, la presenza di una connessione seriale.

Premetto che il pc mi manda una stringa di dati solo al variare dei parametri, quindi appena faccio la connessione, dal pc non mi arriva niente fino al cambiamento di qualche parametro.

Ho provato con questo codice ma probabilmente non mi è chiara la funzione "if(Serial)" in quanto mi da sempre risultato true.


Code: [Select]

void setup()
{
Serial.begin(9600);
}


void loop()
{
int stato = (Serial);
if (stato = 1)
{
   
   Serial.println("Seriale rilevata");
}
else
{
   Serial.println("Nessuna seriale");
}
}


Grazie in anticipo.

leo72

if(Serial) serve a controllare se una connessione seriale è stata aperta.
Tu però hai anche bisogno di monitorare se arrivano dei dati.
Potrebbe anche esserti utile Serial.available(), che restituisce la presenza o meno di dati arrivati sulla seriale.

Quindi potresti fare 2 test nidificati, uno per verificare se la connessione seriale è disponibile ed uno, dopo il primo, per verificare se sono arrivati dei dati.

staffani

Ciao Leo e grazie per la tua risposta.

Serial.available() lo uso subito dopo per ricevere i dati seriali, ho ridotto il codice per non postare chilometri inutili. Quello che mi lascia sconcertato è l'uso di if(Serial). Dice tutto e dice niente, almeno per me.

Se cancello la riga Serial.begin(9600), il comando if(Serial) mi restituisce sempre valore true!!
Ma come fa a darmi valore true se io neanche ho inizializzato una porta seriale?
Per me è incomprensibile e ci sto sbattendo la testa.

Quello che vorrei, è segnalare su un display, la connessione e l'apertura di una comunicazione seriale senza che ci sia stato scambio di dati. Solo l'apertura tra le due porte.
L'unica soluzione che mi rimane, penso, è monitorare il pin DTR che va a 1 quando si instaura l'apertura tra due porte di comunicazione seriali, anche se preferirei lasciare il cablaggio con i soliti tre fili RX, TX, GND.

leo72

Ho provato questo sketch compilato su Arduino UNO.
Code: [Select]

void setup() {
    delay(2000);
    Serial.begin(9600);
    pinMode(13, OUTPUT);
}

void loop() {
    if(Serial) {
        digitalWrite(13, HIGH);
    } else {
        digitalWrite(13, LOW);
    }
    delay(250);
}

Alimento l'Arduino con jack, Il led è spento. Appena collego la porta USB, il led si accende. Quindi if(Serial) rileva correttamente la presenza o meno della connessione seriale.

cyberhs

Ciao staffani,

probabilmente hai collegato il PC ad una porta seriale tra quelle messe a disposizione dal MEGA.

Per farlo dovresti aver usato un adattatore USB-RS232 e poi un convertitore di livello RS232-TTL.

Perché invece non usi direttamente la Serial0 che ha il vantaggio di essere collegata alla porta USB?

Come ulteriore vantaggio avresti la possibilità di emulare il software direttamente dalMonitor Seriale.

Se il problema è il fatto del Reset sotware, questo può essere facilmene escluso con un condensatore elettrolitico da 1-10 mF.

Ettore Massimo Albani

staffani

#5
Sep 09, 2012, 01:53 pm Last Edit: Sep 09, 2012, 02:43 pm by staffani Reason: 1
Grazie a Leo per la stesura corretta del codice, provato ma non funziona, il led rimane sempre acceso anche a cavo scollegato sia su arduino uno che mega  =(
Alimento Arduino 'uno con il jack e dopo due secondi il led si accende, senza aver inserito il cavo usb.

Grazie anche a cyberhs, Ettore, che mi ha aperto gli occhi su un errore che commettevo.
Praticamente, connetto il software del pc tramite la porta utilizzata dalla scheda Mega.... che pollo!
Userò un cavetto convertitore rs232(ttl)/usb

Come sempre, siete fantastici   :)

Buona domenica a tutti e grazie di nuovo  ;)

Mimmo.

staffani

Niente da fare  :(

Risolto il problema del reset, grazie alla dritta di Ettore, usando un cavo convertitore, ma il comando if(Serial) proprio non ne vuole sapere.

Con il codice di leo, quanto di più elementare possa esserci, il led si accende passati due secondi da quando alimento le schede, sia la UNO che la MEGA (tramite jack) senza nessun cavo inserito.

Non so che altro fare  =(

leo72

Ho provato adesso, con la mia UNO R1. Se scollego la USB e alimento la scheda solo tramite jack, il led si spenge e non si riaccende dopo 2 secondi.

1) che versione dell'IDE usi?
2) che versione di Arduino UNO hai?

astrobeed


Niente da fare  :(


Per forza, non esiste nessun modo su Arduino, ad esclusione della Leonardo, per sapere se è fisicamente collegato ad una seriale, è una questione hardware e non software, puoi solo verificare se il buffer della seriale contiene dei caratteri e di conseguenza dedurne che c'è una connessione seriale attiva.
Fare una if (serial) serve solo per sapere se c'è la seriale, non se è collegata, solo sulla Leonardo if(serial) dice se è aperta o meno la seriale USB, ma in questo caso c'è il modo per saperlo visto che è legato all'enumerazione USB.

http://arduino.cc/en/Serial/IfSerial

staffani



Niente da fare  :(


Per forza, non esiste nessun modo su Arduino, ad esclusione della Leonardo....
http://arduino.cc/en/Serial/IfSerial


Allora perchè viene riportata anche la sintassi relativa alla MEGA?
Non ha senso, dato che non funziona.

Per leo72:
1.0.1
UNO R2 (quella con chip 8U2 al posto dell'FTDI)

ale92



Niente da fare  :(


Per forza, non esiste nessun modo su Arduino, ad esclusione della Leonardo, per sapere se è fisicamente collegato ad una seriale, è una questione hardware e non software, puoi solo verificare se il buffer della seriale contiene dei caratteri e di conseguenza dedurne che c'è una connessione seriale attiva.
Fare una if (serial) serve solo per sapere se c'è la seriale, non se è collegata, solo sulla Leonardo if(serial) dice se è aperta o meno la seriale USB, ma in questo caso c'è il modo per saperlo visto che è legato all'enumerazione USB.

http://arduino.cc/en/Serial/IfSerial


scusa ma a leo72 funziona con la UNO, com'è possibile?

astrobeed

Non voglio fare il pedante, però almeno leggetela la reference.

Quote

Description
Indicates if the specified Serial port is ready.
On the Leonardo, if (Serial) indicates wether or not the USB CDC serial connection is open. For all other instances, including if (Serial1) on the Leonardo, this will always returns true.
This was introduced in Arduino 1.0.1.


Quote

Returns
boolean : returns true if the specified serial port is available. This will only return false if querying the Leonardo's USB CDC serial connection before it is ready.


Da notare che la variabile Serial è stata introdotta specificamente per la Leonardo, il suo uso primario è sapere se c'è una connessione USB CDC attiva.

Definizione di  "Serial" nel core.
Code: [Select]

Serial_::operator bool() {
bool result = false;
if (_usbLineInfo.lineState > 0)
result = true;
delay(10);
return result;
}

Serial_ Serial;



leo72

Astro, tu hai ragione ed anch'io mi baso sul reference. Però il reference dice proprio che if(Serial) restituisce se la seriale è "pronta" (ready). Ma staccando il connettore USB, il led si spenge, quindi io interpreto come seriale non pronta. Che generalizzando si può anche pensare come un "connessione seriale assente". Se l'interfaccia seriale non trova la linea, darà una risposta di non pronto. O c'è qualcosa di più profondo che non ho capito?

astrobeed


Astro, tu hai ragione ed anch'io mi baso sul reference. Però il reference dice proprio che if(Serial) restituisce se la seriale è "pronta" (ready).


Ready è inteso nel senso di UART inizializzata, e per estensione presente, del resto mi dovresti spiegare come fa l'UART del ATMEGA328 a capire se è collegata a o meno ad un device esterno, ovvero quale registro mi darebbe questa informazione ?

leo72

Sei nel giusto.
Però allora cos'è che fa lo sketch che ho scritto? Perché agganciando il cavo USB si accende il led? Forse che l'8U2 spedisce qualche segnale di acknowlegde al 328 e la sua USART, rispondendo "presente", si attiva e if(Serial) dice che essa è "pronta"?

Go Up