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