Skip to content

Commit

Permalink
Handle booleans in PDO correctly
Browse files Browse the repository at this point in the history
Fixes #104
  • Loading branch information
christiansandberg committed Mar 20, 2019
1 parent 16c8c11 commit f6a35e3
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 3 deletions.
12 changes: 10 additions & 2 deletions canopen/pdo/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,11 @@ def get_data(self):

if bit_offset or self.length % 8:
# Need information of the current variable type (unsigned vs signed)
od_struct = self.od.STRUCT_TYPES[self.od.data_type]
data_type = self.od.data_type
if data_type == objectdictionary.BOOLEAN:
# A boolean type needs to be treated as an U08
data_type = objectdictionary.UNSIGNED8
od_struct = self.od.STRUCT_TYPES[data_type]
data = od_struct.unpack_from(self.pdo_parent.data, byte_offset)[0]
# Shift and mask to get the correct values
data = (data >> bit_offset) & ((1 << self.length) - 1)
Expand All @@ -521,7 +525,11 @@ def set_data(self, data):
if bit_offset or self.length % 8:
cur_msg_data = self.pdo_parent.data[byte_offset:byte_offset + len(self.od) // 8]
# Need information of the current variable type (unsigned vs signed)
od_struct = self.od.STRUCT_TYPES[self.od.data_type]
data_type = self.od.data_type
if data_type == objectdictionary.BOOLEAN:
# A boolean type needs to be treated as an U08
data_type = objectdictionary.UNSIGNED8
od_struct = self.od.STRUCT_TYPES[data_type]
cur_msg_data = od_struct.unpack(cur_msg_data)[0]
# data has to have the same size as old_data
data = od_struct.unpack(data)[0]
Expand Down
14 changes: 14 additions & 0 deletions test/sample.eds
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,20 @@ DataType=0x0004
AccessType=rw
PDOMapping=1

[2005]
ParameterName=BOOLEAN value
ObjectType=0x7
DataType=0x0001
AccessType=rw
PDOMapping=1

[2006]
ParameterName=BOOLEAN value 2
ObjectType=0x7
DataType=0x0001
AccessType=rw
PDOMapping=1

[3002]
ParameterName=Sensor Sampling Rate (Hz)
ObjectType=0x7
Expand Down
10 changes: 9 additions & 1 deletion test/test_pdo.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,35 @@ def test_bit_mapping(self):
map.add_variable('UNSIGNED8 value', length=4) # 0x2002
map.add_variable('INTEGER8 value', length=4) # 0x2003
map.add_variable('INTEGER32 value') # 0x2004
map.add_variable('BOOLEAN value', length=1) # 0x2005
map.add_variable('BOOLEAN value 2', length=1) # 0x2006

# Write some values
map['INTEGER16 value'].raw = -3
map['UNSIGNED8 value'].raw = 0xf
map['INTEGER8 value'].raw = -2
map['INTEGER32 value'].raw = 0x01020304
map['BOOLEAN value'].raw = False
map['BOOLEAN value 2'].raw = True

# Check expected data
self.assertEqual(map.data, b'\xfd\xff\xef\x04\x03\x02\x01')
self.assertEqual(map.data, b'\xfd\xff\xef\x04\x03\x02\x01\x02')

# Read values from data
self.assertEqual(map['INTEGER16 value'].raw, -3)
self.assertEqual(map['UNSIGNED8 value'].raw, 0xf)
self.assertEqual(map['INTEGER8 value'].raw, -2)
self.assertEqual(map['INTEGER32 value'].raw, 0x01020304)
self.assertEqual(map['BOOLEAN value'].raw, False)
self.assertEqual(map['BOOLEAN value 2'].raw, True)

self.assertEqual(node.tpdo[1]['INTEGER16 value'].raw, -3)
self.assertEqual(node.tpdo[1]['UNSIGNED8 value'].raw, 0xf)
self.assertEqual(node.tpdo[1]['INTEGER8 value'].raw, -2)
self.assertEqual(node.tpdo[1]['INTEGER32 value'].raw, 0x01020304)
self.assertEqual(node.tpdo['INTEGER32 value'].raw, 0x01020304)
self.assertEqual(node.tpdo[1]['BOOLEAN value'].raw, False)
self.assertEqual(node.tpdo[1]['BOOLEAN value 2'].raw, True)

# Test diferent types of access
self.assertEqual(node.pdo[0x1600]['INTEGER16 value'].raw, -3)
Expand Down

1 comment on commit f6a35e3

@Sandyman
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In pdo/base.py lines 498-502: since the mapping was created for BOOLEAN in STRUCT_TYPES, I don't quite see what the use is of this if statement.

Am I missing something?

Please sign in to comment.