Diferència entre revisions de la pàgina «Transmissió d'un número real de tipus IEEE-754 (4 bytes) i llur recuperació a NodeRED»
(Hi ha 18 revisions intermèdies del mateix usuari que no es mostren) | |||
Línia 1: | Línia 1: | ||
− | = Transmissió d'un nombre real IEEE-754 = | + | = Transmissió d'un nombre real en format IEEE-754 = |
== Representació d'un nombre real (tipus ''float'' en C de 4 bytes) en format IEEE-754 == | == Representació d'un nombre real (tipus ''float'' en C de 4 bytes) en format IEEE-754 == | ||
[https://www.geeksforgeeks.org/ieee-standard-754-floating-point-numbers/ IEEE Standard 754 Floating Point Numbers] | [https://www.geeksforgeeks.org/ieee-standard-754-floating-point-numbers/ IEEE Standard 754 Floating Point Numbers] | ||
Línia 12: | Línia 12: | ||
#define N_DATA_BYTES 4 | #define N_DATA_BYTES 4 | ||
− | '''union uFloat{ | + | '''union uFloat{''' |
− | float f; | + | '''float f;''' |
− | unsigned char uc[4]; | + | '''unsigned char uc[4];''' |
− | };''' | + | '''};''' |
− | static uint8_t mydata[N_DATA_BYTES]; | + | '''static uint8_t mydata[N_DATA_BYTES];''' |
void vVisualitzacioFloatEnBytes(float fNum){ | void vVisualitzacioFloatEnBytes(float fNum){ | ||
Línia 31: | Línia 31: | ||
Serial.println(); | Serial.println(); | ||
} | } | ||
+ | |||
+ | Exemple fent-ne ús: [https://www.binefa.cat/training/codes/esp32/lora/IoT-02-22_ttn-otaa_dam_02_float.zip IoT-02-22_ttn-otaa_dam_02_float.ino] | ||
[http://www.xtec.cat/formaciotic/ateneu_historic/materials/td97/d97m7/d97m7te.htm Per si us cal repassar la diferència entre una '''unió''' i una '''estructura''' en C] (Cerqueu la imatge que clarifica la diferència) | [http://www.xtec.cat/formaciotic/ateneu_historic/materials/td97/d97m7/d97m7te.htm 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 | + | = Recuperació d'un nombre real a NodeRED = |
== Instal·lació del node ''node-red-contrib-float'' == | == Instal·lació del node ''node-red-contrib-float'' == | ||
Node [https://flows.nodered.org/node/node-red-contrib-float 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''. | Node [https://flows.nodered.org/node/node-red-contrib-float 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''. | ||
Línia 41: | Línia 43: | ||
[[Image:Ieee754NodeRED.png|center|Flux descodificant IEEE-754]] | [[Image:Ieee754NodeRED.png|center|Flux descodificant IEEE-754]] | ||
− | El flux de NodeRED superior el podeu descarregar aquí: [https://www.binefa.cat/training/codes/nodered/exempleDescodificantIEEE754.json Arxiu ''exempleDescodificantIEEE754.json'' amb un flux de NodeRED com a exemple de descodificació IEEE-754] | + | El flux de NodeRED superior el podeu descarregar aquí: [https://www.binefa.cat/training/codes/nodered/exempleDescodificantIEEE754.json 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'' === | ||
+ | [[Image:Ieee754NodeRedInjeccio.png|center|Flux descodificant IEEE-754]] | ||
+ | |||
+ | === Funció ''n -> 2 decimals'' === | ||
+ | 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]'' === | ||
+ | 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'' === | ||
+ | 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 = | ||
+ | == Exemple de conversió de tres nombres reals a 12 bytes (3 x 4 bytes) == | ||
+ | #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: [https://www.binefa.cat/training/codes/esp32/lora/IoT-02-22_ttn-otaa_dam_03_floats.zip IoT-02-22_ttn-otaa_dam_03_floats.ino] | ||
+ | |||
+ | = Recuperació de tres nombres reals a NodeRED = | ||
+ | [[Image:Ieee754NodeRedTresFloat.png|center|Flux descodificant tres nombres reals IEEE-754]] | ||
+ | |||
+ | El flux de NodeRED superior el podeu descarregar aquí: [https://www.binefa.cat/training/codes/nodered/exempleDescodificantIEEE754_3reals.json 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)'' == | ||
+ | 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'' == | ||
+ | msg.payload = msg.payload.uplink_message.frm_payload; | ||
+ | return msg; |
Revisió de 20:31, 6 feb 2022
Contingut
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
Enllaç a un codificador / descodificador de nombres reals IEEE-754 (Codi a GitHub d'en Ray Toal)
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]
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]
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]
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;