Я разрабатываю контроллер для панели назначения шины Mobite c. Предполагаемый уровень связи: SBC
-> USB 2 RS485 [FTDI]
-> Mobitec
.
Я также впервые работаю с последовательным интерфейсом и RS485.
Хотя при разработке моя рабочая станция - ОС Ma c - если это может что-то изменить.
Как узнать, что это устройство FTDI?
$ system_profiler SPUSBDataType
USB:
USB 3.0 Bus:
Host Controller Driver: AppleUSBXHCIWPT
PCI Device ID: 0x9cb1
PCI Revision ID: 0x0003
PCI Vendor ID: 0x8086
FT230X Basic UART:
Product ID: 0x6015
Vendor ID: 0x0403 (Future Technology Devices International Limited)
Version: 10.00
Serial Number: DN05Q09Q
Speed: Up to 12 Mb/s
Manufacturer: FTDI
Location ID: 0x14100000 / 8
Current Available (mA): 500
Current Required (mA): 90
Extra Operating Current (mA): 0
Используя библиотеку node-serialport
, я написал следующий код:
const SerialPort = require("serialport");
const port = new SerialPort("/dev/tty.usbserial-DN05Q09Q", {
autoOpen: false,
baudRate: 4800
});
port.on("open", () => {
console.log("Opened", port.path);
});
port.open((error) => {
if (error) {
return void console.error(`Error opening port`, port.path, error);
}
port.write(/* Buffer with a length of 23 bytes (proprietary structure) */, (error) => {
if (error) {
return void console.error(
"Error while writing...",
port.path,
error
);
}
console.log(
"Written successfully.",
port.path
);
});
});
$ node script.js
Opened /dev/tty.usbserial-DN05Q09Q
Written successfully. /dev/tty.usbserial-DN05Q09Q
Но, к сожалению, хотя в журналах нет ошибок, и я вижу светодиод активности на моем USB 2 RS485
устройство, кажется, что целевое устройство не получает сообщение, поскольку оно не отвечает должным образом (дисплей не обновляет светодиоды).
Хотя, если я хочу добавить Тайм-аут после записи, например, так:
port.write(/* Buffer with a length of 33 bytes (proprietary structure) */, (error) => {
if (error) {
return void console.error(
"Error while writing...",
port.path,
error
);
}
console.log(
"Written successfully.",
port.path
);
console.log("Starting a timeout after write...");
setTimeout(() => {
console.log("Timeout after write expired.");
}, 1000)
});
$ node script.js
Opened /dev/tty.usbserial-DN05Q09Q
Written successfully. /dev/tty.usbserial-DN05Q09Q
Starting a timeout after write...
Timeout after write expired.
Работает.
Очевидно, устройство будет реагировать быстрее, чем указанная секунда.
Но, учитывая, что если я измените время ожидания на 10ms
, оно не будет работать. Если я изменю его на 50ms
, он, кажется, будет работать постоянно, но я заметил некоторые редкие исключения 1 . 40ms
, кажется, работает ~ 5% времени.
1 Исключения возникают при изменении полезных нагрузок. Как будто какое-то состояние было оставлено в последовательном порту.
Я также попытался SerialPort.drain
после записи в обратном вызове записи. Также пытался drain
параллельно.
Ни один не помог.
К сожалению, у меня нет производственного предназначенного SB C для тестирования с этим, так как он будет работать Linux и это может что-то изменить.
В своих усилиях по отладке я попытался watch -n .1 node script.js
проверить, связано ли это с какими-то внутренними буферами устройства, но оно работает безупречно с 50ms
. 10ms
один не зарегистрируется ни разу. 40ms
дает результат ~ 5%.
Является ли тайм-аут известной вещью в последовательном мире, и есть известные схемы, чтобы обойти это? Может быть, это проблема MacOS? Может быть, адаптер RS485 требует дополнительной обработки?
Неужели здесь нет подсказок ...