Pages: 1 2 [3]   Go Down
Author Topic: "estrarre" il punto decimale da un float, come fare?  (Read 4141 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

Scusa gingardu però è difficile capire cosa vuoi fare, nel primo post chiedi di sapere in che posizione numerica si trova la virgola, quindi di conoscere i valori prima della virgola e dopo non ti interessa come scrivi qui:

Quote
cifra1=0  //  non ha il punto decimale
cifra2=0 //  non ha il punto decimale
cifra3=1 //  HA il punto decimale
cifra4=0  //  non ha il punto decimale
cifra5=0  //  non ha il punto decimale
cifra6=0  //  non ha il punto decimale 

quindi qualcuno non approva a convertire il valore in string, però se ti serve sapere la posizione perchè non farlo?

Se poi tu dicessi in sintesi perchè vuoi questo valore, da dove arriva questo numero float,  questa insolita domanda sulla posizione della virgola.... te lo faccio io lo sketch dimmi cosa vuoi fare smiley

ciao



ovviamente le cose le chiedo perche ho intenzione poi di "usarle"  voglio sapere dove si trova la virgola perche il tutto va "inviato" a 6 display 7 segmenti quindi teoricamente dovvrebbe esserre tutto semplice,
ma vedo che all'atto pratico non è cosi,
ora se la variabile assume un valore intero tra zero e 999999  il tutto viene visualizzato correttamente,
(il contenuto della variabile arriva da una lettura di un sensore,  ma questo non vedo che importanza puo avere)

(metto xx per ricordare che il display ha 6 cifre)
se la variabile ha i decimali esempio xx99.99   deve succedere questo

mi deve portare a uno la cifra che ha il punto decimale  e a zero quelle che non c'è l'hanno
attenzione queste variabili che sono che sono chiamate cifra1 cifra2 ...cifra 6   servono solo come "segnali,
potevo benissimo chiamarli mela1 mela2 mela3

cifra1=0  //  non ha il punto decimale
cifra2=0 //  non ha il punto decimale
cifra3=1 //  HA il punto decimale
cifra4=0  //  non ha il punto decimale
cifra5=0  //  non ha il punto decimale
cifra6=0  //  non ha il punto decimale  


è in  piu   mi deve trasformare il numero con decimale in numero intero
in questo caso 99.99 va trasformato in 9999

altro esempio   x123.66

cifra1=0  //  non ha il punto decimale
cifra2=0 //   non ha il punto decimale
cifra3= 0 //  non ha il punto decimale
cifra4=1  //  HA il punto decimale
cifra5=0  //  non ha il punto decimale
cifra6=0  //  non ha il punto decimale  

in questo caso  123.66    va trasformato in 12366  

da notare che
1.1    1.11   1.111  hanno il punto decimale su cifra diversa   precisamente quinta quarta e terza,

invece 1.1    11.1     111.1     1111.1    11111.1    hanno il decimale tutti sulla stessa cifra guardando il display  e precisamente la penultima contando da sinista  (la quinta)
 
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

se è solo la posizione che ti serve
Code:
String stringa = "6546456456457.56720";
byte x; byte c; byte par;
char charBuf[30];

void setup()
{
  Serial.begin(9600);
 
  stringa.toCharArray(charBuf, 40);  
  char *p = charBuf;  
  while (*p != '\0')
  {
    c++;
    if (*p == '.') { par=c; ++p; continue;}          
    ++p;
  }  
 
 //----------------------------------debug-----------------------------------------------
   Serial.println("stringa esaminata " + stringa);
   Serial.println("il punto si trova alla posizione " + (String)(par) + " da sinistra");
   Serial.println("il punto si trova alla posizione " + (String)(c-par+1) + " da destra");  
   Serial.println("totale dei caratteri  " + (String)c);    
}

void loop(){}

ho provato questo codice ma se lo sposto nel loop inizia a "dare i numeri"
potrebbe essere valido  a patto che  puo stare nel loop, e dia sempre lo stesso risultato  se il numero e lo stesso
bisognerebbe anche associare string al numero  (variabile)  da analizzare
Logged


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

Genova
Offline Offline
Faraday Member
**
Karma: 43
Posts: 3486
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

infatti è tutto più semplice se dici che devi inviarli a dei display a 7 seg, ecco perchè volevi il numero prima della virgola!! per accendere il punto!! ...

come sono collegati ad arduino questi display? tutti in parallelo, usi un MAX o un 595?
quanti sono i display? bisognerebbe saperlo per dare una grandezza massima alle variabili.

i pin usati dovrebbero essere 8 + n° ENABLE di ogni display dico bene?

ora penso che sia molto più semplice  smiley-lol dato che c'è una vastità di esempi compresi gli sketch

http://www.sqlskills.com/blogs/paulselec/post/Arduino-cascading-shift-registers-to-drive-7-segment-displays.aspx
http://arduino.cc/forum/index.php/topic,36600.15.html
http://arduino.cc/forum/index.php/topic,95817.0.html
http://tronixstuff.wordpress.com/tag/7-segment/
http://tronixstuff.wordpress.com/2011/07/21/tutorial-arduino-and-the-nxp-saa1064-4-digit-led-display-driver/
http://arduino.cc/playground/Main/DirectDrive88884Digit7SegmentDisplay

« Last Edit: October 11, 2012, 11:45:46 am by pablos » Logged

no comment

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

i display  sono 6  collegatì in parallelo nessun integrato aggiuntivo solo trasistor su i segmenti e sul comune

piu che i display   il problema e il numero

basterebbe che una variabile (tipo byte)   prende il valore della posizione della cifra con la virgola   partendo da destra,
cosi non ci sono frantendimenti.

e una variabile (tipo long)  che prende il valore del numero senza virgola,

es: numero   1.99999

byte a=6;
long b=199999;



es: numero   345.654

byte a=4;
long b=345654;
« Last Edit: October 11, 2012, 05:22:56 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
God Member
*****
Karma: 8
Posts: 691
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i display  sono 6  collegatì in parallelo nessun integrato aggiuntivo solo trasistor su i segmenti e sul comune

piu che i display   il problema e il numero

basterebbe che una variabile (tipo byte)   prende il valore della posizione della cifra con la virgola   partendo da destra,
cosi non ci sono frantendimenti.

e una variabile (tipo long)  che prende il valore del numero senza virgola   senza arrotondare però   smiley-twist,

es: numero   1.99999

byte a=6;
long b=199999;



es: numero   345.654

byte a=4;
long b=345654;
Logged


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

Genova
Offline Offline
Faraday Member
**
Karma: 43
Posts: 3486
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ho capito, ma non ti conviene stabilire 2 decimali  dopo la virgola lasciando il punto sempre acceso al massimo avrai xxxx.00, se stabilisci delle regole si semplifica lo sketch.
Ora non so che valori devi rappresentare, ma se prendi le ultime 2 cifre a destra sai che sono i decimali sempre senza cercare il punto, tutte le cifre che vengono prima del punto possono variare da 1 a 4 cifre

es
1234.56
  989.23
   25.12
     4.00

più o meno uno schema tipo questo


* display7seg_anim_preview.gif (22.8 KB, 333x245 - viewed 26 times.)
« Last Edit: October 11, 2012, 06:24:55 pm by pablos » Logged

no comment

Genova
Offline Offline
Faraday Member
**
Karma: 43
Posts: 3486
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

non so come hai sviluppato il programma fino ad ora e ne che arduino hai.

Per semplificare il processo sarebbe bello prendere ad esempio il gruppo D di pin che sono 8 (D0-D7)
e fare una cosa simile:

Segmento A - Pin 0
Segmento B - Pin 1
Segmento C - Pin 2
Segmento D - Pin 3
Segmento E - Pin 4
Segmento F - Pin 5
Segmento G - Pin 6
Segmento H - Pin 7
Enable displ 1 - pin ...
Enable displ 2 - pin ...
Enable displ 3 - pin ...
....

i valori corrispondenti decodifica BCD
0 => B00111111
1 => B00000110
2 => B01011011
3 => B01001111
4 => B01100110
5 => B01101101
6 => B01111101
7 => B00000111
8 => B01111111
9 => B01101111


Code:
int val[]={B00111111, B00000110, B01011011, B01001111, B01100110, B01101101, B01111101, B00000111, B01111111, B01101111};
byte num[6];

void setup(){
  DDRD = B11111111; //imposto i pin in OUTPUT
}

void loop(){

//-----scomposizione delle cifre in byte da caricare nell'array "num[]"
//...
//...
//...

   for(int i=0; i<7;i++)
  {
    //il numero che possiede la virgola accenderà anche il pin 0  val[numero da rappresentare]+1
    PORTD = val[numero da rappresentare contenuto nell' array es. num[i] ]; //0-9
    delay(1000);
  }
}

ora resta ricavare le cifre singolarmente (le metterei in un array di byte a 6 celle), e pilotare i singoli display, domani ci do un occhio

ciao

« Last Edit: October 12, 2012, 04:05:23 am by pablos » Logged

no comment

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

il lavoro per visualizzare le cifre c'è gia      qualsiasi valore  che assume una certa variabile (x)
viene visualizzata,

quello che sto cercando di fare e di far visualizzare anche numeri con la virgola,

e per far accendere il punto decimale ci vuole un riferimento di qualche tipo
piu che altro bisogna  trovare un sistema   tipo  prendere il numero  es 123.456

se necessario trasformarlo in stringa e contare da destra verso sinistra   fino a trovare la virgola associare il conteggio a una variabile,  questo è gia metà del lavoro

l'altra metà consiste di prendere sempre lo stesso numero  trasfotmarlo in stringa (suppongo)  eliminare   la virgola e ritrasformare   il numero stringa   in numero normale senza virgola tipo lon  123456

un sistema l'avevo trovato ma arduino ha una tendenza ad arrotondare in maniera assurda se metto1.99998  lo ttasforma in 2.00   in automatico  e vanifica tutto
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

sembrache ho risolto   smiley-cool  
il float  xx viene trasformato in stringa dalla prima parte del codice
la seconda parte del codice che il codice postato da   pablos    aggiustato  (o massacrato)  da me
trova la posizione della virgola partendo da destra

questa parte


    if (posizione == 1 ) ff=xx*1;    
     if (posizione == 2 ) ff=xx*10;
     if (posizione == 3 ) ff=xx*100;
     if (posizione == 4 ) ff=xx*1000;
     if (posizione == 5 ) ff=xx*10000;
     if (posizione == 6 ) ff=xx*100000;
    

con l'aiuto   della posizione virgola ff  (long)  prende il valore   di xx  moltiplicato  che significa
avere xx numero   senza virgola  e senza quei maledetti arrotondamenti  che di solito fa il float  smiley-twist

ho aggiunto   un "segnale "  se il float è minore si uno (se è minore gli viene sommato uno e poi gli viene sottratto in "sede opportuna"

l'ho testato un po e sembra reggere anche con float 3,99999  scrive giusto  smiley-cool  è ancora da testare a fondo però


Code:

String stringa ;
byte x; byte c; byte par;
char charBuf[9];
byte   posizione ;
float xx;
long ff;
byte segnalazero = 0;
void setup()
{
  Serial.begin(9600);
}

void loop(){
  
        xx =3.7;   //float da trattare
  
 
  if (xx<1) xx=xx+1, segnalazero = 1;
  
  
   char buffer[9];
char *result;
float number=xx;  //xx e il numero float che viene convertito instring con il nome result
result = dtostrf(number, 0, 5, buffer);
//Serial.println(result);
//result = dtostrf(number, 4, 5, buffer);
//Serial.println(result);
 
delay (1000);
  stringa = result;
  stringa.toCharArray(charBuf, 9);  
  char *p = charBuf;  
  while (*p != '\0')
  {
    c++;
    if (*p == '.') { par=c; ++p; continue;}          
    ++p;
  }  
 posizione=(c-par+1);
 
//----------------------------------debug-----------------------------------------------
   Serial.println("stringa esaminata " + stringa);
  
       Serial.print("posizione virgola    " );
          Serial.println(posizione);
         //Serial.println(millis());
    // c=0;
     if (posizione == 1 ) ff=xx*1;    
     if (posizione == 2 ) ff=xx*10;
     if (posizione == 3 ) ff=xx*100;
     if (posizione == 4 ) ff=xx*1000;
     if (posizione == 5 ) ff=xx*10000;
     if (posizione == 6 ) ff=xx*100000;
    
      Serial.print("NUMERO INTRERO    "  );
       Serial.println(ff);
       Serial.print("segnalazero   "  );
      
       Serial.println(segnalazero );
        Serial.println("     "  );
    }
« Last Edit: October 12, 2012, 06:57:14 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...

0
Offline Offline
Shannon Member
****
Karma: 136
Posts: 10525
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

anzichè fare

 if (posizione == 1 ) ff=xx*1;    

etc..
non puoi usare una formula?

ff=xx*Math.pow(10, posizione-1);  //pow è l'elevazione a potenza (base, esponente). un numero alla 0 è = ad 1
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Pages: 1 2 [3]   Go Up
Jump to: