CAN Bus Communication

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
satya369
Posts: 32
Joined: Tue Aug 18, 2015 3:45 am

CAN Bus Communication

Post by satya369 » Fri May 20, 2016 6:58 pm

Hello everyone,

Pretty new to micropython but trying to do my best to learn things as I work on small projects.
I am working on a small project where I want to read CAN bus data or write CAN bus data. I have a device that already talks over CAN. I have included the specification of the CAN bus in the code.
I am using a SN65HVD230 to connect between external device and the uPython board and tried to run the below code to see if I get any response. But so far no luck.

CAN_TX on SN65HVD230 is connected to Y3 and CAN_RX is connected to Y4 terminals on the uPython board. I have enabled the terminating resistor on the SN65HVD230 using the jumper.

Does anyone have any inputs on this?
I am little confused about the time quanta, not sure if I have selected the prescale correctly or not.

Code: Select all

#External Device Settings
#Propagation Segment: 7, Phase Segment 1= 4, Phase Segment 2= 4, RJW: 1
#time quantum = 250 ns
#bit rate = 250kbps, 29 bit identifier, 8 bytes of data. 

import pyb
from pyb import CAN
can = CAN(1, CAN.NORMAL)

#extframe=True for 29bit identifier, PCL1=42000000 (42MHz, 23.8095nsec),250kbps #prescale = 250/23.809
can.init(CAN.NORMAL,True,10,sjw=1,bs1=4,bs2=4)  

can.setfilter(0, CAN.LIST16, 0, (65366))  # set a filter to receive messages with id=65366= 0XFF56
#can.send('message!', 123)   # send a message with id 123
can.recv(0,timeout=5000)                 # receive message on FIFO 0

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

Re: CAN Bus Communication

Post by dhylands » Fri May 20, 2016 9:47 pm

The datasheet shows that for the SN65HVD230, Pin 1 is D, and is called CAN TX and this is a "driver input" (i.e. input to the SN65HVD230). CAN1_TX on Y4 is an output, so Y3 should connect to pin 1 on the SN65HVD230, and Y4 (CAN1_RX) should connect to pin 4 (R or CAN RX).

I've not used CAN myself yet, so if that doesn't resolve the issue, then I'll let somebody else chime in.

PappaPeppar
Posts: 30
Joined: Thu Dec 18, 2014 10:38 pm

Re: CAN Bus Communication

Post by PappaPeppar » Fri May 20, 2016 10:15 pm

Hi.

The parameters to the set filter call can not work. you should get an error on that line. The filter definition must be a list or an tuple that is four elements long when using CAN.LIST16 filters. In your code you try to use a single integer. Then I would like to suggest to use a catch all filter, such as setfilter(0, CAN.MASK32, 0, (0,0)), in the beginning.
Then to your init function, bs1=4, bs2=4, sjw=1 and prescaler=10 gives according to my calculations (which might be wrong) a baudrate of 347 107,44 bits/s, is that what you want?

satya369
Posts: 32
Joined: Tue Aug 18, 2015 3:45 am

Re: CAN Bus Communication

Post by satya369 » Mon May 23, 2016 2:12 pm

I tried your suggestions. See the attachment. I am getting an OS error 116.

http://www.waveshare.com/sn65hvd230-can-board.htm
I am using this board for connection between the external device and the upython board. connected CAN TX to Y3 and CAN RX to Y4 and tried executing the code in the screen shot. But no success.

PappaPeppar: My external device is operating at a baud rate of 250 Kbps.
Attachments
CAN OSError 116.JPG
CAN OSError 116.JPG (30.18 KiB) Viewed 10438 times

folke
Posts: 8
Joined: Thu Jun 04, 2015 3:26 pm

Re: CAN Bus Communication

Post by folke » Mon May 23, 2016 4:02 pm

Hi,

This works for me for a CAN bus at 250 kbps with extended frame:

Code: Select all

''' Init for 250 kbps <=> bit time 4 µs. If 42 MHz clk is prescaled by 21, we get 8 subparts 'tq'
	of a bit time from theese parts (# tq): sync(1) + bs1(5) + bs2(2) = 8 * tq = 4µs => 250 kbps'''
