trasmissione da serial monitor che succede esattamente?

ho uno sketc che inserendo delle cifre da 0 a 99999999 nella riga di comando del serial monitor e premendo invio

una variabile nello sketc assume sempre il valore della cifra inviata senza perdere mai un colpo :slight_smile:

volevo sapere da qualche guru come "vengono spedite" e ricevute le cifre in che ordine sopra tutto al pin rx del 328
che succede di preciso

e infine la cosa più importante, cosa e come scrivere in un altro 328 usato come "trasmettitore" per fare la stessa cosa
es; serial monitor 123 più invio
es altro atmega serial.write (123) serial.write oppure (321) oppure serial.write(1) serial.write(2) serial.write(3) o cosa ?

gingardu:
volevo sapere da qualche guru come "vengono spedite" e ricevute le cifre in che ordine sopra tutto al pin rx del 328
che succede di preciso

Come vengono spedite le cifre dipende da come è fatto il programma che si occupa di questa cosa e di conseguenza anche quello che riceve si deve adeguare.
Ipotizzando che dall'altra parte usi una cosa come il serial monitor di Arduino le cifre vengono spedite codificate in ASCII e nell'ordine di inserimento, ovvero se scrivi "12345" viene spedito prima "1", poi "2",......"5".

es altro atmega serial.write (123) serial.write oppure (321) oppure serial.write(1) serial.write(2) serial.write(3) o cosa ?

La serial.write invia in formato binario, ovvero se scrivi 1 invia 0x01, e al massimo accetta valori compresi tra 0 e 255 (0x00, 0xff), accetta anche un array di valori, sempre tra 0 e 255, e li trasmette in ordine crescente, cioè a partire da array[0] fino a array[n] e restituisce il numero di byte inviati.
Se devi inviare delle stringe alfanumeriche è meglio se usi la classica serial.print().

astrobeed:
La serial.write invia in formato binario, ovvero se scrivi 1 invia 0x0**1**

Ti eri dimenticato una cifra :wink:

leo72:
Ti eri dimenticato una cifra :wink:

Vero, corretto :slight_smile:
Devo ancora smaltire l'overdose di panettone e cotechino :grin:

astrobeed:

gingardu:
volevo sapere da qualche guru come "vengono spedite" e ricevute le cifre in che ordine sopra tutto al pin rx del 328
che succede di preciso

Come vengono spedite le cifre dipende da come è fatto il programma che si occupa di questa cosa e di conseguenza anche quello che riceve si deve adeguare.
Ipotizzando che dall'altra parte usi una cosa come il serial monitor di Arduino le cifre vengono spedite codificate in ASCII e nell'ordine di inserimento, ovvero se scrivi "12345" viene spedito prima "1", poi "2",......"5".

es altro atmega serial.write (123) serial.write oppure (321) oppure serial.write(1) serial.write(2) serial.write(3) o cosa ?

La serial.write invia in formato binario, ovvero se scrivi 1 invia 0x01, e al massimo accetta valori compresi tra 0 e 255 (0x00, 0xff), accetta anche un array di valori, sempre tra 0 e 255, e li trasmette in ordine crescente, cioè a partire da array[0] fino a array[n] e restituisce il numero di byte inviati.
Se devi inviare delle stringe alfanumeriche è meglio se usi la classica serial.print().

:fearful: il serial monitor e una cosa che fa parte dell'ide e se si mette una cifra e si preme invio sulla tastiera del pc si comporterà sempre alla stessa maniera indipendentemente se lo sketc di arduino lo decodifica correttamente o meno

ora chiedo se : e la stessa identica cosa tra mettere 12345 nel serial monitor e mettere serial.print(12345) nello schetc dell'arduino trasmittente ad un altro arduino collegati via seriale

gingardu:
...
ora chiedo se : e la stessa identica cosa tra mettere 12345 nel serial monitor e mettere serial.print(12345) nello schetc dell'arduino trasmittente ad un altro arduino collegati via seriale

SI, purché il serial monitor NON sia impostato per trasmettere dei caratteri aggiuntivi (es. CR, LF o CR LF) a fine stringa (guarda in basso a destra, il primo dei due campi che puoi impostare) :wink:

