main.swift 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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 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("\nOther: ", terminator:"")
  33. } else if (!myturn && myself){
  34. myturn = true
  35. print("\nMe: ", terminator:"")
  36. }
  37. print(characterToPrint, terminator:"")
  38. }
  39. do {
  40. print("Attempting to open port: \(portName)")
  41. try serialPort.openPort()
  42. print("Serial port \(portName) opened successfully.")
  43. defer {
  44. serialPort.closePort()
  45. print("Port Closed")
  46. }
  47. serialPort.setSettings(receiveRate: .baud9600,
  48. transmitRate: .baud9600,
  49. minimumBytesToRead: 1)
  50. prepareStdin()
  51. //Turn off output buffering if not multiple threads will have problems printing
  52. setbuf(stdout, nil);
  53. //Run the serial port reading function in another thread
  54. var readingThread = pthread_t()
  55. let pthreadFunc: @convention(c) (UnsafeMutableRawPointer?) -> UnsafeMutableRawPointer? = {
  56. observer in
  57. while true{
  58. do{
  59. var readCharacter = try serialPort.readChar()
  60. printToScreenFrom(myself: false, characterToPrint: readCharacter)
  61. } catch {
  62. print("Error: \(error)")
  63. }
  64. }
  65. }
  66. pthread_create(&readingThread, nil, pthreadFunc, nil)
  67. print("\nReady to send and receive messages in realtime!")
  68. print("\nMe: ", terminator:"")
  69. while true {
  70. var enteredKey = getKeyPress()
  71. printToScreenFrom(myself: true, characterToPrint: enteredKey)
  72. var _ = try serialPort.writeChar(enteredKey)
  73. }
  74. } catch PortError.failedToOpen {
  75. print("Serial port \(portName) failed to open. You might need root permissions.")
  76. } catch {
  77. print("Error: \(error)")
  78. }