Skip to content

Commit 9912bbe

Browse files
committed
add utils.long_list_to_word and float example
1 parent 8d09cac commit 9912bbe

File tree

2 files changed

+71
-11
lines changed

2 files changed

+71
-11
lines changed

examples/float_support.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
4+
# how-to add float support to ModbusClient
5+
6+
from pyModbusTCP.client import ModbusClient
7+
from pyModbusTCP import utils
8+
9+
10+
class FloatModbusClient(ModbusClient):
11+
def read_float(self, address, number=1):
12+
reg_l = self.read_holding_registers(address, number * 2)
13+
if reg_l:
14+
return [utils.decode_ieee(f) for f in utils.word_list_to_long(reg_l)]
15+
else:
16+
return None
17+
18+
def write_float(self, address, floats_list):
19+
b32_l = [utils.encode_ieee(f) for f in floats_list]
20+
b16_l = utils.long_list_to_word(b32_l)
21+
return self.write_multiple_registers(address, b16_l)
22+
23+
24+
c = FloatModbusClient(host='localhost', port=502, auto_open=True)
25+
26+
# write 10.0 at @0
27+
c.write_float(0, [10.0])
28+
29+
# read @0 to 9
30+
float_l = c.read_float(0, 10)
31+
print(float_l)
32+
33+
c.close()

pyModbusTCP/utils.py

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def get_bits_from_int(val_int, val_size=16):
2525
bits = [None] * val_size
2626
# fill bits list with bit items
2727
for i, item in enumerate(bits):
28-
bits[i] = bool((val_int>>i)&0x01)
28+
bits[i] = bool((val_int >> i) & 0x01)
2929
# return bits list
3030
return bits
3131

@@ -43,7 +43,8 @@ def decode_ieee(val_int):
4343
:returns: float result
4444
:rtype: float
4545
"""
46-
return struct.unpack("f",struct.pack("I", val_int))[0]
46+
return struct.unpack("f", struct.pack("I", val_int))[0]
47+
4748

4849
def encode_ieee(val_float):
4950
"""Encode Python float to int (32 bits integer) as an IEEE single precision
@@ -55,7 +56,7 @@ def encode_ieee(val_float):
5556
:returns: IEEE 32 bits (single precision) as Python int
5657
:rtype: int
5758
"""
58-
return struct.unpack("I",struct.pack("f", val_float))[0]
59+
return struct.unpack("I", struct.pack("f", val_float))[0]
5960

6061

6162
################################
@@ -64,28 +65,55 @@ def encode_ieee(val_float):
6465
def word_list_to_long(val_list, big_endian=True):
6566
"""Word list (16 bits int) to long list (32 bits int)
6667
67-
By default word_list2long() use big endian order. For use little endian, set
68+
By default word_list_to_long() use big endian order. For use little endian, set
6869
big_endian param to False.
6970
7071
:param val_list: list of 16 bits int value
7172
:type val_list: list
7273
:param big_endian: True for big endian/False for little (optional)
7374
:type big_endian: bool
74-
:returns: 2's complement result
75+
:returns: list of 32 bits int value
7576
:rtype: list
7677
"""
7778
# allocate list for long int
78-
long_list = [None] * int(len(val_list)/2)
79+
long_list = [None] * int(len(val_list) / 2)
7980
# fill registers list with register items
8081
for i, item in enumerate(long_list):
8182
if big_endian:
82-
long_list[i] = (val_list[i*2]<<16) + val_list[(i*2)+1]
83+
long_list[i] = (val_list[i * 2] << 16) + val_list[(i * 2) + 1]
8384
else:
84-
long_list[i] = (val_list[(i*2)+1]<<16) + val_list[i*2]
85+
long_list[i] = (val_list[(i * 2) + 1] << 16) + val_list[i * 2]
8586
# return long list
8687
return long_list
8788

8889

90+
def long_list_to_word(val_list, big_endian=True):
91+
"""Long list (32 bits int) to word list (16 bits int)
92+
93+
By default long_list_to_word() use big endian order. For use little endian, set
94+
big_endian param to False.
95+
96+
:param val_list: list of 32 bits int value
97+
:type val_list: list
98+
:param big_endian: True for big endian/False for little (optional)
99+
:type big_endian: bool
100+
:returns: list of 16 bits int value
101+
:rtype: list
102+
"""
103+
# allocate list for long int
104+
word_list = list()
105+
# fill registers list with register items
106+
for i, item in enumerate(val_list):
107+
if big_endian:
108+
word_list.append(val_list[i] >> 16)
109+
word_list.append(val_list[i] & 0xffff)
110+
else:
111+
word_list.append(val_list[i] & 0xffff)
112+
word_list.append(val_list[i] >> 16)
113+
# return long list
114+
return word_list
115+
116+
89117
#########################################################
90118
# 2's complement of int value (scalar and list) functions
91119
#########################################################
@@ -100,9 +128,9 @@ def get_2comp(val_int, val_size=16):
100128
:rtype: int
101129
"""
102130
# test MSBit (1 for negative)
103-
if (val_int&(1<<(val_size-1))):
131+
if val_int & (1 << (val_size - 1)):
104132
# do complement
105-
val_int = val_int - (1<<val_size)
133+
val_int -= 1 << val_size
106134
return val_int
107135

108136

@@ -199,4 +227,3 @@ def toggle_bit(value, offset):
199227
"""
200228
mask = 1 << offset
201229
return int(value ^ mask)
202-

0 commit comments

Comments
 (0)