Guglielmo

gpb01:

gingardu:
...
ora chiedo se : e la stessa identica cosa tra mettere 12345 nel serial monitor e mettere serial.print(12345) nello schetc dell'arduino trasmittente ad un altro arduino collegati via seriale

SI, purché il serial monitor NON sia impostato per trasmettere dei caratteri aggiuntivi (es. CR, LF o CR LF) a fine stringa (guarda in basso a destra, il primo dei due campi che puoi impostare) :wink:

Guglielmo

quindi tra 2 arduino va bene anche il serial.print (12345) e non c'è bisogno di scomporre la cifra in singole cifre e inviarle una per una giusto?

forse è colpa mia :~ che non riesco a spiegarmi,
il serial monitor (nudo è crudo) quando gli scrivo dentro la riga di comando 12345 (dodicimilatrecentoquaratacinque) e poi premo invio nella tastiera suppongo che invierà 5 numeri un numero alla volta (in codifica ascii)
fino a qui siamo d'accordo giusto? :slight_smile:
se voglio far fare la stessa cosa da un arduino all'altro tramite seriale quello che trasmette basta scrivere Serial.print (12345) ; ?
mi pare che dici di no,
bisogna scrivere Serial.print ("12345" ) da come dici :astonished:

quindi il serial monitor tecnicamente "aggiunge le virgolette" a qualsiasi cosa che viene scritto dentro la riga di comando,

quindi non ho speranza di inviare il mio numero/variabile (long 12345 (dodicimilatrecentoquaratacinque) con un semplice Serial.print (12345)

ovviamente è un non senso inviare Serial.print ("12345" ) perché il numero non è mai lo stesso puo essere zero come 99999

che posso fare

vediamo "se ci siamo" 8)
K = 12345 ;
Serial.parseInt( K ); equivale a..... serial.print ( "12345" )

e se K è negativo posso trasformarlo in positivo e aggiungergli 2 milioni,

e nel ricevente
if (numero_ricevuto > 1000000) numero_ricevuto = numero_ricevuto - 2000000 (*-1);

State facendo un gran casino e dicendo un mucchio di cazz..e XD XD XD

LEGGETEVELI I REFERENCE !!! ... "Serial.print() : Prints data to the serial port as human-readable ASCII text" e "..Serial.print(78) gives "78" .."

Guglielmo

Edit : Nid ... stai facendo una gran confusione ... quella che manda i dati in binario è la Serial.write()

gingardu:
quindi tra 2 arduino va bene anche il serial.print (12345) e non c'è bisogno di scomporre la cifra in singole cifre e inviarle una per una giusto?

Si, giusto, da un lato fai la Serial.print(12345) e, dall'altro lato, ricevi i caratteri "12345" ...
... io però ti consiglio di far seguire la tua Serial.print() da una Serial.write(0x0D) che trasmette un CR e che ti permette facilmente, nel tuo loop di ricezione carattere a carattere (... dal lato in cui ricevi i vari caratteri), di capire quando la tua stringa a terminata :wink:

Guglielmo

Guglielmo,

e se l'Arduino trasmittente viene avviato prima del ricevente (o per qualche altro motivo viene saltato il primo carattere), come fa il ricevente ad individuare con certezza l'inizio della stringa, scartando eventualmente via via i caratteri già in coda?
Nell'esempio di gingardu non c'è un protocollo, solo numeri e non si sa a priori quale sia il primo.

@ andreino : Ovvio che se si vuole fare una cosa fatta bene il discorso di complica e di parecchio ...

STX , >------- DATI ------< , ETX, CRC, EOT a cui si risponde ACK o NAK ... e così via ...

... tanto per fare un protocollo proprio banale banale :wink:

Guglielmo

@Guglielmo

Ok!

Allora, se Serial.print(78) equivale a Serial.print("78"), per indicare come carattere di start per esempio il '#', potrei ugualmente scrivere:
Serial.print("#") e Serial.write(35)?

