gobot.io/x/gobot@v1.16.0/platforms/megapi/megapi_adaptor.go (about)

     1  package megapi
     2  
     3  import (
     4  	"io"
     5  	"time"
     6  
     7  	"go.bug.st/serial"
     8  	"gobot.io/x/gobot"
     9  )
    10  
    11  var _ gobot.Adaptor = (*Adaptor)(nil)
    12  
    13  // Adaptor is the Gobot adaptor for the MakeBlock MegaPi board
    14  type Adaptor struct {
    15  	name              string
    16  	port              string
    17  	connection        io.ReadWriteCloser
    18  	serialMode        *serial.Mode
    19  	writeBytesChannel chan []byte
    20  	finalizeChannel   chan struct{}
    21  }
    22  
    23  // NewAdaptor returns a new MegaPi Adaptor with specified serial port used to talk to the MegaPi with a baud rate of 115200
    24  func NewAdaptor(device string) *Adaptor {
    25  	c := &serial.Mode{BaudRate: 115200}
    26  	return &Adaptor{
    27  		name:              "MegaPi",
    28  		connection:        nil,
    29  		port:              device,
    30  		serialMode:        c,
    31  		writeBytesChannel: make(chan []byte),
    32  		finalizeChannel:   make(chan struct{}),
    33  	}
    34  }
    35  
    36  // Name returns the name of this adaptor
    37  func (megaPi *Adaptor) Name() string {
    38  	return megaPi.name
    39  }
    40  
    41  // SetName sets the name of this adaptor
    42  func (megaPi *Adaptor) SetName(n string) {
    43  	megaPi.name = n
    44  }
    45  
    46  // Connect starts a connection to the board
    47  func (megaPi *Adaptor) Connect() error {
    48  	if megaPi.connection == nil {
    49  		sp, err := serial.Open(megaPi.port, megaPi.serialMode)
    50  		if err != nil {
    51  			return err
    52  		}
    53  
    54  		// sleeping is required to give the board a chance to reset
    55  		time.Sleep(2 * time.Second)
    56  		megaPi.connection = sp
    57  	}
    58  
    59  	// kick off thread to send bytes to the board
    60  	go func() {
    61  		for {
    62  			select {
    63  			case bytes := <-megaPi.writeBytesChannel:
    64  				megaPi.connection.Write(bytes)
    65  				time.Sleep(10 * time.Millisecond)
    66  			case <-megaPi.finalizeChannel:
    67  				megaPi.finalizeChannel <- struct{}{}
    68  				return
    69  			default:
    70  				time.Sleep(10 * time.Millisecond)
    71  			}
    72  		}
    73  	}()
    74  	return nil
    75  }
    76  
    77  // Finalize terminates the connection to the board
    78  func (megaPi *Adaptor) Finalize() error {
    79  	megaPi.finalizeChannel <- struct{}{}
    80  	<-megaPi.finalizeChannel
    81  	if err := megaPi.connection.Close(); err != nil {
    82  		return err
    83  	}
    84  	return nil
    85  }