Skip to content

Commit f25004c

Browse files
authored
Merge pull request #2724 from adafruit/can_bus_bff
adding CAN Bus BFF examples
2 parents 92898c5 + 17d8ec9 commit f25004c

File tree

6 files changed

+352
-0
lines changed

6 files changed

+352
-0
lines changed

CAN_Bus_BFF/Arduino/MCP2515_CAN_BFF_Receive/.none.test.only

Whitespace-only changes.
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// SPDX-FileCopyrightText: 2024 Limor Fried for Adafruit Industries
2+
//
3+
// SPDX-License-Identifier: MIT
4+
5+
#include <Adafruit_MCP2515.h>
6+
#include <Adafruit_SSD1306.h>
7+
#include <Fonts/FreeSans9pt7b.h>
8+
9+
#define CS_PIN A3
10+
#define CAN_BAUDRATE (250000)
11+
12+
Adafruit_MCP2515 mcp(CS_PIN);
13+
Adafruit_SSD1306 oled(128, 64, &Wire1, -1);
14+
15+
16+
void setup() {
17+
Serial.begin(115200);
18+
while(!Serial) delay(10);
19+
Serial.println("MCP2515 OLED Receiver test!");
20+
21+
if (!mcp.begin(CAN_BAUDRATE)) {
22+
Serial.println("Error initializing MCP2515.");
23+
while(1) delay(10);
24+
}
25+
Serial.println("MCP2515 chip found");
26+
27+
if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3D)) {
28+
Serial.println(F("SSD1306 allocation failed"));
29+
while(1) delay(10);
30+
}
31+
oled.display();
32+
delay(1000);
33+
oled.clearDisplay();
34+
oled.display();
35+
oled.setFont(&FreeSans9pt7b);
36+
oled.setTextColor(SSD1306_WHITE);
37+
}
38+
39+
void loop() {
40+
// try to parse packet
41+
int packetSize = mcp.parsePacket();
42+
43+
if (packetSize) {
44+
// received a packet
45+
Serial.print("Received ");
46+
47+
48+
Serial.print("packet with id 0x");
49+
Serial.print(mcp.packetId(), HEX);
50+
Serial.print(" and length ");
51+
Serial.println(packetSize);
52+
53+
// only look for correct length packets
54+
if (packetSize != 3) return;
55+
56+
// wait till all data is ready!
57+
while (mcp.available() != 3) {
58+
delay(1);
59+
}
60+
uint8_t button_state = 0;
61+
int16_t val = 0;
62+
63+
button_state = mcp.read();
64+
val = mcp.read();
65+
val <<= 8;
66+
val |= mcp.read();
67+
68+
Serial.print("Button is ");
69+
if (button_state) Serial.print("pressed");
70+
else Serial.print("released");
71+
Serial.print(" & value is ");
72+
Serial.println(val);
73+
74+
oled.clearDisplay();
75+
oled.setCursor(0, 15);
76+
oled.println("CAN receiver");
77+
oled.print("Val: "); oled.println(val);
78+
oled.print("Button ");
79+
if (button_state) oled.print("DOWN");
80+
else oled.print("UP");
81+
oled.display();
82+
}
83+
}

CAN_Bus_BFF/Arduino/MCP2515_CAN_Feather_Send/.none.test.only

