Reputation: 1
I'm working on a Raspberry Pi based device to communicate with cars via the OBD plug. I have a CAN bus hat (https://www.waveshare.com/wiki/2-CH_CAN_HAT) on a RPi 4.
I can't seem to make the filters work though.
I am able to set working filters by adding lines in the demo provided with the hat :
import os
import can
import time
os.system('sudo ip link set can0 type can bitrate 500000')
os.system('sudo ifconfig can0 up')
can0 = can.interface.Bus(channel='can0', bustype='socketcan') # socketcan_native
can0.set_filters([{"can_id" : 0x688, "can_mask" : 0xFFF, "extended" : False}])
timeout = 999.0
start_time = time.time()
while time.time() - start_time < timeout:
msg = can0.recv(0.1)
if msg is not None:
print("Received message on can0:", msg)
else:
print('Timeout occurred, no message.')
can0.shutdown()
os.system('sudo ifconfig can0 down')
but when I try to set the filters in the same manner in my code it doesn't work, it's as if filters aren't set at all and all IDs are able to pass, my code is kinda long so I'll post only relevant bits.
CAN buses setting :
#configuration des parametres du CAN0 sur le terminal à distance
os.system('sudo ip link set can0 type can bitrate 500000')
os.system('sudo ifconfig can0 txqueuelen 65536')
os.system('sudo ifconfig can0 up')
#configuration des parametres du CAN1 (can bsi) sur le terminal à distance
os.system('sudo ip link set can1 type can bitrate 500000')
os.system('sudo ifconfig can1 txqueuelen 65536')
os.system('sudo ifconfig can1 up')
#affichge de l'etat des can
os.system('dmesg | grep spi')
#configuration de l'interface du can0
can0 = can.interface.Bus(channel = 'can0', bustype = 'socketcan')# socketcan_native
print("can0 initialised \n")
#configuration de l'interface du can1
can1 = can.interface.Bus(channel = 'can1', bustype = 'socketcan')# socketcan_native
print("can1 initialised \n")
filters setting (further down the code) :
#selection du bus de communication
if bus == 1 :
canbus = can0
else:
canbus = can1
#paramétrage du filtre
print("avant filtre")
canbus.set_filters([{"can_id" : repID, "can_mask" : 0xFFF, "extended" : False}])
print("apres filtre")
I tried to set the filters for both buses instead of using my variable "canbus", it didn't change the outcome. Maybe it has to do with the dynamic filters setting ? I change the filters every second or so.
here is the full subfunction in which the filters are edited, repID and reqID are CAN adresses like 0x650 or 0x742 for example.
def request_info_PSA(reqID, repID, bus):
"""
recherche les références du calculateur à l'adresse spécifiée en entrée'
Parameters
----------
reqID : INT (valeur en hexa) adresse de requete du calculateur
repID : INT (valeur en hexa) adresse de réponse du calculateur
bus : INT numéro du bus a utiliser (1 ou 2)
Returns
-------
refPart : STRING référence du matériel
refPart2 : STRING référence complémentaire du matériel
"""
refComplete = False
refPart = ""
refPart2 = ""
#selection du bus de communication
if bus == 1 :
canbus = can0
else:
canbus = can1
#paramétrage du filtre
print("avant filtre")
canbus.set_filters([{"can_id" : repID, "can_mask" : 0xFFF, "extended" : False}])
print("apres filtre")
startTime = time.time()
trame = 1
while refComplete == False :
# sortie de boucle (timeout)
if (time.time() - startTime > 2.0) :
refPart = refPart2 = "Pas de reponse"
break
# Envoi des différentes trames de requete
if trame == 1 :
msg_REQ = can.Message(is_extended_id=False, arbitration_id=reqID, data=dem_Acces_1)
time.sleep(0.1)
trame = 2
elif trame == 2 :
msg_REQ = can.Message(is_extended_id=False, arbitration_id=reqID, data=dem_Acces_2)
time.sleep(0.1)
trame = 3
elif trame == 3 :
msg_REQ = can.Message(is_extended_id=False, arbitration_id=reqID, data=dem_Acces_3)
time.sleep(0.1)
trame = 1
canbus.send(msg_REQ)
# lecture du buffer
msg_REP = canbus.recv(0.1)
if msg_REP == None :
continue
# Réponse du véhicule selon cas 1 ou 2
if comp_CAN(msg_REP.data,rep_Acces_1) or comp_CAN(msg_REP.data, rep_Acces_2):
canbus.stop_all_periodic_tasks(remove_tasks=True)
msg_REQ = can.Message(is_extended_id=False, arbitration_id=reqID, data=data_PSA_1)
canbus.send(msg_REQ)
# récupération des références
while refComplete == False :
# lecture du buffer
msg_REP = canbus.recv(timeout=0.5)
if msg_REP == None :
break
# Reception de la premiere trame de réponse
if (msg_REP.data[0]==0x10):
for i in range(0,4):
refPart = refPart + "%02x" % msg_REP.data[i+4]
# Envoi de la demande des trames suivantes
msg_REQ = can.Message(is_extended_id=False, arbitration_id=reqID, data=data_extend_PSA)
canbus.send(msg_REQ)
# Reception de la seconde trame de réponse
elif msg_REP.data[0]==0x21:
refPart = refPart + "%02x" % msg_REP.data[1]
for i in range(0,4) :
refPart2 = refPart2 + "%02x" % msg_REP.data[i+4]
# Reception de la derniere trame de réponse
elif msg_REP.data[0]==0x22:
refPart2 = refPart2 + "%02x" % msg_REP.data[1]
refComplete = True
# Timeout
elif (time.time() - startTime > 2.0) :
break
# Réponse du véhicule selon cas 3
elif comp_CAN(msg_REP.data,rep_Acces_31) or comp_CAN(msg_REP.data,rep_Acces_32):
canbus.stop_all_periodic_tasks(remove_tasks=True)
msg_REQ = can.Message(is_extended_id=False, arbitration_id=reqID, data=data_PSA_2)
canbus.send(msg_REQ)
# récupération des références
while refComplete == False :
# lecture du buffer
msg_REP = canbus.recv(timeout=0.5)
if msg_REP == None :
break
# Reception de la premiere trame de réponse
if (msg_REP.data[0]==0x10):
for i in range(0,3):
refPart = refPart + "%02x" % msg_REP.data[i+5]
# Envoi de la demande des trames suivantes
msg_REQ = can.Message(is_extended_id=False, arbitration_id=reqID, data=data_extend_PSA)
canbus.send(msg_REQ)
# Reception de la seconde trame de réponse
elif msg_REP.data[0]==0x21:
for i in range(0,2) :
refPart = refPart + "%02x" % msg_REP.data[i+1]
for j in range (0,3) :
refPart2 = refPart2 + "%02x" % msg_REP.data[j+5]
# Reception de la derniere trame de réponse
elif msg_REP.data[0]==0x22:
for i in range (0,2) :
refPart2 = refPart2 + "%02X" % msg_REP.data[i+1]
refComplete = True
# Timeout
elif (time.time() - startTime > 2.0) :
break
# Sortie de fonction
return refPart, refPart2
Any ideas ?
Upvotes: -1
Views: 110
Reputation: 1
I've manage to track down the issue.
When calling filters, they are applied after the current RX buffer, so those unwanted messages I've been getting are from before the filter was applied.
I just need to figure how to flush the rx buffer just after setting up the filter and it should do the trick, I'll update.
Upvotes: 0