Estoy tratando de averiguar la escala del valor que obtengo de un nodo de lectura modbus, y terminé haciéndolo de la manera difícil. Así que necesito convertir los 4 bytes del búfer a un valor decimal en un nodo de función. De esta manera, puedo ajustar fácilmente los parámetros de escala y modbus manualmente.
Pensé que la forma más fácil sería:
Bytes -> Bits -> (aplicar diferentes parámetros) -> Valor decimal -> aplicar escalado opcional
Y eso es lo que intenté hacer, pero no funciona y no sé por qué. O no hace nada (produce NaN), o node-red simplemente deja de ejecutarse. Y tengo que deshabilitar el flujo de los archivos de nodo rojo. Luego reinicie la frambuesa pi, luego inicie manualmente node-red nuevamente.
var In = msg.buffer; var i; var j; var Bit; var Bits = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; var BitVal8 = [128,64,32,16,8,4,2,1] var BitVal32 = [1,2,4,8,16,32,64,128] var Negative; var Out; //Sjekker om MSB er 1 if (In[0] >= 128) { Negative= true; In[0] -= 128; } //Regner ut verdien av hvert bit i et 32 bit word for (i= 8; i<32;i++) { j = i-1; BitVal32[i]= (BitVal32[j]*2); } //Går gjennom alle 4 bytes (0-3) for (i= 0; i<4; i++) { //Går gjennom alle bits (0-7) og legger de inn rett i 32 bit var for (j=0; j<8; j++) { Bit= (j+1)*(i+1)-1; if ((In[i]/BitVal8[j])>1) { In[i]-= BitVal8[j]; Bits[Bit]=1; } } } //Konverterer 32 bit var til decimal var for (i = 0; i < 32; i++) { if (Bits[i]==1) { Out+=BitVal32[i]; } } //Hvis MSB var 1, negates tallet if (Negative) { Out= Out*-1; } msg.payload = Out; node.status({fill:"blue",shape:"ring",text:msg.topic + ": " + msg.payload}); return msg;Usé estos nodos por un tiempo. Pero no puedo hacer que funcionen con ciertas variables de la unidad modbus. Porque el parámetro modbus es diferente en ellos.
Lea esta página, pero es lo contrario de lo que quiero hacer y no lo entiendo lo suficientemente bien como para aplicarlo a mi situación.
1: Un i++ en el bucle j-for provocó que el nodo rojo fallara algunas veces.
2: La fórmula para calcular en qué bit debería escribir en la var de 32 bits era incorrecta. fue (byte+1)*(bit+1)-1, que funciona en algunos momentos, no en todos. La nueva fórmula es ((Byte+1)*8-8+bit
3: En el último bucle for, agrego el valor de cada bit a la señal de salida. Pero la variable BitValue pasó de pequeña a grande, no de grande a pequeña (era LE, debería ser BE)
Código nuevo y funcional:
var In = msg.buffer; var i; var j; var Bit; var Bits = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; var BitVal8 = [128,64,32,16,8,4,2,1] var BitVal32 = [2147483648] var Negative; var Out= 0; //Sjekker om MSB er 1 if (In[0] >= 128) { Negative= true; In[0] -= 128; } //Regner ut verdien av hvert bit i et 32 bit word for (i= 1; i<32;i++) { j = i-1; BitVal32[i]= (BitVal32[j]/2); } //Går gjennom alle 4 bytes (0-3) for (i= 0; i<4; i++) { //Går gjennom alle bits (0-7) og legger de inn rett i 32 bit var for (j=0; j<8; j++) { Bit= (((i+1)*8)-8+j); if ((In[i]/BitVal8[j])>=1) { In[i]-= BitVal8[j]; Bits[Bit]=1; } } } //Konverterer 32 bit var til decimal var for (i = 0; i < 32; i++) { if (Bits[i]==1) { Out+=BitVal32[i]; } } //Hvis MSB var 1, negates tallet if (Negative) { Out= Out*-1; } msg.payload = Out; node.status({fill:"blue",shape:"ring",text:msg.topic + ": " + msg.payload}); return msg;