Initial Commit
This commit is contained in:
commit
91eb608abf
77
CAN-arduino.ino
Normal file
77
CAN-arduino.ino
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/**************************************************************
|
||||||
|
* TestVESC.ino
|
||||||
|
*
|
||||||
|
* Leon Abelmann, March 2026
|
||||||
|
*
|
||||||
|
* Version 1.0 - Set dutycyle, wait, stop, wait, repeat
|
||||||
|
* Information:
|
||||||
|
* https://github.com/waas-rent/vesc_can_sdk/blob/main/CAN_PROTOCOL.md
|
||||||
|
* https://github.com/vedderb/bldc/blob/master/documentation/comm_can.md
|
||||||
|
* Use VESC tool to set parameters on the VESC controller
|
||||||
|
* Load and save configurations using File menu
|
||||||
|
* Read and write configuration to VESC using M and A buttons on right
|
||||||
|
* VESC Dev Tools / Terminal is your friend, type help
|
||||||
|
**************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "CAN.h"
|
||||||
|
#include "VESC_controller.h"
|
||||||
|
|
||||||
|
/* Initialize CAN bus, ports match the Next! breakout board */
|
||||||
|
mbed::CAN can1(PB_5, PB_13);
|
||||||
|
|
||||||
|
/* VESC controllers . Read/Set with VESCTool software */
|
||||||
|
VESC_controller VESC1 = VESC_controller(0x5A); // Hex (0x5A = 90 decimal )
|
||||||
|
VESC_controller VESC2 = VESC_controller(0x5B); // Hex (0x5B = 91 decimal )
|
||||||
|
|
||||||
|
int dutycycle1 = 30000; // Range is -100000 - 100000
|
||||||
|
int dutycycle2 = 30000;
|
||||||
|
|
||||||
|
/* Setup CAN bus and serial communcation */
|
||||||
|
void setup() {
|
||||||
|
//switch relays over to VESC
|
||||||
|
pinMode(D10, OUTPUT);
|
||||||
|
digitalWrite(D10, LOW);
|
||||||
|
|
||||||
|
// Setup CAN bus
|
||||||
|
can1.frequency(500000);
|
||||||
|
|
||||||
|
// Serial communication (for debugging)
|
||||||
|
Serial.begin(115200);
|
||||||
|
delay(1000);
|
||||||
|
Serial.write("VescControl is starting up!");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t serial_data;
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
mbed::CANMessage canMsg;
|
||||||
|
|
||||||
|
while(Serial.available()){
|
||||||
|
Serial.readBytes(&serial_data,1);
|
||||||
|
Serial.print("found digit: ");
|
||||||
|
Serial.println(serial_data);
|
||||||
|
//dutycycle1 = serial_data;
|
||||||
|
VESC2.setDutyCycle(serial_data*784-100000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Print data of status message 1 received from VESC
|
||||||
|
// Switch on in VESC tool - General / CAN Message Rate
|
||||||
|
// Set frequency to 2 Hz for example
|
||||||
|
// Is there a message waiting on the bus?
|
||||||
|
while (can1.read(canMsg)) {
|
||||||
|
//Serial.println(canMsg.id);
|
||||||
|
// Check if the message is a status 1 message from VESC1 (0x0009)
|
||||||
|
if (canMsg.id == 0x00090000 | VESC1.getVescID()) {
|
||||||
|
VESC1.getStatus1(canMsg);
|
||||||
|
}
|
||||||
|
if (canMsg.id == 0x00090000 | VESC2.getVescID()) {
|
||||||
|
VESC2.getStatus1(canMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
|
||||||
66
VESC_controller.cpp
Normal file
66
VESC_controller.cpp
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
#include "VESC_controller.h"
|
||||||
|
extern mbed::CAN can1;
|
||||||
|
|
||||||
|
int32_t VESC_controller::setDutyCycle(int32_t duty) {
|
||||||
|
mbed::CANMessage canMsg;
|
||||||
|
// VESC uses extended message IDs
|
||||||
|
// The message ID is the combination of the command and the VESC ID
|
||||||
|
// Set duty cycle = 0x0000, vescID = 0x5A for example, than
|
||||||
|
// combined ID = 0x0000005A
|
||||||
|
canMsg.id = 0x000000000 | vescId;
|
||||||
|
canMsg.format = CANExtended;
|
||||||
|
canMsg.len = 4; // Message length
|
||||||
|
// Convert duty cycle to 4 bytes
|
||||||
|
// 32-bit big endian signed number
|
||||||
|
canMsg.data[3] = (duty >> 0) & 0xFF;
|
||||||
|
canMsg.data[2] = (duty >> 8) & 0xFF;
|
||||||
|
canMsg.data[1] = (duty >> 16) & 0xFF;
|
||||||
|
canMsg.data[0] = (duty >> 24) & 0xFF;
|
||||||
|
|
||||||
|
// Send message on CAN bus
|
||||||
|
can1.write(canMsg);
|
||||||
|
|
||||||
|
current_duty_cycle = duty;
|
||||||
|
return current_duty_cycle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VESC_controller::getStatus1(const mbed::CANMessage &canMsg) {
|
||||||
|
// For debug:
|
||||||
|
// // Serial.print("CAN Message Data: ");
|
||||||
|
// for (int i = 0; i < canMsg.len; i++) {
|
||||||
|
// if (canMsg.data[i] < 0x10) // Serial.print("0"); // Print leading zero for single-digit hex
|
||||||
|
// // Serial.print(canMsg.data[i], HEX);
|
||||||
|
// // Serial.print(" ");
|
||||||
|
// }
|
||||||
|
// // Serial.println();
|
||||||
|
|
||||||
|
// Extract Current (bytes 4-5)
|
||||||
|
int16_t current_raw = (canMsg.data[4] << 8) | canMsg.data[5];
|
||||||
|
float current = current_raw / 10.0f; // Scale by 10
|
||||||
|
|
||||||
|
// Extract Duty Cycle (bytes 6-7)
|
||||||
|
int16_t duty_raw = (canMsg.data[6] << 8) | canMsg.data[7];
|
||||||
|
float duty = duty_raw / 1000.0f; // Scale by 1000
|
||||||
|
|
||||||
|
// Print results
|
||||||
|
// Serial.print("Current: ");
|
||||||
|
// Serial.print(current);
|
||||||
|
readout_motor_current = current;
|
||||||
|
// Serial.print(" A, Duty: ");
|
||||||
|
// Serial.print(duty*100);
|
||||||
|
readout_duty_cycle = duty*100;
|
||||||
|
// Serial.println("%");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VESC_controller::verifyDutyCycle(){
|
||||||
|
return readout_duty_cycle == current_duty_cycle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VESC_controller::getDataFromVesc(){
|
||||||
|
getStatus1(lastCanMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t VESC_controller::getVescID(){
|
||||||
|
|
||||||
|
return vescId;
|
||||||
|
}
|
||||||
25
VESC_controller.h
Normal file
25
VESC_controller.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#include "CAN.h"
|
||||||
|
|
||||||
|
class VESC_controller{
|
||||||
|
private:
|
||||||
|
uint8_t vescId =0;
|
||||||
|
int32_t current_duty_cycle=0;
|
||||||
|
int32_t readout_motor_current=0;
|
||||||
|
int32_t readout_duty_cycle=0;
|
||||||
|
mbed::CANMessage lastCanMessage;
|
||||||
|
|
||||||
|
public:
|
||||||
|
int32_t setDutyCycle(int32_t duty_cycle);
|
||||||
|
void getStatus1(const mbed::CANMessage &canMsg);
|
||||||
|
bool verifyDutyCycle();
|
||||||
|
void getDataFromVESC();
|
||||||
|
void getDataFromVesc();
|
||||||
|
uint8_t getVescID();
|
||||||
|
VESC_controller(uint8_t address){
|
||||||
|
vescId = address;
|
||||||
|
current_duty_cycle=0;
|
||||||
|
readout_motor_current=0;
|
||||||
|
readout_duty_cycle=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
Loading…
x
Reference in New Issue
Block a user