Pages: 1 [2]   Go Down
Author Topic: simulare un analogread tramite serial monitor e tastiera  (Read 3232 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
God Member
*****
Karma: 8
Posts: 691
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

per tenere insieme l'invio ho usato questo
Code:
...
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
Logged


Le cose si possono considerare facili in due casi: quando le si conosce bene o quando non le si conosce affatto...

piacenza
Online Online
God Member
*****
Karma: 0
Posts: 707
prima della pazzia c'è la passione
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ciao
puoi provare questo:
Code:
#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:
Code:
#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
Logged


Offline Offline
God Member
*****
Karma: 8
Posts: 691
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ciao
puoi provare questo:
Code:
#include <string.h>       

oppure questo:
stefano

ok  dai li ho provati   e mi sa che uno di noi due deve cambiare spacciatore,  smiley-cool 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  smiley-money

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
Logged


Le cose si possono considerare facili in due casi: quando le si conosce bene o quando non le si conosce affatto...

Offline Offline
God Member
*****
Karma: 8
Posts: 691
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:

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;



    }
   
 
  } 
Logged


Le cose si possono considerare facili in due casi: quando le si conosce bene o quando non le si conosce affatto...

Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 335
Posts: 23134
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
http://arduino.cc/en/Serial/Print
Quote
Numbers are printed using an ASCII character for each digit.

http://arduino.cc/en/Serial/Write
Quote
Writes binary data to the serial port.
Logged


Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 335
Posts: 23134
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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 afferSe scrivi Serial.write(65) ti spedisce il byte 65mare che Serial.write(65) spedisce 65 e basta.

Allora, per spiegarti meglio rielaboro la mia affermazione completandola con le parti volutamente tralasciate:
Quote
Se scrivi Serial.write(65) l'Arduino ti spedisce un dato di tipo byte contenente il valore 65
La seriale spedisce singoli bit ma il tipo di dati più semplice che tratta è il tipo byte. Un byte è un dato ad 8 bit che può contenere un valore numerico che varia da 0 a 255. L'arduino ha un buffer seriale che altro non è che un array di byte. Per spedire un byte, io uso Serial.write, che mi inserisce il byte nel buffer, dal quale poi viene prelevato e spedito sulla seriale. Chiaro, no? Adesso affrontiamo il problema sulla ricezione.

In ricezione si opera sempre a livello di byte: se spedisco un byte, spedisco e ricevo 8 bit. Alla ricezione se inserisco il valore in una variabile di tipo byte, utilizzerò il suo valore numerico. Posso però usare anche il tipo char. Il tipo char è particolare perché nell'ANSI C rappresenta un carattere stampabile. Quindi un carattere rappresentato dal codice ASCII del valore memorizzato. Quindi se il valore 65 lo memorizzo in un byte, avrò solo il "numero" 65. Se lo memorizzo in un char, lo potrò considerare sia come valore (es.: char a=65) sia come carattere (es.: char a='A').
La notazione decimale non cambia la carte in regola ma è solo un modo differente per indicare al compilatore il valore da memorizzare. Così vale per il binario. Insomma, 0x41 = 0b01000001 = 65
Logged


Offline Offline
Jr. Member
**
Karma: 2
Posts: 98
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@GINGARDU
scusa se non ho commentato il codice ma ero di fretta...ho sistemato il programma...bastava riportare il vettore ai valori iniziali dopo il serial print
Code:

int vet[2] = { -2, -2 };  //numero arbitrario, usato per vedere se è stato inserito un numero o no (non so perchè tu abbia messo -3 in quello da tre cifre, il -2 non centra niente con la dimensione dell'array) non ho
//usato -1 perchè significa che non ci sono dati da leggere (secondo la serial available) quindi si poteva fare confusione
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;   //trasformo da codice ascii a numero utilizzabile
    cont++;
    delay(50); //sinceramente non so il motivo tecnico ma l'ho messo perchè mi si è accesa una lampadina, senza la serial available da dei "falsi negativi" cioè legge un byte, poi anche sei hai messo 2 numeri l'istruzione //dice che non c'è più niente da leggere e quindi esce dal while, forse l'esecuzione è troppo veloce per i sui gusti, non so....
  }
  if(cont > 0) //se ho letto qualcosa fai la conversione altrimenti niente
  {
    cont = 0;
    if (vet[1] == -2) //se vet[1] = a -2 cioè il valore iniziale significa che c'era solo un numero da leggere quindi è un numero da 0 a 9
    {
      x = vet[0];
    }
    else
    {
      x = vet[0] * 10 + vet[1]; //altrimenti faccio la formulina perchè è un numero da 10 a 99
    }

    Serial.println(x);
    vet[0] = -2;   //fix per il bug della versione precedente
    vet[1] = -2;
  }
}

