Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CAN "Transmit Buffer Full" Error #1766

Closed
MattJmt opened this issue Apr 18, 2024 · 1 comment
Closed

CAN "Transmit Buffer Full" Error #1766

MattJmt opened this issue Apr 18, 2024 · 1 comment

Comments

@MattJmt
Copy link

MattJmt commented Apr 18, 2024

Hello,

I am using a 2-Channel Isolated CAN Expansion HAT to control two DC Motors via a Raspberry Pi 4B. I am using python-can 4.3.1.

When starting the python script, I receive the "Transmit Buffer Full" Error from can/interfaces/socketcan/socketcan.py.

However, if successfully running cangen can0 and candump can0 in the terminal before running the python script, the CAN works perfectly. It sometimes happens that running cangen can0 and candump can0 yields write: no buffer space available, in which case the CAN doesn't work. Attempting to change the CAN interface settings with functions such as sudo ifconfig can0 txqueuelen 1000 results in these errors RNETLINK answers: Invalid argument. The can0 is initialised with txqueuelen = 65536, so I don't know why I get these errors, which seem to be very random.

I checked the following threads, without any success:

I asked the manufacturer for advice, who recommended to add bus.flush_tx_buffer(). This didn't change anything.

I have provided below the python script.

Any help is fully appreciated!

EDIT: Continuing to troubleshoot the issue, I observe that when I turn the Raspberry Pi on, running ifconfig indicates no issues. However running cangen can0, which results in the "write: No buffer space available" error message, I observe a significant amount of TX errors, as depicted below:

image

I have tried changing the bitrate, turning the can0 interface down then up, still doesn't resolve the issue. The only solution which works after multiple attempts is to reboot the Raspberry Pi, for which the TX errors seem to halve after every reboot.

Below is a screenshot when running ip -det link show can0
image

This is the code to put the CAN Bus up at boot:
sudo nano /etc/network/interfaces

auto can0
iface can0 inet manual
pre-up /sbin/ip link set can0 up type can bitrate 1000000 dbitrate 8000000 restart-ms 1000 berr-reporting on fd on
up /sbin/ifconfig can0 up
down /sbin/ifconfig can0 down
post-up /sbin/ip link set can0 txqueuelen 65536

--
Communication.py

import can
import tmotor_can_utils as tcan
from can.interface import Bus
from can import Message
import socket
import busio
import board
import numpy as np
import binascii

class motorCommunication():
    def __init__(self, CAN_ID):
        self.lim = tcan.AK60_LIMITS()
        self.codes = tcan.TMOTOR_SPECIAL_CAN_CODES()
        self.CAN_ID = CAN_ID

        # CAN bus for sending messages
        self.bus = Bus(channel="can0", bustype="socketcan", bitrate=1000000)

        self.ENABLE_MOTOR_MSG = tcan.tmotor_CAN_message(data = self.codes.ENABLE_CAN_DATA, CAN_ID = self.CAN_ID)
        self.DISABLE_MOTOR_MSG = tcan.tmotor_CAN_message(data = self.codes.DISABLE_CAN_DATA, CAN_ID = self.CAN_ID)
        self.TARE_MOTOR_MSG = tcan.tmotor_CAN_message(data = self.codes.ZERO_CAN_DATA, CAN_ID = self.CAN_ID)
        self.DATA_STOP_MOTOR = tcan.pack_cmd_data(0, 0, 0, 0, 0)
        self.STOP_MOTOR_MSG = tcan.tmotor_CAN_message(data = self.DATA_STOP_MOTOR, CAN_ID = self.CAN_ID)

    def enable(self):                                       
        self.bus.send(self.ENABLE_MOTOR_MSG)

    def disable(self):                                      
        self.bus.send(self.DISABLE_MOTOR_MSG)

    def stop(self):                                         
        self.bus.send(self.STOP_MOTOR_MSG)
    
    def shutdw(self):                                       
        self.bus.shutdown()

    def tare(self):                                         # command to zero the motor's position
        self.bus.send(self.TARE_MOTOR_MSG)
    
    def resetTxBuffer(self):
        self.bus.flush_tx_buffer()

    def send_command(self, p_des, v_des, kp_des, kd_des, t_ff):             # command to motor with desired params
        data_cmd = tcan.pack_cmd_data(p_des, v_des, kp_des, kd_des, t_ff)
        message_cmd = tcan.tmotor_CAN_message(data = data_cmd, CAN_ID = self.CAN_ID)
        try:
            self.bus.send(message_cmd)
            '''print("[communication.py] Message sent")'''
        except Exception as e:
            print("[communication.py] Error during send: ", repr(e))

Motor Communication Class in the main code.

from can.interface import Bus
import can
can.rc['interface'] = 'socketcan'
can.rc['channel'] = 'can0'
can.rc['bitrate'] = 1000000
class readCANBusLoop_m1(threading.Thread):
    def __init__(self, name, sys_state):
        threading.Thread.__init__(self)
        self.name = name
        self.sys_state = sys_state
        self.can_read_fs = 2 * FS

        filters = [{"can_id": 0x000, "can_mask": 0x7FF, "extended": False}]
        self.bus = Bus(channel="can0", bustype="socketcan", can_filters=filters, bitrate=1000000)

        # Temporary motor state placeholders
        self.motor1_state_cur = MotorState()
        self.running = 	True

    def stop(self):
        self.running = 	False
        self.bus.shutdown()
         
    def resetCAN(self):
        self.bus.flush_tx_buffer()

    def run(self):
        while self.running:
            next_time_instant = time.perf_counter() + (1.0 / self.can_read_fs)

            cur_msg = self.bus.recv(timeout = 0)
            while cur_msg is not None:
                can_id, position, velocity, torque, temperature, error_code = tcan.unpack_reply(cur_msg.data)

                # Attempt to get the next message
                cur_msg = self.bus.recv(timeout = 0)

            time.sleep(max(next_time_instant-time.perf_counter(),0))
@marckleinebudde
Copy link

discussion continued here: linux-can/can-utils#514

@MattJmt MattJmt closed this as completed Apr 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants