gobot.io/x/gobot@v1.16.0/drivers/gpio/pir_motion_driver.go (about) 1 package gpio 2 3 import ( 4 "time" 5 6 "gobot.io/x/gobot" 7 ) 8 9 // PIRMotionDriver represents a digital Proximity Infra Red (PIR) motion detecter 10 type PIRMotionDriver struct { 11 Active bool 12 pin string 13 name string 14 halt chan bool 15 interval time.Duration 16 connection DigitalReader 17 gobot.Eventer 18 } 19 20 // NewPIRMotionDriver returns a new PIRMotionDriver with a polling interval of 21 // 10 Milliseconds given a DigitalReader and pin. 22 // 23 // Optionally accepts: 24 // time.Duration: Interval at which the PIRMotionDriver is polled for new information 25 func NewPIRMotionDriver(a DigitalReader, pin string, v ...time.Duration) *PIRMotionDriver { 26 b := &PIRMotionDriver{ 27 name: gobot.DefaultName("PIRMotion"), 28 connection: a, 29 pin: pin, 30 Active: false, 31 Eventer: gobot.NewEventer(), 32 interval: 10 * time.Millisecond, 33 halt: make(chan bool), 34 } 35 36 if len(v) > 0 { 37 b.interval = v[0] 38 } 39 40 b.AddEvent(MotionDetected) 41 b.AddEvent(MotionStopped) 42 b.AddEvent(Error) 43 44 return b 45 } 46 47 // Start starts the PIRMotionDriver and polls the state of the sensor at the given interval. 48 // 49 // Emits the Events: 50 // MotionDetected - On motion detected 51 // MotionStopped int - On motion stopped 52 // Error error - On button error 53 // 54 // The PIRMotionDriver will send the MotionDetected event over and over, 55 // just as long as motion is still being detected. 56 // It will only send the MotionStopped event once, however, until 57 // motion starts being detected again 58 func (p *PIRMotionDriver) Start() (err error) { 59 go func() { 60 for { 61 newValue, err := p.connection.DigitalRead(p.Pin()) 62 if err != nil { 63 p.Publish(Error, err) 64 } 65 switch newValue { 66 case 1: 67 if !p.Active { 68 p.Active = true 69 p.Publish(MotionDetected, newValue) 70 } 71 case 0: 72 if p.Active { 73 p.Active = false 74 p.Publish(MotionStopped, newValue) 75 } 76 } 77 78 select { 79 case <-time.After(p.interval): 80 case <-p.halt: 81 return 82 } 83 } 84 }() 85 return 86 } 87 88 // Halt stops polling the button for new information 89 func (p *PIRMotionDriver) Halt() (err error) { 90 p.halt <- true 91 return 92 } 93 94 // Name returns the PIRMotionDriver name 95 func (p *PIRMotionDriver) Name() string { return p.name } 96 97 // SetName sets the PIRMotionDriver name 98 func (p *PIRMotionDriver) SetName(n string) { p.name = n } 99 100 // Pin returns the PIRMotionDriver pin 101 func (p *PIRMotionDriver) Pin() string { return p.pin } 102 103 // Connection returns the PIRMotionDriver Connection 104 func (p *PIRMotionDriver) Connection() gobot.Connection { return p.connection.(gobot.Connection) }