Skip to content

Commit d18e18a

Browse files
authored
Merge pull request #1293 from jepler/jepler-feathercan
Add examples for upcoming Adafruit Feather M4 CAN guide
2 parents 1e67df9 + 7211f85 commit d18e18a

File tree

4 files changed

+182
-0
lines changed

4 files changed

+182
-0
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import struct
2+
3+
import board
4+
import canio
5+
import digitalio
6+
7+
# If the CAN transceiver has a standby pin, bring it out of standby mode
8+
if hasattr(board, 'CAN_STANDBY'):
9+
standby = digitalio.DigitalInOut(board.CAN_STANDBY)
10+
standby.switch_to_output(False)
11+
12+
# If the CAN transceiver is powered by a boost converter, turn on its supply
13+
if hasattr(board, 'BOOST_ENABLE'):
14+
standby = digitalio.DigitalInOut(board.CAN_STANDBY)
15+
standby.switch_to_output(True)
16+
17+
can = canio.CAN(rx=board.CAN_RX, tx=board.CAN_TX, baudrate=250_000, auto_restart=True)
18+
listener = can.listen(matches=[canio.Match(0x408)], timeout=.9)
19+
20+
old_bus_state = None
21+
old_count = -1
22+
23+
while True:
24+
bus_state = can.state
25+
if bus_state != old_bus_state:
26+
print(f"Bus state changed to {bus_state}")
27+
old_bus_state = bus_state
28+
29+
message = listener.receive()
30+
if message is None:
31+
print("No messsage received within timeout")
32+
continue
33+
34+
data = message.data
35+
if len(data) != 8:
36+
print(f"Unusual message length {len(data)}")
37+
continue
38+
39+
count, now_ms = struct.unpack("<II", data)
40+
gap = count - old_count
41+
old_count = count
42+
print(f"received message: id={message.id:x} count={count} now_ms={now_ms}")
43+
if gap != 1:
44+
print(f"gap: {gap}")
45+
46+
print("Sending ACK")
47+
can.send(canio.Message(id=0x409, data=struct.pack("<I", count)))

FeatherCAN_CircuitPython/listener.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import struct
2+
3+
import board
4+
import canio
5+
import digitalio
6+
7+
# If the CAN transceiver has a standby pin, bring it out of standby mode
8+
if hasattr(board, 'CAN_STANDBY'):
9+
standby = digitalio.DigitalInOut(board.CAN_STANDBY)
10+
standby.switch_to_output(False)
11+
12+
# If the CAN transceiver is powered by a boost converter, turn on its supply
13+
if hasattr(board, 'BOOST_ENABLE'):
14+
standby = digitalio.DigitalInOut(board.CAN_STANDBY)
15+
standby.switch_to_output(True)
16+
17+
can = canio.CAN(rx=board.CAN_RX, tx=board.CAN_TX, baudrate=250_000, auto_restart=True)
18+
listener = can.listen(matches=[canio.Match(0x408)], timeout=.9)
19+
20+
old_bus_state = None
21+
old_count = -1
22+
23+
while True:
24+
bus_state = can.state
25+
if bus_state != old_bus_state:
26+
print(f"Bus state changed to {bus_state}")
27+
old_bus_state = bus_state
28+
29+
message = listener.receive()
30+
if message is None:
31+
print("No messsage received within timeout")
32+
continue
33+
34+
data = message.data
35+
if len(data) != 8:
36+
print(f"Unusual message length {len(data)}")
37+
continue
38+
39+
count, now_ms = struct.unpack("<II", data)
40+
gap = count - old_count
41+
old_count = count
42+
print(f"received message: count={count} now_ms={now_ms}")
43+
if gap != 1:
44+
print(f"gap: {gap}")
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import struct
2+
import time
3+
4+
import board
5+
import canio
6+
import digitalio
7+
8+
# If the CAN transceiver has a standby pin, bring it out of standby mode
9+
if hasattr(board, 'CAN_STANDBY'):
10+
standby = digitalio.DigitalInOut(board.CAN_STANDBY)
11+
standby.switch_to_output(False)
12+
13+
# If the CAN transceiver is powered by a boost converter, turn on its supply
14+
if hasattr(board, 'BOOST_ENABLE'):
15+
standby = digitalio.DigitalInOut(board.CAN_STANDBY)
16+
standby.switch_to_output(True)
17+
18+
can = canio.CAN(rx=board.CAN_RX, tx=board.CAN_TX, baudrate=250_000, auto_restart=True)
19+
listener = can.listen(matches=[canio.Match(0x409)], timeout=.1)
20+
21+
old_bus_state = None
22+
count = 0
23+
24+
while True:
25+
bus_state = can.state
26+
if bus_state != old_bus_state:
27+
print(f"Bus state changed to {bus_state}")
28+
old_bus_state = bus_state
29+
30+
now_ms = (time.monotonic_ns() // 1_000_000) & 0xffffffff
31+
print(f"Sending message: count={count} now_ms={now_ms}")
32+
33+
message = canio.Message(id=0x408, data=struct.pack("<II", count, now_ms))
34+
while True:
35+
can.send(message)
36+
37+
message_in = listener.receive()
38+
if message_in is None:
39+
print("No ACK received within timeout")
40+
continue
41+
42+
data = message_in.data
43+
if len(data) != 4:
44+
print(f"Unusual message length {len(data)}")
45+
continue
46+
47+
ack_count = struct.unpack("<I", data)[0]
48+
if ack_count == count:
49+
print(f"Received ACK")
50+
break
51+
else:
52+
print(f"Received incorrect ACK: {ack_count} should be {count}")
53+
54+
time.sleep(.5)
55+
count += 1

FeatherCAN_CircuitPython/sender.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import struct
2+
import time
3+
4+
import board
5+
import canio
6+
import digitalio
7+
8+
# If the CAN transceiver has a standby pin, bring it out of standby mode
9+
if hasattr(board, 'CAN_STANDBY'):
10+
standby = digitalio.DigitalInOut(board.CAN_STANDBY)
11+
standby.switch_to_output(False)
12+
13+
# If the CAN transceiver is powered by a boost converter, turn on its supply
14+
if hasattr(board, 'BOOST_ENABLE'):
15+
standby = digitalio.DigitalInOut(board.CAN_STANDBY)
16+
standby.switch_to_output(True)
17+
18+
can = canio.CAN(rx=board.CAN_RX, tx=board.CAN_TX, baudrate=250_000, auto_restart=True)
19+
20+
old_bus_state = None
21+
count = 0
22+
23+
while True:
24+
bus_state = can.state
25+
if bus_state != old_bus_state:
26+
print(f"Bus state changed to {bus_state}")
27+
old_bus_state = bus_state
28+
29+
now_ms = (time.monotonic_ns() // 1_000_000) & 0xffffffff
30+
print(f"Sending message: count={count} now_ms={now_ms}")
31+
32+
message = canio.Message(id=0x408, data=struct.pack("<II", count, now_ms))
33+
can.send(message)
34+
35+
time.sleep(.5)
36+
count += 1

0 commit comments

Comments
 (0)