Writing and reading floats

Asked by hchagnot

Hi,

I tried to adapt the code I found in the thread "Reading floats" to write floats but it doesn't work. Here is a part of my code:

//------------------------------------------------
// Calling part
//------------------------------------------------
int addr = 0x98;
int nbWords = 2;
float floatValue = 27.11;
int ret = writeFloatValue(addr, nbWords, floatValue);

//------------------------------------------------
// writeFloatValue method
//------------------------------------------------
int writeFloatValue(int startingAddress, int nbWordsToWrite, float value) {
 int *source = convertFloatToTwo16BitWords(value);
 return writeValue(startingAddress, nbWordsToWrite, source);
}

// -------------------------------------------------------------------------
// Converts a float into two 16bit words.
// -------------------------------------------------------------------------
int* convertFloatToTwo16BitWords(float real) {

 int IEEE; // IEEE 754 32bit float data
 int LSW; // Least Significant Word 16bit of IEEE
 int MSW; // Most Significant Word 16bit of IEEE

 IEEE = *((int *)&real);
 LSW = IEEE << 16;
 LSW = LSW >> 16;
 MSW = IEEE >> 16;

 printf("IEEE = %d\n", IEEE);
 printf("LSW = %d\n", LSW);
 printf("MSW = %d\n", MSW);

 int *result = (int *)malloc(2 * sizeof(int));
 memset(result, 0, 2 * sizeof(int));
 result[0] = MSW;
 result[1] = LSW;
 return result;
}

// -------------------------------------------------------------------------
// Writes the values in the slave from the array given in argument
// -------------------------------------------------------------------------
int writeValue(int startingAddress, int nbWordsToWrite, uint16_t *source) {
 printf("Writing values: ");
 int i;
 for (i=0; i < nbWordsToWrite; i++) {
  printf("0x%X ", source[i]);
 }
 printf("at address 0x%X\n", startingAddress);

 // Trigger the write
 triggerWriteModbus(&modbusParameters, slave);
 // Write
 int ret = writeModbus(&modbusParameters, slave, startingAddress, nbWordsToWrite, source);
 if (ret != nbWordsToWrite) {
  printf("\tError while writing %d words at address 0x%X (%d)\n", nbWordsToWrite, startingAddress, ret);
  return -1;
 }
 printf("\tWrites %d words at address 0x%X\n", nbWordsToWrite, startingAddress);
 waitAWhile();
 return 0;
}

Here is the output I got:

Writing float value: 27.110001
at address 0x98
IEEE = 1104732488
LSW = -7864
MSW = 16856

Any help ?
Hélène

Question information

Language:
English Edit question
Status:
Answered
For:
libmodbus Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
Launchpad Janitor (janitor) said :
#1

This question was expired because it remained in the 'Open' state without activity for the last 15 days.

Revision history for this message
Stéphane Raimbault (sra) said :
#2

The latest version of libmodbus (no tarball yet, get the code from BZR trunk) contains an API to read/write float numbers.

Revision history for this message
Craig (craig-cigasmachine) said :
#3

In the trunk, shouldn't the words be reversed?

i = (((uint32_t)src[1]) << 16) + src[0];

Revision history for this message
Stéphane Raimbault (sra) said :
#4

The order used by libmodbus seems to be the most common. Other libraries have worked around this problem by providing handy functions to swap/reverse bytes for various float formats (but you need to know which one to use...). Feel free to submit patch with macro/functions in this goal if you want.

Can you help with this problem?

Provide an answer of your own, or ask hchagnot for more information if necessary.

To post a message you must log in.