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