Commit 22a68981987f6c42feba5d299fbf0f6ca3ed7cf7
1 parent
77c8c416
New API modbus_read_float() and modbus_write_float() for float values
Showing
5 changed files
with
59 additions
and
1 deletions
NEWS
| 1 | -libmodbus 2.2.0 (2009-06-01) | 1 | +libmodbus 2.2.0 (2009-XX-01) |
| 2 | ============================ | 2 | ============================ |
| 3 | +- New API to read and write float values | ||
| 3 | - New API for slave server (see MIGRATION) | 4 | - New API for slave server (see MIGRATION) |
| 4 | - New slave server able to handle multiple connections | 5 | - New slave server able to handle multiple connections |
| 5 | - Slave only replies to broadcast queries or queries with its slave ID | 6 | - Slave only replies to broadcast queries or queries with its slave ID |
src/modbus.c
| @@ -1964,3 +1964,24 @@ uint8_t get_byte_from_bits(const uint8_t *src, int address, int nb_bits) | @@ -1964,3 +1964,24 @@ uint8_t get_byte_from_bits(const uint8_t *src, int address, int nb_bits) | ||
| 1964 | 1964 | ||
| 1965 | return value; | 1965 | return value; |
| 1966 | } | 1966 | } |
| 1967 | + | ||
| 1968 | +/* Read a float from 4 bytes in Modbus format */ | ||
| 1969 | +float modbus_read_float(const uint16_t *src) | ||
| 1970 | +{ | ||
| 1971 | + float real; | ||
| 1972 | + uint32_t ireal = (src[1] << 16) + src[0]; | ||
| 1973 | + real = *((float *)&ireal); | ||
| 1974 | + | ||
| 1975 | + return real; | ||
| 1976 | +} | ||
| 1977 | + | ||
| 1978 | +/* Write a float to 4 bytes in Modbus format */ | ||
| 1979 | +void modbus_write_float(float real, uint16_t *dest) | ||
| 1980 | +{ | ||
| 1981 | + uint32_t ireal; | ||
| 1982 | + | ||
| 1983 | + ireal = *((uint32_t *)&real); | ||
| 1984 | + /* Implicit mask 0xFFFF */ | ||
| 1985 | + dest[0] = ireal; | ||
| 1986 | + dest[1] = ireal >> 16; | ||
| 1987 | +} |
src/modbus.h
| @@ -344,6 +344,12 @@ void set_bits_from_bytes(uint8_t *dest, int address, int nb_bits, | @@ -344,6 +344,12 @@ void set_bits_from_bytes(uint8_t *dest, int address, int nb_bits, | ||
| 344 | To obtain a full byte, set nb_bits to 8. */ | 344 | To obtain a full byte, set nb_bits to 8. */ |
| 345 | uint8_t get_byte_from_bits(const uint8_t *src, int address, int nb_bits); | 345 | uint8_t get_byte_from_bits(const uint8_t *src, int address, int nb_bits); |
| 346 | 346 | ||
| 347 | +/* Read a float from 4 bytes in Modbus format */ | ||
| 348 | +float modbus_read_float(const uint16_t *src); | ||
| 349 | + | ||
| 350 | +/* Write a float to 4 bytes in Modbus format */ | ||
| 351 | +void modbus_write_float(float real, uint16_t *dest); | ||
| 352 | + | ||
| 347 | #ifdef __cplusplus | 353 | #ifdef __cplusplus |
| 348 | } | 354 | } |
| 349 | #endif | 355 | #endif |
tests/unit-test-master.c
| @@ -36,6 +36,7 @@ int main(void) | @@ -36,6 +36,7 @@ int main(void) | ||
| 36 | int address; | 36 | int address; |
| 37 | int nb_points; | 37 | int nb_points; |
| 38 | int ret; | 38 | int ret; |
| 39 | + float real; | ||
| 39 | 40 | ||
| 40 | /* RTU parity : none, even, odd */ | 41 | /* RTU parity : none, even, odd */ |
| 41 | /* modbus_init_rtu(&mb_param, "/dev/ttyS0", 19200, "none", 8, 1, SLAVE); */ | 42 | /* modbus_init_rtu(&mb_param, "/dev/ttyS0", 19200, "none", 8, 1, SLAVE); */ |
| @@ -253,6 +254,30 @@ int main(void) | @@ -253,6 +254,30 @@ int main(void) | ||
| 253 | printf("OK\n"); | 254 | printf("OK\n"); |
| 254 | 255 | ||
| 255 | 256 | ||
| 257 | + printf("\nTEST FLOATS\n"); | ||
| 258 | + /** FLOAT **/ | ||
| 259 | + printf("1/2 Write float: "); | ||
| 260 | + modbus_write_float(UT_REAL, tab_rp_registers); | ||
| 261 | + if (tab_rp_registers[1] == (UT_IREAL >> 16) && | ||
| 262 | + tab_rp_registers[0] == (UT_IREAL & 0xFFFF)) { | ||
| 263 | + printf("OK\n"); | ||
| 264 | + } else { | ||
| 265 | + printf("FAILED (%x != %x)\n", | ||
| 266 | + *((uint32_t *)tab_rp_registers), UT_IREAL); | ||
| 267 | + goto close; | ||
| 268 | + } | ||
| 269 | + | ||
| 270 | + printf("2/2 Read float: "); | ||
| 271 | + real = modbus_read_float(tab_rp_registers); | ||
| 272 | + if (real == UT_REAL) { | ||
| 273 | + printf("OK\n"); | ||
| 274 | + } else { | ||
| 275 | + printf("FAILED (%f != %f)\n", real, UT_REAL); | ||
| 276 | + goto close; | ||
| 277 | + } | ||
| 278 | + | ||
| 279 | + printf("\nAt this point, error messages doesn't mean the test has failed\n"); | ||
| 280 | + | ||
| 256 | /** ILLEGAL DATA ADDRESS **/ | 281 | /** ILLEGAL DATA ADDRESS **/ |
| 257 | printf("\nTEST ILLEGAL DATA ADDRESS:\n"); | 282 | printf("\nTEST ILLEGAL DATA ADDRESS:\n"); |
| 258 | 283 | ||
| @@ -465,6 +490,8 @@ int main(void) | @@ -465,6 +490,8 @@ int main(void) | ||
| 465 | } | 490 | } |
| 466 | free(tab_rp_registers_bad); | 491 | free(tab_rp_registers_bad); |
| 467 | 492 | ||
| 493 | + printf("\nALL TESTS PASS WITH SUCCESS.\n"); | ||
| 494 | + | ||
| 468 | close: | 495 | close: |
| 469 | /* Free the memory */ | 496 | /* Free the memory */ |
| 470 | free(tab_rp_status); | 497 | free(tab_rp_status); |
tests/unit-test.h
| @@ -42,4 +42,7 @@ const uint16_t UT_INPUT_REGISTERS_ADDRESS = 0x08; | @@ -42,4 +42,7 @@ const uint16_t UT_INPUT_REGISTERS_ADDRESS = 0x08; | ||
| 42 | const uint16_t UT_INPUT_REGISTERS_NB_POINTS = 0x1; | 42 | const uint16_t UT_INPUT_REGISTERS_NB_POINTS = 0x1; |
| 43 | const uint16_t UT_INPUT_REGISTERS_TAB[] = { 0x000A }; | 43 | const uint16_t UT_INPUT_REGISTERS_TAB[] = { 0x000A }; |
| 44 | 44 | ||
| 45 | +const float UT_REAL = 916.540649; | ||
| 46 | +const uint32_t UT_IREAL = 0x4465229a; | ||
| 47 | + | ||
| 45 | #endif /* _UNIT_TEST_H_ */ | 48 | #endif /* _UNIT_TEST_H_ */ |