simulare un analogread tramite serial monitor e tastiera

volevo qualche "indizio" per poter mettere il valore a una variabile (tipo analogRead per intenderci)
tramite la tastiera e il serial monitor,
es inviare tramite tastiera un numero tra 0 e 99 la variabile "x" si associa al numero inviato e lo mantiene
fino a non se ne invia un altro

La questione della lettura dei dati da seriale e del riversamento in variabili contenitore è stata affrontata tantissime volte sul forum, con esempi di ogni tipo. Ti consiglierei una piccola ricerca per trovare tutte le risposte del caso.

mannaggia sembrava una "cosa da nulla" ma a quanto vedo è abbastanza ostico trasferire un numero a piu cifre da tastiera all'arduino

Ciao....ma non si riesce con il Serial.read() ?
Ho dato un'occhiata nel reference e non sembra così complicato...
Questo è l'esempio di codice riportato:

int incomingByte = 0;	// for incoming serial data

void setup() {
	Serial.begin(9600);	// opens serial port, sets data rate to 9600 bps
}

void loop() {

	// send data only when you receive data:
	if (Serial.available() > 0) {
		// read the incoming byte:
		incomingByte = Serial.read();

		// say what you got:
		Serial.print("I received: ");
		Serial.println(incomingByte, DEC);
	}
}

Sulla seriale viaggiano singoli byte.
Se trasmetti un valore da 0 a 255, quindi contenuto in un byte, non hai problemi: spedisci 1 byte, leggi 1 byte e sei a posto. Se quel byte poi è un char, allora con 65 ottieni "A", con 66 ottieni "B" ecc.
Il problema nasce quando devi trasmettere numeri più grandi, devi scomporre in trasmissione e ricomporre in ricezioni usando singoli byte,.

Sulla seriale viaggiano singoli byte.
Se trasmetti un valore da 0 a 255, quindi contenuto in un byte, non hai problemi: spedisci 1 byte, leggi 1 byte e sei a posto. Se quel byte poi è un char, allora con 65 ottieni "A", con 66 ottieni "B" ecc.
Il problema nasce quando devi trasmettere numeri più grandi, devi scomporre in trasmissione e ricomporre in ricezioni usando singoli byte,.

Quindi con un numero compreso tra 0 e 99 (come dice GINGARDU) non ci dovrebbero essere problemi sfruttando il codice di esempio che c'è nel reference ?

Se scrivi Serial.write(65) ti spedisce il byte 65. Se poi lo interpreti in ricezione come valore (65) o come carattere (A) dipende da te

Ok.

leo72:
Se scrivi Serial.write(65) ti spedisce il byte 65. Se poi lo interpreti in ricezione come valore (65) o come carattere (A) dipende da te

MI chiarisci questo concetto, che io ogni tanto vado in palla con le conversioni?
Io 65 non lo chiamerei un byte, al limite lo chiamarei un byte espresso in forma decimale o anche un esadecimale 0x65 (che poi varrebbe 101), tant'è che lo puoi invece interpretare come char ed assegnargli direttamente il valore decimale.
In definitiva io sarei portato ad affermare che Serial.write(65) spedisce 65 e basta.

se spedisci 65 ti spedisce un byte del valore 65 quindi in binario 1000001
a questo punto se lo leggi dal serial monitor dell'ide lui lo converte in ascii quindi 1000001 -> A, oppure se lo leggi da un altro programma fatto da te puoi scegliere se leggerlo come 1000001, o 65 o A

se invece fai una serial write con "65" allora lui capisce che deve mandare una serie di byte in questo caso 2, uno con il codice ascii del 6 e uno con il codice ascii del 5, allora sul serial monitor verrà visualizzato 65

stefa24:
ciao
per una mia applicazione ho risolto in questo modo

if(Serial.available()>0)

{
   input-char=Serial.read(); 
   }




i caratteri, come mi hanno spiegato nel forum, vengono letti uno alla volta quindi potrebbe essere piu' utile questo



if(Serial.available()>0)
{
   input-char+=Serial.read(); 
   }




stefano

mah sembra strano che possa funzionare perche non vedo come possa distinguere come possa fermarsi dall'associare una serie di numeri da un altra
o ci dovrebbe essere un limite temporale tipo se i numeri vengono inviati entro 100 millisecondi vengono considerati appartenere alla stessa cifra,