...come il precedente...se ti servono 3 cifre ci sono da fare alcune modifiche

@leo72
da quello che leggo nella pagina del write
Serial.write(str)
str: a string to send as a series of bytes
quindi se mando "65" mando 2 byte, quello del 6 e quello de 5
o sto perdendo qualcosa?
Logged

Lamezia Terme
Offline Offline
Shannon Member
****
Karma: 574
Posts: 12679
Le domande di chi vuol imparare rappresentano la sua sete di sapere
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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 afferSe scrivi Serial.write(65) ti spedisce il byte 65mare che Serial.write(65) spedisce 65 e basta.

Allora, per spiegarti meglio rielaboro la mia affermazione completandola con le parti volutamente tralasciate:
Quote
Se scrivi Serial.write(65) l'Arduino ti spedisce un dato di tipo byte contenente il valore 65
La seriale spedisce singoli bit ma il tipo di dati più semplice che tratta è il tipo byte. Un byte è un dato ad 8 bit che può contenere un valore numerico che varia da 0 a 255. L'arduino ha un buffer seriale che altro non è che un array di byte. Per spedire un byte, io uso Serial.write, che mi inserisce il byte nel buffer, dal quale poi viene prelevato e spedito sulla seriale. Chiaro, no? Adesso affrontiamo il problema sulla ricezione.

In ricezione si opera sempre a livello di byte: se spedisco un byte, spedisco e ricevo 8 bit. Alla ricezione se inserisco il valore in una variabile di tipo byte, utilizzerò il suo valore numerico. Posso però usare anche il tipo char. Il tipo char è particolare perché nell'ANSI C rappresenta un carattere stampabile. Quindi un carattere rappresentato dal codice ASCII del valore memorizzato. Quindi se il valore 65 lo memorizzo in un byte, avrò solo il "numero" 65. Se lo memorizzo in un char, lo potrò considerare sia come valore (es.: char a=65) sia come carattere (es.: char a='A').
La notazione decimale non cambia la carte in regola ma è solo un modo differente per indicare al compilatore il valore da memorizzare. Così vale per il binario. Insomma, 0x41 = 0b01000001 = 65
un libro stampato, alla fine la mia principale confisione era tra print e write, me ne rendo conto ora dopo la tua correzione ad Ale92, leggerò con interesse la tua risposta al dubbio che ha sollevato. Grazie smiley
Logged


Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 335
Posts: 23134
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@ale:
Il metodo .write è il metodo "grezzo", nel senso che serve a spedire i dati sempre come byte. Quindi quando spedisci una stringa essa viene scomposta nei singoli byte. Il metodo .print sgrezza invece i dati cercando di spedirli in formato "umano" e può gestire molti più tipi di dato, non ultimo dati formattati con basi differenti. Dipende sempre da cosa devi spedire e come lo devi ricevere.
Se vuoi spedire byte io ti consiglio .write, per spedire dati ad un terminale meglio .print.
Logged


Lamezia Terme
Offline Offline
Shannon Member
****
Karma: 574
Posts: 12679
Le domande di chi vuol imparare rappresentano la sua sete di sapere
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@ale:
Il metodo .write è il metodo "grezzo", nel senso che serve a spedire i dati sempre come byte. Quindi quando spedisci una stringa essa viene scomposta nei singoli byte. Il metodo .print sgrezza invece i dati cercando di spedirli in formato "umano" e può gestire molti più tipi di dato, non ultimo dati formattati con basi differenti. Dipende sempre da cosa devi spedire e come lo devi ricevere.
Se vuoi spedire byte io ti consiglio .write, per spedire dati ad un terminale meglio .print.
però non chiarisci se 65 è un byte o due byte come sostiene lui
Logged


Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 335
Posts: 23134
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

