Skip to content

Commit 7cbdcf5

Browse files
author
Christian Sandberg
committed
Add SYNC support.
1 parent 65ac211 commit 7cbdcf5

File tree

5 files changed

+59
-6
lines changed

5 files changed

+59
-6
lines changed

canopen/emcy.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ def __init__(self):
3232
self.log = []
3333

3434
def on_emcy(self, can_id, data, timestamp):
35+
if can_id == 0x80:
36+
return
3537
code, register, data = EMCY_STRUCT.unpack(data)
3638
if code & 0xFF == 0:
3739
entry = ErrorReset(code, register, data, timestamp)

canopen/network.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import can
66

77
from .node import Node
8+
from .sync import SyncProducer
89

910

1011
logger = logging.getLogger(__name__)
@@ -18,6 +19,7 @@ def __init__(self):
1819
self.notifier = None
1920
self.nodes = []
2021
self.send_lock = threading.Lock()
22+
self.sync = SyncProducer(self)
2123
# NMT to all nodes
2224
#self.nmt = NmtNode(0)
2325

canopen/pdo.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@ def __init__(self, parent):
2424
def on_message(self, can_id, data, timestamp):
2525
for pdo_map in self.tx.values():
2626
if pdo_map.cob_id == can_id:
27-
pdo_map.data = data
28-
pdo_map.timestamp = timestamp
27+
with pdo_map.receive_condition:
28+
pdo_map.data = data
29+
pdo_map.timestamp = timestamp
30+
pdo_map.receive_condition.notify_all()
2931

3032
def get_by_name(self, name):
3133
for pdo_maps in (self.rx, self.tx):
@@ -53,11 +55,10 @@ def export(self, filename):
5355
continue
5456
frame = canmatrix.Frame("PDO_0x%X" % pdo_map.cob_id,
5557
Id=pdo_map.cob_id,
56-
dlc=len(pdo_map.data),
5758
extended=0)
5859
for var in pdo_map.map:
5960
is_signed = var.od.data_type in objectdictionary.SIGNED_TYPES
60-
if_float = var.od.data_type == objectdictionary.REAL32
61+
is_float = var.od.data_type == objectdictionary.REAL32
6162
min_value = var.od.min
6263
max_value = var.od.max
6364
if min_value is not None:
@@ -68,14 +69,15 @@ def export(self, filename):
6869
startBit=var.offset,
6970
signalSize=len(var.od),
7071
is_signed=is_signed,
71-
is_float=if_float,
72+
is_float=is_float,
7273
factor=var.od.factor,
7374
min=min_value,
7475
max=max_value,
7576
unit=var.od.unit)
7677
for value, desc in var.od.value_descriptions.items():
7778
signal.addValues(value, desc)
7879
frame.addSignal(signal)
80+
frame.calcDLC()
7981
db._fl.addFrame(frame)
8082
exportdbc.exportDbc(db, filename)
8183

@@ -118,6 +120,7 @@ def __init__(self, pdo_node, com_index, map_index):
118120
self.timestamp = None
119121
self.period = None
120122
self.transmit_thread = None
123+
self.receive_condition = threading.Condition()
121124
self.stop_event = threading.Event()
122125

123126
def __getitem__(self, key):
@@ -251,6 +254,12 @@ def stop(self):
251254
self.transmit_thread.join(2)
252255
self.transmit_thread = None
253256

257+
def wait_for_reception(self, timeout=10):
258+
with self.receive_condition:
259+
self.timestamp = None
260+
self.receive_condition.wait(timeout)
261+
return self.timestamp
262+
254263
def _periodic_transmit(self):
255264
while not self.stop_event.is_set():
256265
start = time.time()

canopen/sync.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import time
2+
import threading
3+
4+
5+
class SyncProducer(object):
6+
7+
def __init__(self, network):
8+
self.network = network
9+
self.period = None
10+
self.transmit_thread = None
11+
self.stop_event = threading.Event()
12+
13+
def transmit(self):
14+
self.network.send_message(0x80, [])
15+
16+
def start(self, period=None):
17+
"""Start periodic transmission of SYNC message in a background thread."""
18+
if period is not None:
19+
self.period = period
20+
21+
if not self.period:
22+
raise ValueError("A valid transmission period has not been given")
23+
24+
if not self.transmit_thread or not self.transmit_thread.is_alive():
25+
self.stop_event.clear()
26+
self.transmit_thread = threading.Thread(target=self._periodic_transmit)
27+
self.transmit_thread.daemon = True
28+
self.transmit_thread.start()
29+
30+
def stop(self):
31+
self.stop_event.set()
32+
if self.transmit_thread:
33+
self.transmit_thread.join(2)
34+
self.transmit_thread = None
35+
36+
def _periodic_transmit(self):
37+
while not self.stop_event.is_set():
38+
start = time.time()
39+
self.transmit()
40+
time.sleep(self.period - (time.time() - start))

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from setuptools import setup, find_packages
22

3-
__version__ = "0.3.0.dev3"
3+
__version__ = "0.3.0.dev4"
44

55
setup(
66
name="canopen",

0 commit comments

Comments
 (0)