CAN, OSError: 116
CAN, OSError: 116
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.
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.
Re: CAN, OSError: 116
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?
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?
Re: CAN, OSError: 116
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:
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.
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 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.
Re: CAN, OSError: 116
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
{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
Re: CAN, OSError: 116
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, ...)
If you want to test CAN without a connection use the loopback mode: CAN(1, CAN.LOOPBACK, ...)
Re: CAN, OSError: 116
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
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
Re: CAN, OSError: 116
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).
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).
Re: CAN, OSError: 116
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!
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!
Re: CAN, OSError: 116
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
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
Re: CAN, OSError: 116
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!
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!