adding CAN Bus BFF examples

Adding Arduino and CircuitPython CAN Bus BFF examples
This commit is contained in:
Liz 2024-01-30 17:09:49 -05:00
parent 92898c54a0
commit 17d8ec9437
6 changed files with 352 additions and 0 deletions

View file

@ -0,0 +1,83 @@
// SPDX-FileCopyrightText: 2024 Limor Fried for Adafruit Industries
//
// SPDX-License-Identifier: MIT
#include <Adafruit_MCP2515.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeSans9pt7b.h>
#define CS_PIN A3
#define CAN_BAUDRATE (250000)
Adafruit_MCP2515 mcp(CS_PIN);
Adafruit_SSD1306 oled(128, 64, &Wire1, -1);
void setup() {
Serial.begin(115200);
while(!Serial) delay(10);
Serial.println("MCP2515 OLED Receiver test!");
if (!mcp.begin(CAN_BAUDRATE)) {
Serial.println("Error initializing MCP2515.");
while(1) delay(10);
}
Serial.println("MCP2515 chip found");
if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3D)) {
Serial.println(F("SSD1306 allocation failed"));
while(1) delay(10);
}
oled.display();
delay(1000);
oled.clearDisplay();
oled.display();
oled.setFont(&FreeSans9pt7b);
oled.setTextColor(SSD1306_WHITE);
}
void loop() {
// try to parse packet
int packetSize = mcp.parsePacket();
if (packetSize) {
// received a packet
Serial.print("Received ");
Serial.print("packet with id 0x");
Serial.print(mcp.packetId(), HEX);
Serial.print(" and length ");
Serial.println(packetSize);
// only look for correct length packets
if (packetSize != 3) return;
// wait till all data is ready!
while (mcp.available() != 3) {
delay(1);
}
uint8_t button_state = 0;
int16_t val = 0;
button_state = mcp.read();
val = mcp.read();
val <<= 8;
val |= mcp.read();
Serial.print("Button is ");
if (button_state) Serial.print("pressed");
else Serial.print("released");
Serial.print(" & value is ");
Serial.println(val);
oled.clearDisplay();
oled.setCursor(0, 15);
oled.println("CAN receiver");
oled.print("Val: "); oled.println(val);
oled.print("Button ");
if (button_state) oled.print("DOWN");
else oled.print("UP");
oled.display();
}
}

View file