oppure il dato dovrebbe contenere un simbolo di inizio e uno di fine tipo *789# per il numero 789

int vet[2] = { -2, -2 };  
int cont = 0;
int x = 0;

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

void loop()
{
  while (Serial.available() > 0)
  {
    vet[cont] = Serial.read()-48;   
    cont++;
    delay(50);
  }
  if(cont > 0)
  {
    cont = 0;
    if (vet[1] == -2)
    {
      x = vet[0];
    }
    else
    {
      x = vet[0] * 10 + vet[1];
    }

    Serial.println(x);
  }
}

con questo codice dovresti risolvere, il serial print finale serve solo per controllare che va tutto bene...è fatto di fretta e solo per numeri di 1-2 cifre...se ti serve più elasticità (ad esempio anche centinaia) è da modificare

ale92:

int vet[2] = { -2, -2 };  

int cont = 0;
int x = 0;

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

void loop()
{
 while (Serial.available() > 0)
 {
   vet[cont] = Serial.read()-48;  
   cont++;
   delay(50);
 }
 if(cont > 0)
 {
   cont = 0;
   if (vet[1] == -2)
   {
     x = vet[0];
   }
   else
   {
     x = vet[0] * 10 + vet[1];
   }

Serial.println(x);
 }
}




con questo codice dovresti risolvere, il serial print finale serve solo per controllare che va tutto bene...è fatto di fretta e solo per numeri di 1-2 cifre...se ti serve più elasticità (ad esempio anche centinaia) è da modificare

ok la faccenda di sottrarre 48 l'avevo intuita e provata anch'io ma mi ero fermato a un solo numero per volta

questa idea e quella giusta e se commenti le righe in modo comprensoibile del lavoro che svolgono comprendiamo dui piu,

ha anche un qualcosa da aggiustare mi pare se metto i numeri da 1 a 9 pare che non funziona bene
invece da 11 a 99 sembra tutto ok

es: se metto un numero a 2 cifre es: 67 e poi metto 1 scrive 17 $)
es: se metto un numero a 2 cifre es: 89 e poi metto 5 scrive 59 $)

mah.. forse non hai afferrato   con questo codice non puoi affibiare quello che scrivi a nulla 
che roba è ?     srivi nella riga sopra e appare nella finestra sotto!!!  sempre nel pc

esatto a quanto pare non ho afferrato pensavo che quello che scrivo lo metto come caratteri nella variabile e lo scrivo nella finestra per controllo scusa se ti ho fatto perdere tempo, grazie per l'analisi

stefano

quello che hai scritto puo funzionare ma solo un carattere/numero per volta
il problema è quando devi inviare 2 o pi caratteri/numeri e temerli assieme anche nell'arduino

es: se metto if Serial.read() == A digitalvrite (13) HIGH

mettendo la A nel serial monitor il led si accende,

se al posto della A voglio mettere 2 lettere o due numeri (o una parola tipo LUCE_SCALE) non funziona piu

per tenere insieme l'invio ho usato questo

...
while(cell.available()>0)
  {
    delay(50);
      incoming_char=Serial.read();
    
       stringOne+=String(incoming_char);
         
    
   } 
Serial.println(stringOne);  //stampa di controllo
...

+= sia con numeri che caratteri

stefano

stefa24:
per tenere insieme l'invio ho usato questo

...

while(cell.available()>0)
  {
    delay(50);
      incoming_char=Serial.read();
   
       stringOne+=String(incoming_char);
         
   
   }
Serial.println(stringOne);  //stampa di controllo
...




+= sia con numeri che caratteri

stefano

purtroppo cosi com'è non mi riesce di provarlo non so se bisogna caricare anche qualche libreria,
per quello che intendo io se nel serial monitor metto 436 e faccio invio stringOne deve prendere il valore 436 se succede questo siamo a cavallo

ciao
puoi provare questo:

#include <string.h>         //Used for string manipulations

char incoming_char=0;//Will hold the incoming character from the Serial Port.
String stringOne;

void setup()
{
  delay(500);  //pausa
  
  Serial.begin(9600);//Initialize serial ports for communication.
 
   delay(500);  //pausa
}

