You are not logged in.
Pages: 1
Topic closed
Now that I've got my RPi reading values from my PLC (awesome) I need to convert them into something useful. The values in the PLC are stored in a mix of HEX and BCD values (common to most HMIs).
Example - I'm reading line pressure via the MTM block from the Modbus Slave as a 16 bit register. The value received is decimal 4633 = binary 0001 0010 0001 1001. In BCD this converts to the actual line pressure of 1219 (each digit is represented by its respective 4 bits).
Is there any easy way to specify or convert bases in Rex? I've been digging but not found anything yet.
Thanks!
Offline
In a REXLANG block you can do something like this by shifting/masking the bits.
pressure = ((input & 0x0F) + ((input>>4 & 0x0F)*10) + ((input>>8 & 0x0F)*100) + ((input>>12 & 0x0F)*1000));
I did not test the code but I guess you got the idea...
Last edited by scoobsalamander (2016-05-04 07:35:29)
Offline
Thumbs up scoobsalamander! And here is how to do it using function blocks.
The principle is the same: Take the four bits, convert it to decimal numbers and multiply it by 1, 10, 100 and 1000 respectively.
There are two approaches to obtaining the binary form of a Modbus register. The first one is faster but a bit tricky for the first use, that's why I included both of them.
Here is the mdl file.
Monarco HAT for Raspberry Pi - Lightweight I/O for monitoring, archiving and control.
Raspberry Pi in industrial automation!
Offline
Here a tested example for four signals.....
/************************************************************
*
* REXLANG - BCD to INT
*
*************************************************************/
long input(0) input_u0;
long input(1) input_u1;
long input(2) input_u2;
long input(3) input_u3;
double output(0) output_y0;
double output(1) output_y1;
double output(2) output_y2;
double output(3) output_y3;
long init(void)
{
return 0;
}
long main(void)
{
output_y0 = ((input_u0 & 0x0F) + ((input_u0>>4 & 0x0F)*10) + ((input_u0>>8 & 0x0F)*100) + ((input_u0>>12 & 0x0F)*1000));
output_y1 = ((input_u1 & 0x0F) + ((input_u1>>4 & 0x0F)*10) + ((input_u1>>8 & 0x0F)*100) + ((input_u1>>12 & 0x0F)*1000));
output_y2 = ((input_u2 & 0x0F) + ((input_u2>>4 & 0x0F)*10) + ((input_u2>>8 & 0x0F)*100) + ((input_u2>>12 & 0x0F)*1000));
output_y3 = ((input_u3 & 0x0F) + ((input_u3>>4 & 0x0F)*10) + ((input_u3>>8 & 0x0F)*100) + ((input_u3>>12 & 0x0F)*1000));
return 0;
}
long exit(void)
{
return 0;
}
Offline
long main(void) { output_y0 = ((input_u0 & 0x0F) + ((input_u0>>4 & 0x0F)*10) + ((input_u0>>8 & 0x0F)*100) + ((input_u0>>12 & 0x0F)*1000)); output_y1 = ((input_u1 & 0x0F) + ((input_u1>>4 & 0x0F)*10) + ((input_u1>>8 & 0x0F)*100) + ((input_u1>>12 & 0x0F)*1000)); output_y2 = ((input_u2 & 0x0F) + ((input_u2>>4 & 0x0F)*10) + ((input_u2>>8 & 0x0F)*100) + ((input_u2>>12 & 0x0F)*1000)); output_y3 = ((input_u3 & 0x0F) + ((input_u3>>4 & 0x0F)*10) + ((input_u3>>8 & 0x0F)*100) + ((input_u3>>12 & 0x0F)*1000)); return 0; }
Isn't it possible to implement a function for that?
Offline
Should be possible, maybe you can put your inputs in an array and iterate over it.
Offline
Isn't it possible to implement a function for that?
Yes it is possible (and recommended!). Find the code below:
/************************************************************
*
* REXLANG - BCD to DOUBLE
*
*************************************************************/
long input(0) input_u0;
long input(1) input_u1;
long input(2) input_u2;
long input(3) input_u3;
double output(0) output_y0;
double output(1) output_y1;
double output(2) output_y2;
double output(3) output_y3;
double bcd2double(long bcd)
{
return ((bcd & 0x0F) + ((bcd>>4 & 0x0F)*10) + ((bcd>>8 & 0x0F)*100) + ((bcd>>12 & 0x0F)*1000));
}
long init(void)
{
return 0;
}
long main(void)
{
output_y0 = bcd2double(input_u0);
output_y1 = bcd2double(input_u1);
output_y2 = bcd2double(input_u2);
output_y3 = bcd2double(input_u3);
return 0;
}
long exit(void)
{
return 0;
}
Monarco HAT for Raspberry Pi - Lightweight I/O for monitoring, archiving and control.
Raspberry Pi in industrial automation!
Offline
@jaroslav_sobota : is it possible to put all the values from the inputs in one 'long' array? I tried but it didn't want to compile....maybe I used the wrong syntax.....
Last edited by scoobsalamander (2016-05-04 17:34:20)
Offline
Tried all three methods, didn't get the INHEXD block working but BDHEXD worked and scoobsalamander/ jaroslav code/function work great!
Offline
Pages: 1
Topic closed