Im trying to figure out the scaling of the value i get from a modbus read node, and ended up doing it the hard way. So i need to convert the 4 bytes from the buffer, to decimal value in a function node. This way i can easily tweak the scaling and modbus parameters manually.
I thought the easiest way would be:
Bytes -> Bits -> (apply different parameters) -> Decimal value -> apply optional scaling
And thats what i tried making, but it does not work and i dont se why. Either it does nothing(outputs NaN), or node-red just stops running. And i have to disable the flow from the node-red files. Then restart the raspberry pi, then manually start node-red again.
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;
I used these nodes for a while. But i cant get them to work with certain variables from the modbus unit. Becuse the modbus parameter is different on them.
Read through this page, but its the opposite of what i want to do and i dont understand it well enough to apply it to my situation.
1: A i++ in the j-for loop caused node red to crash sometimes.
2: The formula to calculate which bit it should write to in the 32 bit var was wrong. was (byte+1)*(bit+1)-1, which works at some times not all. New formula is ((Byte+1)*8-8+bit
3: At the verry last for loop, i add the value of each bit to the output signal. But the BitValue variable went from small to big, not big to small (was LE, should be BE)
New and working code:
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;