Transmissió d'un número real de tipus IEEE-754 (4 bytes) i llur recuperació a NodeRED

De binefa.com
Salta a la navegació Salta a la cerca

Transmissió d'un nombre real en format IEEE-754[modifica]

Representació d'un nombre real (tipus float en C de 4 bytes) en format IEEE-754[modifica]

IEEE Standard 754 Floating Point Numbers

How to convert decimal numbers from base ten to 32 bit single precision IEEE 754 binary floating point standard

Enllaç a un codificador / descodificador de nombres reals IEEE-754 (Codi a GitHub d'en Ray Toal)

Exemple de codificació / descodificació IEEE-754

Exemple de conversió d'un nombre real a 4 bytes[modifica]

Codi en C de l'IDE d'Arduino:

#define N_DATA_BYTES 4

union uFloat{
 float f;
 unsigned char uc[4];
};

static uint8_t mydata[N_DATA_BYTES];

void vVisualitzacioFloatEnBytes(float fNum){
  union uFloat ufA;
  int i,k;

  ufA.f = fNum;
  Serial.print("Vector de bytes: ");
  for(i = N_DATA_BYTES - 1 , k = 0 ; i >= 0 ; i-- , k++ ){
    mydata[k] = ufA.uc[i];
    Serial.print(mydata[k],DEC);Serial.print(" ");
  }
  Serial.println();
}

Exemple fent-ne ús: IoT-02-22_ttn-otaa_dam_02_float.ino

Per si us cal repassar la diferència entre una unió i una estructura en C (Cerqueu la imatge que clarifica la diferència)

Recuperació d'un nombre real a NodeRED[modifica]

Instal·lació del node node-red-contrib-float[modifica]

Node node-red-contrib-float de NodeRED per a convertir números reals en format IEEE-754 apartir d'una cadena de zeros i uns. Instal·leu-ho anant a Menú / Settings / Palette / Install cercant IEEE-754.

Exemple d'ús al NodeRED emprant el node node-red-contrib-float[modifica]

Flux descodificant IEEE-754

El flux de NodeRED superior el podeu descarregar aquí: Arxiu exempleDescodificantIEEE754.json amb un flux importable a NodeRED com a exemple de descodificació IEEE-754

Node d'injecció -12.3 en cadena de 32 zeros i uns[modifica]

Flux descodificant IEEE-754

Funció n -> 2 decimals[modifica]

Per a assegurar que tan sols es visualitzin dos decimals (es multiplica i es divideix per 100):

msg.payload = parseFloat(parseInt(msg.payload * 100))/100;
return msg;

Funció Injecció de -12.35 --> [193,69,153,154][modifica]

Pas dels 4 bytes en base 10 que representen el número real -12.35:

msg.payload = [193,69,153,154];
return msg;

Funció Vector 4 números -> Cad 0 i 1[modifica]

Funció que converteix els quatre bytes del nombre real a una cadena de 32 zeros i uns:

var vector = msg.payload;
var zerosUns = "";
var currentBits = "";
for(var i = 0; i < 4; i++){
   currentBits = vector[i].toString(2);
   while(currentBits.length < 8)
       currentBits = "0" + currentBits;
   zerosUns += currentBits;
}
return [msg,{"payload":zerosUns}];

Transmissió de tres nombres reals en format IEEE-754[modifica]

Exemple de conversió de tres nombres reals a 12 bytes (3 x 4 bytes)[modifica]

#define N_DATA_BYTES 12

#define NUM_FLOAT_A -12.35f
#define NUM_FLOAT_B  12.35f
#define NUM_FLOAT_C -12.30f

union uFloat {
 float f;
 unsigned char uc[4];
};

static uint8_t mydata[N_DATA_BYTES];

void vSetFloatAtFrame(float fValue, unsigned char* ucFrame, int nPos) {
 union uFloat ufA;
 int i, k;

 ufA.f = fValue;
 Serial.print("Vector de bytes: ");
 for (i = 3 , k = 0 ; i >= 0 ; i-- , k++ ) {
   ucFrame[k+nPos] = ufA.uc[i];
   Serial.print(ucFrame[k+nPos], DEC); Serial.print(" ");
 }
 Serial.println();
}

void do_send(osjob_t* j) {
 // Check if there is not a current TX/RX job running
 if (LMIC.opmode & OP_TXRXPEND) {
   Serial.println(F("OP_TXRXPEND, not sending"));
 } else {
   vSetFloatAtFrame(NUM_FLOAT_A,mydata,0);
   vSetFloatAtFrame(NUM_FLOAT_B,mydata,4);
   vSetFloatAtFrame(NUM_FLOAT_C,mydata,8);
   // Prepare upstream data transmission at the next possible time.
   LMIC_setTxData2(1, mydata, N_DATA_BYTES, 0);
   Serial.println(F("Packet queued"));
 }
 // Next TX is scheduled after TX_COMPLETE event.
}

Exemple fent-ne ús: IoT-02-22_ttn-otaa_dam_03_floats.ino

Recuperació de tres nombres reals a NodeRED[modifica]

Flux descodificant tres nombres reals IEEE-754

El flux de NodeRED superior el podeu descarregar aquí: Arxiu exempleDescodificantIEEE754_3reals.json amb un flux importable a NodeRED com a exemple de descodificació de tre nombres reals en format IEEE-754

Funció Rebent 3 floats (12 bytes)[modifica]

var vector = msg.payload;
var currentBits = "";
var zerosUns = ["","",""];

if(vector.length == 12){
   for(var k = 0; k < 3; k++){
       for(var i = 0; i < 4; i++){
           currentBits = vector[i+4*k].toString(2);
           while(currentBits.length < 8)
               currentBits = "0" + currentBits;
           zerosUns[k] += currentBits;
       }
   }
   
   return [{"payload":zerosUns[0]},
           {"payload":zerosUns[1]},
           {"payload":zerosUns[2]}];
}

Funció --> payload[modifica]

msg.payload = msg.payload.uplink_message.frm_payload;
return msg;