handmade0octopus / esp32-twai-can Goto Github PK
View Code? Open in Web Editor NEWESP32 driver for TWAI / CAN for adruino
License: MIT License
ESP32 driver for TWAI / CAN for adruino
License: MIT License
Hey,
thank you for creating this repo of using CAN BUS, really came in handy.
At first it didnt quite work for me until i read again the datasheet of my chip "SN65HVD230" and released i am missing an enable pin.
Hence, i would like to suggest to add 2 example codes i wrote in a fork from this repo and include communication between 2 ESP's based on your code and SN65HVD230 RS Enable/Standby pin.
Hi handmade0octopus,
first of all thank you very much for creating this library.
After some hours of analysing I was able to modify your code to be more general and more explaining.
I post this demo-code here. You might want to remove the debug-macros that are at the to
// MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START *
// a detailed explanation how these macros work is given in this tutorial
// https://forum.arduino.cc/t/comfortable-serial-debug-output-short-to-write-fixed-text-name-and-content-of-any-variable-code-example/888298
#define dbg(myFixedText, variableName) \
Serial.print( F(#myFixedText " " #variableName"=") ); \
Serial.println(variableName);
#define dbgi(myFixedText, variableName,timeInterval) \
{ \
static unsigned long intervalStartTime; \
if ( millis() - intervalStartTime >= timeInterval ){ \
intervalStartTime = millis(); \
Serial.print( F(#myFixedText " " #variableName"=") ); \
Serial.println(variableName); \
} \
}
#define dbgc(myFixedText, variableName) \
{ \
static long lastState; \
if ( lastState != variableName ){ \
Serial.print( F(#myFixedText " " #variableName" changed from ") ); \
Serial.print(lastState); \
Serial.print( F(" to ") ); \
Serial.println(variableName); \
lastState = variableName; \
} \
}
#define dbgcf(myFixedText, variableName) \
{ \
static float lastState; \
if ( lastState != variableName ){ \
Serial.print( F(#myFixedText " " #variableName" changed from ") ); \
Serial.print(lastState); \
Serial.print( F(" to ") ); \
Serial.println(variableName); \
lastState = variableName; \
} \
}
// MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END *
/*
Serial.begin(115200);
Serial.println("Setup-Start");
PrintFileNameDateTime();
BlinkHeartBeatLED(OnBoard_LED,250);
static unsigned long MyTestTimer;
if ( TimePeriodIsOver(MyTestTimer,1000) ) {
*/
#include <ESP32-TWAI-CAN.hpp>
// Showcasing simple use of ESP32-TWAI-CAN library driver.
// Default for ESP32
const byte CAN_TX = 5; // which means connect GPIO-Pin with this number with the Tx-output on the CAN-transeiver
const byte CAN_RX = 4; // which means connect GPIO-Pin with this number with the Rx-input on the CAN-transeiver
CanFrame rxFrame;
int myCounter;
void setup() {
Serial.begin(115200);
Serial.println("Setup-Start");
PrintFileNameDateTime();
Serial.println();
// You can set custom size for the queues - those are default
byte QueueSize = 5;
ESP32Can.setRxQueueSize(QueueSize);
ESP32Can.setTxQueueSize(QueueSize);
Serial.print("ESP32Can.setRxQueueSize(");
Serial.print(QueueSize);
Serial.println(")");
Serial.print("ESP32Can.setTxQueueSize(");
Serial.print(QueueSize);
Serial.println(")");
int CAN_Speed = 500;
Serial.print("ESP32Can.begin(ESP32Can.convertSpeed(");
Serial.print(CAN_Speed);
Serial.print("), CAN_TX=");
Serial.print(CAN_TX);
Serial.print(", CAN_RX=");
Serial.print(CAN_RX);
Serial.print(", 10, 10) )");
Serial.println();
// for what reason ever this number / 2 = kbs kilobits per second
// this odd convertSpeed-function needs (500 / 2) as input to configure the canbus-speed 500 kbs
if (ESP32Can.begin(ESP32Can.convertSpeed(CAN_Speed / 2), CAN_TX, CAN_RX, 10, 10) ) {
Serial.println("CAN bus started successfully!");
}
else {
Serial.println("starting CAN bus failed!");
}
}
void loop() {
static unsigned long MyTestTimer;
if ( TimePeriodIsOver(MyTestTimer, 400) ) {
myCounter++;
if (myCounter > 999) {
myCounter = 0;
}
sendCanFrame('A', myCounter);
}
// You can set custom timeout, default is 1000 milliseconds
if (ESP32Can.readFrame(rxFrame, 100)) {
// Comment out if too many frames
Serial.printf("Received frame: %03X \r\n", rxFrame.identifier);
if (rxFrame.identifier == 0x7E8) { // Standard OBD2 frame responce ID
Serial.printf("Collant temp: %3d°C \r\n", rxFrame.data[3] - 40); // Convert to °C
}
}
}
void sendCanFrame(uint8_t obdId, int Number) {
char myDigitBuffer[10] = " ";
itoa(Number, myDigitBuffer, 10); // itoa convert integer to ASCII-coded char-array
CanFrame myDataFrame = { 0 };
//obdFrame.identifier = 0x7DF; // Default OBD2 address;
myDataFrame.identifier = 0x7FF;
myDataFrame.extd = 0;
myDataFrame.data_length_code = 8;
myDataFrame.data[0] = myDigitBuffer[0];
myDataFrame.data[1] = myDigitBuffer[1];
myDataFrame.data[2] = myDigitBuffer[2];
myDataFrame.data[3] = 'H';
myDataFrame.data[4] = 'e';
myDataFrame.data[5] = 'l';
myDataFrame.data[6] = 'l';
myDataFrame.data[7] = 'o';
// Accepts both pointers and references
printCanFrame(myDataFrame);
ESP32Can.writeFrame(myDataFrame); // timeout defaults to 1 ms
}
void printCanFrame(CanFrame p_CAN_Frame) {
Serial.println("sending CAN-frame");
Serial.print("identifier=");
Serial.print(p_CAN_Frame.identifier, HEX);
Serial.print(" frame length=");
Serial.print(p_CAN_Frame.data_length_code);
Serial.print(" data as ASCII-Code#");
for (byte IdxNr = 0; IdxNr < 8; IdxNr++) {
Serial.print(char(p_CAN_Frame.data[IdxNr]) );
}
Serial.print("#");
Serial.println();
}
// helper-functions
void PrintFileNameDateTime() {
Serial.println( F("Code running comes from file ") );
Serial.println( F(__FILE__) );
Serial.print( F(" compiled ") );
Serial.print( F(__DATE__) );
Serial.print( F(" ") );
Serial.println( F(__TIME__) );
}
// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
unsigned long currentMillis = millis();
if ( currentMillis - startOfPeriod >= TimePeriod ) {
// more time than TimePeriod has elapsed since last time if-condition was true
startOfPeriod = currentMillis; // a new period starts right here so set new starttime
return true;
}
else return false; // actual TimePeriod is NOT yet over
}
void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
static unsigned long MyBlinkTimer;
pinMode(IO_Pin, OUTPUT);
if ( TimePeriodIsOver(MyBlinkTimer, BlinkPeriod) ) {
digitalWrite(IO_Pin, !digitalRead(IO_Pin) );
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.