forked from Mbmatthews/PKP2600SI-Arduino-CAN-Controller
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Stefan Hirschenberger
committed
May 22, 2024
1 parent
abcf733
commit 02ff170
Showing
4 changed files
with
184 additions
and
174 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
323 changes: 168 additions & 155 deletions
323
examples/PkpInitialConfiguration/PkpInitialConfiguration.ino
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,184 +1,197 @@ | ||
// This sketch sends the proper CAN messages to configure a PKP2600SI in the way that is expected for the actual sketch to control it. | ||
|
||
#include <mcp2515.h> | ||
|
||
#define KEYPAD_CAN_ID 0x15 | ||
#define PKP_BAUDRATE_125k 0x04 | ||
#define PKP_BAUDRATE_250k 0x03 | ||
#define PKP_BAUDRATE_500k 0x02 | ||
#define PKP_BAUDRATE_1M 0x00 | ||
|
||
uint8_t keypadBaudrate = PKP_BAUDRATE_1M; | ||
CAN_SPEED mcpBaudrate = CAN_1000KBPS; // should be same speed as above | ||
CAN_CLOCK mcpClockSpeed = MCP_8MHZ; | ||
|
||
|
||
MCP2515 mcp2515(10); | ||
// This sketch provides a basic configuration for your keyboard without using the actual classes from the library | ||
|
||
#define USE_MCP2515 // Comment this line to use Arduino CAN (Feather M4 CAN) | ||
|
||
#include <SPI.h> | ||
#ifdef USE_MCP2515 | ||
#include <mcp2515.h> | ||
|
||
CS_PIN_MCP 10 | ||
MCP_CLOCK_SPEED MCP_8MHZ | ||
#else | ||
#include <Adafruit_CAN.h> | ||
#endif | ||
|
||
enum PKPBaudRate: uint8_t{ | ||
PKP_BAUDRATE_0020k = 0x07, | ||
PKP_BAUDRATE_0050k = 0x06, | ||
PKP_BAUDRATE_0125k = 0x04, | ||
PKP_BAUDRATE_0250k = 0x03, | ||
PKP_BAUDRATE_0500k = 0x02, | ||
PKP_BAUDRATE_1000k = 0x00 | ||
}; | ||
|
||
//Configuration here: | ||
#define KEYPAD_ACT_CAN_ID 0x15 | ||
#define KEYPAD_NEW_CAN_ID 0x16 | ||
#define KEYPAD_NEW_BAUD_RATE PKP_BAUDRATE_1000k; | ||
#define KEYPAD_ACTVIE_AT_STARTUP 1 //1: enable, 0: disable | ||
#define KEYPAD_STARTUP_LED_SHOW 1 //1: complete show (default), 0: disable, 2: fast flash | ||
#define KEYPAD_HEARTBEAT_INTERVAL 500 //0: heartbeat production disabled, otherwise hearteat interval [ms] | ||
#define KEYPAD_PERIODIC_TX_INTERVAL 0 //0: eventbased pdo transmission, otherwise pdo interval [ms] | ||
|
||
#ifdef USE_MCP2515 | ||
MCP2515 mcp2515(CS_PIN_MCP, MCP_CLOCK_SPEED); | ||
CAN_SPEED mcpBaudrate = CAN_1000KBPS; | ||
CAN_CLOCK mcpClockSpeed = MCP_8MHZ; | ||
#else | ||
Adafruit_CAN can; | ||
#endif | ||
|
||
void setup() { | ||
Serial.begin(115200); | ||
// start MCP SPI comms, and check if things are actually working before continuing to config the MCP (when SPI is not working, this always returns | ||
// ERROR_OK so this doesn't work) | ||
bool MCP_OK = false; | ||
while (!MCP_OK) { | ||
if (mcp2515.reset() == MCP2515::ERROR_OK) { | ||
Serial.println("MCP OK"); | ||
MCP_OK = true; | ||
} | ||
delay(5); | ||
#ifdef USE_MCP2515 | ||
setupMCP2515(); | ||
#else | ||
setupArduinoCAN(); | ||
#endif | ||
keypadConfigure(keypadNewBaudrate); | ||
} | ||
|
||
void loop() { | ||
// put your main code here, to run repeatedly: | ||
} | ||
|
||
#ifdef USE_MCP2515 | ||
void setupMCP2515() { | ||
while (mcp2515.reset() != MCP2515::ERROR_OK) { | ||
Serial.println("MCP reset failed. Retrying..."); | ||
delay(100); | ||
} | ||
Serial.println("MCP OK"); | ||
mcp2515.setBitrate(mcpBaudrate, mcpClockSpeed); | ||
mcp2515.setNormalMode(); | ||
keypadConfigure(keypadBaudrate); | ||
} | ||
|
||
void loop() { | ||
// put your main code here, to run repeatedly: | ||
#else | ||
void setupArduinoCAN() { | ||
if (!can.begin(CAN_1000KBPS)) { | ||
Serial.println("CAN initialization failed"); | ||
while (1); | ||
} | ||
Serial.println("CAN initialized"); | ||
} | ||
#endif | ||
|
||
void sendMessage(const struct can_frame &msg) { | ||
#ifdef USE_MCP2515 | ||
mcp2515.sendMessage(&msg); | ||
#else | ||
can.send(msg); | ||
#endif | ||
} | ||
|
||
void keypadConfigure(uint8_t newBaudrate) { | ||
// This function has delays. Yes it is sloppy. However, the keypad will reboot on some commands and | ||
// time is needed to not blast messages to the transceiver before it can actually send them all out. | ||
// Normally using timers is great for doing this efficiently, but this function SHOULD NOT be called | ||
// often, if ever. It is included more as an ease of use thing to configure your keypad in the way | ||
// the library expects it to be configured so you don't have to manually configure it with a USB-CAN interface. | ||
// YMMV | ||
|
||
struct can_frame configurationMsg; | ||
|
||
// Send mesage to change CAN protocol to CANOpen if the current protocol is J1939 | ||
configurationMsg.can_id = 0x18EF2100 | CAN_EFF_FLAG; | ||
configurationMsg.can_dlc = 8; | ||
configurationMsg.data[0] = 0x04; | ||
configurationMsg.data[1] = 0x1B; | ||
configurationMsg.data[2] = 0x80; | ||
configurationMsg.data[3] = 0x00; | ||
configurationMsg.data[4] = 0xFF; | ||
configurationMsg.data[5] = 0xFF; | ||
configurationMsg.data[6] = 0xFF; | ||
configurationMsg.data[7] = 0xFF; | ||
mcp2515.sendMessage(MCP2515::TXB1, &configurationMsg); | ||
struct can_frame txMsg = {0}; | ||
txMsg.can_id = 0x18EF2100 | CAN_EFF_FLAG; | ||
txMsg.can_dlc = 8; | ||
txMsg.data[0] = 0x04; | ||
txMsg.data[1] = 0x1B; | ||
txMsg.data[2] = 0x80; | ||
txMsg.data[3] = 0x00; | ||
txMsg.data[4] = 0xFF; | ||
txMsg.data[5] = 0xFF; | ||
txMsg.data[6] = 0xFF; | ||
txMsg.data[7] = 0xFF; | ||
sendMessage(txMsg); | ||
delay(1000); | ||
|
||
configureKeypadNewBaudRate(KEYPAD_NEW_BAUD_RATE); | ||
|
||
// send message to configure keypad Baud Rate | ||
configurationMsg.can_id = 0x600 + KEYPAD_CAN_ID; | ||
configurationMsg.can_dlc = 8; | ||
configurationMsg.data[0] = 0x2F; | ||
configurationMsg.data[1] = 0x10; | ||
configurationMsg.data[2] = 0x20; | ||
configurationMsg.data[3] = 0x00; | ||
configurationMsg.data[4] = newBaudrate; | ||
// BYTE 4 configures the baud rate | ||
// 0x00 = 1000k (1M) | ||
// 0x02 = 500k | ||
// 0x03 = 250k | ||
// 0x04 = 125k (default) | ||
configurationMsg.data[5] = 0x00; | ||
configurationMsg.data[6] = 0x00; | ||
configurationMsg.data[7] = 0x00; | ||
|
||
mcp2515.setConfigMode(); | ||
mcp2515.setBitrate(CAN_125KBPS); | ||
mcp2515.setNormalMode(); | ||
mcp2515.sendMessage(&configurationMsg); | ||
delay(1000); | ||
|
||
mcp2515.setConfigMode(); | ||
mcp2515.setBitrate(CAN_250KBPS); | ||
mcp2515.setNormalMode(); | ||
mcp2515.sendMessage(&configurationMsg); | ||
delay(1000); | ||
setKeypadActiveAtStartup(KEYPAD_ACTVIE_AT_STARTUP); | ||
enableCANOpenKeypads(KEYPAD_ACT_CAN_ID); | ||
setStartupLEDShow(KEYPAD_STARTUP_LED_SHOW); | ||
setPeriodicTransmissionTime(); | ||
setKeypadModeToPeriodicTransmission(); | ||
configureKeypadNewNodeAddress(KEYPAD_NEW_CAN_ID); | ||
} | ||
|
||
mcp2515.setConfigMode(); | ||
mcp2515.setBitrate(CAN_500KBPS); | ||
mcp2515.setNormalMode(); | ||
mcp2515.sendMessage(&configurationMsg); | ||
void configureKeypadNewNodeAddress(uint8_t newCanId) | ||
{ | ||
struct can_frame txMsg = {0}; | ||
txMsg.can_id = 0x600 + KEYPAD_ACT_CAN_ID; | ||
txMsg.can_dlc = 5; | ||
txMsg.data[0] = 0x2F; | ||
txMsg.data[1] = 0x13; | ||
txMsg.data[2] = 0x20; | ||
txMsg.data[3] = 0x00; | ||
txMsg.data[4] = newCanId; | ||
sendMessage(txMsg); | ||
delay(1000); | ||
} | ||
|
||
mcp2515.setConfigMode(); | ||
mcp2515.setBitrate(CAN_1000KBPS); | ||
mcp2515.setNormalMode(); | ||
mcp2515.sendMessage(&configurationMsg); | ||
void configureKeypadNewBaudRate(uint8_t newBaudrate) { | ||
struct can_frame txMsg = {0}; | ||
txMsg.can_id = 0x600 + KEYPAD_ACT_CAN_ID; | ||
txMsg.can_dlc = 5; | ||
txMsg.data[0] = 0x2F; | ||
txMsg.data[1] = 0x10; | ||
txMsg.data[2] = 0x20; | ||
txMsg.data[3] = 0x00; | ||
txMsg.data[4] = newBaudrate; | ||
sendMessage(txMsg); | ||
delay(1000); | ||
} | ||
|
||
|
||
// set baudrate back to keypad baudrate and continue | ||
mcp2515.setConfigMode(); | ||
mcp2515.setBitrate(mcpBaudrate); | ||
mcp2515.setNormalMode(); | ||
|
||
// Set keypad to be already active at startup | ||
configurationMsg.can_id = 0x600 + KEYPAD_CAN_ID; | ||
configurationMsg.can_dlc = 8; | ||
configurationMsg.data[0] = 0x2F; | ||
configurationMsg.data[1] = 0x12; | ||
configurationMsg.data[2] = 0x20; | ||
configurationMsg.data[3] = 0x00; | ||
// configurationMsg.data[4] = 0x01; //enable | ||
configurationMsg.data[4] = 0x00; // disable | ||
configurationMsg.data[5] = 0x00; | ||
configurationMsg.data[6] = 0x00; | ||
configurationMsg.data[7] = 0x00; | ||
mcp2515.sendMessage(&configurationMsg); | ||
void setKeypadActiveAtStartup(uint8_t StartupActive) { | ||
struct can_frame txMsg = {0}; | ||
txMsg.can_id = 0x600 + KEYPAD_ACT_CAN_ID; | ||
txMsg.can_dlc = 5; | ||
txMsg.data[0] = 0x2F; | ||
txMsg.data[1] = 0x12; | ||
txMsg.data[2] = 0x20; | ||
txMsg.data[3] = 0x00; | ||
txMsg.data[4] = StartupActive; | ||
sendMessage(txMsg); | ||
delay(1000); | ||
} | ||
|
||
// send message to enable any CANopen keypad on the bus | ||
configurationMsg.can_id = 0x000; | ||
configurationMsg.can_dlc = 8; | ||
configurationMsg.data[0] = 0x01; | ||
configurationMsg.data[1] = 0x00; | ||
configurationMsg.data[2] = 0x00; | ||
configurationMsg.data[3] = 0x00; | ||
configurationMsg.data[4] = 0x00; | ||
configurationMsg.data[5] = 0x00; | ||
configurationMsg.data[6] = 0x00; | ||
configurationMsg.data[7] = 0x00; | ||
mcp2515.sendMessage(&configurationMsg); | ||
void enableCANOpenKeypads(uint8_t id) { | ||
struct can_frame txMsg = {0}; | ||
txMsg.can_id = 0x000; | ||
txMsg.can_dlc = 2; | ||
txMsg.data[0] = 0x01; | ||
txMsg.data[1] = id; | ||
sendMessage(txMsg); | ||
delay(1000); | ||
} | ||
|
||
|
||
// Set startup LED show | ||
configurationMsg.can_id = 0x600 + KEYPAD_CAN_ID; | ||
configurationMsg.can_dlc = 8; | ||
configurationMsg.data[0] = 0x2F; | ||
configurationMsg.data[1] = 0x14; | ||
configurationMsg.data[2] = 0x20; | ||
configurationMsg.data[3] = 0x00; | ||
// configurationMsg.data[4] = 0x00; //disable | ||
// configurationMsg.data[4] = 0x01; //full show | ||
configurationMsg.data[4] = 0x02; // fast flash | ||
configurationMsg.data[5] = 0x00; | ||
configurationMsg.data[6] = 0x00; | ||
configurationMsg.data[7] = 0x00; | ||
mcp2515.sendMessage(&configurationMsg); | ||
void setStartupLEDShow(uint8_t ledShow) { | ||
struct can_frame txMsg = {0}; | ||
txMsg.can_id = 0x600 + KEYPAD_ACT_CAN_ID; | ||
txMsg.can_dlc = 5; | ||
txMsg.data[0] = 0x2F; | ||
txMsg.data[1] = 0x14; | ||
txMsg.data[2] = 0x20; | ||
txMsg.data[3] = 0x00; | ||
txMsg.data[4] = ledShow; // fast flash | ||
sendMessage(txMsg); | ||
delay(1000); | ||
} | ||
|
||
// Set periodic transmission time | ||
configurationMsg.can_id = 0x600 + KEYPAD_CAN_ID; | ||
configurationMsg.can_dlc = 8; | ||
configurationMsg.data[0] = 0x2B; | ||
configurationMsg.data[1] = 0x00; | ||
configurationMsg.data[2] = 0x18; | ||
configurationMsg.data[3] = 0x05; | ||
configurationMsg.data[4] = 0x28; | ||
configurationMsg.data[5] = 0x01; | ||
configurationMsg.data[6] = 0x00; | ||
configurationMsg.data[7] = 0x00; | ||
mcp2515.sendMessage(&configurationMsg); | ||
void setPeriodicTransmissionTime() { | ||
struct can_frame txMsg = {0}; | ||
txMsg.can_id = 0x600 + KEYPAD_ACT_CAN_ID; | ||
txMsg.can_dlc = 6; | ||
txMsg.data[0] = 0x2B; | ||
txMsg.data[1] = 0x00; | ||
txMsg.data[2] = 0x18; | ||
txMsg.data[3] = 0x05; | ||
txMsg.data[4] = 0x28; | ||
txMsg.data[5] = 0x01; | ||
sendMessage(txMsg); | ||
delay(1000); | ||
} | ||
|
||
// Set keypad mode to periodic transmission | ||
configurationMsg.can_id = 0x600 + KEYPAD_CAN_ID; | ||
configurationMsg.can_dlc = 8; | ||
configurationMsg.data[0] = 0x2F; | ||
configurationMsg.data[1] = 0x00; | ||
configurationMsg.data[2] = 0x18; | ||
configurationMsg.data[3] = 0x05; | ||
configurationMsg.data[4] = 0x01; | ||
configurationMsg.data[5] = 0x00; | ||
configurationMsg.data[6] = 0x00; | ||
configurationMsg.data[7] = 0x00; | ||
mcp2515.sendMessage(&configurationMsg); | ||
void setKeypadModeToPeriodicTransmission() { | ||
struct can_frame txMsg = {0}; | ||
txMsg.can_id = 0x600 + KEYPAD_ACT_CAN_ID; | ||
txMsg.can_dlc = 5; | ||
txMsg.data[0] = 0x2F; | ||
txMsg.data[1] = 0x00; | ||
txMsg.data[2] = 0x18; | ||
txMsg.data[3] = 0x05; | ||
txMsg.data[4] = 0x01; | ||
sendMessage(txMsg); | ||
delay(1000); | ||
} |
Oops, something went wrong.