Rilevare porta seriale

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.

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.

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.

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.

Ho provato questo sketch compilato su Arduino UNO.

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.

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

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

Buona domenica a tutti e grazie di nuovo :wink:

Mimmo.

Niente da fare :frowning:

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 =(

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?

staffani:
Niente da fare :frowning:

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.

astrobeed:

staffani:
Niente da fare :frowning:

Per forza, non esiste nessun modo su Arduino, ad esclusione della Leonardo....
if(Serial) - Arduino Reference

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)

astrobeed:

staffani:
Niente da fare :frowning:

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.

if(Serial) - Arduino Reference

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

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

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.

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.

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

Serial_ Serial;

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?

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

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 ?

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

Leo,
nella tua scheda UNO hai già l'8U2 come convertitore usb/seriale o ancora l'FTDI?

L'FTDI c'è solo fino alla 2009, su tutte le UNO c'è il nuovo chippino Atmega8U2/16U2 (a seconda delle versioni).

leo72:
Però allora cos'è che fa lo sketch che ho scritto?

Non so perché da te il tuo sketch apparentemente funziona, però l'ho appena provato su una UNO R1, su una UNO R3, su una MEGA2560 R1, su una Luigino 328 (con FTDI) ottenendo sempre lo stesso risultato, alimentando solo da batteria il led rimane sempre acceso, collegando/scollegando il cavo USB il led rimane sempre acceso.
Ribadisco il concetto, l'ATMEGA328 non ha alcun modo per accorgersi se c'è o meno collegato un device all'UART, non esiste nessun registro che fornisce questa informazione e senza usare i bit aggiuntivi per l'handshake hardware, quelli usati dalla RS232, è impossibile ottenere tale informazione.
Solo sulla Leonardo è possibile sapere se è realmente collegata ad un pc la seriale, esclusivamente tramite USB, per via di come funziona la USB e perché è integrata nel micro stesso.

astrobeed:
Non so perché da te il tuo sketch apparentemente funziona, però l'ho appena provato su una UNO R1,

Dipenderà dal sistema operativo?
Il mio sketch sulla Leonardo non funziona, nel senso che il led è sempre spento. Però ho notato una cosa con questa scheda: nel momento in cui connetto il cavettino USB, il led RX fa 1 lampeggio. Forse c'è uno scambio di dati che l'8U2 rileva ed usa per aprire la seriale verso il 328?

leo72:
Dipenderà dal sistema operativo?

Leo non so più come dirtelo, la questione è puramente hardware non ha niente a che vedere con il S.O., l'ATMEGA328, ma anche l'ATMEGA2560, non hanno nessun modo per rilevare la connessione di un dispositivo sulla seriale se non c'è un traffico dati, la if(serial) è stata introdotta specificatamente per la Leonardo perché ti permette di sapere se sei connesso tramite USB al pc, in tutti gli altri casi torna sempre true.

Però ho notato una cosa con questa scheda: nel momento in cui connetto il cavettino USB, il led RX fa 1 lampeggio. Forse c'è uno scambio di dati che l'8U2 rileva ed usa per aprire la seriale verso il 328?

Se stiamo parlando della Leonardo, che non ho, sopra non c'è l'ATMEGA328, c'è l'ATMEGA32u4 che ha la USB onboard,