@ -0,0 +1,133 @@
// SPDX-FileCopyrightText: 2024 Limor Fried for Adafruit Industries
//
// SPDX-License-Identifier: MIT
#include "Adafruit_seesaw.h"
#include <seesaw_neopixel.h>
#include <Adafruit_MCP2515.h>
#include <Adafruit_NeoPixel.h>
#define CS_PIN PIN_CAN_CS // for Feather RP2040 CAN, change if needed!
Adafruit_MCP2515 mcp(CS_PIN);
#define CAN_BAUDRATE (250000) // must match the other devices!
#define SS_SWITCH 24
#define SS_NEOPIX 6
#define SEESAW_ADDR 0x36
Adafruit_seesaw ss;
seesaw_NeoPixel sspixel = seesaw_NeoPixel(1, SS_NEOPIX, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixel(1, 21, NEO_GRB + NEO_KHZ800);
int16_t encoder_position;
bool button_state;
void setup() {
Serial.begin(115200);
delay(500);
while (!Serial) delay(10);
Serial.println("MCP2515 Sender test!");
if (!mcp.begin(CAN_BAUDRATE)) {
Serial.println("Error initializing MCP2515.");
while(1) delay(10);
}
Serial.println("MCP2515 chip found");
Serial.println("Looking for seesaw!");
if (! ss.begin(SEESAW_ADDR) || ! sspixel.begin(SEESAW_ADDR)) {
Serial.println("Couldn't find seesaw on default address");
while(1) delay(10);
}
Serial.println("seesaw started");
uint32_t version = ((ss.getVersion() >> 16) & 0xFFFF);
if (version != 4991){
Serial.print("Wrong firmware loaded? ");
Serial.println(version);
while(1) delay(10);
}
Serial.println("Found Product 4991");
// set not so bright!
sspixel.setBrightness(20);
sspixel.show();
// ditto built in pixel
pinMode(NEOPIXEL_POWER, OUTPUT);
digitalWrite(NEOPIXEL_POWER, HIGH);
pixel.begin();
pixel.setBrightness(20);
pixel.show();
// use a pin for the built in encoder switch
ss.pinMode(SS_SWITCH, INPUT_PULLUP);
// get starting position
encoder_position = ss.getEncoderPosition();
button_state = ss.digitalRead(SS_SWITCH);
}
void loop() {
bool new_button = ss.digitalRead(SS_SWITCH);
if (new_button != button_state) {
Serial.println("Button pressed!");
}
int32_t new_position = ss.getEncoderPosition();
// did we move around or button change?
if ((new_button != button_state) ||
(encoder_position != new_position)) {
encoder_position = new_position; // and save for next round
button_state = new_button;
pixel.setPixelColor(0, Wheel(new_position & 0xFF));
pixel.show();
Serial.print("Sending Position ");
Serial.print(encoder_position);
Serial.print(" & Button ");
Serial.println(button_state);
mcp.beginPacket(0x12);
if (ss.digitalRead(SS_SWITCH)) {
mcp.write(0);
} else {
mcp.write(1);
}
mcp.write(encoder_position >> 8);
mcp.write(encoder_position & 0xFF);
if (mcp.endPacket()) {
Serial.println("Done");
// change the neopixel color on success
sspixel.setPixelColor(0, Wheel(new_position & 0xFF));
} else {
Serial.println("Failure");
// turn off neopixel on failure
sspixel.setPixelColor(0, 0x00);
}
sspixel.show();
}
// don't overwhelm serial port
delay(10);
}
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if (WheelPos < 85) {
return sspixel.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if (WheelPos < 170) {
WheelPos -= 85;
return sspixel.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return sspixel.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

View file

@ -0,0 +1,66 @@
# SPDX-FileCopyrightText: 2024 ladyada for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import time
import board
import terminalio
import displayio
from digitalio import DigitalInOut
from adafruit_mcp2515.canio import Message, RemoteTransmissionRequest
from adafruit_mcp2515 import MCP2515 as CAN
import adafruit_displayio_ssd1306
from adafruit_display_text import label
displayio.release_displays()
i2c = board.STEMMA_I2C()
# STEMMA OLED setup
display_bus = displayio.I2CDisplay(i2c, device_address=0x3D, reset=None)
display = adafruit_displayio_ssd1306.SSD1306(display_bus, width=128, height=64)
cs = DigitalInOut(board.A3)
cs.switch_to_output()
spi = board.SPI()
can_bus = CAN(
spi, cs, loopback=False, silent=False
) # use loopback to test without another device
splash = displayio.Group()
display.root_group = splash
font = terminalio.FONT
main_area = label.Label(
font, text="CAN Receiver", color=0xFFFFFF)
main_area.anchor_point = (0.5, 0.0)
main_area.anchored_position = (display.width / 2, 0)
msg_area = label.Label(
font, text="ID: ", color=0xFFFFFF)
msg_area.anchor_point = (0.0, 0.5)
msg_area.anchored_position = (0, display.height / 2)
val_area = label.Label(
font, text="Val: ", color=0xFFFFFF)
val_area.anchor_point = (0.0, 1.0)
val_area.anchored_position = (0, display.height)
splash.append(main_area)
splash.append(msg_area)
splash.append(val_area)
while True:
with can_bus.listen(timeout=1.0) as listener:
message_count = listener.in_waiting()
for i in range(message_count):
print(message_count, "messages available")
msg = listener.receive()
print("Message from ", hex(msg.id))
msg_area.text = f"ID: {hex(msg.id)}"
if isinstance(msg, Message):
print("message data:", msg.data)
val_area.text = f"Val: {msg.data}"
if isinstance(msg, RemoteTransmissionRequest):
print("RTR length:", msg.length)
time.sleep(0.1)

View file

@ -0,0 +1,70 @@
# SPDX-FileCopyrightText: Copyright (c) 2024 ladyada for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import time
import board
from rainbowio import colorwheel
from digitalio import DigitalInOut
from adafruit_mcp2515 import MCP2515 as CAN
from adafruit_mcp2515.canio import Message
from adafruit_seesaw import seesaw, neopixel, rotaryio, digitalio
cs = DigitalInOut(board.CAN_CS)
cs.switch_to_output()
spi = board.SPI()
can_bus = CAN(
spi, cs, loopback=False, silent=False
) # use loopback to test without another device
i2c = board.I2C() # uses board.SCL and board.SDA
# i2c = board.STEMMA_I2C() # For using the built-in STEMMA QT connector on a microcontroller
seesaw = seesaw.Seesaw(i2c, addr=0x36)
seesaw_product = (seesaw.get_version() >> 16) & 0xFFFF
print("Found product {}".format(seesaw_product))
if seesaw_product != 4991:
print("Wrong firmware loaded? Expected 4991")
seesaw.pin_mode(24, seesaw.INPUT_PULLUP)
button = digitalio.DigitalIO(seesaw, 24)
pixel = neopixel.NeoPixel(seesaw, 6, 1)
pixel.brightness = 0.3
button_held = False
color = 0
encoder = rotaryio.IncrementalEncoder(seesaw)
last_position = 0
while True:
with can_bus.listen(timeout=5.0) as listener:
position = -encoder.position
if position != last_position:
if position > last_position:
color += 5
else:
color -= 5
color = (color + 256) % 256 # wrap around to 0-256
pixel.fill(colorwheel(color))
last_position = position
str_pos = str(position)
byte_pos = str_pos.encode()
message = Message(id=0x1234ABCD, data=byte_pos, extended=True)
send_success = can_bus.send(message)
print("Send success:", send_success)
if not button.value and not button_held:
button_held = True
message = Message(id=0x1234ABCD, data=b"pressed", extended=True)
send_success = can_bus.send(message)
print("Send success:", send_success)
if button.value and button_held:
button_held = False
message = Message(id=0x1234ABCD, data=b"released", extended=True)
send_success = can_bus.send(message)
print("Send success:", send_success)
time.sleep(0.1)