E "dall'altro capo" leggerò sempre '#', se non sbaglio (ora non posso provare...)

(Ascii table)

Si, come da reference ...

... Serial.print() : Prints data to the serial port as human-readable ASCII text.
... Serial.write() : Writes binary data to the serial port.

Quindi ... Serial.print('A') == Serial.write(0x41) :wink:

Guglielmo

Aspetta, è proprio qui che mi perdo... :blush:

il "mio" (DEC) 35 voleva essere "#"

il "tuo" (HEX) 0x41 è "A", che io avrei inviato con write(65)

Allora urge ultima conferma (ormai ci siamo :)):

'A' = (65, DEC) = (0x41, HEX)

nid69ita:

gpb01:
State facendo un gran casino e dicendo un mucchio di cazz..e XD XD XD
LEGGETEVELI I REFERENCE !!! ... "Serial.print() : Prints data to the serial port as human-readable ASCII text" e "..Serial.print(78) gives "78" .."
Guglielmo
Edit : Nid ... stai facendo una gran confusione ... quella che manda i dati in binario è la Serial.write()

Verissimo, scusate, soprattutto @giga. Ha ragione Guglielmo. Per pulizia del thread ho tolto i miei post erronei. Sorry. :blush:

mah.. di solito ci sono almeno 2 modi per raggiungere lo stesso scopo non vedo (fino a che non provo) il motivo perché non dovrebbe funzionare peccato che non ho un altro arduino =( (ma ancora per poco)

se prendo il numero 123456 faccio modulo 10 e separo le cifre e le associo a variabili byte aggiungo 48 (che nel codice ricevente viene sottratto 48) e poi serial.print alle variabili quache accolrgimento/delay per evitare la trasmissione senza sosta ..... chi prova? :wink:

codice ricevente

  long vet[9] = {-2, -2, -2, -2, -2, -2, -2, -2, -2 }; 
long cont = 0;
long serialx = 0;

void setup()
{
  // start serial port at 9600 bps:
  Serial.begin(9600);
}

void loop()
{
  while (Serial.available() > 0)
  {
    vet[cont] = Serial.read()-48;   //trasformo da codice ascii a numero utilizzabile
    cont++;
    delay(60); 
  }
  
   if (vet[0] < -2 || vet[1] < -2 || vet[2] < -2 || vet[3] < -2 || vet[4] < -2 || vet[5] < -2 || vet[6] < -2 || vet[7] < -2 || vet[8] < -2) 
   Serial.println(" ATTENZIONE DEVI  INSERIRE SOLO NUMERI DA 1 A 999999999  ");

   if (vet[0] > 9 || vet[1] > 9 || vet[2] > 9 || vet[3] > 9 || vet[4] > 9 || vet[5] > 9 || vet[6] > 9 || vet[7] > 9 || vet[8] > 9) 
   Serial.println("   ATTENZIONE DEVI  INSERIRE SOLO NUMERI DA 1 A 999999999  ");
   


  if(cont > 0) //se ho letto qualcosa fai la conversione altrimenti niente
  {
    cont = 0;
    
    
      if (vet[8] == -2 && vet[7] == -2 && vet[6] == -2 &&  vet[5] ==  -2  && vet[4] ==  -2  && vet[3] ==  -2  && vet[2] ==  -2  && vet[1] ==  -2 ) 
                                                                                // in tutti gli if a seguire viene verificato se i numeri
    {                                                                         // piu a sx sono tutti a zero  e vengono usati quelli piu a destra
      serialx = vet[0];                                                           // cosi non ciene visualizzato il loro stato = 0
    }
    else
    
    if (vet[8] == -2 && vet[7] == -2 && vet[6] == -2 && vet[5] ==  -2  && vet[4] ==  -2  && vet[3] ==  -2  && vet[2] ==  -2 ) //  
    {
      serialx = (vet[0]* 10 +   vet[1]    );
    }
    else
    if  (vet[8] == -2 && vet[7] == -2 && vet[6] == -2 &&  vet[5] ==  -2  && vet[4] ==  -2  && vet[3] ==  -2 ) //
    {
      serialx = (vet[0] * 100 + vet[1]* 10+ vet[2]);
    } 
    else
    if  (vet[8] == -2 && vet[7] == -2 && vet[6] == -2 && vet[5] ==  -2  && vet[4] ==  -2  )
    {
      serialx = (vet[0] * 1000 + vet[1] * 100 + vet[2]* 10 + vet[3]);  
      } else
      if  (vet[8] == -2 && vet[7] == -2 && vet[6] == -2 && vet[5] ==  -2   )
      {
      serialx = (vet[0] * 10000 + vet[1] * 1000 + vet[2]* 100 + vet[3]* 10 + vet[4]);  
      
      } else
       if  (vet[8] == -2 && vet[7] == -2 && vet[6] == -2 )
      {
      serialx = (vet[0] * 100000 + vet[1] * 10000 + vet[2]* 1000 + vet[3]* 100 + vet[4]* 10 + vet[5]);  
      
      } else 
       
        if  (vet[8] == -2 && vet[7] == -2 )
      {
      serialx = (vet[0] * 1000000 + vet[1] * 100000 + vet[2]* 10000 + vet[3]* 1000 + vet[4]* 100 + vet[5]* 10+ vet[6]);  
      
      } else  
       
          if  (vet[8] == -2 )
      {
      serialx = (vet[0] * 10000000 + vet[1] * 1000000 + vet[2]* 100000 + vet[3]* 10000 + vet[4]* 1000 + vet[5]* 100 + vet[6]* 10+ vet[6]);  
      
      } else 
       
       
       
 serialx = (vet[0] * 100000000 + vet[1] * 10000000 + vet[2]* 1000000 + vet[3]* 100000 + vet[4]* 10000 + vet[5]* 1000 + vet[6]* 100 + vet[7] * 10 + vet[8]); 
       
      
 if (vet[0] < -2 || vet[1] < -2 || vet[2] < -2 || vet[3] < -2 || vet[4] < -2 || vet[5] < -2 || vet[6] < -2 || vet[7] < -2 || vet[8] < -2 ) serialx = 0;
 if (vet[0] > 9 || vet[1] > 9 || vet[2] > 9 || vet[3] > 9 || vet[4] > 9 || vet[5] > 9 || vet[6] > 9 || vet[7] > 9 || vet[8] > 9)  serialx = 0;
 
 if (serialx == -2 || serialx== -1) serialx=0; //messo per evitare di prendere il punto come valido -2   e lo / -1
          
     Serial.println( vet[0]);
     Serial.println( vet[1]);
     Serial.println( vet[2]);
     Serial.println( vet[3]);
     Serial.println( vet[4]);
     Serial.println( vet[5]);
     Serial.println( vet[6]);
     Serial.println( vet[7]);
     Serial.println( vet[8]);
     
 if (vet[0] >= -2 && vet[1]  >= -2 &&  vet[2]  >= -2 &&  vet[3] >= -2 && vet[4] >= -2 && vet[5] >= -2 && vet[6] >= -2 && vet[7] >= -2 && vet[8] >= -2 &&
  vet[0] <= 9 && vet[1] <= 9 &&  vet[2] <= 9 &&  vet[3] <= 9 &&  vet[4] <= 9 &&  vet[5] <= 9 &&  vet[6] <= 9 &&  vet[7] <= 9 &&  vet[8] <= 9 ) 
     Serial.println(" NUMERO INSERITO  "),   Serial.println(serialx);

   if (serialx == 0)   Serial.println(" REINSERISCI UN  NUMERO DA 1 A 999999999  ")  ;
          
    

    
    vet[0] = -2;  
    vet[1] = -2;
    vet[2] = -2;
    vet[3] = -2;
    vet[4] = -2; 
    vet[5] = -2; 
    vet[6] = -2; 
    vet[7] = -2;
    vet[8] = -2;       
  }

}

Senza offesa, ma non si può guardare :sweat_smile:
Usi un array di long, poi fai una serie di check con catene di if, moltiplicazioni.. una cosa COMPLICATISSIMA per un compito molto più semplice di quel che non è.

leo72:
Senza offesa, ma non si può guardare :sweat_smile:

+1

... come complicarsi la vita quando non serve ]:smiley: ]:smiley: ]:smiley:

