I am having a weird issue with my CAN bus MCP2515 communicating with my Arduino. I am trying to control 4 motors communicating over CAN and using a keypad with 4 LED indicator lights.
Code 1 attached uses the serial print to execute the bouncemotor function, this was working fine.
Code 2 attached integrates an LED and keypad to turn the motors off and on using the same bouncemotor function, this code compiles but is not working at all, and seems to brick the MCP2515. When I revert to code 1 the code compiles but now does not receive any commands.
Things I have tried and have not worked:
- swapped out the MCP2515, initially it works with code 1 but when swapping between code 1 to 2 code breaks the MCP2515.
- changed bitrate and clock speed (saw this in another thread).
-
checked wires (don't see how this could be an issue if initially working with code 1 but why not)
-
removed terminal resistor
-
checked if keypad and LEDS work seperately with same wiring ( they do)
attached are code 1 and code 2, and my schematic. Please give me any ideas you have! Thank You!
Code 1:
#include <SPI.h> // SPI Library
#include <mcp2515.h> // CAN Library
struct can_frame canMsg;
MCP2515 mcp2515(10); // MCP2515 CS pin on 10
// Define motor IDs
#define MOTOR_1 0x141 // Motor 141 (-45° to -135°)
#define MOTOR_2 0x142 // Motor 142 (45° to 135°)
#define MOTOR_3 0x143 // Motor 143 (Mirrors Motor 142)
#define MOTOR_4 0x144 // Motor 144 (Mirrors Motor 141)
// Define movement positions (hex values for angles)
const uint8_t motor1_low[8] = {0xA4, 0x00, 0xF4, 0x01, 0x6C, 0xEE, 0xFF, 0xFF}; // -45°
const uint8_t motor1_high[8] = {0xA4, 0x00, 0xF4, 0x01, 0x44, 0xCB, 0xFF, 0xFF}; // -135°
const uint8_t motor2_low[8] = {0xA4, 0x00, 0xF4, 0x01, 0x94, 0x11, 0x00, 0x00}; // 45°
const uint8_t motor2_high[8] = {0xA4, 0x00, 0xF4, 0x01, 0xBC, 0x34, 0x00, 0x00}; // 135°
const uint8_t motor_reset[8] = {0xA4, 0x00, 0xF4, 0x01, 0x00, 0x00, 0x00, 0x00}; // 0°
bool running = false; // Flag to track if motion should run
void setup() {
Serial.begin(115200);
mcp2515.reset();
mcp2515.setBitrate(CAN_1000KBPS, MCP_8MHZ);
mcp2515.setNormalMode();
Serial.println("CAN Bus Initialized");
Serial.println("Press '1' to start motion. Press '2' to stop and reset.");
}
// Function to send a command to a motor
void sendCommand(uint16_t motorID, const uint8_t* data) {
canMsg.can_id = motorID;
canMsg.can_dlc = 8;
for (int i = 0; i < 8; i++) {
canMsg.data[i] = data[i];
}
mcp2515.sendMessage(&canMsg);
Serial.print("Sent to ");
Serial.print(motorID, HEX);
Serial.print(": ");
for (int i = 0; i < 8; i++) {
Serial.print(canMsg.data[i], HEX);
Serial.print(" ");
}
Serial.println();
}
// Function to alternate movement
void bounceMotors() {
// Move Motor 141 & 144 to -45° and Motor 142 & 143 to 135°
sendCommand(MOTOR_1, motor1_low);
sendCommand(MOTOR_4, motor1_low); // Motor 144 now mirrors Motor 141
sendCommand(MOTOR_2, motor2_high);
sendCommand(MOTOR_3, motor2_high); // Motor 143 now mirrors Motor 142
delay(300); // Wait for movement
// Move Motor 141 & 144 to -135° and Motor 142 & 143 to 45°
sendCommand(MOTOR_1, motor1_high);
sendCommand(MOTOR_4, motor1_high); // Motor 144 now mirrors Motor 141
sendCommand(MOTOR_2, motor2_low);
sendCommand(MOTOR_3, motor2_low); // Motor 143 now mirrors Motor 142
delay(300); // Wait for movement
}
// Function to reset motors to 0°
void resetMotors() {
sendCommand(MOTOR_1, motor_reset);
sendCommand(MOTOR_2, motor_reset);
sendCommand(MOTOR_3, motor_reset);
sendCommand(MOTOR_4, motor_reset);
Serial.println("Motors reset to 0°");
}
void loop() {
// Check for user input
if (Serial.available() > 0) {
char command = Serial.read();
if (command == '1') {
running = true; // Start the motion
Serial.println("Starting motion...");
}
else if (command == '2') {
running = false; // Stop motion
Serial.println("Stopping motion and resetting motors...");
resetMotors();
}
}
// If running, execute movement
if (running) {
bounceMotors();
}
}
Code 2:
#include <SPI.h> // SPI Library
#include <mcp2515.h> // CAN Library
#include <Keypad.h> // Keypad Library
// LED Pin
const int GREEN_LED = A0;
struct can_frame canMsg;
MCP2515 mcp2515(10); // MCP2515 CS pin on 10
// Define motor IDs
#define MOTOR_1 0x141 // Motor 141 (-45° to -135°)
#define MOTOR_2 0x142 // Motor 142 (45° to 135°)
#define MOTOR_3 0x143 // Motor 143 (Mirrors Motor 142)
#define MOTOR_4 0x144 // Motor 144 (Mirrors Motor 141)
// Define movement positions (hex values for angles)
const uint8_t motor1_low[8] = {0xA4, 0x00, 0xF4, 0x01, 0x6C, 0xEE, 0xFF, 0xFF}; // -45°
const uint8_t motor1_high[8] = {0xA4, 0x00, 0xF4, 0x01, 0x44, 0xCB, 0xFF, 0xFF}; // -135°
const uint8_t motor2_low[8] = {0xA4, 0x00, 0xF4, 0x01, 0x94, 0x11, 0x00, 0x00}; // 45°
const uint8_t motor2_high[8] = {0xA4, 0x00, 0xF4, 0x01, 0xBC, 0x34, 0x00, 0x00}; // 135°
const uint8_t motor_reset[8] = {0xA4, 0x00, 0xF4, 0x01, 0x00, 0x00, 0x00, 0x00}; // 0°
// Keypad Configuration
const byte ROWS = 1;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{ '1', '2', '3', '4' }
};
// Keypad Pins
byte rowPins[ROWS] = { 5 }; // Common pin
byte colPins[COLS] = { 6, 7, 8, 9 }; // Column pins
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
bool running = false; // Flag to track if motion should run
bool ledState = false; // Flag to track LED state
void setup() {
Serial.begin(115200);
// Initialize CAN Bus
mcp2515.reset();
mcp2515.setBitrate(CAN_1000KBPS, MCP_8MHZ);
mcp2515.setNormalMode();
// Initialize LED
pinMode(GREEN_LED, OUTPUT);
digitalWrite(GREEN_LED, LOW);
Serial.println("CAN Bus and Keypad Initialized");
Serial.println("Press Button 1 to start/stop motor motion");
}
// Function to send a command to a motor
void sendCommand(uint16_t motorID, const uint8_t* data) {
canMsg.can_id = motorID;
canMsg.can_dlc = 8;
for (int i = 0; i < 8; i++) {
canMsg.data[i] = data[i];
}
mcp2515.sendMessage(&canMsg);
Serial.print("Sent to ");
Serial.print(motorID, HEX);
Serial.print(": ");
for (int i = 0; i < 8; i++) {
Serial.print(canMsg.data[i], HEX);
Serial.print(" ");
}
Serial.println();
}
// Function to alternate movement
void bounceMotors() {
// Move Motor 141 & 144 to -45° and Motor 142 & 143 to 135°
sendCommand(MOTOR_1, motor1_low);
sendCommand(MOTOR_4, motor1_low); // Motor 144 now mirrors Motor 141
sendCommand(MOTOR_2, motor2_high);
sendCommand(MOTOR_3, motor2_high); // Motor 143 now mirrors Motor 142
delay(300); // Wait for movement
// Move Motor 141 & 144 to -135° and Motor 142 & 143 to 45°
sendCommand(MOTOR_1, motor1_high);
sendCommand(MOTOR_4, motor1_high); // Motor 144 now mirrors Motor 141
sendCommand(MOTOR_2, motor2_low);
sendCommand(MOTOR_3, motor2_low); // Motor 143 now mirrors Motor 142
delay(300); // Wait for movement
}
// Function to reset motors to 0°
void resetMotors() {
sendCommand(MOTOR_1, motor_reset);
sendCommand(MOTOR_2, motor_reset);
sendCommand(MOTOR_3, motor_reset);
sendCommand(MOTOR_4, motor_reset);
Serial.println("Motors reset to 0°");
}
void loop() {
// Get key press
char key = keypad.getKey();
// Process the key press
if (key != NO_KEY) {
switch(key) {
case '1':
// Toggle motor running state
running = !running;
// Toggle LED state
ledState = !ledState;
digitalWrite(GREEN_LED, ledState);
if (running) {
Serial.println("Starting motor motion...");
} else {
Serial.println("Stopping motor motion and resetting...");
resetMotors();
}
break;
}
}
// If running, execute movement
if (running) {
bounceMotors();
}
}