Whitespace-only changes.
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
// SPDX-FileCopyrightText: 2024 Limor Fried for Adafruit Industries
2+
//
3+
// SPDX-License-Identifier: MIT
4+
5+
#include "Adafruit_seesaw.h"
6+
#include <seesaw_neopixel.h>
7+
#include <Adafruit_MCP2515.h>
8+
#include <Adafruit_NeoPixel.h>
9+
10+
11+
#define CS_PIN PIN_CAN_CS // for Feather RP2040 CAN, change if needed!
12+
Adafruit_MCP2515 mcp(CS_PIN);
13+
14+
15+
#define CAN_BAUDRATE (250000) // must match the other devices!
16+
#define SS_SWITCH 24
17+
#define SS_NEOPIX 6
18+
#define SEESAW_ADDR 0x36
19+
20+
Adafruit_seesaw ss;
21+
seesaw_NeoPixel sspixel = seesaw_NeoPixel(1, SS_NEOPIX, NEO_GRB + NEO_KHZ800);
22+
Adafruit_NeoPixel pixel(1, 21, NEO_GRB + NEO_KHZ800);
23+
24+
25+
int16_t encoder_position;
26+
bool button_state;
27+
28+
void setup() {
29+
Serial.begin(115200);
30+
delay(500);
31+
while (!Serial) delay(10);
32+
33+
Serial.println("MCP2515 Sender test!");
34+
if (!mcp.begin(CAN_BAUDRATE)) {
35+
Serial.println("Error initializing MCP2515.");
36+
while(1) delay(10);
37+
}
38+
Serial.println("MCP2515 chip found");
39+
40+
Serial.println("Looking for seesaw!");
41+
if (! ss.begin(SEESAW_ADDR) || ! sspixel.begin(SEESAW_ADDR)) {
42+
Serial.println("Couldn't find seesaw on default address");
43+
while(1) delay(10);
44+
}
45+
Serial.println("seesaw started");
46+
47+
uint32_t version = ((ss.getVersion() >> 16) & 0xFFFF);
48+
if (version != 4991){
49+
Serial.print("Wrong firmware loaded? ");
50+
Serial.println(version);
51+
while(1) delay(10);
52+
}
53+
Serial.println("Found Product 4991");
54+
55+
// set not so bright!
56+
sspixel.setBrightness(20);
57+
sspixel.show();
58+
59+
// ditto built in pixel
60+
pinMode(NEOPIXEL_POWER, OUTPUT);
61+
digitalWrite(NEOPIXEL_POWER, HIGH);
62+
pixel.begin();
63+
pixel.setBrightness(20);
64+
pixel.show();
65+
66+
// use a pin for the built in encoder switch
67+
ss.pinMode(SS_SWITCH, INPUT_PULLUP);
68+
69+
// get starting position
70+
encoder_position = ss.getEncoderPosition();
71+
button_state = ss.digitalRead(SS_SWITCH);
72+
}
73+
74+
void loop() {
75+
bool new_button = ss.digitalRead(SS_SWITCH);
76+
77+
if (new_button != button_state) {
78+
Serial.println("Button pressed!");
79+
}
80+
81+
int32_t new_position = ss.getEncoderPosition();
82+
// did we move around or button change?
83+
if ((new_button != button_state) ||
84+
(encoder_position != new_position)) {
85+
86+
encoder_position = new_position; // and save for next round
87+
button_state = new_button;
88+
89+
pixel.setPixelColor(0, Wheel(new_position & 0xFF));
90+
pixel.show();
91+
92+
Serial.print("Sending Position ");
93+
Serial.print(encoder_position);
94+
Serial.print(" & Button ");
95+
Serial.println(button_state);
96+
97+
mcp.beginPacket(0x12);
98+
if (ss.digitalRead(SS_SWITCH)) {
99+
mcp.write(0);
100+
} else {
101+
mcp.write(1);
102+
}
103+
mcp.write(encoder_position >> 8);
104+
mcp.write(encoder_position & 0xFF);
105+
if (mcp.endPacket()) {
106+
Serial.println("Done");
107+
// change the neopixel color on success
108+
sspixel.setPixelColor(0, Wheel(new_position & 0xFF));
109+
} else {
110+
Serial.println("Failure");
111+
// turn off neopixel on failure
112+
sspixel.setPixelColor(0, 0x00);
113+
}
114+
sspixel.show();
115+
}
116+
117+
// don't overwhelm serial port
118+
delay(10);
119+
}
120+
121+
122+
uint32_t Wheel(byte WheelPos) {
123+
WheelPos = 255 - WheelPos;
124+
if (WheelPos < 85) {
125+
return sspixel.Color(255 - WheelPos * 3, 0, WheelPos * 3);
126+
}
127+
if (WheelPos < 170) {
128+
WheelPos -= 85;
129+
return sspixel.Color(0, WheelPos * 3, 255 - WheelPos * 3);
130+
}
131+
WheelPos -= 170;
132+
return sspixel.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
133+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# SPDX-FileCopyrightText: 2024 ladyada for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
import time
5+
import board
6+
import terminalio
7+
import displayio
8+
from digitalio import DigitalInOut
9+
from adafruit_mcp2515.canio import Message, RemoteTransmissionRequest
10+
from adafruit_mcp2515 import MCP2515 as CAN
11+
import adafruit_displayio_ssd1306
12+
from adafruit_display_text import label
13+
14+
displayio.release_displays()
15+
16+
i2c = board.STEMMA_I2C()
17+
# STEMMA OLED setup
18+
display_bus = displayio.I2CDisplay(i2c, device_address=0x3D, reset=None)
19+
display = adafruit_displayio_ssd1306.SSD1306(display_bus, width=128, height=64)
20+
21+
cs = DigitalInOut(board.A3)
22+
cs.switch_to_output()
23+
spi = board.SPI()
24+
25+
can_bus = CAN(
26+
spi, cs, loopback=False, silent=False
27+
) # use loopback to test without another device
28+
29+
splash = displayio.Group()
30+
display.root_group = splash
31+
32+
font = terminalio.FONT
33+
main_area = label.Label(
34+
font, text="CAN Receiver", color=0xFFFFFF)
35+
main_area.anchor_point = (0.5, 0.0)
36+
main_area.anchored_position = (display.width / 2, 0)
37+
38+
msg_area = label.Label(
39+
font, text="ID: ", color=0xFFFFFF)
40+
msg_area.anchor_point = (0.0, 0.5)
41+
msg_area.anchored_position = (0, display.height / 2)
42+
43+
val_area = label.Label(
44+
font, text="Val: ", color=0xFFFFFF)
45+
val_area.anchor_point = (0.0, 1.0)
46+
val_area.anchored_position = (0, display.height)
47+
48+
splash.append(main_area)
49+
splash.append(msg_area)
50+
splash.append(val_area)
51+
52+
while True:
53+
with can_bus.listen(timeout=1.0) as listener:
54+
55+
message_count = listener.in_waiting()
56+
for i in range(message_count):
57+
print(message_count, "messages available")
58+
msg = listener.receive()
59+
print("Message from ", hex(msg.id))
60+
msg_area.text = f"ID: {hex(msg.id)}"
61+
if isinstance(msg, Message):
62+
print("message data:", msg.data)
63+
val_area.text = f"Val: {msg.data}"
64+
if isinstance(msg, RemoteTransmissionRequest):
65+
print("RTR length:", msg.length)
66+
time.sleep(0.1)
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2024 ladyada for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
import time
5+
import board
6+
from rainbowio import colorwheel
7+
from digitalio import DigitalInOut
8+
from adafruit_mcp2515 import MCP2515 as CAN
9+
from adafruit_mcp2515.canio import Message
10+
from adafruit_seesaw import seesaw, neopixel, rotaryio, digitalio
11+
12+
cs = DigitalInOut(board.CAN_CS)
13+
cs.switch_to_output()
14+
spi = board.SPI()
15+
16+
can_bus = CAN(
17+
spi, cs, loopback=False, silent=False
18+
) # use loopback to test without another device
19+
20+
i2c = board.I2C() # uses board.SCL and board.SDA
21+
# i2c = board.STEMMA_I2C() # For using the built-in STEMMA QT connector on a microcontroller
22+
seesaw = seesaw.Seesaw(i2c, addr=0x36)
23+
24+
seesaw_product = (seesaw.get_version() >> 16) & 0xFFFF
25+
print("Found product {}".format(seesaw_product))
26+
if seesaw_product != 4991:
27+
print("Wrong firmware loaded? Expected 4991")
28+
29+
seesaw.pin_mode(24, seesaw.INPUT_PULLUP)
30+
button = digitalio.DigitalIO(seesaw, 24)
31+
pixel = neopixel.NeoPixel(seesaw, 6, 1)
32+
pixel.brightness = 0.3
33+
34+
button_held = False
35+
color = 0
36+
37+
encoder = rotaryio.IncrementalEncoder(seesaw)
38+
last_position = 0
39+
40+
while True:
41+
with can_bus.listen(timeout=5.0) as listener:
42+
position = -encoder.position
43+
44+
if position != last_position:
45+
if position > last_position:
46+
color += 5
47+
else:
48+
color -= 5
49+
color = (color + 256) % 256 # wrap around to 0-256
50+
pixel.fill(colorwheel(color))
51+
last_position = position
52+
str_pos = str(position)
53+
byte_pos = str_pos.encode()
54+
message = Message(id=0x1234ABCD, data=byte_pos, extended=True)
55+
send_success = can_bus.send(message)
56+
print("Send success:", send_success)
57+
58+
if not button.value and not button_held:
59+
button_held = True
60+
message = Message(id=0x1234ABCD, data=b"pressed", extended=True)
61+
send_success = can_bus.send(message)
62+
print("Send success:", send_success)
63+
64+
if button.value and button_held:
65+
button_held = False
66+
message = Message(id=0x1234ABCD, data=b"released", extended=True)
67+
send_success = can_bus.send(message)
68+
print("Send success:", send_success)
69+
70+
time.sleep(0.1)

0 commit comments

Comments
 (0)