Guglielmo

Non ho capito bene qual'è l'obbiettivo, penso che si voglia inviare una valore numerico in virgola mobile
e riceverlo dall'altro lato.

Ci sono varie soluzioni, alcune semplici e altre meno, quale usare dipende dall'applicazione e cosa realmente ci aspettiamo di ricevere e dal dispositivo preposto a ricevere.

Se ho un numero, sul quale compio delle operazioni matematiche e voglio spedirlo via seriale al terminale di arduino
dovrei poter usare il metodo size_t Print::println(double num, int digits) che viene ereditato da Serial e quindi scrivere Serial.print(22.22, 4) dove:
@int digit dovrebbe essere il numero massimo di cifre dopo la virgola.

Ciò che viene spedito è una rappresentazione ASCII dei @double num e viene terminato da un carattere 'nl' (new line).

Chi riceve quindi opera con una collezione di caratteri ASCII che rappresentano un numero, sul quale non possiamo fare operazioni matematiche, ma siamo costretti a convertire il ricevuto in un numero e di questo dobbiamo sapere il tipo, cioè se float o intero.

Se invece vogliamo spedire numeri reali e ricevere numeri reali possiamo farlo ma ora il pranzo è pronto.

@gingardu
Il codice è complesso, poco flessibile e per niente elegante ed efficiente, con questo non vuol dire che è da buttare,
ma che devi valutare se procedere su questa strada o cercare una soluzione più elegante o meglio un pattern conosciuto e collaudato. Se decidi di procedere per la tua strada dovrai rendere il codice elegante, efficiente, semplice, flessibile ecc. e il percorso è lungo ma può dare soddisfazioni e inoltre si impara tanto, solo che poi ti renderai conto che gira e rigira sei arrivato alla soluzione a problemi già conosciuti detti appunto pattern, questo in fase di apprendimento è un percorso da lodare.

