CAN Bus

The official pyboard running MicroPython.
This is the reference design and main target board for MicroPython.
You can buy one at the store.
Target audience: Users with a pyboard.
artur
Posts: 12
Joined: Thu Dec 08, 2016 8:05 pm

CAN Bus

Post by artur » Thu Dec 08, 2016 9:05 pm

Hi!

I am starting this topic because I have not seen much discussion about getting the pyboard running with CAN bus. My intention is to implement a CANopen tailored protocol used for satellites (http://www.esa.int/Our_Activities/Space ... etwork_Bus).

I have done such an implementation for Atmel MCU using C. Now I would like to port this to micropython and use the pyboard for it.

However, I am stumbling already sending a single CAN frame. The frame is transmitted by pyboard, but seen as erroneous and hence not acknowledged by a CAN-USB debugger device.

Questions:
1) What is the default CAN bus baudrate on pyb?
2) How to set it to 1 Mbps?

User avatar
kamikaze
Posts: 154
Joined: Tue Aug 16, 2016 10:10 am
Location: Latvia
Contact:

Re: CAN Bus

Post by kamikaze » Fri Dec 09, 2016 12:01 pm

I would suggest you to use search first. There were some discussions.

Also schematics and code would bring the light on your setup.

artur
Posts: 12
Joined: Thu Dec 08, 2016 8:05 pm

Re: CAN Bus

Post by artur » Fri Dec 09, 2016 8:49 pm

Thanks! Indeed, I did not see those forum entries during my search. This one helped me:
http://forum.micropython.org/viewtopic. ... bus#p11870

Namely, to set the CAN baudrate:

# This worked for 125k baud rate
can1.init(CAN.NORMAL, extframe=False, prescaler=16, sjw=1, bs1=14, bs2=6)
# This worked for 250k baud rate
can1.init(CAN.NORMAL, extframe=False, prescaler=8, sjw=1, bs1=14, bs2=6)
# This worked for 500k baud rate
can1.init(CAN.NORMAL, extframe=False, prescaler=4, sjw=1, bs1=14, bs2=6)
# This worked for 1M baud rate
can1.init(CAN.NORMAL, extframe=False, prescaler=2, sjw=1, bs1=14, bs2=6)

User avatar
kamikaze
Posts: 154
Joined: Tue Aug 16, 2016 10:10 am
Location: Latvia
Contact:

Re: CAN Bus

Post by kamikaze » Sat Dec 10, 2016 2:16 pm

artur wrote: # This worked for 1M baud rate
can1.init(CAN.NORMAL, extframe=False, prescaler=2, sjw=1, bs1=14, bs2=6)
Can you show a schematics for CAN bus transceiver connection? because I can't get 1Mbps, 500Kbps is the limit for me :/

artur
Posts: 12
Joined: Thu Dec 08, 2016 8:05 pm

Re: CAN Bus

Post by artur » Sun Dec 11, 2016 9:07 pm

I don't have schematics but I can tell you the setup. I am using Pyboard v1.1 connected to an Atmel ATA6561 CAN transceiver, which is connected to a CAN-USB debug terminal.
The ATA6561 is connected to pyboard as follows:

ATA - Pyboard:
TXD - Y4
GND - GND
VCC - 3V3
RXD - Y3
VIO - V+
STBY - GND

The 1 Mbps works fine with that.

User avatar
kamikaze
Posts: 154
Joined: Tue Aug 16, 2016 10:10 am
Location: Latvia
Contact:

Re: CAN Bus

Post by kamikaze » Sun Dec 11, 2016 9:39 pm

artur wrote:The 1 Mbps works fine with that.
Do you use any resistors between CANH and CANL ?

artur
Posts: 12
Joined: Thu Dec 08, 2016 8:05 pm

Re: CAN Bus

Post by artur » Mon Dec 12, 2016 9:14 am

yes, of course as described in the CAN bus spec: 120 Ohm.

Note that there exists an improved version of the terminal resistance configuration (see ECSS-E-ST-50-15C, A.3):
The use of split termination is a concept that is growing in popularity because emission reduction and filtering of common-mode noise can be achieved very easily. Split termination is a modified standard termination in which the single 120 Ω resistor on each end of the bus is split into two 60 Ω resistors, with a bypass capacitor tied between the resistors and to ground.

giacomoalbe
Posts: 9
Joined: Thu Dec 22, 2016 10:15 pm

Re: CAN Bus

