ORSSerialPort
ORSSerialPort 是一个用于 macOS 的易于使用的 Objective-C 串行端口库。它对于编写 Objective-C 或 Swift Mac 应用程序并与外部设备(最常见的是 RS-232)通过串行端口通信的程序员很有用。您可以使用 ORSSerialPort 打开连接到 Arduino 项目、机器人、数据采集设备、业余无线电台和其他各种设备的应用程序。使用 ORSSerialPort 打开端口并发送数据可以像这样简单
ORSSerialPort *serialPort = [ORSSerialPort serialPortWithPath:@"/dev/cu.KeySerial1"];
serialPort.baudRate = @4800;
[serialPort open];
[serialPort sendData:someData]; // someData is an NSData object
[serialPort close]; // Later, when you're done with the port
或者在 Swift 中:
let serialPort = ORSSerialPort(path: "/dev/cu.KeySerial1")
serialPort.baudRate = 4800
serialPort.open()
serialPort.sendData(someData) // someData is an NSData object
serialPort.close() // Later, when you're done with the port
ORSSerialPort 在 MIT 许可下发布,意味着您可以将其用于封闭源代码项目和开源项目。然而,即使在封闭源代码项目中,您也必须包含 ORSSerialPort 版权声明的一份公开可访问副本,您可以在 LICENSE 文件中找到它。
如果您对 ORSSerialPort 有任何疑问、建议或贡献,请 联系我。我也很乐意听到您在使用它时的有趣项目。
本 README 提供了 ORSSerialPort 库的概览,旨在提供足够的信息以快速启动。您可以在 http://cocoadocs.org/docsets/ORSSerialPort/ 上阅读 ORSSerialPort 的完整技术文档。ORSSerialPort wiki 也包含详细的文档。
本 README 中的示例代码是 Objective-C 编写的。然而,ORSSerialPort 也容易从 Swift 代码中使用。示例文件夹包含所有四个示例项目的 Swift 版本。有关更多信息,请参阅下面的“示例项目”部分。
如何使用 ORSSerialPort
将 ORSSerialPort 添加到项目的几种方法。您可以使用附带的框架项目,如 Carthage,CocoaPods,或手动将 ORSSerialPort 的源代码包含到您的项目中。有关这些方法的详细说明,请参阅 安装 ORSSerialPort 指南。
打开端口并设置
您可以通过两种方式获取 ORSSerialPort
实例。最简单的方法是使用 ORSSerialPortManager
的 availablePorts
数组(下面将解释)。另一种方法是通过串行端口的 BSD 设备路径来获取新的 ORSSerialPort
实例。
ORSSerialPort *port = [ORSSerialPort serialPortWithPath:@"/dev/cu.KeySerial1"];
请注意,您必须像上面示例中所示那样将完整路径提供给 +serialPortWithPath:
。
获取端口实例后,可以使用 -open
方法打开它。当您完成对该端口的操作后,可以使用 -close
方法关闭它。
可以使用 ORSSerialPort
提供的各个属性来设置端口设置,如波特率、停止位数、校验位和高低位控制设置等。
port.baudRate = @9600;
port.parity = ORSSerialPortParityNone;
port.numberOfStopBits = 1;
port.usesRTSCTSFlowControl = YES;
有关更多信息,请参阅 入门指南。
发送数据
通过将 NSData
对象传递给 -sendData:
方法来发送原始数据
NSData *dataToSend = [self.sendTextField.stringValue dataUsingEncoding:NSUTF8StringEncoding];
[self.serialPort sendData:dataToSend];
接收数据
要接收数据,您可以实现 ORSSerialPortDelegate
协议中 -serialPort:didReceiveData:
方法,并设置 ORSSerialPort
实例的代理属性。如以下说明,此方法始终在主队列中调用。以下是一个示例实现
- (void)serialPort:(ORSSerialPort *)serialPort didReceiveData:(NSData *)data
{
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
[self.receivedDataTextView.textStorage.mutableString appendString:string];
[self.receivedDataTextView setNeedsDisplay:YES];
}
ORSSerialPortDelegate
ORSSerialPort
包含一个委托属性和一个名为 ORSSerialPortDelegate
的委托协议。端口会向其委托报告事件,包括接收数据、端口开启/关闭事件、从系统中移除和错误。有关更多信息,请参阅入门指南,或阅读ORSSerialPort.h 文档。
ORSSerialPortManager
ORSSerialPortManager
是一个单例类(每个应用一个实例),可用于获取可用的串行端口列表。使用管理器的 availablePorts
属性来获取端口列表
NSArray *ports = [[ORSSerialPortManager sharedSerialPortManager] availablePorts];
可使用键盘和值观察来观察 ORSSerialPortManager 的 availablePorts
,以便在USB串行适配器插入或移除时收到通知。此外,它还会在这些事件发生时发布 NSNotifications。当Mac进入睡眠状态时,它还会关闭打开的串行端口,并在唤醒时自动重新打开它们。这可以防止我在将机器置于睡眠状态下看到的问题,即串行端口驱动程序可能在端口保持开启状态下挂起。请注意,使用 ORSSerialPortManager
是可选的。它提供了一些很好的功能,但仅 ORSSerialPort
是发送和接收数据的必需品。
有关 ORSSerialPortManager 的更多信息,请参阅入门指南,或阅读ORSSerialPortManager.h 文档。
ORSSerialPacketDescriptor
接收到的串行数据将按照接收到的顺序传递到您的应用程序。像 ORSSerialPort 这样的底层库无法知道您发送和接收数据的结构和格式。例如,您可能期待一个完整的数据包, but receive callbacks for each byte. 通常,这需要您维护一个缓冲区,用接收到的数据填充,只有当接收到完整的数据包时才进行处理。为了消除手动管理和缓冲接收数据的需求,ORSSerialPort 包含一个数据包解析API。这是通过 ORSSerialPacketDescriptor
和 ORSSerialPort
上相关的方法实现的。
有关 ORSSerialPort 数据包解析API的更多信息,请参阅数据包解析API指南,阅读ORSSerialPacketDescriptor.h 文档,并查看数据包解析演示示例应用程序。
ORSSerialRequest
通常,应用程序需要向设备发送命令,然后等待收到的特定响应后再继续执行。为了简化实现这类场景,ORSSerialPort 包含了一个请求/响应 API。这是通过 ORSSerialRequest
和与 ORSSerialPort
关联的方法实现的。
例如,一个从连接的设备读取温度的程序可能执行以下操作
- (void)readTemperature
{
NSData *command = [@"$TEMP?;" dataUsingEncoding:NSASCIIStringEncoding];
ORSSerialPacketDescriptor *responseDescriptor =
[[ORSSerialPacketDescriptor alloc] initWithMaximumPacketLength:9
userInfo:nil
responseEvaluator:^BOOL(NSData *data) {
return [self temperatureFromResponsePacket:data] != nil;
}];
ORSSerialRequest *request =
[ORSSerialRequest requestWithDataToSend:command
userInfo:nil
timeoutInterval:kTimeoutDuration
responseDescriptor:responseDescriptor];
[self.serialPort sendRequest:request];
}
- (void)serialPort:(ORSSerialPort *)port didReceiveResponse:(NSData *)data toRequest:(ORSSerialRequest *)request
{
NSString *response = [[NSString alloc] initWithData:data usingEncoding:NSASCIIStringEncoding];
NSLog(@"response = %@", response);
self.temperature = [self temperatureFromResponsePacket:data];
}
- (void)serialPort:(ORSSerialPort *)port requestDidTimeout:(ORSSerialRequest *)request
{
NSLog(@"command timed out!);
}
有关 ORSSerialPort 的请求/响应 API 的更多信息,请参阅 请求/响应 API 指南,阅读 ORSSerialRequest.h 中的文档,以及查看 请求ResponseDemo 示例应用程序。
示例项目
ORSSerialPort 包含一个名为 Examples 的文件夹,其中包含演示使用 ORSSerialPort 的小程序的 Xcode 项目。每个示例都可用 同时 在 Objective-C 和 Swift 中。以下示例应用程序包含
- ORSSerialPortDemo - 简单的图形串行终端示例应用程序。这是 ORSSerialPort 的主要示例。
- CommandLineDemo - 命令行应用程序示例。
- PacketParsingDemo - GUI 应用程序示例,演示了 ORSSerialPacketDescriptor 的使用。
- RequestResponseDemo - GUI 应用程序示例,演示了 ORSSerialRequest 的使用。
您可以在 ORSSerialPort wiki 上了解更多有关这些示例的信息。
贡献
对 ORSSerialPort 的贡献非常欢迎。然而,建议贡献者在开始任何贡献的工作之前先阅读 贡献指南。如果您有任何关于具体贡献的问题,也可以自由地打开 GitHub issue 或 发送电子邮件。