Qualunque oggetto informatico è composto da numeri binari, qualunque numero binario può essere inviato via seriale o altro mezzo di trasmissione. La dimensione più piccola che possiamo inviare attraverso la connessione seriale è il byte, cioè 8 bit. Un oggetto di qualunque tipo viene conservato in memoria, questa è composta da cella consecutive da un byte cd, pertanto qualunque oggetto può essere prelevato byte per byte e inviato alla seriale un numero totale di volte tanto quanto è grande l'oggetto.

Il metodo: size_t Print::write(const uint8_t *buffer, size_t size) viene ereditato pubblicamente dalla classe Serial, pertanto lo si può usare per spedire qualunque oggetto via seriale. Posso anche spedire un oggetto di classe utente, cioè una istanza di una mia classe.
Es: Dbase myDbase;
myDbase è istanza oggetto di classe Dbase e pertanto posso spedirlo così:
Serial.write((uint8_t )&myDbase, sizeof(myDbase));
L'operazione di cast (uint8_t
) è necessaria per trasformare il puntatore ad un oggetto myDbase a puntatore a byte.

Se sizeof(myObject) per qualche motivo non ritorna la dimensione reale, l'oggetto verrà: o spedito parzialmente o verranno spedite porzioni di memoria che non appartengono a myObject.

Ora se il ricevente colleziona in un buffer tutti i byte trasmessi correttamente sarà possibile ricostituire l'oggetto myObject che abbiamo inviato. Sarà sufficiente creare un puntatore Dbase myDbase = (Dbase)recvBuffer;
Quello che facciamo è fare il cast di un oggetto array di byte (cioè il buffer) a puntatore di classe Dbase.
Adesso se tutto è andato a buon fine posso usare myDbase. Attenzione che se Dbase ha membri puntatori ad oggetto esterni alla classe Dbase questi punteranno ad aree di memoria che avevano un senso per il trasmittente e non è detto che abbiano un senso per il ricevente.

Per sperimentare si può fare una prova, ma perché tutto abbia un senso dobbiamo creare un protocollo.

Ciao.