hardbyte / hardbyte/python-can
Timeout for slcan Notifier breaks communication
- 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
Evaluación
Este issue todavía no se ha evaluado.