Hi,
I was hoping someone here might be able to help with an example of how to use the dispatcher in a loop and if a condition is met, send a relevant response.
Currently I've just been interacting with Pyvit in a simple while loop with dev.recv
. However I'm not sure how to interact with the dispatcher given things are threaded.
Basically, I have a simple program using Pyvit acting as an ECU to send things such as RPM and Speed when requested by a connected device.
As an example:
#!/usr/bin/env python3
from pyvit import can
from pyvit.hw import socketcan
import os,sys,termios,tty,time
SupportedPIDsRequest = "0201000000000000"
RPMRequest = "02010C0000000000"
VINReq = "0209020000000000"
RPMResp = 'cansend vcan0 7E8#04410C1094000000'
VINResp = 'cansend vcan0 7E8#1014490201355445 && sleep 0.1 && ' \
'cansend vcan0 7E8#214D5535324E3636 &&' \
'cansend vcan0 7E8#225A323236373433'
def resp_function():
resp = can.Frame(0x7E8)
resp.data = frameData
dev.send(resp)
print(resp)
return resp
dev = socketcan.SocketCanDev("vcan0")
dev.start()
while True:
CanFrameRecv = dev.recv()
if CanFrameRecv.arb_id == int(0x7DF):
if (bytes(CanFrameRecv.data)) == bytes.fromhex(SupportedPIDsRequest):
print('\nSupported PIDs Request : ' + SupportedPIDsRequest)
frameData = [0x06, 0x41, 0x00, 0x00, 0x18, 0x30, 0x01]
response = resp_function()
print('Supported PIDs Response : ' + str(resp_function().data))
elif (bytes(CanFrameRecv.data)) == bytes.fromhex(RPMRequest):
print('\nRPM Request Received : ' + RPMRequest)
print('RPM Response : ' + RPMResp)
os.system(RPMResp)
elif (bytes(CanFrameRecv.data)) == bytes.fromhex(VINReq):
print('VIN Req : ' + VINReq)
print(VINResp)
os.system(VINResp)
As you can see, I'm "cheating" with the VIN, and just sending the frames out without actually checking if a frame control message is received. I want to improve this, and actually use the ISO-TP functionality.
My issue is I've struggled to get ISO-TP messages working nicely.
Using the isotp_test
I was able to get an idea on how to send an ISO-TP frame, provided you send a frame control message.
#!/usr/bin/env python3
import threading
from multiprocessing import Queue
from pyvit.hw import socketcan
from pyvit.dispatch import Dispatcher
from pyvit.proto.isotp import IsotpInterface
dev = socketcan.SocketCanDev("vcan0")
disp = Dispatcher(dev)
recv_queue = Queue()
disp.add_receiver(recv_queue)
# set up an isotp interface Sender/Receiver arb id
sender = IsotpInterface(disp, 0x7DF, 0x7E8)
receiver = IsotpInterface(disp, 0x7E8, 0x7DF)
disp.start()
""" ISOTP transmission and reception of a multi-frame message"""
print("payload creation")
payload = [0x49, 0x02, 0x01, 0x31, 0x41, 0x31, 0x4A, 0x43, 0x35, 0x34, 0x34, 0x34, 0x52, 0x37, 0x32, 0x35, 0x32, 0x33, 0x36, 0x37]
# we need to run this in a thread so that the flow control frame is
# sent and received, as IsotpInterfaces block
print("starting tx_thread")
tx_thread = threading.Thread(target=sender.send, args=(payload,))
tx_thread.start()
# we'll receive data in this thread
resp = receiver.recv()
# wait for the transmitting thread to finish, then verify the result
tx_thread.join()
## I'm really not too sure what the above " .join"actually does....
print("finished")
Example:
pi@rpi-hos:~/repos/pyvit $ python3 print_all_frames.py
payload creation
starting tx_thread
[16, 20, 73, 2, 1, 49, 65, 49] <SEND CONTROL FRAME>
[33, 74, 67, 53, 52, 52, 52, 82]
[34, 55, 50, 53, 50, 51, 54, 55]
finished
I'm just not sure how to interact with the Dispatcher send and receive methods/threads within a while loop.
I'm starting to get the impression my main loop should also be a thread but again not sure how to do this.
Sorry if this is an annoying question - I'm still pretty new to python.
Thanks,
Matt