Reputation: 11
I am new (very new!!) to swift and straggling to make my UI to send a string over the serial port. I've managed to open the port and read/parse the incoming traffic but when it comes to send a string, nothing is sent.
What I need to do is typing in the sendTextField
and when press the SendButton
to send the string to serial port. Also, when I print the data
which is what I want to send over serial port, it prints the number of bytes I try to send (i.e. 5 bytes). Shouldn't this be the string "Hello" that I try to send to serial port?
I am using Xcode Version 11.2 (11B52) and Swift 5.
Any help will be really appreciated. Thank you in advance!
This is how I call the "send" function:
@IBAction func SendButton(_ sender: Any) {
let TxData = sendTextField.stringValue
SFSerialIn.SendSerialData(TxData)
}
My main program is below:
import ORSSerial
import IOKit
import IOKit.serial
let SFSerialRegexp =
"(?<SFmode>[A-Z]+),\\s*" + "(?<prox>[0-1]),\\s*"
class SFSerialIn: NSObject, ORSSerialPortDelegate {
let path = "/dev/cu.usbserial-AI0484S9"
let baudRate: NSNumber = 115200
var serialPort: ORSSerialPort?
var delegate: SFSerialDelegate?
var stringBuffer = ""
var regex: NSRegularExpression!
var receivedBufferStart = false
override init() {
regex = try! NSRegularExpression(pattern: SFSerialRegexp)
}
deinit {
disconnect()
}
func SendSerialData(_ TxData: String){
let data = Data(TxData.utf8)
serialPort?.send(data)
print(TxData)
print(data)
}
func connect() {
if let serialPort = ORSSerialPort(path: path) {
serialPort.baudRate = baudRate
serialPort.delegate = self
serialPort.open()
} else {
print("Failed to open serial port")
}
}
func disconnect() {
serialPort?.close()
print("closing port...")
}
func serialPort(_ serialPort: ORSSerialPort, didReceive data: Data) {
guard let string = String(data: data, encoding: .utf8)
else {
return
}
stringBuffer += string
parseBuffer()
}
func parseBuffer() {
let lines = stringBuffer.split { $0.isNewline }
guard lines.count > 1 else {
return
}
let nextLines = lines[1...].joined()
if !receivedBufferStart {
stringBuffer = nextLines
receivedBufferStart = true
return
}
let line = String(lines[0])
if let matchResult = regex.firstMatch(in: line, range: NSRange(..<line.endIndex, in: line)) {
let sensorFrame = SFFrame(matchResult: matchResult, string: line)
delegate?.receive(sensorFrame: sensorFrame)
stringBuffer = nextLines
return
}
print("Failed to parse line :(")
stringBuffer = nextLines
}
func serialPort(_ serialPort: ORSSerialPort, didEncounterError error: Error) {
print("Serial port encountered error", error)
}
func serialPortWasOpened(_ serialPort: ORSSerialPort) {
print("Serial port opened")
}
func serialPortWasClosed(_ serialPort: ORSSerialPort) {
print("Serial port closed")
}
func serialPortWasRemovedFromSystem(_ serialPort: ORSSerialPort) {
print("Serial port was removed from system")
}
}
protocol SFSerialDelegate {
func receive(sensorFrame: SFFrame)
}
extension StringProtocol {
var data: Data { .init(utf8) }
}
Upvotes: 1
Views: 282
Reputation: 21373
It doesn't look to me like you're ever storing the opened serial port in your serialPort
instance property. So, when you do serialPort?.send(data)
, serialPort
is nil, and the ?
(optional chaining) operator means that send()
isn't called.
Try storing the serial port in your property after opening it:
func connect() {
if let serialPort = ORSSerialPort(path: path) {
serialPort.baudRate = baudRate
serialPort.delegate = self
serialPort.open()
self.serialPort = serialPort
} else {
print("Failed to open serial port")
}
}
Upvotes: 2