main.swift 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import Foundation
  2. import SwiftSerial
  3. let arguments = CommandLine.arguments
  4. guard arguments.count >= 2 else {
  5. print("Need serial port name, e.g. /dev/ttyUSB0 or /dev/cu.usbserial as the first argument.")
  6. exit(1)
  7. }
  8. print("Connect a null modem serial cable between two machines before you continue to use this program")
  9. let portName = arguments[1]
  10. let serialPort: SerialPort = SerialPort(path: portName)
  11. var myturn = true
  12. // Prepares the stdin so we can getchar() without echoing
  13. func prepareStdin() {
  14. // Set up the control structure
  15. var settings = termios()
  16. // Get options structure for stdin
  17. tcgetattr(STDIN_FILENO, &settings)
  18. //Turn off ICANON and ECHO
  19. settings.c_lflag &= ~tcflag_t(ICANON | ECHO)
  20. tcsetattr(STDIN_FILENO, TCSANOW, &settings)
  21. }
  22. func getKeyPress () -> UnicodeScalar {
  23. let valueRead: Int = Int(getchar())
  24. guard let charRead = UnicodeScalar(valueRead) else{
  25. return UnicodeScalar("")!
  26. }
  27. return charRead
  28. }
  29. func printToScreenFrom(myself: Bool, characterToPrint: UnicodeScalar){
  30. if(myturn && !myself){
  31. myturn = false
  32. print("\n\nOther: ", terminator:"")
  33. } else if (!myturn && myself){
  34. myturn = true
  35. print("\n\nMe: ", terminator:"")
  36. }
  37. print(characterToPrint, terminator:"")
  38. }
  39. func backgroundRead() {
  40. while true{
  41. do{
  42. let readCharacter = try serialPort.readChar()
  43. printToScreenFrom(myself: false, characterToPrint: readCharacter)
  44. } catch {
  45. print("Error: \(error)")
  46. }
  47. }
  48. }
  49. do {
  50. print("Attempting to open port: \(portName)")
  51. try serialPort.openPort()
  52. print("Serial port \(portName) opened successfully.")
  53. defer {
  54. serialPort.closePort()
  55. print("Port Closed")
  56. }
  57. serialPort.setSettings(receiveRate: .baud9600,
  58. transmitRate: .baud9600,
  59. minimumBytesToRead: 1)
  60. prepareStdin()
  61. //Turn off output buffering if not multiple threads will have problems printing
  62. setbuf(stdout, nil);
  63. //Run the serial port reading function in another thread
  64. #if os(Linux)
  65. var readingThread = pthread_t()
  66. let pthreadFunc: @convention(c) (UnsafeMutableRawPointer?) -> UnsafeMutableRawPointer? = {
  67. observer in
  68. backgroundRead()
  69. return nil
  70. }
  71. pthread_create(&readingThread, nil, pthreadFunc, nil)
  72. #elseif os(OSX)
  73. DispatchQueue.global(qos: .userInitiated).async {
  74. backgroundRead()
  75. }
  76. #endif
  77. print("\nReady to send and receive messages in realtime!")
  78. print("\nMe: ", terminator:"")
  79. while true {
  80. var enteredKey = getKeyPress()
  81. printToScreenFrom(myself: true, characterToPrint: enteredKey)
  82. var _ = try serialPort.writeChar(enteredKey)
  83. }
  84. } catch PortError.failedToOpen {
  85. print("Serial port \(portName) failed to open. You might need root permissions.")
  86. } catch {
  87. print("Error: \(error)")
  88. }