Example #1
0
    def start(self, device, node_id):
        if node_id < 1 or node_id > 127:
            raise CANopenException('Node identifier needs to be in the range of 1 to 127.')

        print('Starting CANopen device with Node ID %d(0x%02X)' % (node_id, node_id))
        self.event.start()
        self.driver = SocketCAN(device=device)
        self.receiver.start()
        self.timer.start()
        self.nmt = NMT(canopen=self, node_id=node_id)

        # Bootup message
        data = bytearray()
        data.append(self.nmt.operatingState)
        self.send(0x700 + self.nmt.node_id, data)

        self.nmt.operatingState = self.nmt.OPERATIONAL
Example #2
0
class CANopen:
    def __init__(self):
        self.driver = None
        self.event = Event()
        self.receiver_alive = True
        self.receiver = Thread(target=self.run)
        self.timer = Timer()
        self.nmt = None

    def start(self, device, node_id):
        if node_id < 1 or node_id > 127:
            raise CANopenException('Node identifier needs to be in the range of 1 to 127.')

        print('Starting CANopen device with Node ID %d(0x%02X)' % (node_id, node_id))
        self.event.start()
        self.driver = SocketCAN(device=device)
        self.receiver.start()
        self.timer.start()
        self.nmt = NMT(canopen=self, node_id=node_id)

        # Bootup message
        data = bytearray()
        data.append(self.nmt.operatingState)
        self.send(0x700 + self.nmt.node_id, data)

        self.nmt.operatingState = self.nmt.OPERATIONAL

    def send(self, node_id, data):
        self.driver.send(node_id, data)

    def register(self, handler):
        self.event += handler

    def run(self):
        while self.receiver_alive:
            try:
                # TODO do not block, then we can not terminate
                message = self.driver.recv()
                # TODO use new thread to emit events
                self.event(message=message)
            except CANopenException:
                print('Problem receiving data.')

    def stop(self):
        print('Stopping CANopen device')
        self.nmt.delete()
        self.timer.stop()
        self.receiver_alive = False
        self.driver.close()
        self.receiver.join()
        self.event.stop()

    def SDOupload(self, node_id, index, subindex, type, value):
        # only expedited yet
        if len(value) > 4:
            raise CANopenException('Can not upload more than 4 bytes currently.')

        data = bytearray()
        # command byte
        data.append(0x23 | (4 - len(data)) << 2)
        # index LSB
        data.append(index & 0xff)
        data.append((index >> 8) & 0xff)
        # sub-index
        data.append(subindex)
        # data TODO LSB
        data.append(value)

        receive = SDOResponse()
        self.event += receive.receive()
        try:
            self.send(0x580 + node_id, data)
            return receive.get()
        finally:
            self.event -= receive.receive()

    def SDOread(self, node_id, index, subindex, type):
        return 0