L'ho già chiarito. Più che dire che write spedisce byte, che devo scrivere?  smiley-razz
Io parlo di 65, lui parla di "65"  smiley-wink
Se scrivo Serial.write(65) io spedisco il valore 65.
Se scrivo Serial.print(65) spedisco "65", ossia spedisco il carattere "6" ed il carattere "5", vale a dire i byte 54 e 53.

Cito da: http://arduino.cc/en/Serial/Write
Quote
write()
Description

Writes binary data to the serial port. This data is sent as a byte or series of bytes; to send the characters representing the digits of a number use the print() function instead.

Syntax

Serial.write(val)

(....)
val: a value to send as a single byte

Cito da: http://arduino.cc/en/Serial/Print
Quote
print()
Description

Prints data to the serial port as human-readable ASCII text
. This command can take many forms. Numbers are printed using an ASCII character for each digit. Floats are similarly printed as ASCII digits, defaulting to two decimal places. Bytes are sent as a single character. Characters and strings are sent as is. For example:

    Serial.print(78) gives "78"
Logged


Offline Offline
God Member
*****
Karma: 8
Posts: 691
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:

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

}


se ti serve più elasticità (ad esempio anche centinaia) è da modificare
ho aggiustato il tuo codice (senza comprenderlo al 100%    smiley-cry  )     adesso come digito le cifre da 000  a 999
la variabile prende quel valore,
mi sta venendo la " malsana idea   smiley-cool che si potrebbe usare per attivare/disattivare  tutte le cose in un impianto domotico semplicemente digitando un codice a 3 cifre  o meglio   magari prima si digitano 3 cifre (es: 123) e si attiva un qualcosa per 5 secondi  e finche e attivata si puo inviare il codice per spegnere una luce/altro  magari prima il serial monitor   ti stampa LUCE CANTINA ACCESA  445 X OFF,
si digita 123  e poi subito  445   e la luce si spegne smiley-razz

con un arduino 2 si potrebbe gestire anche un appartamento grande  lo scoglio piu grande e far visualizzare le cose attive in maniera leggibile sul serial monitor senza  bloccare troppo  il micro,
magari un refresh ogni 10 secondi

qualsiasi consiglio e ben accetto
« Last Edit: August 26, 2012, 03:37:51 pm by GINGARDU » Logged


Le cose si possono considerare facili in due casi: quando le si conosce bene o quando non le si conosce affatto...

Offline Offline
Jr. Member
**
Karma: 2
Posts: 98
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ho aggiustato il tuo codice (senza comprenderlo al 100%    smiley-cry  )   
è abbastanza normale...di solito è difficile capire programmi fatti da altri...ognuno pensa in modo diverso e quello che per me è normale per te è arabo e viceversa...se vuoi qualche commento in più dimmi la parte poco chiara e cerco di chiarire

mi sta venendo la " malsana idea   smiley-cool che si potrebbe usare per attivare/disattivare  tutte le cose in un impianto domotico semplicemente digitando un codice a 3 cifre  o meglio   magari prima si digitano 3 cifre (es: 123) e si attiva un qualcosa per 5 secondi  e finche e attivata si puo inviare il codice per spegnere una luce/altro  magari prima il serial monitor   ti stampa LUCE CANTINA ACCESA  445 X OFF,
si digita 123  e poi subito  445   e la luce si spegne smiley-razz

con un arduino 2 si potrebbe gestire anche un appartamento grande  lo scoglio piu grande e far visualizzare le cose attive in maniera leggibile sul serial monitor senza  bloccare troppo  il micro,
magari un refresh ogni 10 secondi

