Hello, I'm relatively new to VESC and CAN, but I need a way to communicate to my VESC6 using an esp32.
My idea is using CAN to communicate and using Lisp to implement the stuff I need (like cruise control, emergency stopping and eventually full self-driving).
For now, my setup is:
VESC6
BLDC
Esp32
TJA1051 (a can transciver)
I was able to put 2 esp32 communicating with can with the following code and with 2 120ohm resistors:
#include
#include
//Boards Managers:
// -esp32 by Espressif
//librarys:
// -ESP32-TWAI-CAN
//Board:
// -XIAO_ESP32C3
// Default for ESP32
#define CAN_TX 21
#define CAN_RX 20
CanFrame rxFrame;
void sendRandomString() {
// Generate a random string of 8 characters
char randomString[9]; // 8 characters + null terminator
for (int i = 0; i < 8; i++) {
randomString[i] = 'A' + (char)random(0, 26); // Random uppercase letter
}
randomString[8] = '\0'; // Null terminator
// Prepare CAN frame
CanFrame frame = { 0 };
frame.identifier = 0x7DF; // Default OBD2 address
frame.extd = 0;
frame.data_length_code = 8;
for (int i = 0; i < 8; i++) {
frame.data[i] = randomString[i];
}
// Send CAN frame
ESP32Can.writeFrame(frame); // timeout defaults to 1 ms
Serial.printf("Transmit frame: %03X: ", frame.identifier);
for (byte i = 0; i < 8; i++)
Serial.printf(" %c", frame.data[i]);
Serial.printf("\n");
}
void setup() {
// Setup serial for debugging.
Serial.begin(115200);
Serial.println("\n\nESP32-TWAI-CAN Send/Receive test - Initialize");
// Set pins
ESP32Can.setPins(CAN_TX, CAN_RX);
// You can set custom size for the queues - those are default
ESP32Can.setRxQueueSize(5);
ESP32Can.setTxQueueSize(5);
// .setSpeed() and .begin() functions require to use TwaiSpeed enum,
// but you can easily convert it from numerical value using .convertSpeed()
ESP32Can.setSpeed(ESP32Can.convertSpeed(125)); //500));
// You can also just use .begin()..
if (ESP32Can.begin()) {
Serial.println("CAN bus started!");
} else {
Serial.println("CAN bus failed!");
}
// or override everything in one command;
// It is also safe to use .begin() without .end() as it calls it internally
if (ESP32Can.begin(ESP32Can.convertSpeed(250), CAN_TX, CAN_RX, 10, 10)) {
Serial.println("CAN bus started!");
} else {
Serial.println("CAN bus failed!");
}
}
void loop() {
// // Send a random string every second
// sendRandomString();
// delay(1000);
// frame received? You can set custom timeout, default is 1000
if (ESP32Can.readFrame(rxFrame, 1000)) {
// Print frame contents
Serial.printf("Received frame: %03X: ", rxFrame.identifier);
for (byte i = 0; i < rxFrame.data_length_code; i++) {
Serial.printf(" %c", rxFrame.data[i]);
}
Serial.printf("\n");
} else {
Serial.println("No frame received within timeout period.");
}
}
I was also able to send and receive CAN messages between my VESC and VESC express with Lisp:
(define arr (array-create 5))
;;(print (buflen arr))
(print (bufset-i32 arr 0 12))
(print (bufget-i32 arr 0))
(loopwhile t {
(print "sent")
(canmsg-send 10 1 arr)
(sleep 1)
})
(loopwhile t {
(print "Recieving....")
(define recived (canmsg-recv 1 -1))
(print "byte 0")
(print (bufget-i32 recived 0))
(print "byte array size")
(print (buflen recived))
(print "--------------")
(sleep 1)
})
What can I do now to receive and send data between my esp32 and VESC? First, I don't know which resistors to use on the esp? Also, I dont know if my can would even work with VESC?
If you have any example with a similar setup would be very helpful also.
Thanks a lot for reading this! DV