So I am pretty new to can bus stuff but i need a way to "select" certain bits(46-30) of the 64 bit Data part of the can frame. Here is what i have so far.
import os
import time
import can
mcFilters = [
{"can_id": 0x08850225, "can_mask": 0x1FFFFFFF, "extended": True},
{"can_id": 0x08850245, "can_mask": 0x1FFFFFFF, "extended": True},
{"can_id": 0x08850265, "can_mask": 0x1FFFFFFF, "extended": True},
{"can_id": 0x08850285, "can_mask": 0x1FFFFFFF, "extended": True},
]
def setup_can_interface():
print("\n\rCAN Data Parser")
print("Bring up CAN0....")
# Bring down the interface if it's already up
os.system("sudo /sbin/ip link set can0 down")
# Bring up the interface with the correct settings
os.system("sudo /sbin/ip link set can0 up type can bitrate 250000")
time.sleep(0.1)
print("Ready")
def shutdown_can_interface():
os.system("sudo /sbin/ip link set can0 down")
print("\n\rCAN interface shut down")
def initialize_bus():
try:
bus = can.interface.Bus(
channel="can0", bustype="socketcan", can_filters=mcFilters
) # Correct interface type
print("Initialized bus & Filter")
return bus
except OSError:
print("Cannot find PiCAN board.")
exit()
def parse_can_message(message):
# Function to parse CAN message data
parsed_data = {
"timestamp": message.timestamp,
"arbitration_id": message.arbitration_id,
"dlc": message.dlc,
"data": message.data,
}
# Example: Print data in hex format
data_str = " ".join(f"{byte:02x}" for byte in message.data)
parsed_data["data_str"] = data_str
return parsed_data
def main():
setup_can_interface()
print("The setup_can_interface done")
bus = initialize_bus()
print("Bus varible is set")
try:
print("In the try")
while True:
message = bus.recv() # Wait until a message is received.
parsed_message = parse_can_message(message)
print(f"Timestamp: {parsed_message['timestamp']:.6f}")
print(f"ID: {parsed_message['arbitration_id']:x}")
print(f"DLC: {parsed_message['dlc']}")
print(f"Data: {parsed_message['data_str']}")
print("-" * 30)
except KeyboardInterrupt:
shutdown_can_interface()
print("\n\rKeyboard interrupt")
if __name__ == "__main__":
main()
Right now it will just filter out certain can Id's and print what ever it contains. I am using the python-can library . If you need more info please let me know
I know it had to something with bit manipulation and the can mask but other then that i am stuck. Any help will be most grateful
I need help figuring out how to select certain bits from the 8 bytes of data. Is that what the 'can_mask' does or is that for the whole can frame?
According to the documentation:
A filter matches, when
<received_can_id> & can_mask == can_id & can_mask
. If extended is set as well, it only matches messages where<received_is_extended> == extended
. Else it matches every messages based only on the arbitration ID and mask.
So it looks like can_mask
is only applied to the can id. If you want to extract certain bits from the data, you'll need to use Python's bitwise operators to mask and shift things as necessary.