USB2CAN with Arduino UNO

Hi everyone,

During a project, I have built a CAN architecture with Arduino compatibility. I used the CAN shield from Sparkfun using the MCP2515 with the Arduino UNO.
By using an existing CAN library (http://modelrail.otenko.com/arduino/arduino-controller-area-network-can), I got a simplified protocol to communicate information from sensors and actuators through my nodes.
The next step would be to use the UNO as a programmer in order to reconfigure a node through the CAN bus by sending the program from the PC to the node using the USB and CAN connection.
Fabian Greif, a German, has already tackled the subject (http://www.kreatives-chaos.com/) and built its own CAN debugger based on AT90CAN128 in order to communicate directly with the bus. There is also a CAN bootloader to allow the reconfiguration from CAN messages.
If programming with the Arduino IDE is relatively easy for a novice like me, programming AVR processors (and reading the code of another, besides in German) is not obvious to me.
So if any of you have tips / ideas / suggestions for me to adapt this type of program to my Arduino UNO, you have my all ears :slight_smile:
Thank you in advance!

Yellow

Up ?

Hello,

yellowsky:
So if any of you have tips / ideas / suggestions for me to adapt this type of program to my Arduino UNO, you have my all ears :slight_smile:

Aktuell werden ATMega8/88/168, ATMega16/32 und ATMega644 unterstützt, weitere AVRs können allerdings ohne große Änderungen eingebaut werden.
http://translate.google.com/#auto/en/Aktuell%20werden%20ATMega8%2F88%2F168%2C%20ATMega16%2F32%20und%20ATMega644%20unterstützt%2C%20weitere%20AVRs%20können%20allerdings%20ohne%20große%20Änderungen%20eingebaut%20werden.

Currently ATMega8/88/168, ATMega16/32 and ATmega644 are supported, but further AVRs can be installed without major changes.

Mit dem hier vorgestellten Bootloader lassen sich AVRs die an einem MCP2515 angeschlossen sind über den CAN Bus programmieren.
http://translate.google.com/#auto/en/Mit%20dem%20hier%20vorgestellten%20Bootloader%20lassen%20sich%20AVRs%20die%20an%20einem%20MCP2515%20angeschlossen%20sind%20über%20den%20CAN%20Bus%20programmieren.

With the presented bootloader AVR can be connected to an MCP2515 programming via the CAN bus.

From that Google translation it looks like you don't have to do anything special to get his bootloader working on your Uno.

Hello Coding Badly and thanks for your reply.

Indeed the CAN bootloader is working on my UNO without any particular changes in the code, the main problem is to transfer a sketch into a specific node by using a board as a USB2CAN module (i.e made that kind of communication : PC --> USB --> UNO --> CAN --> node).
Maybe there is a simplest solution, but that's what I'm trying to do.

Der PC Teil ist in Python geschrieben wird über die Kommandozeile gestartet. Eine entsprechende GUI fehlt noch, vielleicht hat ja jemand Lust daran weiterzumachen?

The PC part is written in Python started from the command line. A corresponding GUI is still missing, maybe someone would like to continue it?

Looks like the Python script is available under Downloads.

Sorry there is a misunderstanding, maybe I should explain more in detail what I've currently done.

I've downloaded all files relative to CAN in the kreative chaos website (bootloader, python script and CAN debugger program for at90can128) and translated instructions as well.
The bootloader and the python script can be used without changes in my architecture. What I'm trying to do is to modify the CAN debugger program to be executed into my UNO. Because I don't need all functionalities of his debugger, I focus my work to make the usb2can protocol working on Arduino IDE. I think that this part is included into usbcan_protocol that's why I built my own library with these files and wrote this sketch :

#include <CAN.h>
#include <usbcan_protocol.h>
#include <SoftwareSerial.h>
#include <SPI.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>

#include "utils.h"

#define BUS_SPEED 250


int led = 13;

void setup(){
      Serial.begin(9600);
      CAN.begin();
      CAN.baudConfig(BUS_SPEED);
      Serial.println("Start");
      delay(1000);
      pinMode(led, OUTPUT);   
      CAN.setMode(NORMAL);  // set to "NORMAL" for standard com
}


void loop()
{
	static char buffer[40];
        static uint8_t pos;

	// get commands
	while(Serial.available()) /// receive USB Data
	{
		char chr = Serial.read(); // read the incoming data
		if (chr != '\r'){ // wait the end of the message
                        digitalWrite(led, LOW);
			buffer[pos] = chr;
			pos++;
			
			if (pos >= sizeof(buffer)) {
				// format-error: command to long!
				pos = 0;
			}
		}
		else {
                        digitalWrite(led, HIGH);
			buffer[pos] = '\0';
			USB.usbcan_decode_command(buffer, pos); // try to send by CAN
			pos = 0;
		}
	}
}

I've also attached my library to this post.

Now my architecture is composed of 3 boards : One UNO as programmer which receive data sent by the python script, another which will receive the sketch into a CAN frame, and finally UNO as a CAN listener which will monitor the activity on the bus for debugging.

However when I launch the script in a shell, I'm stuck in the reception part and my led never blink.

CAN.zip (10.8 KB)

However when I launch the script in a shell, I'm stuck in the reception part and my led never blink.

Do you ever send a carriage-return terminated command?

Good point ! I've missed the \r after my decode command.
But I realised that communication must be bidirectional because the .hex file is sent only after an acknowledgement from the client. I'll fix it.
Thank you

I've successfully made a bidirectional communication USB <-> CAN into the UNO sketch and a CAN message is correctly sent by the UNO after the execution of the python script.

Little change in my architecture, I'm now using a homemade board compatible Arduino Leonardo as client (http://wiki.splashelec.com/index.php/CANinterfacer).
I've put my listener on the bus to see what happens and realised that the message is not consumed by the Leonardo, even if I pressed the reset button to enter in the bootloader section.

Because I've forgot to set the BOOT_LED to my port, I couldn't see that in fact it was the bootloader that didn't work. (I thought everything was ok because the MCP2515 RX led was ON when the CAN message is sent through the bus, great mistake)

What I've done :
Set the BOOT_LED to the correct port
Set the MCP2515_CS and MCP2515_INT to the correct port
In the makefile, change the MCU to mega32, the freq to 16Mhz.
Because my Leonardo is a 2048 words, I've also changed the BOOTSTART value to 0x7000.
When I make the .hex file I have two warning concerning the redefinition of RAMSTART but I think that it is just a #ifdef problem.
The fact is that the BOOT_LED doesn't blink which means that the bootloader itself doesn't work on my board with what I've done.

But there are differences about fuses. Indeed mine is 0xFF for lfuse, 0xD8 for hfuse and on the website the programming is done with 0x94 and 0xDC.
I don't think that change my fuses is a good idea. Because I'm not a booloader expert, I don't know where those settings are defined into the code. Or maybe we can't but it is strange because these settings use an Ext low freq crystal...

Maybe I've missed something...

Thank you.

I've tried to change fuses and unfortunately it bricks my board and the bootloader still doesn't work. However I'm able to recover it with a function generator :sweat_smile:

Any other ideas ?

That sounds like the oscillator is not running.

This is the fuse calculator I normally use... http://www.engbedded.com/fusecalc/

I've used the same calculator to see the difference between his settings and mine.
So in my board there is an External Cystal Osc 8Mhz and a 2048 words boot flash size.
His settings put an External Low-Frequency Crystal, a clock output on C7 (my boot led port...) and a 512 words boot flash size.

I see no reason why this bootloader would not work with my settings... but maybe I'm wrong.
When I put the caterina-leonardo bootloader into, everything is fine... :~