Post by giacomoalbe » Wed Mar 01, 2017 5:27 pm

Hi guys!

I reopen this recent discussion because I'm running into troubles trying to create a CAN bus between 2 different PyBoards 1.1.

I've got the MCP2561 CAN Transceiver (here the datasheet if someone needs it http://ww1.microchip.com/downloads/en/D ... 05167C.pdf).

The problem is that right now I'm not able to get the two boards to communicate.

The connection between the CAN TX and the PyBoard are as following:

CAN TX --> PyBoard

TX --> Y4
RX --> Y£
VSS --> GND
VDD --> 3v3

I've seen that this configuration is similar to other pin-compatible CAN Transceiver TCAN337GDR, used by @kamikaze in his project. Actually the board itself in which the CAN Tx is located is one of the Kamikaze's one.

The code I'm installing in both boards is the following

Receiver

[code]
import pyb
from pyb import CAN

can = CAN(1,CAN.NORMAL)

can.init(CAN.NORMAL, extframe=False, prescaler=16, sjw=1, bs1=14, bs2=6)
can.setfilter(0, CAN.LIST16, 0, (123,123,125,126))

while (True):
can.send('prova', 223)
print("Sending prova to id 223")
pyb.delay(500)
pyb.LED(4).toggle()

[/code]

Sender

[code]
import pyb
from pyb import CAN

can = CAN(1,CAN.NORMAL)

can.init(CAN.NORMAL, extframe=False, prescaler=16, sjw=1, bs1=14, bs2=6)
can.setfilter(0, CAN.LIST16, 0, (123,123,125,126))

while (True):
can.send('prova', 223)
print("Sending prova to id 223")
pyb.delay(500)
pyb.LED(4).toggle()
[/code]

Actually the sender is able to make 3 attempts of sending and after that it crashed and gives a OS ERROR 16.

The receiver is not able to receive nothing, though.
Where to you think the problem reside?

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: CAN Bus

Post by dhylands » Wed Mar 01, 2017 7:40 pm

I wired up 2 boards using the MCP2562. My wiring was like this:

Pin 1 - TXD - X4
Pin 2 - VSS - GND - To GND on bus
Pin 3 - VDD - VIN
Pin 4 - RXD - X3
Pin 5 - VIO - 3v3
Pin 6 - CANL - To CANL on bus
Pin 7 - CANH - To CANH on bus
Pin 8 - STBY - GND

and since I only had 2 nodes, I also had a 120 ohm resistor between CANL and CANH on each board (only needed at the ends of the bus).

and the 2 programs I used were can_send.py:

Code: Select all

import pyb

can = pyb.CAN(1, pyb.CAN.NORMAL, prescaler=16, sjw=1, bs1=14, bs2=6)    # 125k baud
can.setfilter(0, pyb.CAN.LIST16, 0, (133, 134, 135, 136))

can.send(b'Test', 123)
and can_echo.py:

Code: Select all

import pyb

can = pyb.CAN(1, pyb.CAN.NORMAL, prescaler=16, sjw=1, bs1=14, bs2=6)    # 125k baud
can.setfilter(0, pyb.CAN.LIST16, 0, (123, 124, 125, 126))

while True:
    if can.any(0):
        msg = can.recv(0)
        print('Got msg =', msg)
    pyb.wfi()
On the MCP2561 it looks like Pin 5 is SPLIT instead of VIO and SPLIT is defined as an output that should be left unconnected.

giacomoalbe
Posts: 9
Joined: Thu Dec 22, 2016 10:15 pm

Re: CAN Bus

Post by giacomoalbe » Thu Mar 02, 2017 6:31 pm

Many thanks @dhylands for the lighting fast answer!

You are a life saver, really!

Since I noticed you are really a PRO with CAN and uPython , I'd like to ask two questions about what you said:

1) Does the STBY pin need to be connected to ground? If I leave it simply as is (no connection) would't it be "0" always?
2) Is it possible to increase the baud rate with the by changing the settings in the can init OR with MCP2562 the maximum speed is 125kbaud? This chip should support high speed CAN, so it seems to be that this can be easily achieved by setting things in the right way, but asking is never wrong, in my opinion :D :D

Tomorrow morning I'll try to apply your suggestion both in the hardware and in the software, then I'll let you know if I'll work!

After that should be a good thing to post a guide somewhere on the Web in order for other to easily manage to setup CAN communication with uPython! Thinking about doing this, in order to give back to the (astonishingly kind) community who helped out!

Post Reply