void loop() 
{
//while a character is coming from the terminal to the Arduino
while(Serial.available()>0)
{
  delay(50);
   incoming_char=Serial.read();
     stringOne+=String(incoming_char);
 
     Serial.print(stringOne);  
}
Serial.println(stringOne);

}

oppure questo:

#include <string.h>         //Used for string manipulations

char incoming_char=0;//Will hold the incoming character from the Serial Port.
String stringOne;

void setup()
{
  delay(500);  //pausa
  
  Serial.begin(9600);//Initialize serial ports for communication.
 
   delay(500);  //pausa
}

void loop() 
{
//if a character is coming from the terminal to the Arduino
if(Serial.available()>0)
{
  delay(500);
   incoming_char=Serial.read();
        Serial.print(incoming_char);  
}
}

stefano

stefa24:
ciao
puoi provare questo:

#include <string.h>

oppure questo:
stefano

ok dai li ho provati e mi sa che uno di noi due deve cambiare spacciatore, 8) comunque a parte gli scherzi
grazie per la tua collaborazione, li ho provati il secondo fa piu o meno cosi:
se si scrive un qualcosa esempio, arduino stampa le lettere a 2 a 2 doppie aa rr dd ecc
e po sempre l'ultima in ripetizione associata a incoming_char
incoming_char assume il valore dell'ultima lettera/numero scritto e lo mantiene e non so (almeno io ) che uso se ne puo fare,

la prima cosi com'è stampa e fa assumere alla variabile stringOne quello che immetti nel seria monitor
il che ci siamo quasi a quello che intendevo io all'inizio,

pero non riconosce la fine di una serire di cifre o lettere
se metto 123 stampa 123 se attendo 10 secondi e immetto 567 stampa 123567 e fa sempre cosi $)

dopo un secondo di attesa all'inserimento di una nuova serie di caratteri /cifre dovvrebbe cancellare il vecchio e tenere il nuovo es se metto 123 attendo 1 secondo e metto 445 dovrebbe usare solo 445

comnque mi pare che questo codice e a buon punto
a patto che si inseriscono sempre 3 cifre da 000 a 999
la variabile x assume il valore digitato di volta in volta
forse ha bisogno di qualche piccolo ritocco ancora ma ci siamo

int vet[3] = { -3, -3 };  
int cont= 0 ;
int x = 0;



void setup()
{

  Serial.begin(9600);
}

void loop()
{

 
  while (Serial.available() > 0)
  {
    vet[cont] = Serial.read()-48;   
    cont++;


if (vet[cont] > 9 )  Serial.println("IMMETTERE SOLO NUMERI ");  

 x= vet[0]*100 + vet[1] *10 + vet[2];

  if (cont < 3  )  Serial.println("IMMETTERE SEPRE 3 CIFRE");

 
       Serial.print("vet[0]    "); Serial.println(vet[0]);
       Serial.print("vet[1]    ");Serial.println(vet[1]);
       Serial.print("vet[2]    "); Serial.println(vet[2]);
       
         if (vet[0] < 0 || vet[0] > 9 )  Serial.println("IMMETTERE SOLO NUMERI  0 ");
           if (vet[1] < 0 || vet[1] > 9  )  Serial.println("IMMETTERE SOLO NUMERI  1 ");
             if (vet[2] < 0 || vet[2] > 9  )  Serial.println("IMMETTERE SOLO NUMERI  2 ");
         
        Serial.println(x);
        Serial.println(cont);
   
        

 if (cont >= 3) cont=0;



    }
   
  
  }

ale92:
se spedisci 65 ti spedisce un byte del valore 65 quindi in binario 1000001
a questo punto se lo leggi dal serial monitor dell'ide lui lo converte in ascii quindi 1000001 -> A, oppure se lo leggi da un altro programma fatto da te puoi scegliere se leggerlo come 1000001, o 65 o A

se invece fai una serial write con "65" allora lui capisce che deve mandare una serie di byte in questo caso 2, uno con il codice ascii del 6 e uno con il codice ascii del 5, allora sul serial monitor verrà visualizzato 65

No. Un attimo, stai facendo confusione.
Per spedire "65" come una coppia di byte devi usare Serial.print(65). Se vuoi spedire il valore di un byte, usi proprio Serial.write(65) come ti ho detto.

Numbers are printed using an ASCII character for each digit.

Writes binary data to the serial port.