RS-232 Radio Scanner

I have a Radio Scanner that I had built a VB.NET application in windows to send commands to the scanner via a USB to RS-232 on the radio. I would like to have the same ability on the MAC using Swift. Is this even possible? in VB.NET is was pretty easy and a fun project. I have been searching for 2 days and have found nothing. Newb to Swift and programming on the MAC.


The following would be the same as hitting the scan button on the radio.


2 = STX

15 = Code for the scan Key

3 = ETX

5D = sum not including STX


Private Sub KEYPAD_SCAN_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles KEYPAD_SCAN.Click

D = 0

Dim TARRANT() As Byte = New Byte() {2, &H4B, 15, 3, &H5D}

mySerialPort.Write(TARRANT, 0, 5)

End Sub

If I understand well, all you do is write to the serial port ? Exact ?


If so, have a look on how to do on Mac, and send the right commands:

h ttps://www.mac-usb-serial.com/docs/tutorials/serial-port-programming-swift-mac-os-x.html

My developer son looked at that. No help.

When you say looked at that, does that mean he succeeded to write to the serial port through USB ?


Can you read the serial port as well ?

No indications that it was sending to serial port.

Ok, so report when you have enough information on what your developer has done so far.

Tried for myself. From the page you posted:


When I run "pod update" the result is [!] The dependency `ORSSerialPort` is not used in any concrete target.


Previous to this step everything looks good.


It does create the pod dir in the project directory, with 3 sub dir's called headers, Local Podspecs, and Target support files. all of which are empty.


Regards

It isn’t necessary to bring in a pod just to talk to the serial port. On macOS, like any UNIX-based system, the serial port is exposed as a character device file. You can access that using UNIX standard

open
,
close
,
read
and
write
system calls. Calling those from Swift is a bit challenging, so here’s the simplest example:
import Foundation

let fd = open("/dev/cu.usbmodem12345671", O_RDWR)
assert(fd >= 0)

let bytesWritten = write(fd, "AT\r\n", 4)
assert(bytesWritten == 3)

var dataRead = [UInt8](repeating: 0, count: 32)
let bytesRead = read(fd, &dataRead, dataRead.count)
assert(bytesRead >= 0)

dataRead.removeLast(32 - bytesRead)
print(dataRead) // prints: [65, 84, 13, 13, 10, 79, 75, 13, 10]

let junk = close(fd)
assert(junk == 0)

Some things to note:

  • If you interpret the output from line 14 as ASCII, you get

    AT\r\r\nOK\r\n
    , which is what you’d expect.
  • In line 3 I’ve hard-coded the character device path. In a real app you’d want to discover the serial port in the I/O Registry, which is an entirely separate kettle of (complex) fish.

  • I’m talking to a USB modem, so I’ve sent it a simple

    AT
    command with a trailing CR (
    \r
    ) and LF (
    \n
    ). In a real app you’d want to wrap
    write
    with something that accepts a
    Data
    value. Here’s an example of what that might look like:
    func write(fd: Int32, data: Data) throws -> Int {
        let dataCount = data.count
        return try data.withUnsafeBytes { (dataPtr: UnsafePointer<UInt8>) -> Int in
            let bytesWritten = write(fd, dataPtr, dataCount)
            guard bytesWritten >= 0 else {
                let err = errno
                throw NSError(domain: NSPOSIXErrorDomain, code: Int(err), userInfo: nil)
            }
            return Int(bytesWritten)
        }
    }

    .

  • Lines 9 and 10 read the data into a

    [UInt8]
    . Again, you’d probably want a wrapper that works in terms of
    Data
    .

Good luck!

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
RS-232 Radio Scanner
 
 
Q