Чтение с последовательного порта в Swift 4 с использованием ORSSerialPort

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

func serialPort(_ serialPort: ORSSerialPort, didReceive data: Data) {
    // Do things
}

Однако есть ли что-то вроде ORSSerialPort.read()?

1 ответ

Решение

Я не думаю ORSSerialPort.read() хорошая идея Я знаю, что некоторые другие последовательные библиотеки написаны таким образом, но единственный способ для этого - read() блокировать (возможно с тайм-аутом), пока байт не поступит в порт. Блокировка ввода / вывода усложняет написание хорошего адаптивного приложения, и я хочу отвести разработчиков, использующих ORSSerialPort, от этого подхода.

Вместо этого вы должны действительно реализовать serialPort(_:, didReceive:) в вашем ORSSerialPort делегировать. Когда данные поступают в последовательный порт, этот метод вызывается с полученными данными, и вы можете делать с ним все, что захотите.

Тем не менее, если ваше устройство обменивается данными с использованием протокола типа команда / ответ (т. Е. Каждый раз, когда вы отправляете команду, устройство отправляет некоторый ответ), вам следует обратиться к API запроса / ответа ORSSerialPort. Он позволяет вам явно определить формат ожидаемых ответов на команды, а сам ORSSerialPort будет обрабатывать асинхронно ожидающие, анализирующие и проверяющие ответы. См. Документацию для получения дополнительной информации об этой части ORSSerialPort. Библиотека также включает пример проекта RequestResponseDemo, который демонстрирует использование этого API. Обе версии Swift и Objective-C включены.

Библиотека ORSSerialPort популярна и в целом хороша. Однако я обнаружил, что это не работает с последовательными устройствами TTY. Это было в первую очередь из-за использования IOKit для обнаружения последовательных портов - он обнаруживал только физические устройства.

Скорее всего, в вашем случае это нормально, но если вы хотите протестировать свой код, но не хотите подключаться к физическому устройству, он падает. Хороший код всегда нуждается в проверке. Итак, проверьте https://github.com/kpishere/POSIXSerialPort, чтобы узнать об очень простом API последовательного интерфейса, это именно то, что вам нужно для записи и ответа на входящие данные, а также работает с физическими или виртуальными устройствами (как изначально предполагалось Unix!).

Однако на ваш вопрос вы не хотите напрямую вызывать read(). Вы понимаете, является ли это блокирующим чтением? Затем вы начинаете работать с потоками. Оба предлагаемых API изолируют вас от этого и позволяют мыслить в терминах модели, управляемой событиями, - это значительно упрощает код.

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