Discuss issues and ideas you have to configuring displays with PowerVision
-
Josh.b@ST
- Posts: 18
- Joined: Tue Dec 06, 2011 10:00 am
Post
by Josh.b@ST » Wed Aug 27, 2014 8:11 am
After reading through various posts and trying different methods, i still cannot get my PV450 to receive a signed value correctly over CAN. I am trying to receive a 32 bit signed integer in the following format:
CAN ID: 0x193
Byte 0 = 0C
Byte 1 = FE
Byte 2 = FF
Byte 3 = FF
The variable has a resolution of 0.01 and works in the range of -40.00 to +150.00. With the CAN data set to the values above, i am expecting a value of -5.
Here is my code so far:
Code: Select all
void $e_Convert_Signed$ ()
{
double NewVariable = 0;
double SignedVariable = 0;
smRead(VariableIDs.Limit_TMinusCoolant_Alarm, NewVariable); //read variable received from CAN
SignedVariable = utos(NewVariable); //call function to convert to signed format
smWrite(VariableIDs.Scaled_Coolant_Alarm, (SignedVariable / 100)); //scale to show in format xx.xx
}
double utos( double x ) //convert unsigned to signed
{
uint u;
int s;
u = x;
s = u & 0xFFFF;
x = s;
return x;
}
Has anybody else found a solution that has worked for them? Any ideas, support or advice would be greatly appreciated.
Many thanks in advance.
-
stalley
- Enovation Controls Development
- Posts: 618
- Joined: Tue Mar 18, 2014 12:57 pm
Post
by stalley » Wed Aug 27, 2014 11:30 am
Hi Josh.b,
Have you tried using 0xFFFFFFFF in the utos() function in place of the 0xFFFF?
Sara Talley
Software Engineer
Enovation Controls
-
Josh.b@ST
- Posts: 18
- Joined: Tue Dec 06, 2011 10:00 am
Post
by Josh.b@ST » Thu Aug 28, 2014 3:59 am
Thank you for your response Sara, however when it is set to the value you mention it still does not work. All of my positive values are displayed correctly but as soon as the value goes negative, the variable seems to be set to the maximum value for the displayed numeric field (1500.00).
Please see below for how i have the numeric field set up to display my value.
- Numeric field set up
- PVCS.JPG (13.83 KiB) Viewed 172 times
Many thanks.
stalley wrote:Hi Josh.b,
Have you tried using 0xFFFFFFFF in the utos() function in place of the 0xFFFF?
-
ksaenz
- Enovation Controls Development
- Posts: 263
- Joined: Thu Aug 19, 2010 7:53 am
Post
by ksaenz » Thu Aug 28, 2014 8:45 am
Hi Josh,
I suspected that the int32 was just too big for the double so I broke it in two parts and that seems to work.
- FFCAN.png (25.8 KiB) Viewed 168 times
- script.png (27.31 KiB) Viewed 168 times
- remote diagnostics.png (2.42 KiB) Viewed 168 times
Code: Select all
int utos( uint u ) //convert unsigned to signed
{
int s;
s = u & 0xFFFFFFFF;
return s;
}
//---------------------------------------------------------------------------------------------
// Murphy Scripting
// - Leave EventName as $e_Convert_Signed$ for main script method
//---------------------------------------------------------------------------------------------
void $e_Convert_Signed$ ()
{
uint lsb = 0;
uint msb = 0;
uint UnsignedVariable = 0;
double SignedVariable = 0;
smRead( VariableIDs.lsb, lsb ); //read variable received from CAN
smRead( VariableIDs.msb, msb );
UnsignedVariable = ( msb << 16 ) + lsb;
SignedVariable = utos( UnsignedVariable ); //call function to convert to signed format
smWrite( VariableIDs.SignedVariable, ( SignedVariable / 100 ) ); //scale to show in format xx.xx
}
Regards,
ksaenz
-
Josh.b@ST
- Posts: 18
- Joined: Tue Dec 06, 2011 10:00 am
Post
by Josh.b@ST » Thu Aug 28, 2014 10:05 am
I have also found another workaround which has worked.
Code: Select all
void $e_Convert_Signed$ ()
{
//This will be used to convert received CAN values to signed values
//PV450 cannot receive signed values
double Coolant_Alarm_Temp = 0;
double Coolant_Alarm = 0;
smRead(VariableIDs.Limit_TMinusCoolant_Alarm, Coolant_Alarm_Temp);
if (Coolant_Alarm_Temp > 2147483647)
{
Coolant_Alarm = ((((4294967295 - Coolant_Alarm_Temp) + 1) * -1) / 100);
}
else
{
Coolant_Alarm = (Coolant_Alarm_Temp / 100);
}
smWrite(VariableIDs.Scaled_Coolant_Alarm, Coolant_Alarm);
}
It basically checks to see if the received value is greater than the maximum value of a 32 bit signed value (this means it is signed), we then use the maximum size of a 32 bit unsigned value and take away our received value from it, we add one to use it in the correct number base, multiply by -1 to invert the value and then divide by 100 to put it into the format i require for display purposes (xx.xx).
Hopefully this post with the various solutions will help someone else as well as myself. I will also try splitting up the received value into 2 variables as previously suggested.
Thanks for everyone's help.