Teensy 3.1 and CAN Bus

OK thank you Fyod,

i will test later, but if it works fine in your tests, it should be fine here too.

I just hope that i don't have to do too many changes in my arduino sketch to get it running with the teensy.
 
Hello,

everything is fine, i can receive everything i need :)

But what about sending messages?
i know it is "Can.write(msg)" but how should the message look like?
i.e. i have something to send like:

Code:
unsigned char fanspeed[8]          = {0x02, 0x01, 0x10, 0x21, 0x01, 0xFF, 0x03, 0x02};

how do i send this 8 bytes with FlexCan Library?

In Arduino it is very easy:

Code:
CAN.sendMsgBuf(0x020, 0, 8, fanspeed);

Sorry, FlexCan Lib is very new to me.

Thanks

BR
Thomas
 
I have searched the forum and have not seen a definitive answer if the FlexCAN library works with extended ID (29 bit) which is required for J1939.

I can see the ID is defined as a unsigned 32 bit variable but I am not quite sure how the library will be configured for 29 bit ID is if this is done based on the ID value?

Thanks

Bruce
 
I have searched the forum and have not seen a definitive answer if the FlexCAN library works with extended ID (29 bit) which is required for J1939.

I can see the ID is defined as a unsigned 32 bit variable but I am not quite sure how the library will be configured for 29 bit ID is if this is done based on the ID value?

Thanks

Bruce


Yes Flex can does work with with j1939, earlier in this thread i posted a snippet of code i use for extracting active fault codes. For receiving extended messages i did not need to make any changes, but for sending extended messages i believe you need to set EX = 1; I don't have the code in front of me at the moment.
 
... for sending extended messages i believe you need to set EX = 1; I don't have the code in front of me at the moment.
Yes, looking at the code, one would use, eg:
CAN_message_t msg;
msg.ext = 1; // set message-type to extended.

Further, I think we should change to .ext to boolean type, or at least define some constants: CAN_STD=0 and CAN_EXT=1, say.

David
 
Hi,

I have two cards teensy 3.1, connecting pin 3 to pin 4 of the second card and pin 4 of the first scehda to pin 3 of the second, you can get them to communicate with the library through CANBUS FlexCan?

Thank you
 
I have two cards teensy 3.1, connecting pin 3 to pin 4 of the second card and pin 4 of the first scehda to pin 3 of the second, you can get them to communicate with the library through CANBUS FlexCan?

I'm pretty sure the CAN hardware looks at the RX pin while transmitting, so you can't get 2 chips to talk by just connecting TX to RX and RX to TX, as you would for normal serial.

However, you might be able to get it working with diodes and a resistor, or with a logic gate like 74HC08. Here's an app note with the resistor+diodes way.
 

Attachments

  • siemens_AP2921.pdf
    19.8 KB · Views: 285
This may be stating the overly obvious, but also make sure you have a good ground connection between the boards. This scheme won't have great noise margin with the diodes, so a good common ground is essential.
 
This may be stating the overly obvious, but also make sure you have a good ground connection between the boards. This scheme won't have great noise margin with the diodes, so a good common ground is essential.

Using just the diodes works, I have tried it. However it is not a very robust system, but would be ok for a small (both in number of nodes and length of bus) system.
 
Thanks for the answers, since I'm a programmer and are not very experienced with electronics, now own two cards teensy 3.1, I can indicate the electronic components to be purchased?

Thank you
 
I have a problems getting the Teensy 3.1 to send CAN packets.
My program receives the CAN packets without a problem so I assume this means the transceiver is wired up correctly.
I am using the SN65HVD230, VS is pulled to ground and VRef is left floating

This is the code to send
msg.len = 8;
msg.id = 0x222;
for( int idx=0; idx<8; ++idx ) {
msg.buf[idx] = '0'+idx;
}
if (CANbus.write(msg) == 0)
Serial.println("Write failed");
else
Serial.println("Write OK");

The first eight writes return "Write OK" then every write fails because the TX buffers are full.
I don't see any 222 messages on my CAN bus Analyzer.

Any idea what I am doing wrong.
 
I have had similar woes with the SN65, but haven't had time to look further into it.
In my case, reading from a VW CAN simulator and a PC also connected to the network via serial CAN tx, when the SN65 started reading, it caused the PC to get kicked off the CAN network.
I don't have any problems with the MCP2551 chip.
Not sure if this has anything to do with your case, just wanted to mention that the SN may require something that's getting overlooked (atleast in my case).
 
Last edited:
I am using the SN65HVD230, VS is pulled to ground and VRef is left floating
Is there any CAN device actively receiving/acking the CAN packets in the network (not sure if the CAN analyzer is passive or active)? Is the baudrate correct?
 
I had the MCP2551 and a 5v regulator in my first tests, this did the exact same thing.
I have an ECU and the Microchip CAN Analyzer connected to the bus.
No errors showing on the bus.
Speed is set to 500kbps and CAN read works so the speed is correct.
I have also tried a different ECU and no ECU (Just 120 ohm resistor)

