1

i'am absolute beginner in Raspberry and python. Right now i need to solve a problem. I have Raspberry3, PiCAN 2 DUO and source of CAN messages. I did all the setting Raspberry needs to receive CAN messages. Then i used this code, which works perfectly fine:

import can
import time
import os

os.system("sudo /sbin/ip link set can0 up type can bitrate 500000")
time.sleep(0.1) 

try:
    bus = can.interface.Bus(channel='can0', bustype='socketcan_native')
except OSError:
    print('Cannot find PiCAN board.')
    exit()

print('Ready')
try:
    while True:
        message = bus.recv()    # Wait until a message is received.

        c = '{0:f} {1:x} {2:x} '.format(message.timestamp, message.arbitration_id, message.dlc)
        s=''
        for i in range(message.dlc ):
            s +=  '{0:x} '.format(message.data[i])

        print(' {}'.format(c+s))


except KeyboardInterrupt:
    #Catch keyboard interrupt
    os.system("sudo /sbin/ip link set can0 down")

But the problem is, i have to send this - ID 36 / DLC:8 / Data 00 00 00 00 09 00 00 00 - every 100mS and then read what i am receiving. The CAN source can't work without that, if i am not doing it, it just sends random numbers.

Could you advise me, how to remake the code, so i am sendin every 100mS that message and all the time reading what is coming?

Thank you very much

v.hartman
  • 9
  • 2
  • ***"sendin every 100mS ... all the time reading"***: If you want to do things parallel in **one** script, you have to use `threading` or `multiprocessing`. Read [multiprocessing-vs-threading-python?](https://stackoverflow.com/questions/3044580/multiprocessing-vs-threading-python?) – stovfl Dec 23 '19 at 10:59
  • I'm sorry, my stupidity. What i meant was to send a message and read what's coming until next message is going to send, send a message and all over again. – v.hartman Dec 23 '19 at 21:14
  • You want `while True: ; bus.send('ID 36...') ; time.sleep(0.1) ; bus.recv()`? – stovfl Dec 23 '19 at 21:28

1 Answers1

1

Just set up a task for cyclic message sending:

task = can.send_periodic('can0', msg, 0.1)
task.start()

No need for multiprocessing or multithreading.

Receiving can be done like you are doing currently or by using callbacks. It’s all in the documentation of python-can. As written in the documentation, you might have to add

can.rc['interface'] = 'socketcan_ctypes'

after

import can
MSpiller
  • 3,500
  • 2
  • 12
  • 24
  • Hi, thank you for your help. When i tried it, it showed 2 errors. So i rewrite it like 'task = bus.send....', still errors. I did all the updates, if the problem could be that, reboot, but still it shows "AttributeError: 'SocketscanNative_Bus' object has no attribute 'send_periodic'". I tried to look for that, but i could not find anything. – v.hartman Dec 26 '19 at 10:26
  • @v.hartman It has to be can, not bus. I have detailed the answer. Apart from that, just check the documentation and search for send_periodic. – MSpiller Dec 26 '19 at 10:33
  • That you for your effort. I did as you said, but still errors: `Traceback (most recent call last): File "/home/pi/Desktop/zkouska.py", line 26, in task = can.send_periodic('can0',msg,0.1) File "/usr/local/lib/python3.7/dist-packages/python_can-1.4.1-py3.7.egg/can/broadcastmanager.py", line 75, in send_periodic return can.interfaces.interface.CyclicSendTask(channel, message, period) AttributeError: module 'can.interfaces.interface' has no attribute 'CyclicSendTask` But i will try to find the answer in the documentation, as you said – v.hartman Dec 26 '19 at 11:05