Полученное сообщение на CANbus всегда возвращает одно и то же значение с помощью python-can

У меня есть шина CAN (PCAN) с несколькими входами. Я пытаюсь прочитать входные данные в Py thon и распечатать их на консоли. Первое сообщение, которое я получаю от шины, является правильным, однако, если я изменяю состояние на входе, данные в сообщении не изменяются и продолжают выплевывать первые полученные данные. В представлении PCAN я вижу изменение данных, поэтому это не аппаратный сбой.

Мой код:

import can
from time import sleep


def main():
bus = can.interface.Bus(bustype='pcan', channel='PCAN_USBBUS1', bitrate=500000)

try:
    while True:

        # msg = can.Message(arbitration_id=0x232, data=[0x00], is_extended_id=False)
        # try:
        #     bus.send(msg)
        #     print("message sent on {}".format(bus.channel_info))
        # except can.CanError:
        #     print("message not sent!")

        msg = bus.recv(None)
        try:

            if msg.arbitration_id == 0x1B2:
                print(msg)

            if msg.arbitration_id == 0x1B3:
                print(msg)

            if msg.arbitration_id == 0x1B4:
                print(msg)

            if msg.arbitration_id == 0x1B5:
                print(msg)

        except AttributeError:
            print("Nothing received this time")

        sleep(0.2)

except KeyboardInterrupt:
    print("Program Exited")
except can.CanError:
    print("Message NOT sent")

bus.shutdown()


if __name__ == '__main__':
    main()

Я пытался отправить сообщение перед каждым получением, но это не помогло. То же самое с вызовом can.Listener().stop() Функция на слушателя после печати полученного сообщения.

PCAN-view показывает, что оборудование работает, так как я вижу изменения, происходящие на экране.

Например.

  1. в начале входные 0 и 1 находятся на высоком уровне в блоке 0x1B2
  2. bus.recv возвращает [00 03], что правильно
  3. Я очищаю ввод 0 и 1
  4. PCAN-просмотр показывает данные [00 00]
  5. bus.recv возвращает [00 03], что неверно. Это не изменилось.

Я прочитал readthedocs несколько раз, но боюсь, что-то пропустил. Нужно ли очищать буфер ввода? Я только видел информацию о функции для очистки буфера вывода.

1 ответ

Решение

Итак, я решил реализовать это по-другому с помощью буфера и уведомителя. Я также отключил функцию автоматического обновления устройств, чтобы они не спамили по шине.

Я придумал этот класс, чтобы использовать автобус.

import can
import logging


def _get_message(msg):

    return msg


class PCANBus(object):

    RX_SDO = 0x600
    TX_SDO = 0x580
    RX_PDO = 0x200
    TX_PDO = 0x180

    id_unit_a = [120, 121, 122, 123]
    id_unit_b = [124, 125, 126, 127]

    def __init__(self):

        logging.info("Initializing CANbus")

        self.bus = can.Bus(channel="PCAN_USBBUS1", bustype="pcan")
        self.buffer = can.BufferedReader()
        self.notifier = can.Notifier(self.bus, [_get_message, self.buffer])

    def send_message(self, message):

        try:
            self.bus.send(message)
            return True
        except can.CanError:
            logging.error("message not sent!")
            return False

    def read_input(self, id):

        msg = can.Message(arbitration_id=self.RX_PDO + id,
                          data=[0x00],
                          is_extended_id=False)

        self.send_message(msg)
        return self.buffer.get_message()

    def flush_buffer(self):

        msg = self.buffer.get_message()
        while (msg is not None):
            msg = self.buffer.get_message()

    def cleanup(self):

        self.notifier.stop()
        self.bus.shutdown()

    def disable_update(self):

        for i in [50, 51, 52, 53]:

            msg = can.Message(arbitration_id=0x600 + i,
                              data=[0x23, 0xEA, 0x5F, 0x00, 0x00, 0x00, 0x00, 0x00],
                              is_extended_id=False)

            self.send_message(msg)

И может быть использован как:

pcan = PCANBus()
msg = Message(arbitration_id=pcan.RX_PDO + 50, is_extended_id=False, data=[0x4F, 0x00])
pcan.send_message(msg)
ret = pcan.read_input(0x78)
pcan.cleanup()

'ret' содержит ответное сообщение

Другие вопросы по тегам