hardbyte / hardbyte/python-can

Timeout for slcan Notifier breaks communication

Abierto
#727 0 comentarios 0 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
Python
Estrellas
1.6k
Forks
697
Métricas de merge de PR
Sin PR fusionados en 30 d

Descripción

Hello,
For about two days I'm investigating problem with python-can 3.3.2 and hardware called [UCCB](https://github.com/UsbCANConverter-UCCbasic/UCCBEmbedded) which implements (more or less) slcan protocol over USB.

During my tests, I'm using device in loopback mode, so I have changed method `open` in `slcan.py` from:
```
def open(self):
self.write('O')
```
to:
```
def open(self):
self.write('l')
```

Additionally, to monitor data sent and received by `slcan.py` interface I have changed `write` method from:
```
def write(self, string):
self.serialPortOrig.write(string.encode() + self.LINE_TERMINATOR)
self.serialPortOrig.flush()
```
to:
```
def write(self, string):
self.serialPortOrig.write(string.encode() + self.LINE_TERMINATOR)
print("SENT:"+str(string.encode() + self.LINE_TERMINATOR))
self.serialPortOrig.flush()
```
and, similar way, `_recv_internal` from:
```
# If we still don't have a complete message, do a blocking read
if self.LINE_TERMINATOR not in self._buffer:
self._buffer += self.serialPortOrig.read_until(self.LINE_TERMINATOR)

if self.LINE_TERMINATOR not in self._buffer:
# Timed out
return None, False
```
to:
```
# If we still don't have a complete message, do a blocking read
if self.LINE_TERMINATOR not in self._buffer:
self._buffer += self.serialPortOrig.read_until(self.LINE_TERMINATOR)

print("RECEIVED:"+str(self._buffer))

if self.LINE_TERMINATOR not in self._buffer:
# Timed out
return None, False
```

The minimal example which shows problem is:
```
import can, time

class canFramePrinter(can.Listener):

def __init__(self):
super().__init__()

def on_message_received(self,msg):
print("ID: {}\tDLC: {}\t{}".format(msg.arbitration_id,msg.dlc,msg.data.hex()))

canbus = can.interface.Bus(interface="slcan", channel="COM6") ## hardcoded serial port name
canbusNotifier=can.Notifier(canbus,[canFramePrinter()])

tx_msg = can.Message(arbitration_id=0x01, data=[0x11, 0x22], is_extended_id=False)

time.sleep(3)
canbus.send(tx_msg)

time.sleep(3)
canbus.send(tx_msg)

time.sleep(3)
canbus.send(tx_msg)

time.sleep(3)
canbus.send(tx_msg)

time.sleep(3)
```
I have expected that it will be possible to receive from loopback the same frames which were sent, but in the terminal I see following:
```
D:/Python37/python.exe ./test.py
SENT:b'l\r'
RECEIVED:bytearray(b'\r')
RECEIVED:bytearray(b'')
RECEIVED:bytearray(b'')
SENT:b't00121122\r'
RECEIVED:bytearray(b'\x07')
RECEIVED:bytearray(b'\x07')
RECEIVED:bytearray(b'\x07')
RECEIVED:bytearray(b'\x07')
SENT:b't00121122\r'
RECEIVED:bytearray(b'\x07\x07')
RECEIVED:bytearray(b'\x07\x07')
SENT:b't00121122\r'
RECEIVED:bytearray(b'\x07\x07\x07')
RECEIVED:bytearray(b'\x07\x07\x07')
RECEIVED:bytearray(b'\x07\x07\x07')
RECEIVED:bytearray(b'\x07\x07\x07\x07')
SENT:b't00121122\r'
RECEIVED:bytearray(b'\x07\x07\x07\x07')
RECEIVED:bytearray(b'\x07\x07\x07\x07')
RECEIVED:bytearray(b'\x07\x07\x07\x07')
```
0x07 sign is defined as error flag, when command sent to device is not recognised. Flag is duplicated when next error occurs. But when I change `Notifier` instantiation from:
```
canbusNotifier=can.Notifier(canbus,[canFramePrinter()])
```
to:
```
canbusNotifier=can.Notifier(canbus,[canFramePrinter()],None)
```
received terminal output is:
```
D:/Python37/python.exe ./test.py
SENT:b'l\r'
RECEIVED:bytearray(b'\r')
SENT:b't00121122\r'
RECEIVED:bytearray(b'z\r')
RECEIVED:bytearray(b't00121122\r')
ID: 1 DLC: 2 1122
RECEIVED:bytearray(b'z\r')
SENT:b't00121122\r'
RECEIVED:bytearray(b't00121122\r')
ID: 1 DLC: 2 1122
SENT:b't00121122\r'
RECEIVED:bytearray(b'z\r')
RECEIVED:bytearray(b't00121122\r')
ID: 1 DLC: 2 1122
SENT:b't00121122\r'
RECEIVED:bytearray(b'z\r')
RECEIVED:bytearray(b't00121122\r')
ID: 1 DLC: 2 1122
```
what indicates, IMHO, proper operation.

Changing `Notifier` timeout value for any finite value, causes the same problem, but with `None` timeout, I'm not able `stop()` `Notifier` in my target app.

I have not any idea, what goes bad with finite timeout. Have you any ideas, how it can be fixed?

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.