qualsiasi consiglio e ben accetto
sembra quello che succede con i sistemi vocali tipo quello del kinect con la xbox...prima dici xbox (il codice 123) per far capire alla console che vuoi dare un comando poi dici l'oggetto a cui vuoi dare il comando (es Luce cantina o 445) poi dai il parametro per quello oggetto (spenta o off)
trovo che sia comodo per i sistemi con riconoscimento vocale ma visto che tu vuoi fare una cosa scritta forse ci sono metodi più comodi...anche il fatto di togliere il primo comando (xbox o 123) già sarebbe un passo avanti, anche perchè se scrivi qualcosa sul serial monitor è già ovvio che vuoi dare un comando e non c'è bisogno di specificarlo di nuovo
Logged

Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 335
Posts: 23134
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Basterebbe un display LCD 40x4 con un tastierino numerico a fianco, dove uno inserisce i comandi.
Con una password se magari si vuole impedire l'accesso a bambini e ciaccioni  smiley-lol
Sullo stesso display potete riportare anche lo stato dei "servizi" divisi per stanza. Es.: con un menu si scorrono le stanze, poi magari se ne seleziona una e si agisce sui servizi di quella stanza: anzi, a quel punto basta scorrere sulle voci e attivare/disattivare il menu.
Senza computer sempre accesi, senza terminali sempre aperti.
Logged


Offline Offline
God Member
*****
Karma: 8
Posts: 691
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

author=ale92

si, si possono fare molte cose (e tantissime sono state già fatte) personalmente vedo più  arduino per la domotica un po’ come una specie di supervisore/guardiano  che dovrebbe    intervenire solo su richiesta

il doppio codice 123+xxx   era più un modo di evitare  che si attivano/disattivano  cose involontariamente

il tuo codice l'ho modificato cosi aggiungendo la 3° cifra e se viene digitato qualcosa di diverso tipo una lettera o simbolo  porta x a zero e stampa un avviso  

Code:


[code



int vet[3] = { -2, -2, -2 };  //numero arbitrario, usato per vedere se è stato inserito un numero o no (non so perchè tu abbia messo -3 in quello da tre cifre, il -2 non centra niente con la dimensione dell'array) non ho
//usato -1 perchè significa che non ci sono dati da leggere (secondo la serial available) quindi si poteva fare confusione
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;   //trasformo da codice ascii a numero utilizzabile
    cont++;
    delay(50); //sinceramente non so il motivo tecnico ma l'ho messo perchè mi si è accesa una lampadina, senza la serial available da dei "falsi negativi" cioè legge un byte, poi anche sei hai messo 2 numeri l'istruzione //dice che non c'è più niente da leggere e quindi esce dal while, forse l'esecuzione è troppo veloce per i sui gusti, non so....
  }
  
   if (vet[0] < -2 || vet[1] < -2 || vet[2] < -2 )  Serial.println("E' STATO INSERIRTO UN CARATTERE INSERIRE SOLO NUMERI DA 1 A 999  ");

   if (vet[0] > 9 || vet[1] > 9 || vet[2] > 9)  Serial.println("E' STATO INSERIRTO UN CARATTERE  INSERIRE SOLO NUMERI DA 1 A 999  ");
  


  if(cont > 0) //se ho letto qualcosa fai la conversione altrimenti niente
  {
    cont = 0;
    if (vet[1] == -2 && vet[2] == -2) //se vet[1] = a -2 cioè il valore iniziale significa che c'era solo un numero da leggere quindi è un numero da 0 a 9
    {
      x = vet[0];
    }
    else
    if ( vet[2] == -2) //se vet[1] = a -2 cioè il valore iniziale significa che c'era solo un numero da leggere quindi è un numero da 0 a 9
    {
      x = vet[0] * 10 + vet[1];
    }
    else
    {
      x = vet[0] * 100 + vet[1]* 10+ vet[2]; //altrimenti faccio la formulina perchè è un numero da 10 a 99
    }
  
         if (vet[0] < -2 || vet[1] < -2 || vet[2] < -2 ) x =0;
   if (vet[0] > 9 || vet[1] > 9 || vet[2] > 9)  x =0;
    Serial.println(x);
    vet[0] = -2;   //fix per il bug della versione precedente
    vet[1] = -2;
    vet[2] = -2;
  }
}]
« Last Edit: August 30, 2012, 10:38:22 am by GINGARDU » Logged


Le cose si possono considerare facili in due casi: quando le si conosce bene o quando non le si conosce affatto...

Pages: 1 [2]   Go Up
Jump to: