Arduino AT90CAN128 Project

My Nissan Leaf Forum

Help Support My Nissan Leaf Forum:

This site may earn a commission from merchant affiliate links, including eBay, Amazon, and others.

lincomatic

Well-known member
Joined
Jun 10, 2011
Messages
316
I'm building a bare bones CAN Bus interface using Olimex's Header Board for AT90CAN128, which costs $29.95 at Sparkfun.

http://www.sparkfun.com/products/655

The goal is to do it with the Arduino IDE and my USBtinyISP programmer. I just got the board a few hours ago, and quickly got the Arduino Blink sketch up and running without a hitch:

headerboardblink.jpg


Woohoo! That was easier than I expected!
I've posted detailed instructions on how to get this board working with Arduino on my blog:

AVR CAN Bus Project Kickoff http://blog.lincomatic.com/?p=398

There's still a lot to be done. The next step is to build an interface board with a CAN bus transceiver chip, so I can connect it up to the bus, since the header board contains little more than the MCU and a voltage regulator. Then, I need to learn more about CAN bus, and how to program it, both topics of which I have zero knowledge at the moment.
 
The AT90CAN... does most of the CAN reading. The CAN-support .c and .h deliver 2 byte "header" and up to 8 bytes of data for eash CAN message.

Get the schematic for the AVR-CAN board to see what they did: basically uP, CAN transeiver, OBD-CAN interface, power regulator, and RS232 level shifter, since two UARTs are built into this Atmel uP.

What will you do with the data after you read it?

If you want to log all 4 of the LEAF's CAN busses for later examination, and are going to make a board, you might not use the header board, but put 4 CAN tranceivers and 4 AT90CAN128 chips on one board, along with an SD card.

Good work on a quick success.

What software and programmer did you use?
 
I got files called can_lib.h/cpp. What's in CAN-support.c/h and where did you get them?

Yes, I have the AVR-CAN schematic already. That's how I figured out to use the MCP2551 bus transceiver chip. I don't need a regulator, since the header board already has one, and I'm not interested in RS-232, since none of my computers have those ports. Instead I'm going to use a serial->USB converter.

Eventually, I will probably go to a custom PCB, but for now, I'm just interested getting it working.

I'm using Arduino IDE with a USBtinyISP. The USBtinyISP plugs in through the 10-pin ICSP header. This board also works w/ JTAG programmers, but I don't have one of those.

What am I going w/ the data? Monitor SOC, etc like everyone else. Eventually, I want to interface it via bluetooth to the EVSE Chris & I are designing, so that the EVSE can do fancy things like charge to 90% instead of 80% or 100%.
 
I have downloaded AVR Studio 5, but I am not using it.

I downloaded and am using the "Portable" version of WinAVR (lives on a flash-drive) on 32-bit Vista. It seems rather easy to use once one has a "clue" and a good Makefile. It has libraries that my "compile/assemble/link" might be using. Also, I was given a "working" folder of ".c" and ".h" components, at least some of which I do not use. These seem to have been prepared for a board that was only 8 MHz and had a "keypad" of some sort. It seems to have been derived from a "spy.c" CAN-reading example/sample program, probably? originally from Atmel. Finally, I am using the AVRdude that is included in WinAVR for flashing firmware.
 
I have a copy of WinAVR/avrdude as well. I've played around with it a little using Eclipse as an IDE. What do you use as an IDE, or do you just use a text editor and command line tools?

Where did you get the "working" folder of .c and .h components and spy.c? I haven only been able to locate some original sample code from Atmel, with setup instructions to go with their tools.

If you've never heard of Arduino, it's an AVR-based platform that tries to simplify things to the point that non-programmers, such as artists can use it.
http://www.arduino.cc. It has a Java-based IDE that forms a wrapper around avr-gcc/avrdude. While Arduino is designed for boards which conform to their spec, it's easy to adapt the software to work with other AVR platforms. The beauty of Arduino is that it completely hides the complexities of makefiles, etc from the user. This makes it a bit less flexible to use at times, but it simplifies the setup/build procedure immensely, and thus makes working with the AVR accessible to a lot of people who might otherwise be intimidated by it. This is why I want to get it working w/ Arduino. I don't see any well documented AT90CAN128 projects out there, so I'm hoping to help open up the world of CAN bus a bit to more people as cheaply as possible.
 
I have never used Arduino, and basically only know that it exists.

For THIS particular CAN-Project, it seemed to me that the AVR-CAN hardware was well suited, available, and appeared to be smaller in size and cost less than Arduino and Shields. With a friend to give me hints and a working program, for me, the learning curve was easier.

Since I am just working on a 4-page program, I just run (starts with a ".bat" file) the WinAVR's "ProgrammerNotepad" that is nicely integrated with the "Make Clear" and "Make All" functions.

Generally I change or add a few lines of experimental "c" code to my program, maybe a subroutine, some Declarations, etc., then just click "Make All". If there are syntax errors, the error messages link back to the offending line of source in the editor.

I then run AVRdude (via another ".bat" file), flash the AVR-CAN card, and test my changes or my "experiment".

If somebody is seriously interested, I could check to see if we can share the source code file, or the whole folder of files.
 
Right, actual Arduino hardware tends to be expensive. I use it as a convenient way to prototype, and then for more permanent projects, wire up something with a bare AVR or a cheap pcb like this http://cgi.ebay.com/ATTiny48-88-ATM...159?pt=LH_DefaultDomain_0&hash=item415b605917and a USB wall wart. It's too bad the AT90CAN128 doesn't come in a through hole version, or I would have skipped the header board. The MCU is actually quite cheap.

The Arduino IDE can be adapted to almost any AVR-based hardware, and it's easy to use for projects of low to moderate complexity. I'm sure it could be used w/ the AVR-CAN as well.

I may take you up on your offer of code sharing if I get too stuck. For now, I'm going to try to play around with it a bit. I'll be openly sharing any circuits and code that I come up with for the basic capturing of CAN Bus messages. Beyond that, I haven't decided yet what I'm going to do.

I think you're using an adaptation of Atmel's CAN library? http://www.atmel.com/dyn/resources/prod_documents/at90CANLIB_3_2.zip. The can_lib.h/cpp that I have seem to have been hacked from the files in there.
 
It took me hours of testing to get the serial port on the AT90CAN128 to communicate with my PC. I kept getting corrupted data sent back from the board, and was getting so frustrating that I was ready to give up. Finally, I figured out that Olimex doesn't properly set the fuses on the MCU before shipping them out (thanks to evnow, for giving me a piece of the puzzle). Use avrdude to set the low fuse:

avrdude -c usbtinyisp -p at90can128 -Ulfuse:w:0xFF:m

This clears CKDIV8 so that the clock runs at the proper speed.
More details in my blog:

AVR CAN Bus Project – Step 2: Programming Low Fuse http://blog.lincomatic.com/?p=415

Now, I can finally start working on wiring up the MC2551 CAN bus transceiver chip. BTW, the completed hardware will be software compatible with the AVR-CAN board, and thus, Gary's SOC meter firmware should be able to run on it, as well.
 
Got the board all wired up and ready to test. MCU board connected to the MCP2551 transceiver chip. The 6 pin header on the left allows me to select via jumpers Primary, EV, or AV CAN bus to monitor. Initially, I'm going to just power it and send data back to the host via USB while I'm developing the firmware/software. Onboard display capabilities will be added later. The board assembly was relatively easy. Now on the the hard part ... firmware & host software.

canbusboard.jpg


Schematic diagram will follow after I've had a chance to test it and make sure I didn't mess up any of the wiring.
 
Woohoo! I got live data off both the Primary and EV CAN buses! Here is my first sniffing session on the EV CAN bus:

canspy.gif


It turns out can_lib is pretty easy to use. Just a few lines of code is all you need to spy on the bus.
Yes, I know, the 38400 baud rate is too slow. This is just a screen cap of the first time I was able to read live data off the bus.

After I clean up the code a bit I'll post it.
 
Strange about the fuse setting.
I have not needed to do ANYTHING explicit with the AT90CAN128 fuses.
However, AVRdude does mention some fuses, both before and after flashing and verification. I will look at that listing.

Most fuses mentioned there seem to be "named" with 2-character names. I am not sure what I am looking for. Is there such a name for your "lfuse"?

Or, might my "library" of other source files (perhaps the one call to set up the UART 8,N,1 and 115200 baud rate) be "fixing" this problem?

Or, perhaps the AVR-CAN board is shipped with the AT90CAN128 flashed differently from the uP on the Header-Board, perhaps due to the Olimex testing of the AVR-CAN board?
 
Gary,
If you run

avrdude -c usbtiny -p at90can128 -U lfuse:r:lfuse.txt:h

(substitute your AVR programmer's name where i have usbtiny) it will dump your low fuse into lfuse.txt. I'm curious to see what you have in yours. You might be right that there's something in your software compensating for CKDIV8. I tried burning ATmel's CAN spy example into mine, and it was sending garbage to my serial port. It's possible that it doesn't like my modified fuse setting.
 
If you want your output to be compatible with our CAN-Do program:

To get the relatively fast CAN-Message data through the 115200 baud serial link, we send each message as 11 binary bytes: Sync Byte, Low-MsgID byte, High-MsgID (data length in high nibble), and 8 data bytes (padded with 0xFF as needed), as described in another thread.

The Sync byte is 0x53 EOR's with both of the following two "MsgID" bytes.

I send a few pseudo-messages with MsgID high = 0xFF, low = 0xFE, and 8 ASCII characters for the "message".

For example, I send "StartSPY" just after the UART0 is initialized. I send "CANbusON" when the CAN buss is recognized as "active".

Currently, the messages from each CAN buss arrive in the PC on a different COM Port. CAN-Do adds two bytes of "second, milli-second" time stamps as best it can, inserting "date, time" 0xFFFF pseudo messages approximately as most new minutes begin.
 
I'm curious why you use fixed length records. Since you're sending the data length, why not just send the real data byte count instead of padding with FF?

I'm a little unclear about the sync byte. When do you send it out? and is your sync message 53 FF FE?

I like your pseudo message idea. That's useful.

Do you really need to get the actual date & time in the message? I was thinking a 16-bit millisecond count is really all that's needed. It will wrap every 65 seconds, but it's easy to handle that with your pseudo messages.

How do you sync the clocks when you're monitoring 3 buses simultaneously?
 
garygid said:
lfuse = 0xCF

Before and after flashing, and
reading it as you suggested (0xcf).

Interesting ... different from my initial 4F value. Is it possible somewhere in your flashing procedure it's getting manually set?

CF means CKDIV8 isn't set. So our serial codes should be compatible.
 
You are using the Header Board, NOT the AVR-CAN board, right?

Do you have the AVR-CAN schematic?

Some pins are being used in non-standard ways, and I presume the library routines I use take that into consideration.
 
One reason I chose the AVR-CAN boards: the advantage of starting with something that already works. :)

I found that the "standard" delay subroutines were set up for 8 Mhz, not 16 MHz, and changing the global speed caused overflow(s). So, I quickly (but less accurately), made my own.
We do have some more-accurate routines, but I have not had the time to use these, and the accuracy is not yet necessary in my code.
 
garygid said:
You are using the Header Board, NOT the AVR-CAN board, right?

Do you have the AVR-CAN schematic?

Some pins are being used in non-standard ways, and I presume the library routines I use take that into consideration.

I don't know which pins you're referring to. The AVR-CAN schematic looks like a straightforward implementation.

The Arduino code is easy to scale for clock speeds. Just a change to the CPU frequency in boards.txt. The routines they use are pretty good. You can get them by downloading the latest Arduino distribution from http://www.arduino.cc. All source code is included. You should try it out. The coding is a lot easier. I can help you set it up for the AVR-CAN board if you like.
 
Back
Top