Go Down

Topic: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial (Read 15266 times) previous topic - next topic

danyevo

Ciao come fai a far capire al mega chi degli arduini a inviato la temperatura?

gpb01


@Guglielmo
ParseInt e Parsefloat sono, mi pare, nella classe stream, quindi richiamabili anche dalla softserial.
Comunque sarebbe da verificare.


Paolo ... prima di scrivere .. avevo già provato ... mi dice che in SoftwareSerial non esiste la funzione :( .


Se ragionate così allora tutto il core di Arduino è "diseducativo" e si dovrebbero programmare i micro in puro ANSI C.


Buona parte LO E'  ]:D
Tanto è vero che molti, appena decidono di avvicinarsi ad un altra MCU ... vanno "nel pallone" ...  XD

Guglielmo

Edit : Avevo scritto male ... effettivamente parseFloat funziona ;)
Search is Your friend ... or I am Your enemy !

gpb01


Ciao come fai a far capire al mega chi degli arduini a inviato la temperatura?


Basta ch prima dei dati invii un identificativo della board ... in pratica costruisci una struttura in cui c'è "l'indirizzo" del mittente ed "il messaggio" e poi trasmetti il tutto ;)

Guglielmo
Search is Your friend ... or I am Your enemy !

danyevo


danyevo

Per identificare l'arduino che invia la temperatura potrebbe fare così:
Code: [Select]

stringa0 += char('a');  (a) è l'indirizzo
stringa0 += int(t1);  (t1) e la variabile dove è scritta la temperatura
Serial.println(stringa0)  invia la stringa

Giusto..

gpb01


Ma perche usa la libreria softwareserial?


Perché ... ha SEI seriali da gestire e la Mega ne ha fisicamente solo tre ...  :smiley-mr-green:

Ovviamente, con un po' di esperienza, avrebbe potuto semplificare il progetto ...
...  ad esempio usando una sola linea RS485 (con gli appositi adattatori) collegata ad una sola delle seriali della MEGA e da software avrebbe potuto implementare un protocollo di "polling" ... ma magari ci arriverà in futuro ... ora mi sembra veramente agli inizi ... :)

Guglielmo
Search is Your friend ... or I am Your enemy !

danyevo

non è possibile utilizzare una porta seriale  e collegare tutti gli arduini li?
tutti i tx degli arduini vanno nel rx del mega, tutti i rx degli arduini i vanno nel tx del mega
magari sincronizandoli che trasmettono prima uno poi l'altro e così via
magari il mega quando riceve i dati dal primo invia i dati per far partire il secondo poi il terzo ecc ecc

gpb01

NO, non è possibile mettere in parallelo così le porte seriali.

Guglielmo
Search is Your friend ... or I am Your enemy !

astrobeed


NO, non è possibile mettere in parallelo così le porte seriali.


Direttamente no, i TX  sono degli out e metterli brutalmente in parallelo vuol dire fare un corto, però un modo semplice per mettere in parallelo delle UART c'è.
Tenuto conto che lo stato di idle della seriale è 1 logico basta appendere il RX al +5V con una pullup da 10k , mettere in serie ai vari TX un diodo schottky, p.e. un BAT48, collegando il catodo sul TX e i loro anodi in parallello sul RX, in questo modo i vari pin TX sono tra loro isolati e quando uno va a zero logico di conseguenza traina anche l'RX a questo livello consentendo la comunicazione.
Ovviamente con una soluzione di questo tipo è necessario usare un protocollo di comunicazione basato su un address tenendo conto che solo un TX per volta può entrare in funzione, va da se che il TX della Mega deve essere collegato in parallelo su tutti gli RX delle varie UNO.
Scientia potentia est

Etemenanki


... si dovrebbero programmare i micro in puro ANSI C.  ]:D


Perche' vuoi complicarti la vita ? ... vai di binario ... :P XD  ]:D
"Sopravvivere" e' attualmente l'unico lusso che la maggior parte dei Cittadini italiani,
sia pure a costo di enormi sacrifici, riesce ancora a permettersi.

gpb01


Perche' vuoi complicarti la vita ? ... vai di binario ... :P XD  ]:D


Già fatto fanciullo, già fatto ...  ]:D
... e anche per molto tempo, quando all'inizio non potevo permettermi di acquistare neanche un assemblatore (... con quello che negli anni '70 costavano)  XD

Guglielmo
Search is Your friend ... or I am Your enemy !

astrobeed


Già fatto fanciullo, già fatto ...  ]:D


Idem, gli Z80 li programmavo scrivendo direttamente i codici macchina in ram  :smiley-mr-green:
Scientia potentia est

gpb01


Direttamente no, i TX  sono degli out e metterli brutalmente in parallelo vuol dire fare un corto, però un modo semplice per mettere in parallelo delle UART c'è ....


:smiley-mr-green:  Direi che, poveraccio, gli stiamo mettendo una bella confusione in testa ... dato che aveva esordito con :


Come ho già scritto in presentazione riprendo in mano un pò di aggeggi elettronici dopo 15 anni di digiuno ...


Guglielmo
Search is Your friend ... or I am Your enemy !

Marcobz



Direttamente no, i TX  sono degli out e metterli brutalmente in parallelo vuol dire fare un corto, però un modo semplice per mettere in parallelo delle UART c'è ....


