serial_reader.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. package uhf
  2. import (
  3. "errors"
  4. "github.com/tarm/serial"
  5. "io"
  6. "os"
  7. "sync"
  8. "time"
  9. )
  10. type SerialReader struct {
  11. COMPort string
  12. BaudRate int
  13. port *serial.Port
  14. isConnected bool
  15. buffer []byte // 拼包缓冲区
  16. ioMu sync.Mutex
  17. }
  18. func NewSerialReader(comPort string, baudRate int) *SerialReader {
  19. return &SerialReader{
  20. COMPort: comPort,
  21. BaudRate: baudRate,
  22. }
  23. }
  24. func (s *SerialReader) Connect() error {
  25. s.ioMu.Lock()
  26. defer s.ioMu.Unlock()
  27. cfg := &serial.Config{
  28. Name: s.COMPort,
  29. Baud: s.BaudRate,
  30. ReadTimeout: 1 * time.Second,
  31. Size: 8,
  32. Parity: serial.ParityNone,
  33. StopBits: serial.Stop1,
  34. }
  35. port, err := serial.OpenPort(cfg)
  36. if err != nil {
  37. s.isConnected = false
  38. return err
  39. }
  40. s.port = port
  41. s.isConnected = true
  42. return nil
  43. }
  44. func (s *SerialReader) Disconnect() error {
  45. s.ioMu.Lock()
  46. defer s.ioMu.Unlock()
  47. if s.port != nil {
  48. _ = s.port.Close()
  49. }
  50. s.isConnected = false
  51. s.buffer = nil
  52. return nil
  53. }
  54. func (s *SerialReader) IsConnected() bool {
  55. s.ioMu.Lock()
  56. defer s.ioMu.Unlock()
  57. return s.isConnected
  58. }
  59. func (s *SerialReader) SendData(data []byte) error {
  60. s.ioMu.Lock()
  61. defer s.ioMu.Unlock()
  62. return s.sendDataLocked(data)
  63. }
  64. func (s *SerialReader) sendDataLocked(data []byte) error {
  65. if !s.isConnected {
  66. return errors.New("串口未连接")
  67. }
  68. n, err := s.port.Write(data)
  69. if err != nil {
  70. return err
  71. }
  72. if n != len(data) {
  73. return errors.New("发送不完整")
  74. }
  75. return nil
  76. }
  77. // ==============================
  78. // 🔥 关键修复:串口返回完整25字节帧
  79. // ==============================
  80. func (s *SerialReader) ReadData() ([]byte, error) {
  81. s.ioMu.Lock()
  82. defer s.ioMu.Unlock()
  83. return s.readDataLocked()
  84. }
  85. func (s *SerialReader) readDataLocked() ([]byte, error) {
  86. if !s.isConnected {
  87. return nil, errors.New("串口未连接")
  88. }
  89. buf := make([]byte, 1024)
  90. for {
  91. n, err := s.port.Read(buf)
  92. if err != nil {
  93. if err == io.EOF || os.IsTimeout(err) {
  94. break
  95. }
  96. s.isConnected = false
  97. return nil, err
  98. }
  99. if n > 0 {
  100. s.buffer = append(s.buffer, buf[:n]...)
  101. }
  102. // 找25字节完整帧
  103. for len(s.buffer) >= 25 {
  104. if s.buffer[0] == 0xCF {
  105. frame := s.buffer[:25]
  106. s.buffer = s.buffer[25:]
  107. return frame, nil
  108. } else {
  109. s.buffer = s.buffer[1:]
  110. }
  111. }
  112. // 超时退出
  113. if len(s.buffer) == 0 {
  114. break
  115. }
  116. }
  117. return nil, ErrReadTimeout
  118. }
  119. func (s *SerialReader) SendAndRecv(data []byte) ([]byte, error) {
  120. s.ioMu.Lock()
  121. defer s.ioMu.Unlock()
  122. if err := s.sendDataLocked(data); err != nil {
  123. return nil, err
  124. }
  125. time.Sleep(100 * time.Millisecond)
  126. return s.readDataLocked()
  127. }