can.init(can.NORMAL, extframe=True, prescaler=21, sjw=1, bs1=5, bs2=2)

can.setfilter(0, CAN.MASK32, 0, (0x0, 0x0))         # set a filter to receive messages with any id
So you probably need to adjust the timing to get 250 kbps.

Today I found this link: <http://www.bittiming.can-wiki.info> over the subject of timing parameters.

Cheers!

satya369
Posts: 32
Joined: Tue Aug 18, 2015 3:45 am

Re: CAN Bus Communication

Post by satya369 » Mon May 23, 2016 10:09 pm

Were you able to receive and send messages with the below code?

I tried the same on my board and was not able to get any response. Only go OSerror 116.

I also attached FlexCAN setting below. I had a logic analyzer hookup to Y3 and Y4 and was able to see data.
Remember that the prescale divide factor for FlexCAN is offset by 1 (it is actually 16).

Does the settings in the FlexCAN need to be considered when calculating values for uPython? I am little confused about these, still trying to understand what these are.
Attachments
CAN Setting FlexCAN.JPG
CAN Setting FlexCAN.JPG (37.16 KiB) Viewed 10413 times
CAN OSError 116.JPG
CAN OSError 116.JPG (34.81 KiB) Viewed 10413 times

folke
Posts: 8
Joined: Thu Jun 04, 2015 3:26 pm

Re: CAN Bus Communication

Post by folke » Tue May 24, 2016 4:18 am

Hi satya369, my code snippet was from my very first experience with CAN, and I actually do not have access to the CAN hardware anymore. So I have not tested with your code. My code was nearly identical to your last shown.

I had a logic analyzer hooked up to the CAN transceiver (MCP 2562) and I remember that the analyzer showed data coming out of the CAN bus thru the CAN transceiver into the PyBoard as soon as I had connected it correctly (I had to swap Rx and Tx) and the analyzer also showed correct incoming data even before I got the python code correct (I also got timeout error at first). The logic analyzer, at this stage, showed no respons from the PyBoard, i.e. no ACK bit was sent as an acknowledge for each package. The analyzer indicated this by showing NACK after each package. But once I got the timing and the FIFO setup correctly, the ACK signal was generated from the PyBoard. And timeout error disappeared when reading data.

Sorry, but I have no knowledge of FlexCAN. So my only suggestion is that you check for missing ACK to see if you also need to swap Rx and Tx pins between the PyBoard and the CAN transceiver. I also had very short CAN cables so even if my timing setup maybe is not optimal, it works good for me.

I also see you use a fairly old firmware, I use "MicroPython v1.7 on 2016-04-11; PYBv1.0 with STM32F405RG"

Cheers!

satya369
Posts: 32
Joined: Tue Aug 18, 2015 3:45 am

Re: CAN Bus Communication

Post by satya369 » Tue May 24, 2016 5:21 pm

I was able to get this working by swapping the TX and RX. CAN_TX on the transceiver need to be connected to Y4 (TX) and CAN_RX to Y3 (RX). This worked.

Attached below are the CAN messages I got back. But, sometimes not all 8 bytes are shown. Instead a "!", "," are shown or one of the bytes is 12 bits long
Do you know why this might be happening?
Attachments
CAN Messages.JPG
CAN Messages.JPG (41.34 KiB) Viewed 10382 times

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

Re: CAN Bus Communication

Post by dhylands » Tue May 24, 2016 5:49 pm

That's just how python displays strings. '!' and '\x21' are the same thing. So your string of b'\x00\x00\x01\x1b\x01!\x00' is really the same thing as: b'\x00\x00\x01\x1b\x01\x21\x00'.

Python will always try to use ASCII characters when it can.

If you want your string to be all hex, then try something like:

Code: Select all

>>> import ubinascii
>>> data = b'\x00\x00\x01\x1b\x01!\x00'
>>> ubinascii.hexlify(data, ' ')
b'00 00 01 1b 01 21 00'

satya369
Posts: 32
Joined: Tue Aug 18, 2015 3:45 am

Re: CAN Bus Communication

Post by satya369 » Tue May 24, 2016 6:28 pm

Thank you for the clarification.

Post Reply