Skip to content

Commit

Permalink
Add SYNC support.
Browse files Browse the repository at this point in the history
  • Loading branch information
Christian Sandberg committed Sep 19, 2016
1 parent 65ac211 commit 7cbdcf5
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 6 deletions.
2 changes: 2 additions & 0 deletions canopen/emcy.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ def __init__(self):
self.log = []

def on_emcy(self, can_id, data, timestamp):
if can_id == 0x80:
return
code, register, data = EMCY_STRUCT.unpack(data)
if code & 0xFF == 0:
entry = ErrorReset(code, register, data, timestamp)
Expand Down
2 changes: 2 additions & 0 deletions canopen/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import can

from .node import Node
from .sync import SyncProducer


logger = logging.getLogger(__name__)
Expand All @@ -18,6 +19,7 @@ def __init__(self):
self.notifier = None
self.nodes = []
self.send_lock = threading.Lock()
self.sync = SyncProducer(self)
# NMT to all nodes
#self.nmt = NmtNode(0)

Expand Down
19 changes: 14 additions & 5 deletions canopen/pdo.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ def __init__(self, parent):
def on_message(self, can_id, data, timestamp):
for pdo_map in self.tx.values():
if pdo_map.cob_id == can_id:
pdo_map.data = data
pdo_map.timestamp = timestamp
with pdo_map.receive_condition:
pdo_map.data = data
pdo_map.timestamp = timestamp
pdo_map.receive_condition.notify_all()

def get_by_name(self, name):
for pdo_maps in (self.rx, self.tx):
Expand Down Expand Up @@ -53,11 +55,10 @@ def export(self, filename):
continue
frame = canmatrix.Frame("PDO_0x%X" % pdo_map.cob_id,
Id=pdo_map.cob_id,
dlc=len(pdo_map.data),
extended=0)
for var in pdo_map.map:
is_signed = var.od.data_type in objectdictionary.SIGNED_TYPES
if_float = var.od.data_type == objectdictionary.REAL32
is_float = var.od.data_type == objectdictionary.REAL32
min_value = var.od.min
max_value = var.od.max
if min_value is not None:
Expand All @@ -68,14 +69,15 @@ def export(self, filename):
startBit=var.offset,
signalSize=len(var.od),
is_signed=is_signed,
is_float=if_float,
is_float=is_float,
factor=var.od.factor,
min=min_value,
max=max_value,
unit=var.od.unit)
for value, desc in var.od.value_descriptions.items():
signal.addValues(value, desc)
frame.addSignal(signal)
frame.calcDLC()
db._fl.addFrame(frame)
exportdbc.exportDbc(db, filename)

Expand Down Expand Up @@ -118,6 +120,7 @@ def __init__(self, pdo_node, com_index, map_index):
self.timestamp = None
self.period = None
self.transmit_thread = None
self.receive_condition = threading.Condition()
self.stop_event = threading.Event()

def __getitem__(self, key):
Expand Down Expand Up @@ -251,6 +254,12 @@ def stop(self):
self.transmit_thread.join(2)
self.transmit_thread = None

def wait_for_reception(self, timeout=10):
with self.receive_condition:
self.timestamp = None
self.receive_condition.wait(timeout)
return self.timestamp

def _periodic_transmit(self):
while not self.stop_event.is_set():
start = time.time()
Expand Down
40 changes: 40 additions & 0 deletions canopen/sync.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import time
import threading


class SyncProducer(object):

def __init__(self, network):
self.network = network
self.period = None
self.transmit_thread = None
self.stop_event = threading.Event()

def transmit(self):
self.network.send_message(0x80, [])

def start(self, period=None):
"""Start periodic transmission of SYNC message in a background thread."""
if period is not None:
self.period = period

if not self.period:
raise ValueError("A valid transmission period has not been given")

if not self.transmit_thread or not self.transmit_thread.is_alive():
self.stop_event.clear()
self.transmit_thread = threading.Thread(target=self._periodic_transmit)
self.transmit_thread.daemon = True
self.transmit_thread.start()

def stop(self):
self.stop_event.set()
if self.transmit_thread:
self.transmit_thread.join(2)
self.transmit_thread = None

def _periodic_transmit(self):
while not self.stop_event.is_set():
start = time.time()
self.transmit()
time.sleep(self.period - (time.time() - start))
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from setuptools import setup, find_packages

__version__ = "0.3.0.dev3"
__version__ = "0.3.0.dev4"

setup(
name="canopen",
Expand Down

0 comments on commit 7cbdcf5

Please sign in to comment.