2017-09-19 4 views
-8

Ich brauche zu konvertieren Daten, um die Dinge Netzwerk und die Daten zu BytesWie ein Doppel zu einem Hex/Bytes

in müssen zum Senden von Daten zu senden, hin und her über die Dinge, Netzwerk, das Sie brauchen, verwenden Bytes

Einige Funktionen geben einen Schwimmer mit 2 Komma

23,56 oder 4,32

Ich habe große Schwierigkeiten, meine Float zu konvertieren und speichern Sie sie in einem Varaint UUINT8_T meine Daten. Ich habe zu finden, wie mein float Variable

ich eine Schleife wie diese haben zu konvertieren:

/* 
NOTE: 
uinit8_t mydata[64]; 
byte nbMaxCapteurs = 10; 
mesMesures[i][mesCapteur[i].idDuCapteur].valeur => this is a float 
*/ 

memset(mydata, 0xFF, 64); 
uint8_t * ptr = mydata; 
for (byte i = 0; i < nbMaxCapteurs; i++) { 
    if (mesCapteur[i].actif) { 
    *ptr = mesMesures[i][mesCapteur[i].idDuCapteur].valeur; 
    ptr += 15; // How to know the number of step to move the pointer 
    if (i < nbCapteurActif + 1) { 
     *ptr = 0x2C; // virgule 
     ptr += sizeof(char); 
    } 
    } else { 
    *ptr = 0x2C; // virgule pour les capteurs inactifs 
    ptr += sizeof(char); 
    } 
} 
*ptr = '00'; // Close \0 
ptr += sizeof(char); 
printData(); 

Ich bin sehr neu für solche Umwandlungen. Das eigentliche Problem ist hier:

*ptr = mesMesures[i][mesCapteur[i].idDuCapteur].valeur; 

printdata druckt diese:

04 FF FF FF FF FF FF FF FF FF FF FF FF FF FF 2C 18 FF FF FF FF FF FF FF FF FF FF FF FF FF FF 2C CB FF FF FF FF FF FF FF FF FF FF FF FF FF FF 2C A8 FF FF FF FF FF FF FF FF FF FF FF FF FF FF 2C

Aber es sollte bei drucken mindestens dies:

34 2E 33 32 FF FF FF FF FF FF FF FF FF FF 2 FF 18 FF FF FF FF FF FF FF FF FF FF FF FF 2C CB FF FF FF FF FF FF FF FF FF FF FF FF FF 2C A8 FF FF FF FF FF FF FF FF FF FF FF FF FF FF 2C

Da 34 2e 33 32 ist gleich 4,32.

Ich verstehe nicht und weiß nicht, wie ich einen Float-Wert "zusammenführen" und konvertieren kann. Und könntest du mir helfen, den Zeiger nach der Größe des Schwimmers zu bewegen?

Ich bin wirklich mit diesem Thema fest und ich würde wirklich Ihre Hilfe zu schätzen wissen.

+5

Wie viele verschiedene Werte können Ihrer Meinung nach ein 'uint8_t' darstellen? Wie viele Werte gibt es jeweils für zwei Dezimalstellen vor und nach dem Dezimaltrennzeichen? – EOF

+3

Uint8_t ist nur 8 Bit, also nur 256 mögliche Werte. Ein Double mit 1 Ziffer + 2 Dezimalstellen hat 1000 mögliche Werte, also ist es nicht möglich. – stark

+1

Fragen Sie einfach, wie Sie eine Zahl auf 2 Dezimalstellen runden können? Oder fragst du wirklich, es in ein "uint8_t" zu legen? – ikegami

Antwort

3
  • Wenn Sie gegen Null nach zwei Dezimalstellen runden möchten, können Sie die folgenden Befehle verwenden:

    double lum = ((int)(luminosity * 100))/100.0; 
    
  • Wenn Sie zum nächsten (von null rund die Hälfte weg) runden möchten nach zwei Dezimalstellen

    #include <math.h> 
    double lum = round(luminosity * 100)/100.0; 
    

