have you tried starting the I2C before and after flexcan begin?
do you have a sketch?
have you tried different I2C clockspeeds?
did you try modifying the flexcan clock?
Canx.setClock(CLK_60MHz) - check source for different values
have you tried starting the I2C before and after flexcan begin?
do you have a sketch?
have you tried different I2C clockspeeds?
did you try modifying the flexcan clock?
Canx.setClock(CLK_60MHz) - check source for different values
Last edited by tonton81; 08-11-2020 at 03:01 PM.
Ok, so tried to move the <Wire.h> and <FlexCAN_T4> include statements before and after each other. Tried beginning the wire library before and after the can libraries and tried all available Wire.setClock(); speeds including; 10000, 100000, 400000, 1000000 and 3400000. For everything that i changed, the only thing that displays the correct data is if i don't call the can read subroutines
And the can clock speeds are already set to 60MHZ.
#include <FastTouch.h> // capacitive touch library
#include <EEPROM.h> // eeprom access memory
#include <FlexCAN_T4.h> // flexcan library for teensy
#include <Wire.h> // I2c wire library
//#include <ds3231.h> // RTC library
#include <stdio.h> // 10 DOF GY-87
#include <math.h> // 10 DOF GY-87
#include "I2Cdev.h"
#include "HMC5883L.h"
#include <nRF24L01.h> // Radio comms library (MUST BE AFTER FLEXCAN)
#include <RF24.h> // Radio comms library
#include <SPI.h> // SPI comms library
void setup()
{
Serial.begin(115200);
Serial.println("5 inch NEXTION DISPLAY");
Serial.println("I2C begin"); // begin i2c
Wire.setSDA(18); // declare SDA pin
Wire.setSCL(19); // declare SCL pin
Wire.begin(); //start i2c (required for connection) to REAL TIME CLOCK
Wire.setClock(400000);
Serial.println("CAN2 begin"); // can2 begin
Can0.begin();
Can0.setBaudRate(500000); // can2 set baud
Can0.setClock(CLK_60MHz); // can2 clock speed
Can0.enableFIFO(); // can2 fifo
// Can0.enableFIFOInterrupt(1);
// Can0.mailboxStatus();
Serial.println("CAN1 begin"); // can1 begin
Can1.begin();
Can1.setBaudRate(500000); // can 1 set baud 500kb/s
Can1.setClock(CLK_60MHz); // can 1 clock speed
Can1.enableFIFO(); // can 1 fifo
// Can1.enableFIFOInterrupt(1);
// Can1.mailboxStatus();
which specific subroutine causes it to not work? (you said read one..?which)
Hi tonton81,
You were right, finally I have read through the Flexcan part of the IMXRT1062 manual, and it helped a lot to understand the process.
https://www.pjrc.com/teensy/IMXRT1060RM_rev2.pdf
Laszlo
found the problem? I don't think the I2C has any influence on flexcan it should work fine, the triple CAN board from skpang uses an I2C display addon.
Hey tonton81,
here is the loop and sub routines;
if i comment out both CAN_READ(CANREP); and CAN1_READ(CANREP); so that can is not read by the subroutine at all, the i2c data is fine, as soon as can is read, the i2c data changes
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop() {
op_timer = micros();
if ((op_timer - op_gy87) > 20)
{
GY87_READ_SENSORS(); // request I2C data from GY-87
if(SHOW_GY87 == 1){GY87_DISPLAY_DATA();} //display GY-87 data on serial if enabled
op_gy87 = micros();
}
CAN_READ(CANREP); // read Can2 (repeat CANREP number of times)
CAN1_READ(CANREP); // read Can2 (repeat CANREP number of times)
SERIAL_READ_RH(5); // read serial from right screen 5 times
SERIAL_READ_LH(5); // read serial from left screen 5 times
READ_TOUCH();
LED_WARN();
CONSUMPTION(); // updates consumption data from flow meter data
if ((op_timer - op_nextion) > 1000)
{
UPDATE_NEXTION(); // update Nextion screens
op_nextion = micros();
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CAN2 READ CAN2 READ CAN2 READ CAN2 READ CAN2 READ CAN2 READ CAN2 READ CAN2 READ //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void CAN_READ(int rep) {
//Serial.println();
//Serial.println("READ CANBUS 2");
for ( int i = 0 ; i < rep ; i++)
{
if (Can0.read(rxmsg))
{
len = rxmsg.len;
CANRXID = rxmsg.id;
if (SHOW_CAN == true)
{
Serial.println(); Serial.print("RAW ID> "); Serial.print(CANRXID); Serial.print(" RAW LEN> "); Serial.print(len);
}
CONVERT(); // switch case populate can data into variables and conversion calculations
sprintf(msgString, "Standard ID: 0x%.3lX DLC: %1d Data:", CANRXID, len);
if (SHOW_CAN == true) {
Serial.print(msgString);
}
if (SHOW_CAN == true)
{
for (byte i = 0; i < len; i++)
{
sprintf(msgString, " 0x%.2X", rxmsg.buf[i]);
Serial.print(msgString);
int NUMb = rxmsg.buf[i];
Serial.print(" ("); Serial.print(NUMb); Serial.print(")");
}
Serial.print(" MICROS "); Serial.print('\t'); Serial.println(micros());
}
}
// Can0.mailboxStatus();
}
UPDATE_VARIABLES(); // update variable database
delayMicroseconds(CANDELAY);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CAN1 READ CAN1 READ CAN1 READ CAN1 READ CAN1 READ CAN1 READ CAN1 READ CAN1 READ //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void CAN1_READ(int rep) {
// Serial.println("READ CANBUS 1");
for ( int i = 0 ; i < rep ; i++)
{
if (Can1.read(rxmsg))
{
len = rxmsg.len;
CANRXID = rxmsg.id;
if (SHOW_CAN == true)
{
Serial.println(); Serial.print("RAW ID> "); Serial.print(CANRXID); Serial.print(" RAW LEN> "); Serial.print(len);
}
CONVERT(); // switch case populate can data into variables and conversion calculations
sprintf(msgString, "Standard ID: 0x%.3lX DLC: %1d Data:", CANRXID, len);
if (SHOW_CAN == true) {
Serial.print(msgString);
}
if (SHOW_CAN == true)
{
for (byte i = 0; i < len; i++)
{
sprintf(msgString, " 0x%.2X", rxmsg.buf[i]);
Serial.print(msgString);
int NUMb = rxmsg.buf[i];
Serial.print(" ("); Serial.print(NUMb); Serial.print(")");
}
Serial.print(" MICROS "); Serial.print('\t'); Serial.println(micros());
}
}
// Can1.mailboxStatus();
}
delayMicroseconds(CANDELAY);
UPDATE_VARIABLES(); // update variable database
if (SHOW_DATA == true)
{
DISPLAYDATA();
}
}
the subroutine reads the canbus and sends the data to CONVERT(); a conversion routine which bitshifts, does some math and populates a data array for ecu values based on the canrx id. So the CAN side of things works fine but as soon as it is executed it corrupts the incoming data from I2C
very odd, there is no trickery in the read (polling) function, and it doesn't play with timers, interrupts, or other hardware, just reads the memory of the mailbox, what happens if you comment out all those functions CAN_READ and just put a dummy Can0.read(msg) in the loop without handling it?
I'll give it a try and let you know
Just wanted to say thanks for this library. Was able to test all 3 can channels concurrently on T4.1. Test was listen only, for now, 3 separate buses.
Can anyone confirm that can2 & can3 alternate pins are not available on the T4.1?
the only difference between 4.0 and 4.1 is that CAN3 has been routed to pins 30 and 31 at edge of board, the other CAN1 and CAN2 have same regular and alternate pins. It's already updated in the library
Hello,
Can anybody help me to understand, how to use the Waveshare can transceiver SN65HVD230 chip? I want to close the canbus ends with 2pcs separated 120 ohm resistor, so I dont need resistor on the transceiver board. Can I turn it off somehow? There is a jumper on the board, but if I close it, it make a short between the canH and canL, what is not good I think (what is the function of this jumper?). I have removed the resistor from the board, and now I can measure 70ohm between canH and canL. I hoped there will be a brake between them. So now I am lost.
Thanks
Looking at pictures of that board, the "jumper" on the board is probably not meant to be a jumper. More likely its just a 2pin 0.1inch header for connecting to CAN_H/CAN_L. You can connect via this header and/or via the screw terminals. I have no guess as to why you are measuring 70ohms between CAN_H and CAN_L with no termination resistors connected.
Ah, you are right. It must be a connector.
I have sent the question to the Waveshare support.
Hi guys. I'm hoping someone can advise on why I can't seem to read the CAN stream on my car.
I'm using a Teensy 4.0, latest FlexCAN_T4 and a SN65HVD230 CAN transceiver.
I am using the basic barebones code below and using the wiring as shown in the image, unfortunately I am not getting and CAN id's dumped to the Serial monitor and I was wondering if I have done something wrong.
the board is wired as belowCode:#include <FlexCAN_T4.h> FlexCAN_T4<CAN3, RX_SIZE_256, TX_SIZE_16> canBus; static CAN_message_t dashMsg; void setup() { // Init Serial Serial.begin(9600); // while (!Serial) ; // wait for Arduino Serial Monitor Serial.println("Teensy 4.0 CAN Example test"); // Init CAN canBus.begin(); Serial.println("begin"); canBus.setBaudRate(1000000); Serial.println("setbaud"); // Turn LED on pinMode(13, OUTPUT); digitalWrite(13, HIGH); } void loop() { // Get CAN Messages & Update values if (canBus.read(dashMsg) ) { // Flash onboard LED digitalWrite(13, LOW); Serial.println("read"); // Get ID String id = String(dashMsg.id, HEX); Serial.println(id); // Flash onboard LED digitalWrite(13, HIGH); } }
Orange CanL
Yellow CanH
I've added a few print stages just so I could see where it is getting to and it appears to be failing when it gets to the "if (canBus.read(dashMsg) )" line.
I've tried it on the other CAN ports on the Teensy, it's just on pin 14&15 (CAN3) for this last test. I was grasping at straws and tried 0,1 & 2 first.
At this stage I'm lost and will try anything.If anyone has a sniffer code or anything else they suggest I try I'll happily give it a go !
How are you connecting it to your car ?
Are you sure the baud rate is 1000000 on your car ?
Apologies, I didn`t add that. I`m running DTA S80Pro standalone ECU, connected to the CanH & L wires.
From DTA spec.
"CAN bus Baud Rate 1 MBd
Identifiers All 29Bit
6 Data Packets All 8 Bytes Ea.
Send Frequency 10 - 50Hz
All Data Values 16 Bit Signed Sent LSB First (Little Endian)"
Pin 14&15 is not CAN3.
Try and use
FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> can1;
On pin
CRX1 pin 23
CTX1 pin 22.
I have got the answer from the support, I can remove the 120 ohm resistance. I hope it will work. It would be very simple to make a jumper or dip-switch for this function.
Tonton,
Man. This is glorious. Very easy to set up and use. My 4.1 is humming along using this library. Very well done!
I`m stuck trying to write to the Canbus.
I'm running a standalone automotive DTA ECU and digital dash. The ECU canbus output data is read on the digital dash AND on the Teensy. I've removed most of the code that does that, but left in the part that looks at 1013 just to show it works and so I can see the canbus read is working correctly. My larger code reads every data point the ECU is outputting but that will just clutter up this sketch so I've removed it.
I am measuring EGT via a MAX31855 board. This is saved as the variable egt and that's what I want to send to the digital dash via the Canbus.
I have set the digital dash to look at HEX address 1500 and display the EGT value. The dash is set to receive LSB/MSB format.
When this was done on an Arduino UNO using the mcp_can library it worked and the dash displayed the correct value which was averaged over 3 consecutive values. The code for that is below for completeness.
Code:#include <SPI.h> #include "Adafruit_MAX31855.h" #include <mcp_can.h> Adafruit_MAX31855 thermocouple(7,6,5); MCP_CAN CAN(9); unsigned char canMsg[2]; int lastReads[2]; void setup() { Serial.begin(115200); while(!Serial) delay(1); delay(500); while(CAN_OK != CAN.begin(CAN_1000KBPS)) delay(100); lastReads[0] = (int) 0; lastReads[1] = (int) 0; lastReads[2] = (int) 0; } void loop () { double c = thermocouple.readCelsius(); if (isnan(c) || c < 10) { Serial.println("Error"); } else { lastReads[2] = (int) c; long total = 0L; for (int i=0; i<3; i++) { total += lastReads[i]; lastReads[i] = lastReads[i+1] } int average = ((float) sum) / 3; canMsg[0] = (int) average & 0xFF; canMsg[1] = (int) average >> 8; CAN.sendMsgBuf(5376, 1, 2, canMsg); } delay(50); }
I've tried to port it across to the Teensy using FlexCAN but I'm stuck. Obviously I'm doing something wrong in the write part of the sketch but I have absolutely no idea what.
Code:#include <FlexCAN_T4.h> #include <SPI.h> #include "Adafruit_MAX31855.h" FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> canBus; static CAN_message_t dashMsg; #define MAXDO 12 #define MAXCS 10 #define MAXCLK 13 Adafruit_MAX31855 thermocouple(MAXCLK, MAXCS, MAXDO); int curRpm, curTps, curAirTemp, curWaterTemp; double egt =0; double ambient =0; void setup() { Serial.begin(115200); Serial.println("Setup"); // Init CAN canBus.begin(); canBus.setBaudRate(1000000); } void loop() { GetThermocouple(); GetDisplayValues(); canBus.events(); Serial.println("Sending ..."); CAN_message_t msg; msg.len = 8; msg.id = 0x1500; // address ID msg.buf[0] = (int) egt & 0xFF; //LSB msg.buf[1] = (int) egt >> 8; //MSB msg.buf[2] = 3; msg.buf[3] = 4; msg.buf[4] = 5; msg.buf[5] = 6; msg.buf[6] = 7; msg.buf[7] = 8; canBus.write(msg); delay(100); // Get CAN Messages & Update values if (canBus.read(dashMsg) ) { String dtaId = String(dashMsg.id, HEX); // Check ID and update values if (dtaId == "1013") { Group1013(); } } } void Group1013() { curRpm = (int) word(dashMsg.buf[1], dashMsg.buf[0]); curTps = (int) word(dashMsg.buf[3], dashMsg.buf[2]); curWaterTemp = (int) word(dashMsg.buf[5], dashMsg.buf[4]); curAirTemp = (int) word(dashMsg.buf[7], dashMsg.buf[6]); } void GetDisplayValues() { // Display CAN data for each group Serial.println("0x1013 - RPM: " + String(curRpm) + " | TPS: " + String(curTps) + " | Water Temp (C): " + String(curWaterTemp) + " | Air Temp (C): " + String(curAirTemp)); } void GetThermocouple() { Serial.print("ambient = "); double ambient = (thermocouple.readInternal()); Serial.print(ambient); double egt = thermocouple.readCelsius(); Serial.print(" EGT= "); Serial.println((egt)); }
Thats an extended ID, try
Code:msg.flags.extended = 1;
tried it here, is this correct?
/snip of code/ still reading zero on the dash.
Code:CAN_message_t msg; msg.len = 8; msg.flags.extended = 1; msg.id = 0x1500; // address ID msg.buf[0] = (int) egt & 0xFF; //LSB msg.buf[1] = (int) egt >> 8; //MSB msg.buf[2] = 3; msg.buf[3] = 4; msg.buf[4] = 5; msg.buf[5] = 6; msg.buf[6] = 7; msg.buf[7] = 8; canBus.write(msg);