gobot.io/x/gobot@v1.16.0/drivers/aio/analog_sensor_driver.go (about) 1 package aio 2 3 import ( 4 "time" 5 6 "gobot.io/x/gobot" 7 ) 8 9 // AnalogSensorDriver represents an Analog Sensor 10 type AnalogSensorDriver struct { 11 name string 12 pin string 13 halt chan bool 14 interval time.Duration 15 connection AnalogReader 16 gobot.Eventer 17 gobot.Commander 18 rawValue int 19 value float64 20 scale func(input int) (value float64) 21 } 22 23 // NewAnalogSensorDriver returns a new AnalogSensorDriver with a polling interval of 24 // 10 Milliseconds given an AnalogReader and pin. 25 // The driver supports customizable scaling from read int value to returned float64. 26 // The default scaling is 1:1. An adjustable linear scaler is provided by the driver. 27 // 28 // Optionally accepts: 29 // time.Duration: Interval at which the AnalogSensor is polled for new information 30 // 31 // Adds the following API Commands: 32 // "Read" - See AnalogDriverSensor.Read 33 // "ReadValue" - See AnalogDriverSensor.ReadValue 34 func NewAnalogSensorDriver(a AnalogReader, pin string, v ...time.Duration) *AnalogSensorDriver { 35 d := &AnalogSensorDriver{ 36 name: gobot.DefaultName("AnalogSensor"), 37 connection: a, 38 pin: pin, 39 Eventer: gobot.NewEventer(), 40 Commander: gobot.NewCommander(), 41 interval: 10 * time.Millisecond, 42 halt: make(chan bool), 43 scale: func(input int) (value float64) { return float64(input) }, 44 } 45 46 if len(v) > 0 { 47 d.interval = v[0] 48 } 49 50 d.AddEvent(Data) 51 d.AddEvent(Value) 52 d.AddEvent(Error) 53 54 d.AddCommand("Read", func(params map[string]interface{}) interface{} { 55 val, err := d.Read() 56 return map[string]interface{}{"val": val, "err": err} 57 }) 58 59 d.AddCommand("ReadValue", func(params map[string]interface{}) interface{} { 60 val, err := d.ReadValue() 61 return map[string]interface{}{"val": val, "err": err} 62 }) 63 64 return d 65 } 66 67 // Start starts the AnalogSensorDriver and reads the sensor at the given interval. 68 // Emits the Events: 69 // Data int - Event is emitted on change and represents the current raw reading from the sensor. 70 // Value float64 - Event is emitted on change and represents the current reading from the sensor. 71 // Error error - Event is emitted on error reading from the sensor. 72 func (a *AnalogSensorDriver) Start() (err error) { 73 if a.interval == 0 { 74 // cyclic reading deactivated 75 return 76 } 77 var oldRawValue = 0 78 var oldValue = 0.0 79 go func() { 80 timer := time.NewTimer(a.interval) 81 timer.Stop() 82 for { 83 _, err := a.ReadValue() 84 if err != nil { 85 a.Publish(a.Event(Error), err) 86 } else { 87 if a.rawValue != oldRawValue && a.rawValue != -1 { 88 a.Publish(a.Event(Data), a.rawValue) 89 oldRawValue = a.rawValue 90 } 91 if a.value != oldValue && a.value != -1 { 92 a.Publish(a.Event(Value), a.value) 93 oldValue = a.value 94 } 95 } 96 97 timer.Reset(a.interval) 98 select { 99 case <-timer.C: 100 case <-a.halt: 101 timer.Stop() 102 return 103 } 104 } 105 }() 106 return 107 } 108 109 // Halt stops polling the analog sensor for new information 110 func (a *AnalogSensorDriver) Halt() (err error) { 111 if a.interval == 0 { 112 // cyclic reading deactivated 113 return 114 } 115 a.halt <- true 116 return 117 } 118 119 // Name returns the AnalogSensorDrivers name 120 func (a *AnalogSensorDriver) Name() string { return a.name } 121 122 // SetName sets the AnalogSensorDrivers name 123 func (a *AnalogSensorDriver) SetName(n string) { a.name = n } 124 125 // Pin returns the AnalogSensorDrivers pin 126 func (a *AnalogSensorDriver) Pin() string { return a.pin } 127 128 // Connection returns the AnalogSensorDrivers Connection 129 func (a *AnalogSensorDriver) Connection() gobot.Connection { return a.connection.(gobot.Connection) } 130 131 // Read returns the current reading from the sensor without scaling 132 func (a *AnalogSensorDriver) Read() (val int, err error) { 133 return a.connection.AnalogRead(a.Pin()) 134 } 135 136 // SetScaler substitute the default 1:1 return value function by a new scaling function 137 func (a *AnalogSensorDriver) SetScaler(scaler func(int) float64) { 138 a.scale = scaler 139 } 140 141 // ReadValue returns the current reading from the sensor 142 func (a *AnalogSensorDriver) ReadValue() (val float64, err error) { 143 if a.rawValue, err = a.Read(); err != nil { 144 return 145 } 146 a.value = a.scale(a.rawValue) 147 return a.value, nil 148 } 149 150 // Value returns the last read value from the sensor 151 func (a *AnalogSensorDriver) Value() float64 { 152 return a.value 153 } 154 155 // RawValue returns the last read raw value from the sensor 156 func (a *AnalogSensorDriver) RawValue() int { 157 return a.rawValue 158 } 159 160 func AnalogSensorLinearScaler(fromMin, fromMax int, toMin, toMax float64) func(input int) (value float64) { 161 m := (toMax - toMin) / float64(fromMax-fromMin) 162 n := toMin - m*float64(fromMin) 163 return func(input int) (value float64) { 164 if input <= fromMin { 165 return toMin 166 } 167 if input >= fromMax { 168 return toMax 169 } 170 return float64(input)*m + n 171 } 172 }