Broadcast Manager¶
The broadcast manager allows the user to setup periodic message jobs. For example sending a particular message at a given period. The broadcast manager supported natively by several interfaces and a software thread based scheduler is used as a fallback.
This example shows the socketcan backend using the broadcast manager:
1#!/usr/bin/env python
2# coding: utf-8
3
4"""
5This example exercises the periodic sending capabilities.
6
7Expects a vcan0 interface:
8
9 python3 -m examples.cyclic
10
11"""
12
13from __future__ import print_function
14
15import logging
16import time
17
18import can
19
20logging.basicConfig(level=logging.INFO)
21
22
23def simple_periodic_send(bus):
24 """
25 Sends a message every 20ms with no explicit timeout
26 Sleeps for 2 seconds then stops the task.
27 """
28 print("Starting to send a message every 200ms for 2s")
29 msg = can.Message(arbitration_id=0x123, data=[1, 2, 3, 4, 5, 6], is_extended_id=False)
30 task = bus.send_periodic(msg, 0.20)
31 assert isinstance(task, can.CyclicSendTaskABC)
32 time.sleep(2)
33 task.stop()
34 print("stopped cyclic send")
35
36
37def limited_periodic_send(bus):
38 print("Starting to send a message every 200ms for 1s")
39 msg = can.Message(arbitration_id=0x12345678, data=[0, 0, 0, 0, 0, 0], is_extended_id=True)
40 task = bus.send_periodic(msg, 0.20, 1, store_task=False)
41 if not isinstance(task, can.LimitedDurationCyclicSendTaskABC):
42 print("This interface doesn't seem to support a ")
43 task.stop()
44 return
45
46 time.sleep(2)
47 print("Cyclic send should have stopped as duration expired")
48 # Note the (finished) task will still be tracked by the Bus
49 # unless we pass `store_task=False` to bus.send_periodic
50 # alternatively calling stop removes the task from the bus
51 #task.stop()
52
53
54def test_periodic_send_with_modifying_data(bus):
55 print("Starting to send a message every 200ms. Initial data is ones")
56 msg = can.Message(arbitration_id=0x0cf02200, data=[1, 1, 1, 1])
57 task = bus.send_periodic(msg, 0.20)
58 if not isinstance(task, can.ModifiableCyclicTaskABC):
59 print("This interface doesn't seem to support modification")
60 task.stop()
61 return
62 time.sleep(2)
63 print("Changing data of running task to begin with 99")
64 msg.data[0] = 0x99
65 task.modify_data(msg)
66 time.sleep(2)
67
68 task.stop()
69 print("stopped cyclic send")
70 print("Changing data of stopped task to single ff byte")
71 msg.data = bytearray([0xff])
72 msg.dlc = 1
73 task.modify_data(msg)
74 time.sleep(1)
75 print("starting again")
76 task.start()
77 time.sleep(1)
78 task.stop()
79 print("done")
80
81
82# Will have to consider how to expose items like this. The socketcan
83# interfaces will continue to support it... but the top level api won't.
84# def test_dual_rate_periodic_send():
85# """Send a message 10 times at 1ms intervals, then continue to send every 500ms"""
86# msg = can.Message(arbitration_id=0x123, data=[0, 1, 2, 3, 4, 5])
87# print("Creating cyclic task to send message 10 times at 1ms, then every 500ms")
88# task = can.interface.MultiRateCyclicSendTask('vcan0', msg, 10, 0.001, 0.50)
89# time.sleep(2)
90#
91# print("Changing data[0] = 0x42")
92# msg.data[0] = 0x42
93# task.modify_data(msg)
94# time.sleep(2)
95#
96# task.stop()
97# print("stopped cyclic send")
98#
99# time.sleep(2)
100#
101# task.start()
102# print("starting again")
103# time.sleep(2)
104# task.stop()
105# print("done")
106
107
108if __name__ == "__main__":
109
110 reset_msg = can.Message(arbitration_id=0x00, data=[0, 0, 0, 0, 0, 0], is_extended_id=False)
111
112 for interface, channel in [
113 ('socketcan', 'vcan0'),
114 #('ixxat', 0)
115 ]:
116 print("Carrying out cyclic tests with {} interface".format(interface))
117
118 bus = can.Bus(interface=interface, channel=channel, bitrate=500000)
119 bus.send(reset_msg)
120
121 simple_periodic_send(bus)
122
123 bus.send(reset_msg)
124
125 limited_periodic_send(bus)
126
127 test_periodic_send_with_modifying_data(bus)
128
129 #print("Carrying out multirate cyclic test for {} interface".format(interface))
130 #can.rc['interface'] = interface
131 #test_dual_rate_periodic_send()
132
133 bus.shutdown()
134
135 time.sleep(2)
Message Sending Tasks¶
The class based api for the broadcast manager uses a series of
mixin classes.
All mixins inherit from CyclicSendTaskABC
which inherits from CyclicTask
.
- class can.broadcastmanager.CyclicTask[source]¶
Abstract Base for all cyclic tasks.
- abstract stop()[source]¶
Cancel this periodic task.
- Raises
can.CanError – If stop is called on an already stopped task.
- class can.broadcastmanager.CyclicSendTaskABC(message, period)[source]¶
Message send task with defined period
- Parameters
message (can.Message) – The message to be sent periodically.
period (float) – The rate in seconds at which to send the message.
- class can.broadcastmanager.LimitedDurationCyclicSendTaskABC(message, period, duration)[source]¶
Message send task with a defined duration and period.
- Parameters
message (can.Message) – The message to be sent periodically.
period (float) – The rate in seconds at which to send the message.
duration (float) – The duration to keep sending this message at given rate.
- class can.broadcastmanager.MultiRateCyclicSendTaskABC(channel, message, count, initial_period, subsequent_period)[source]¶
A Cyclic send task that supports switches send frequency after a set time.
Transmits a message count times at initial_period then continues to transmit message at subsequent_period.
- Parameters
channel – See interface specific documentation.
message (can.Message) –
count (int) –
initial_period (float) –
subsequent_period (float) –
- class can.ModifiableCyclicTaskABC(message, period)[source]¶
Adds support for modifying a periodic message
- Parameters
message (can.Message) – The message to be sent periodically.
period (float) – The rate in seconds at which to send the message.
- modify_data(message)[source]¶
Update the contents of this periodically sent message without altering the timing.
- Parameters
message (can.Message) – The message with the new
can.Message.data
. Note: The arbitration ID cannot be changed.
- class can.RestartableCyclicTaskABC(message, period)[source]¶
Adds support for restarting a stopped cyclic task
- Parameters
message (can.Message) – The message to be sent periodically.
period (float) – The rate in seconds at which to send the message.
Functional API¶
Warning
The functional API in can.broadcastmanager.send_periodic()
is now deprecated
and will be removed in version 4.0.
Use the object oriented API via can.BusABC.send_periodic()
instead.
- can.broadcastmanager.send_periodic(bus, message, period, *args, **kwargs)[source]¶
Send a
Message
every period seconds on the given bus.- Parameters
bus (can.BusABC) – A CAN bus which supports sending.
message (can.Message) – Message to send periodically.
period (float) – The minimum time between sending messages.
- Returns
A started task instance