I wonder what conditions will stop the Teensy from trying to send the message in the TX buffer.
 
I had the MCP2551 and a 5v regulator in my first tests, this did the exact same thing.
I have an ECU and the Microchip CAN Analyzer connected to the bus.
No errors showing on the bus.
Speed is set to 500kbps and CAN read works so the speed is correct.
I have also tried a different ECU and no ECU (Just 120 ohm resistor)

I wonder what conditions will stop the Teensy from trying to send the message in the TX buffer.

What ECU are you using? Do you use the 120 ohm resistor together with the ECU? Did you try connecting the analyzer directly to the Teensy CAN RX/TX pins (I believe it has an option to do so)?
 
Support for 33.3kbps SWCAN

Hi,
A while back ( https://forum.pjrc.com/threads/24720-Teensy-3-1-and-CAN-Bus?p=44082&viewfull=1#post44082 ) there was some discussion about adding some other CANbus speeds that seems to have been dropped.

I would like to com with the GM single wire can bus (SWCAN) on my Chevy SparkEV. I'm using a Freescale MC33897 single wire CAN transceiver with Collins Kidders due_can software on a Arduino due board with a custom shield and would like to use Teensy 3.2 instead. I tried to add in the function above but get a bunch of define errors. Looks like it's missing a header file. I have not contacted the author, uTasker yet.

My reason for posting here though, is that I haven't seen much discussion about SWCAN. SWCAN seems far more applicable to what people do with the Teensy than regular CAN. With SWCAN you can have a remote node sitting on a 5-26V bus that is 'sleeping @ 60uA'. When a 'WakeUp' message is sent on the bus the transceiver can wake up the teensy to check if it is interested in the ID and then the Teensy can go back to sleep or do whatever. This isn't possible with differential CAN, infact GM uses the SWCAN to wake up it's high speed network in many cases.

On the SparkEV the SWCAN is what all the human interface uses, i.e. door switch, seat sensors, shift position, radio and steering column switches ect. Lots of playing to be had.
 
I changed the CAN chip to the MCP2561 and the CAN TX works.
The SN65HVD230 should work but does not.
On the SN65HVD230 I have the VS pin pulled to ground, I also tried with slope shaping by using a 67kohm resistor to ground (PDF shows 10k-100k for slope shaping).

Has anyone used the SN65HVD230 and managed to send CAN messages. I can receive without a problem.
 
I changed the CAN chip to the MCP2561 and the CAN TX works.
The SN65HVD230 should work but does not.
On the SN65HVD230 I have the VS pin pulled to ground, I also tried with slope shaping by using a 67kohm resistor to ground (PDF shows 10k-100k for slope shaping).

Has anyone used the SN65HVD230 and managed to send CAN messages. I can receive without a problem.
In general I didn't have problems with the 230 chip, except one particular batch, which I've received twice from different sellers. It was labeled 42M and refused to work correctly.
 
Looks like ALOT of different experiences going on with the CAN transceivers in the thread!
Have read this thread back to front a few times and looks like some people have got the MCP2551 working for reading and writing whereas others have not.

I tried getting my MCP2551 and MCP2562 transceivers working with the ECU setup on bench.. and they will READ the bus messages but will not WRITE to the bus.
The read messages are 100% correct as checked with an ELM327 at the same time. Except nothing ever sends!
The buffers all get loaded up.. and a "successful" response is returned from the flex library for all 8 buffers.. but nothing actually pops out of the other end.


I can get the CAN interface working using a different can chip that works at 100kb/s so I can confirm wiring is correct and power it all ok!. The chip is made for slower rates thus 100kb/s is max.
Iv noticed that the Teensy does not send if it detects there is something wrong on the bus.. so when I had no other devices connected to the teensy.. it would load all 8 buffers for each message and not send any of them.
The moment I added the Teensy to the canbus line, it then begun working, send off all buffers and continued sending frames!

Soooooo... The teensy must have some sort of error checking of some sorts?. Which disables the TX and re-enables when ok.

As for coding, Iv stuck with the basic example simply to test, using the same setup CAN message in a loop with a 1000ms delay between writes. And have simply put Serial debug messages in the Flex library to check what the registers are doing.

Has anyone looked any further into the erroring side of the Teensy driver? Setting specific error bits?.
 
Right so everyones on the same page that wants to tinker.. The reference manual can be found here (Its already uploaded on this site):
https://www.pjrc.com/teensy/K20P64M72SF1RM.pdf

Page 38 and 39 are the headings.
And pages 1039 through to 1114 cover everything to know about the can implementation.

Right... soooo... error sections.....
44.3.8 Error Counter (CANx_ECR)
44.3.9 Error and Status 1 register (CANx_ESR1).
44.3.13 Error and Status 2 register (CANx_ESR2)

Page 1042 acknowledges something interesting as well.. this feature:
"SYNC bit status to inform that the module is synchronous with CAN bus"
This could also be handy for alot to indicate if they have their CAN timing correct.


Sooooo... a quick hack together in the flex library:
// -------------------------------------------------------------
uint8_t FlexCAN::ErrorCounter(bool RXorTX)
{
if (RXorTX == 0){return (FLEXCAN0_ECR >> 8);}//shift 8 for RX
else {return (FLEXCAN0_ECR);}

}

// -------------------------------------------------------------
uint32_t FlexCAN::ErrorReport(void)
{
return (FLEXCAN0_ESR1);

}

Also need to add in the header for both functions.

Error count grabs the RX or TX error counts. While testing, I see that my RX has 0 RX issues.. but my TX constantly increases (Gets to 128 then resets as per the reference manual).

For the first two WRITE attempts, I get this:
Write1
CAN RX Error Count: 0
CAN TX Error Count: 57
Error Status: 100000000110110

Write2
CAN RX Error Count: 0
CAN TX Error Count: 111
Error Status: 100001000110110

Only difference is bit 9 which is TXWRN which means repetitive errors during message transmission have occured.

Bit 4 and 5 indicate the Fault confinement State where we can have the following conditions:
00 Error Active
01 Error Passive
1x Bus Off

Soooo... since its 11.. means I have both Error Passive and Bus Off state.

Bus Off state prevents me from writing... but still continues to allow reading. (Sound familiar!!???!!).

Ill keep on tinkering....
 
Added some error code status decoding to help along.. and the first two writes get:

CAN RX Error Count: 0
CAN TX Error Count: 55
Wakeup Error: No
Error Interrupt: Yes
Bus Off Interrupt: Yes
FlexCAN Receiving: No
Error Passive
Bus Off: Yes
FlexCAN Transmitting: No
Idle: No
RX Error Warning: No
TX Error Warning: No
Stuffing Error: No
Form Error: No
CRC Error: No
ACK Error: No
Bit0 Error: Yes
Bit1 Error: No
RX Warning Interrupt Flag: No
TX Warning Interrupt Flag: Yes
FlexCAN Synchronized: No
100100000000110110


CAN RX Error Count: 0
CAN TX Error Count: 224
Wakeup Error: No
Error Interrupt: Yes
Bus Off Interrupt: Yes
FlexCAN Receiving: No
Error Passive
Bus Off: No
FlexCAN Transmitting: Yes
Idle: No
RX Error Warning: No
TX Error Warning: Yes
Stuffing Error: No
Form Error: No
CRC Error: No
ACK Error: No
Bit0 Error: Yes
Bit1 Error: No
RX Warning Interrupt Flag: No
TX Warning Interrupt Flag: Yes
FlexCAN Synchronized: Yes
1100100001001010110

So Bus Sync is going in and out... hmmm... seems I must be missing something..

*Edit
Changed the resistor on the RS pin of the MCP2551 to 10k (Had 22k on it.. oops..) and writing now works
Infact, wiring RS straight to ground has it working also, so anyone thats using the MCP2551, I have it wired up as follows:

1 -> CAN TX
2 -> GROUND (Connected to Teensy ground and OBD2 ground)
3 -> 5v from Teensy Vin pin (5v is from the USB)
4 -> CANRX
5 -> NOT CONNECTED (Vref)
6 -> CANL to OBD2 CANL
7 -> CANH to OBD2 CANH
8 -> RS to Ground

I attempted using the MCP2562 chip again.. and still no luck even with its stby pin set to ground.. unsure why thats not cooperating.

I do hope the above helps others out!
 
Last edited:
Also, I tried disabling the registry error control to prevent the bus off from being able to occur, and when that bit is set to 0, the teensy actually freezes on that exact point... almost like it just couldnt accept that change.
I put the CAN into freeze mode as its required and waited for that freeze to be acknowledged, but still fails to continue after setting that bit.

The Error reporting should be added into the flexCAN library though. The tiny amount of code I posted above in the library is enough to get the actual faults.. and its just a matter of decoding it so you can see whats happening. In my case I was having syncing issues which led me to checking out the RS slope ect. Very handy for fault finding.

Im thinking of adding in an error variable in the CANmsg structure... theres actually 16 bits which are error related so a 16bit int could be used to indicate any faults when receiving or sending.

Also, adding a timer to the write procedure to check if the loaded buffer actually sends off.. if not.. allocate an error and check error registry. Otherwise you end up loading up all 8 buffers.. and nothing happens!!!
There shouldnt.. really.. be any point where you can load up the buffers faster then the teensy pumps them out.. so waiting for each buffer to actually fire off is the best answer... otherwise the current setup is reporting "Yes Iv sent the frame!!" even though it hasnt and its only stored it in the buffer.
I mean, I think the fastest Iv seen something pumped out was 0.5ms (500microseconds) from a tuning tool programming an ECU on 500kb/s CAN. No point loading faster then it can be sent!

If someones interested in helping out, Id be happy to help contribute to the library. Some useful functions such as "Send And Receive" would be useful to alot. And frame management to allow for multiple different tasks be performed on the same received frame neatly in the project (Eg. Send via debug, Check against eeprom memory, send via bluetooth ect).

Just my 2cents!. :)
 
Back
Top