Lettura serial2 e seriale3 su arduino mega

Ciao a tutti, ho un problama di questo genere:
arduino mega con due gps configurati, uno sulla com3 e l'altro sulla com2.
Attualmente ho un pulsante che comanda un rele che devia, a seconda,il filo tx del gps1 o il filo tx del gps2 , all'ingresso dell serial3.
Il dato lo leggo cosi:

if (Serial3.available()) {
  //leggo la prima riga
  char c = Serial3.read();
  if (c != '\n') {
  NMEA += c;
  }
  else {
    Serial.println(NMEA);
    etc etc...... (ma qui è solo decodifica del dato catturato...

Quello che volevo fare è fare il passaggio "del filo" via software, tramite un variabile comandata dal pulsante
piu o meno in questa maniera:

if (Serial3.available() && check == "b" ) {
  //leggo la prima riga
  char c = Serial3.read();
  if (c != '\n') {
  NMEA += c;
  }
  else  if (Serial2.available() && check == "r" ){
    char c = Serial2.read();
  if (c != '\n') {
  NMEA += c;
  }
  }
  else {
    Serial.println(NMEA);
     etc etc...... (ma qui è solo decodifica del dato catturato...

purtroppo non mi funziona, va solo con il controllo su "b"...
E' facile che sia sbagliata anche la procedura...ma non saprei come farla.
Qualcuno saprebbe aiutarmi?
Grazie e buon proseguimento

Mario

>iz1mario: ti ricordo che in conformità al regolamento, punto 7, devi editare il tuo post qui sopra (quindi NON scrivendo un nuovo post, ma utilizzando il bottone More → Modify che si trova in basso a destra del tuo post) e racchiudere le parti di codice all’interno dei tag CODE (… sono quelli che in edit inserisce il bottone con icona fatta così: </>, tutto a sinistra).

In pratica, tutto il tuo codice dovrà trovarsi racchiuso tra due tag: [code] _il _tuo_ codice_ [/code] così da non venire interpretato e non dare adito alla formazione di caratteri indesiderati o cattiva formattazione del testo. Grazie.

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non avrai sistemato il codice come richiesto, nessuno ti potrà rispondere, quindi ti consiglio di farlo al più presto. :wink:

OK...volevo gia farlo, ma non trovavo le icone,chiedo scusa! :wink:
fatto.

Mario

Nessuno sa darmi una mano?

buona giornata! :wink:

Ti manca la chiusura dela parentesi graffa del primo if (prima dell'else if della Serial2).
Consiglio usa la formattazione automatica dell'IDE premendo Ctrl+T ti sarebbe quasi certamente balzato all'occhio.
Comunque la formattazione applicala sempre prima di postare il codice sul forum, diventa difficile leggere un codice di un'altra persona se oltrettutto è pure formattato male

arduino mega con due gps configurati, uno sulla com3 e l'altro sulla com2.
Attualmente ho un pulsante che comanda un rele che devia, a seconda,il filo tx del gps1 o il filo tx del gps2 , all'ingresso dell serial3.

Scusa ma non ho capito. Perché commutare con un relè se i due gps sono collegati su due serial differenti?

Ciao rispondo a Savoriano:

Scusa ma non ho capito. Perché commutare con un relè se i due gps sono collegati su due serial differenti?

Il rele è il primo step di sviluppo, per vedere se funziona tutto indipendentemente dal soft.Il secondo step,questo è lo scopo, è quello di ridurre l'hardware sfruttando le due comm.

Rispondo a fabpolli:

Ctrl+T ti sarebbe quasi certamente balzato all'occhio.

é strano... con ctrl-c attivato (viene visualizzato l'avviso di attivazione)ho ri-scritto passo passo il codice, rifacendo volutamente l'errore, ma non ho notato alcuna differenza nello scritto o negli avvisi.
Bho...forse mi aspetto un autocompletamento della fase finale del loop?forse mi aspetto un avviso di errore?
Comunque corretto.grazie per la vista acuta, purtroppo quando comincio a mettere graffe, alle volte perdo il conto... :slight_smile:

Torno allo sviluppo cosi vedo se funziona tutto!

Grazie e buon proseguimento

Mario

Non è crl+c ma ctrl+T e lo devi fare manualmente ogni qualvolta vuoi formattare il codice perché ne hai scritto di nuovo, non è una cosa che attivi e man mano che scrivi lui lo sistema.

Ciao ragazzi...

Non è crl+c ma ctrl+T

Si...ho solo sbagliato a scrivere... :slight_smile:


Ho fatto il controllo singolo della seriale 3 (solo questa, senza la variabile check) e funziona
Ho fatto il controllo singolo della seriale 2 (solo questa, senza la variabile check) e funziona pure questa.
In ambe due i casi riesco a leggere e docodificare (sostituissco 3 a 2 ...)

if (Serial3.available()) {
    //leggo la prima riga
    char c = Serial3.read();
    if (c != '\n') {
    NMEA += c;
    }

    else {
      setc etc....;

quando inserisco il controllo "check" per fare in lo scambio via software...non funziona piu niente.
mi viene da pensare che il problema sia legato al troppo tempo che ci impiega la verifica di "check".

void decodifica() {
  if (Serial3.available() && check == "b") {
    Serial.print (check);
  char c = Serial3.read();
    if (c != '\n') {
    NMEA += c;
    }
}
else if (Serial2.available() && check == "r") {
  Serial.print (check);
  char c = Serial2.read();
     if (c != '\n') {
    NMEA += c;
    }
}
else {

Forse dovrei lasciare le comm sempre in lettura e poi, con il controllo CHECK, andare a prelevare dal buffer e decodificare quello che trovo nel buffer?
il problema è ...da dove comincio...non ho tutte queste conoscenze

Per le mie conoscene è piu semplice via hardware acnhe se mi piacrebbe togliere un po di "ferramenta"

Se check è un char allora non devi mettere “b” ma ‘b’ stessa cosa ‘r’
Posta tutto il codice

Si…ho solo sbagliato a scrivere…

Se hai un Mac allora è CMD+T.
Se invece hai Win o Linux non c’è motivo che non funzioni con CTRL+T
Puoi usare anche il menu: “Strumenti”>“Formattazione Automatica”

Ciao Savoriano,

grazie per la mano e scusami per l’ignoranza.
Check la uso come stringa ma avevo provato anche come char. dichiarata all’inizion del codice.

String check;

sezione setup inizializzo le seriali

void setup() {
//init seriale hardware
Serial.begin(115200);
Serial2.begin(115200); // pn 16 e 17 per ricevere da gps
Serial3.begin(115200); // pn 14 e 15 per ricevere da gps

nel loop faccio girare una rputine di lettua tastierino numerico per poter , nel proseguo dello sviluppo, programmare alcune funzioni dei gps

void loop() {
char key = kpd.getKey();
if (key) {
tasto = (int) key;
switch (tasto)
{
case 70: // il tasto f fa entrare …etc etcc… scansione di tutta la tastiera

questo è il “case” che attiva lo scambio del rele e delle due seriali. Funziona correttamente dato che il rele viene comandato come da richieste. In questa routine assegno a CHECK il valore “b” di base oppure “r” di rover

case 69: //tasto e
utility = false;
Serial.println(posizione_seriale);
if (posizione_seriale > 1)
{
posizione_seriale = 0;
}
posizione_seriale++;
lcd.clear();
lcd.noCursor(); //rendi invisibile il cursore
lcd.noBlink();
lcd.setCursor(0, 0);
switch (posizione_seriale)
{
case 1:
Serial.println(“comm 1”);
lcd.print(“Check”);
lcd.setCursor(0, 1);
lcd.print(“BASE”);
lcd.setCursor(0, 1);
digitalWrite(rele, HIGH); // accende il rele
check = “b”;
break;
case 2:
Serial.println(“comm 2”);
lcd.print(“Check”);
lcd.setCursor(0, 1);
lcd.print(“ROVER”);
lcd.setCursor(0, 1);
digitalWrite(rele, LOW); // spegne il rele
check = “r”;
break;
}
break;

dop aver fatto la scansione del tastierino,il loop si conclude con questo IF.
UTILITY è legato un tasto del tastierino numerico che assume un valore true o false (il tasto farebbe accedere o meno ad alcune funzioni oppure lasciare la lettura delle seriali,per intenderci).
QUesto IF fa partire le operazioni che riguarda la lettura e decodifica del del dato seriale, che però sono esterne al loop

if (!utility)
{
leggi_seriale();
decodifica();
}
// qui finisce il loop

[quote/]

la funzione leggi_seriale è quella incriminata.
In pratica cosa vorrei fare:
i due gps trasmettono sempre sul loro TX OUT (verso la com3 o la com2 ) io semplicemente voglio che,nel caso check fosse “b” leggesse la com3 , se check fosse “r” leggesse la com2
Non mi importa di perdere qualche dato inquanto le stringhe dei gps sono inviate ogni secondo e per il mio utilizzo questa perdita di un dato non ha influenza (fotogrammetria rtk dove devo aspettare anche qualche minuto per aver un dato stabile quindi, come puoi capire, il secondo perso non importanza)

void leggi_seriale() {
if (Serial3.available() && check == ‘b’) {
Serial.print (check);
char c = Serial3.read();
if (c != ‘\n’) {
NMEA += c;
}
}
else if (Serial2.available() && check == ‘r’) {
Serial.print (check);
char c = Serial2.read();
if (c != ‘\n’) {
NMEA += c;
}
}
else {
Serial.println(NMEA);

}
}

quando le condizioni sono corrette, a seconda se selezionato "b oppure “r” ed ho acquisito il dato di conseguenza, esco dalla procedura, torna nel loop,e passa alla successiva decodifica.

Qui ho un dubbio: ma usando il sistema a funzioni esterne…il percorso uscitalopp>lettura>ritornoloop>decodifica è corretto oppure avviene in maniera parallela cioe’:
lettura seriale…leggo ma nel frattempo il loop va avanti e sono gia in decodifica e quindi, in caso di ritardi, mi sono perso tutto e la mia stringa è facile che sia errata ?

Devo dire che il test con il passaggio fisico viene fatto con una sequenza seriale nella stessa routine: la lettura della singola comm è all’inizio e quidi finche non ha letto non va oltre.

questa è la versione fatta funzioni esterne, quella che non va…

void decodifica() {
Serial.println(NMEA); // da qua parte la decodifica della stringa >>>
posizione_delimitatore = 0;
index = 0;
//questa variabile viene usata per contare tutti i campi trovati
campo = 0;
//printo solo la stringa che mi interessa
if (NMEA.substring(0, 6) == “$GNGGA”)
{ …etce etc etc…

questa è la funzione che uso con il rele (lettura e decodifica assieme) e che funziona

void decodifica() { // qui leggo la seriale e non ne esce finche non c’è \n
if (Serial3.available()) {
//leggo la prima riga
char c = Serial3.read();
if (c != ‘\n’) {
NMEA += c;
}

else {
Serial.println(NMEA); // da qua parte la decodifica della stringa >>>
posizione_delimitatore = 0;
index = 0;
//questa variabile viene usata per contare tutti i campi trovati
campo = 0;
//printo solo la stringa che mi interessa
if (NMEA.substring(0, 6) == “$GNGGA”) etc etc…qui c’è tutta la decodifica…

Mario :slight_smile:

Allora, Arduino è una MCU non mutithread quindi il codice in parallelo non esiste, viene eseguito sequenzialmente.
Quello che posso dirti (e a cui prima non avevo fatto caso) che usare la classe String su Arduino porterà il tuo progetto ad aver quasi sicuramente problemi di memoria con blocchi improvvisi/imprevisti dopo un po’ di tempo che funziona, se cerchi sul forum ne abbiamo parlato millemila volte. Detto che non ho analizzato il codice per scoprire l’eventuale problema io ti suggerisco di iniziare sin da subito ad una completa revisione del programma per rimuovere in tutti i punti l’uso di variabili/codice su fa leva sulla classe String e di sostituirlo con le stringhe classiche del C (array di char) e relative funzioni di manipolazione

>iz1mario: ti ricordo che in conformità al regolamento, punto 7, devi editare il tuo post #10 (quindi NON scrivendo un nuovo post, ma utilizzando il bottone More → Modify che si trova in basso a destra del tuo post) e racchiudere il codice all’interno dei tag CODE (… sono quelli che in edit inserisce il bottone con icona fatta così: </>, tutto a sinistra) e NON dei tag QUOTE !!!

In pratica, tutto il tuo codice dovrà trovarsi racchiuso tra due tag: [code] _il _tuo_ codice_ [/code] così da non venire interpretato e non dare adito alla formazione di caratteri indesiderati o cattiva formattazione del testo. Grazie.

Guglielmo

Secondo me dovresti leggere un GPS aspettare che ti dia il dato che ti interessa e poi switchare sull'altro e fare la stessa cosa.
Ho paura che la tua variabile NMEA sia un miscuglio di caratteri letti dai due GPS.
Mi sembra di ricordare che anche se svuoti il buffer del serial, non vuol dire hai sicuramente tutta la trama del GPS.

RIspondo a fabpolli

i sostituirlo con le stringhe classiche del C

Grazie per la dritta, non è un grosso problema pechè uso la uso solo in questa occasione.Per il discorso MCU, si immaginavo, abituato a sviluppare su macchine recenti, perdo di vista il discorso “processori” semplici.
Ma anche questo non è un problema dato che lo sviluppo l’ho fatto con procedura in linea.
Questa è una versione parallela…in modo da non perdere i ll lavoro di base.

Rispondo a savoriano
Dalle nostre parti si dice “è piu la bagna che lo stufato”… da elettronico, a questo punto , preferisco stare sull versione “hardware” che fino ad ora non mi ha dato nessun problema, facendo conto anche del fatto che uso un rele ss, quindi la commutazione non è meccanica.

Grazie comunque a tutti per il supporto!

mario

Rispondo a fabpolli
Per conoscenza...ho finalemnte capito come funzina ctrl-T... veramente utile!
Ho fatto il passaggio da stringa a char ma c'è una cosa che non risco a fare:

char lat [10]="12.4567890"

se io voglio cambiare, ad esempio, il 4 carattere di questo array se non ho capito male devo fare cosi

lat [4]="x"

alla fine se stampo l'array mi dovrei aspettare

serial.print(lat) // mi dovrebbe stampare 12.x567890
serial.print(lat[4]) // midovrebbe stampare x

è giusto il ragionamento? non so perchè ma non mi fuziona

mario

Se devi modificare il 4 che è il quarto carattere della tua stringa devi fare

lat[3] = 'x';

è un char quindi usa ' e non "

Non dimenticare quello che gpb01 ti ha detto nel messaggio #12

Ciao,
chiedo scusa…ero convito di aver usato i tag per il CODE, non per il QUOTE.

lat[3] = 'x';

Non dimenticare quello che gpb01

Cercherò di stare piu attento in futuro
grazie a tutti e buon proseguimento.

mario