:smiley-mr-green:  Direi che, poveraccio, gli stiamo mettendo una bella confusione in testa ... dato che aveva esordito con :


Come ho già scritto in presentazione riprendo in mano un pò di aggeggi elettronici dopo 15 anni di digiuno ...

Credimi.. quello che ha scritto astrobeed è l'unica cosa che capisco veramente... avrei fatto pure io così ma non so esattamente l'hardware come potrebbe reagire...

Comunque.. oggi a un certo punto mi è sceso sangue dal naso a forza di ragionare. Ho iniziato mettendo sulla UNO um mySerial.println così automaticamente mi accoda al valore il carriage. Giusto ?
Code: [Select]
#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11);

float valore = 0.0 ;       

void setup() 
{

  Serial.begin(9600);
  mySerial.begin(4800);
}

void loop()
{
  valore = 29.57;           
   
  if (valore>0){
     mySerial.println(valore);
     Serial.println(valore);
     delay(1000);

}
}

Sulla MEGA ho adattato lo sketch di Guglielmo per la Serialprint e lanciando il tutto sul serial monitor il valore arrivava ma su stringhe lunghissime e incasinate.
Ho abbassato i baud a 4800 .... ho messo su tutti i valori possibili la MAXCHAR che da come ho capito io indica dopo quanti char ricevuti stampa il dato sul monitor. Dopo MILIONI di tentativi sono arrivato a questo
Code: [Select]
#include <SoftwareSerial.h>                    //includo libreria
SoftwareSerial mySerial(10,11);                //assegno pin tx e rx

#define MAXCHAR  1
#define TERCHAR 0x00

char inputString[MAXCHAR + 1];
char inChar;
byte strIndex;


void setup() {
 
  strIndex = 0;
  inputString[strIndex] = 0x00;
 
  Serial.begin(9600);
  mySerial.begin(4800);
}

void loop() {
 
  if (mySerial.available()) {
    inChar = mySerial.read();
    // se si vogliono vedere in HEX i caratteri che si ricevono
    // togliere il commento alla riga seguente
    // Serial.println(inChar, HEX);
    if (inChar == (char) TERCHAR) {
      // è arrivato il carattere terminatore, si puo' elaborare la stringa
      // In questo esempio semplicemente la si stampa ...
      Serial.println(inputString);
      //
      // finito il suo uso la si ripulisce per un uso successivo
      strIndex = 0;
      inputString[strIndex] = 0x00;
    }
    // NON è arrivato il carattere terminatore, si memorizza il carattere ricevuto
    // e si sposta il fine stringa ...
    inputString[strIndex] = inChar;
    strIndex++;
    if (strIndex > MAXCHAR) {
      // ... NON c'è pi` spazio nella stringa ... bisogna elaborarla e svuotarla
      // In questo esempio semplicemente la si stampa ...
      Serial.println(inputString);
      //
      // e la si ripulisce per un uso successivo
      strIndex = 0;
      inputString[strIndex] = 0x00;
    }
  }
}


Purtroppo però il risultato è questo

Code: [Select]
29.57
29.57
29.57
29.57
29.57
299
299 ..57
29.57
9.57
29.57
29.57
29.57
29.57
29.57
29.57
299

.55 ..57
29.57
2957
29.57
29.57
29.57
29.57
29.57
29.57
299
7

 ..57
29.57
29.5
29.57
29.57
29.57
29.57
29.57
29.57
299

22 ..57


Non capisco....

P.S. : il discorso di astro sulle unioni e puntatori mi ha stuzzicato parecchio però meglio che faccio una cosa alla volta !

gpb01


...
Comunque.. oggi a un certo punto mi è sceso sangue dal naso a forza di ragionare. Ho iniziato mettendo sulla UNO um mySerial.println così automaticamente mi accoda al valore il carriage. Giusto ?


"Errare humanum est, perseverare autem diabolicum" ...  ]:D
... devi leggere il REFERENCE ... non puoi inventare ciò che fanno le istruzioni :

Quote
Prints data to the transmit pin of the software serial port, followed by a carriage return and line feed.


... quindi NO, non va bene, perché accoda DUE caratteri ... non per nulla ti avevo scritto di inviare con una print() il carattere 0x0D !

Code: [Select]
if (valore > 0) {
     mySerial.print(valore);
     mySerial.print(0x0D);
     Serial.println(valore);
     delay(1000);
}


Per il resto ...
... la SoftwareSerial la puoi usare tranquillamente a 9600 e ben oltre, non ti serve farla lavorare a 4800, rallenti solo l'invio.

Poi ... per adattare un codice, prima ti devi mettere li e studiarlo con attenzione !

Non ha senso aver messo MAXCHAR a 1 ... MAXCHAR indica quanti caratteri, al massimo, è lunga la tua string, per poter correttamente dimensionare un array di char per riceverla senza sprecare spazio (altrimenti avrei messo nel codice char inputString[255] e non c'erano problemi). Quindi ...
... valuta la lunghezza massima in caratteri del numero che spedirai ed aggiusta MAXCHAR.

Ti chiedo poi, giusto per essere sicuro ... ti sei ricordato vero di mettere tutte le masse in comune ... quella della MEGA e quelle degli Arduino collegati ?

Guglielmo
Search is Your friend ... or I am Your enemy !

Go Up