Broad casting a floating point variable via CAN Open

Discuss issues and ideas you have to configuring displays with PowerVision
dmeister
Posts: 3
Joined: Wed Nov 28, 2012 10:02 am

Broad casting a floating point variable via CAN Open

Post by dmeister » Fri Aug 07, 2015 12:36 pm

Power Vision has a floating point variable. I am trying to broadcast a decimal number like 0.040 via a CAN Open message. The message contains only 00 00 00 00 in the bytes defined.
Now if the number is 7.040 the message is 07 00 00 00.

So I know my message is being broadcast, but the Murphy device is not writing the decimal (fractional numbers) to the CAN message. So is there a way to write a decimal to the CAN message . I am aware of the IEEE754 conversion formula.
http://www.h-schmidt.net/FloatConverter/IEEE754.html

Can this be done in the Murphy PV 450 or PV 780 or is it impossible till further notice.

Don Meister
stalley
Enovation Controls Development
Enovation Controls Development
Posts: 618
Joined: Tue Mar 18, 2014 12:57 pm

Re: Broad casting a floating point variable via CAN Open

Post by stalley » Fri Aug 07, 2015 1:03 pm

Hello dmeister,

You need to convert floating point value to an unsigned value which can be transmitted in the data of the CAN message. You may also need to convert unsigned data back into a floating point value. These are a couple of scripts you can use to help with the conversions.

Code: Select all

float utof(uint raw)
{
     uint sign;
     int exponent;
     uint mantissa;
     float temp, decimal;
     
     sign = ( raw & 0x80000000 );
     exponent = ( ( raw >> 23 ) & 0xFF ) - 127;
     mantissa = raw & 0x7FFFFF;
    
     temp = 1;
     decimal = 1;
     
     while( !( ( mantissa & 0x7FFFFF) == 0 ) )
     {
           decimal /= 2;
           
           if( ( mantissa & 0x400000 ) == 0x400000 )
           {
                temp += decimal;
           }
           
           mantissa <<= 1;
           mantissa &= 0x7FFFFF;
     }
    
     temp = temp * pow(2, exponent);
     
     if( sign == 0x80000000 )
     {
           temp *= -1;
     }
     
     return temp;
}

uint ftou( float f )
{
     uint u = 0;
     uint sign = 0;
     uint exponent = 0x7F;
     float baseline = 0x02;
     uint mantissa = 0;
     uint mantissa_mask = 0x400000;
     
     if( f == 0 )
     {
           return 0;
     }
     
     if( f < 0 )
     {
           sign = 0x80000000;
           f = abs(f);
     }
     
     while( f < 1 )
     {
           f *= 2;
           exponent--;
     }
     
     while( f >= baseline )
     {
           baseline *= 2;
           exponent++;
     }    
     
     exponent = ( exponent & 0xFF ) << 23;
     
     baseline /= 2;
     f -= baseline;
     
     while( mantissa_mask > 0 )
     {
           baseline /= 2;
           
           if( f >= baseline )
           {
                mantissa |= mantissa_mask;
                f -= baseline;
           }
           
           mantissa_mask >>= 1;
     }
     
     mantissa &= 0x7FFFFF;
     
     u = sign | exponent | mantissa;
     
     return u;
}
There are a couple of posts that might be helpful if you need to convert signed to unsigned also. Please look at the functions that ksaenz provides as these will help you convert a double to an unsigned value that can be transmitted over CAN.

viewtopic.php?f=7&t=992&p=2643&hilit=integer#p2643

viewtopic.php?f=7&t=834&p=2196&hilit=co ... gned#p2196

Thanks for your inquiry. It is possible that others out there might have some ideas for dmeister also...
Sara Talley
Software Engineer
Enovation Controls