CAN, OSError: 116

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Aris
Posts: 14
Joined: Wed Feb 25, 2015 1:00 pm

CAN, OSError: 116

Post by Aris » Thu Mar 26, 2015 7:54 am

Hello,

I wanted to test the CAN bus so I bought two transceivers and make the proper conections between the CAN1 and CAN2 of the pyboard. I tried sending some message with the CAN1 and it seemed to work since I saw the pulses in the oscilloscope. Then I tried to make the CAN2 recieve that information and it didn't work, it generated an error (OSError: 116) instead. I checked the connections and the frequency and I didn't find any mistake. I decided to start again but this time the error was also generated after trying to send the message. I realised that the error is generated after the timeout and sometimes it is also "OSError: 5" while the proceeding I followed is exactly the same.

I started again from the tutorial, which worked properly for me in the begining, so I typed this code:

>>> from pyb import CAN
>>> can = pyb.CAN(1,CAN.LOOPBACK)
>>> can.send('message',123)
>>> can.recv(0)

It did the same, the message could be sent but not recieved. I tried again typing the same code after a soft reset. This time it generated the same error after trying to send a message with no success.

blmorris
Posts: 348
Joined: Fri May 02, 2014 3:43 pm
Location: Massachusetts, USA

Re: CAN, OSError: 116

Post by blmorris » Thu Mar 26, 2015 3:09 pm

I haven't tried to use CAN yet - I have a couple of transceiver chips lying around that I ordered exactly for this, but I haven't gotten around to them yet.
I wonder if you are seeing an issue similar to what we ran into here with I2C
Basically I tried to set up one I2C port on a pyboard as a master and the other as a slave, and tried to send data from one to the other. The problem was that both the send and receive methods were blocking (implemented at the C level as Polling mode rather than Interrupt or DMA) so that the pyboard couldn't run both the send and receive at the same time. Is it possible that is what you are seeing?

-Bryan

Edit- from the code that you posted, it looks like you are using the same CAN instance to send and to receive. I assume that isn't what you meant?

Aris
Posts: 14
Joined: Wed Feb 25, 2015 1:00 pm

Re: CAN, OSError: 116

Post by Aris » Mon Mar 30, 2015 1:40 pm

That is the code shown in the micropython website. It's just an example without using transceiver (that's what the mode "CAN.LOOPBACK" does). But still, it doesn't work. It worked perfectly just once, but not anymore. And now it sends, but doesn't receive. Although sometimes it doesn't neither send nor receive. And I'm writing the same code..

The other code that I've been using to create the interface to communicate can1 with can2 is this:

Code: Select all

from pyb import CAN

can1 = CAN(1)
can1.init(CAN.NORMAL,prescaler = 75, sjw=1,bs1=14,bs2=5)
can2.init(CAN.NORMAL,prescaler = 150, sjw=1,bs1=14,bs2=5) 
can1.send('message',123)
can2.recv(0)
I adjust the frequency of both nodes with the prescaler, to set them both to 28kHz. Then I try to make the can1 send a message and it generates the error after the timeout.

I don't think that's the same problem with the i2c. In my case it can't send any message, so the bus isn't occupied (I don't see any pulse in the bus with the oscilloscope).

I would think that there is a deeper problem with the pyboard. The strange thing is that I could make the can1 send a message once (in the very first try) but I couldn't make the can2 receive it. I haven't been able to make it send or receive anything since then.

Nambabwe
Posts: 6
Joined: Wed Apr 29, 2015 9:04 pm

Re: CAN, OSError: 116

Post by Nambabwe » Wed Apr 29, 2015 9:07 pm

Any luck with this problem? I am seeing the exact same OSError: 116!

{from a fresh power-up, REPL through COM29:}

>>> from pyb import CAN
>>> can = CAN(1, CAN.NORMAL, extframe=False, prescaler=22, sjw=1, bs1=6, bs2=8) # aiming for a 125kbps baud (127k now)
>>> can.setfilter(0, CAN.LIST16, 0, (123, 124, 125, 126))
>>> can.send('hallo', 123)
{5 second timeout}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: 116

Damien
Site Admin
Posts: 647
Joined: Mon Dec 09, 2013 5:02 pm

Re: CAN, OSError: 116

Post by Damien » Wed Apr 29, 2015 9:44 pm

OSError 116 is a timeout. It means that there was no-one on the CAN bus to receive your message. Is the CAN bus connected to anything?

If you want to test CAN without a connection use the loopback mode: CAN(1, CAN.LOOPBACK, ...)

Nambabwe
Posts: 6
Joined: Wed Apr 29, 2015 9:04 pm

Re: CAN, OSError: 116

Post by Nambabwe » Wed Apr 29, 2015 10:18 pm

Yes, I have the pyboard wired to a MCP2562, which in turn is connected to 2 more CAN systems talking fine to each other (they, PIC18F2580 devices, have FTDI serial to USB converters, so I can watch them on the PC too).

Could it be that my baud rate is not close enough to the 125kbps that the other two are using? The CAN_RX pin is seeing the data from the other two devices sending data, but the CAN_TX pin stays HIGH.

I have also seen some 5 and 16 Errors, after fiddling the O-Scope probe around?

>>> can.send('send',123)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: 5
>>> can.send('send',123)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: 16

Damien
Site Admin
Posts: 647
Joined: Mon Dec 09, 2013 5:02 pm

Re: CAN, OSError: 116

Post by Damien » Wed Apr 29, 2015 10:36 pm

Error 5 is an I/O error. Error 16 is a busy error which you can get if you try to send too many messages at once.

Which version of MicroPython are you using (printed when you do a soft reset using ctrl-D)?

Lately there was a change in the send interface to allow sending messages with 0 timeout, which means they are queued in the outgoing mailbox. To not use this feature, try: can.send('test', 123, timetout=5000).

To get a closer frequency to 125k you can try adjusting the CPU freq using pyb.freq(<freq in MHz>). Then adjust the CAN prescaler accordingly.

I don't have much experience with the CAN driver. Henrik Sölver on GitHub (and maybe here on the forum) has experience and wrote a lot of the CAN code. He seems to have it working well and uses all the features (filters etc).

Nambabwe
Posts: 6
Joined: Wed Apr 29, 2015 9:04 pm

Re: CAN, OSError: 116

Post by Nambabwe » Thu Apr 30, 2015 6:14 pm

Ok, we have:
Micro Python v1.3.10 on 2015-02-13; PYBv1.0 with STM32F405RG

and the timeout=5000 line is complaing about extra arguments, do I need a newer version than 1.3.10?

>>> can1.send('test', 123, timetout=5000)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: extra keyword arguments given

Apart from that,

with

>>> pyb.freq()
(168000000, 168000000, 42000000, 84000000)

and
>>> can1 = CAN(1, CAN.NORMAL, extframe=False, prescaler=16, sjw=1, bs1=14, bs2=6)

we have the baud rate spot on at 125k from baud = (42,000,000 / (16 * (1+14+6)))

Again, LOOPBACK works fine, but never do I see any change on the TX pin on either CAN1 or CAN2 and yes, there needs to be an ACK, but does that not come after the TX line has moved at least once or more times?

Upon power-up, both the pins are low, but they do go up once the init "CAN(1,...)" is called.

I also tried hooking CAN1 straight into CAN2 (TX1 to RX2 and RX1 to TX2 with a 100 ohm in between each ), but still get Error 116, maybe I need two transceivers and a 120 ohm to make that work.

Also noticed that the Error 5 and 16 comes after trying to do a can1.send() 4 times to get the error 5 and after that error 16. So most likely some FIFO or buffer is full now. Not saying this is a problem, just noting it, so the next person seeing error 5 or 16 might get a clue!

blmorris
Posts: 348
Joined: Fri May 02, 2014 3:43 pm
Location: Massachusetts, USA

Re: CAN, OSError: 116

Post by blmorris » Fri May 01, 2015 1:25 am

I don't really know that much about CAN, as I haven't taken the time to play with it on the pyboard yet, but there have been a few commits relevant to the CAN module since v1.3.10; you may want to update your firmware.

Also, I don't know if this is a typo or a direct cut-and-paste, but 'timeout' is mis-spelled in '>>> can1.send('test', 123, timetout=5000)'; this could certainly give an extra keyword argument TypeError.

-Bryan

Nambabwe
Posts: 6
Joined: Wed Apr 29, 2015 9:04 pm

Re: CAN, OSError: 116

Post by Nambabwe » Fri May 01, 2015 12:43 pm

Thank you Bryan! That was a typo, but before the cut and paste, scary thing is, I've typed it in wrong twice in REPL!!!

So, can1.send('h', 123, timeout=100) works a lot better, if only the Error: 116 would not follow it! I will upgrade the firmware now and report back!

Post Reply