: Orte, können Sie die folgenden Befehle verwenden
  • Wenn Sie andererseits die Helligkeit in 8 Bits so effizient wie möglich speichern möchten, können Sie den folgenden Algorithmus verwenden.

    In diesem Format können Sie Vergleiche und bestimmte Operationen zur Helligkeit vornehmen.

  • Eine andere Möglichkeit, eine Dezimalzahl in eine Ganzzahl zu packen, ist eine Festkommazahl. Dies funktioniert, indem Sie eine Skalierung für alle Ihre Helligkeiten auswählen, wenn Sie Ihr Programm schreiben. Hier sind die Bereiche von einem einige Skalierungen unterstützt:

    uint8_t 
    ======= 
    Scaling Supported range (binary)   Supported range (decimal) 
    ------- ------------------------------- ----------------------------------------- 
    ... 
    B8  [00000000. .. 111111110. ] [0 .. 512) No odd numbers 
    B7  [ 0000000. .. 11111111. ] [0 .. 256) No decimals 
    B6  [ 000000.0 .. 1111111.1 ] [0 .. 128) .0, .5 
    B5  [ 00000.00 .. 111111.11 ] [0 .. 64) .0, .25, .5, .75 
    B4  [ 0000.000 ..  11111.111] [0 .. 32) Almost one full decimal place 
    ... 
    
    int8_t 
    ====== 
    Scaling Supported range (binary)  Supported range (decimal) 
    ------- ------------------------------ -------------------------------------------- 
    ... 
    B8  [10000000. .. 011111110. ] [-256 .. 256) No odd numbers 
    B7  [ 1000000. .. 01111111. ] [-128 .. 128) No decimals 
    B6  [ 100000.0 .. 0111111.1 ] [ -64 .. 64) .0, .5 
    B5  [ 10000.00 .. 011111.11 ] [ -32 .. 32) .0, .25, .5, .75 
    B4  [ 1000.000 .. 01111.111] [ -16 .. 16) Almost one full decimal place 
    ... 
    

    Wie Sie sehen können, nur 8 Bit mit sehr einschränkend ist, und Sie erhalten nicht die gleiche Flexibilität der Bereiche wie die frühere Methode Kommissionierung. Der Vorteil von Festkommazahlen ist, dass Sie arithmetische Funktionen (Addition, Subtraktion, Multiplikation und Division) für Paare von ihnen ausführen können.

+0

C11 Norm-Entwurf n1570: * 6.3 Conversions 6.3.1.4 Echt floating und integer Wenn ein endlicher Wert des realen floating Typ in einen Integer-Typ umgewandelt wird, anders als _Bool, der Bruchteil (dh verworfen wird, ist der Wert abgeschnitten gegen Null). * Beachten Sie hier eher "abgeschnitten" als "gerundet". – EOF

+0

Das OP möchte nicht abschneiden; Das Ergebnis sollte immer noch Dezimalstellen haben. – ikegami

0

(Ich weiß nichts über Arduino)

Die minimale Änderung, die Sie in der Nähe Ihrer Ziele erhalten ist:

double luminosity; 
uint32_t lum; 
lum = (uint32_t)(luminosity * 100); 

Nun wird lum Ihr Wert von hundert multipliziert enthalten, abgerundet.

Statt 23,45 erhalten Sie 2345. Die Verwendung von uint8_t würde Sie zu sehr einschränken, da der Bereich zu klein ist (0-255). Ob du uint16_t und uint32_t hast, weiß ich nicht.

Diese Technik wird als Festpunktarithmetik bezeichnet.

+0

arduino verwendet 8-Bit-Mikro- und 32-Bit-Arthrometrie ist ein bisschen zu teuer dafür. uint16_t ist genug, denke ich (Multiplikationen und Divisionen von 32bit Integer sind fast genauso teuer wie Operationen auf Floats) –

Verwandte Themen