99package dht // import "tinygo.org/x/drivers/dht"
1010
1111import (
12- "machine"
1312 "runtime/interrupt"
1413 "time"
14+
15+ "tinygo.org/x/drivers"
16+ "tinygo.org/x/drivers/internal/legacy"
17+ "tinygo.org/x/drivers/internal/pin"
1518)
1619
1720// DummyDevice provides a basic interface for DHT devices.
@@ -30,7 +33,8 @@ type DummyDevice interface {
3033// Since taking measurements from the sensor is time consuming procedure and blocks interrupts,
3134// user can avoid any hidden calls to the sensor.
3235type device struct {
33- pin machine.Pin
36+ set pin.OutputFn
37+ get pin.InputFn
3438
3539 measurements DeviceType
3640 initialized bool
@@ -43,8 +47,8 @@ type device struct {
4347// According to documentation pin should be always, but the t *device restores pin to the state before call.
4448func (t * device ) ReadMeasurements () error {
4549 // initial waiting
46- state := powerUp (t .pin )
47- defer t .pin . Set (state )
50+ state := powerUp (t .set , t . get )
51+ defer t .set (state )
4852 err := t .read ()
4953 if err == nil {
5054 t .initialized = true
@@ -93,14 +97,11 @@ func (t *device) HumidityFloat() (float32, error) {
9397// Perform initialization of the communication protocol.
9498// Device lowers the voltage on pin for startingLow=20ms and starts listening for response
9599// Section 5.2 in [1]
96- func initiateCommunication (p machine.Pin ) {
97- // Send low signal to the device
98- p .Configure (machine.PinConfig {Mode : machine .PinOutput })
99- p .Low ()
100+ func initiateCommunication (set pin.OutputFn ) {
101+ set .Low ()
100102 time .Sleep (startingLow )
101103 // Set pin to high and wait for reply
102- p .High ()
103- p .Configure (machine.PinConfig {Mode : machine .PinInput })
104+ set .High ()
104105}
105106
106107// Measurements returns both measurements: temperature and humidity as they sent by the device.
@@ -131,14 +132,14 @@ func (t *device) read() error {
131132 signals := signalsData [:]
132133
133134 // Start communication protocol with sensor
134- initiateCommunication (t .pin )
135+ initiateCommunication (t .set )
135136 // Wait for sensor's response and abort if sensor does not reply
136- err := waitForDataTransmission (t .pin )
137+ err := waitForDataTransmission (t .get )
137138 if err != nil {
138139 return err
139140 }
140141 // count low and high cycles for sensor's reply
141- receiveSignals (t .pin , signals )
142+ receiveSignals (t .get , signals )
142143
143144 // process received signals and store the result in the buffer. Abort if data transmission was interrupted and not
144145 // all 40 bits were received
@@ -158,13 +159,13 @@ func (t *device) read() error {
158159
159160// receiveSignals counts number of low and high cycles. The execution is time critical, so the function disables
160161// interrupts
161- func receiveSignals (pin machine. Pin , result []counter ) {
162+ func receiveSignals (get pin. InputFn , result []counter ) {
162163 i := uint8 (0 )
163164 mask := interrupt .Disable ()
164165 defer interrupt .Restore (mask )
165166 for ; i < 40 ; i ++ {
166- result [i * 2 ] = expectChange (pin , false )
167- result [i * 2 + 1 ] = expectChange (pin , true )
167+ result [i * 2 ] = expectChange (get , false )
168+ result [i * 2 + 1 ] = expectChange (get , true )
168169 }
169170}
170171
@@ -189,33 +190,59 @@ func (t *device) extractData(signals []counter, buf []uint8) error {
189190// waitForDataTransmission waits for reply from the sensor.
190191// If no reply received, returns NoSignalError.
191192// For more details, see section 5.2 in [1]
192- func waitForDataTransmission (p machine. Pin ) error {
193+ func waitForDataTransmission (get pin. InputFn ) error {
193194 // wait for thermometer to pull down
194- if expectChange (p , true ) == timeout {
195+ if expectChange (get , true ) == timeout {
195196 return NoSignalError
196197 }
197198 //wait for thermometer to pull up
198- if expectChange (p , false ) == timeout {
199+ if expectChange (get , false ) == timeout {
199200 return NoSignalError
200201 }
201202 // wait for thermometer to pull down and start sending the data
202- if expectChange (p , true ) == timeout {
203+ if expectChange (get , true ) == timeout {
203204 return NoSignalError
204205 }
205206 return nil
206207}
207208
208- // Constructor function for a DummyDevice implementation.
209- // This device provides full control to the user.
210- // It does not do any hidden measurements calls and does not check
211- // for 2 seconds delay between measurements.
212- func NewDummyDevice (pin machine.Pin , deviceType DeviceType ) DummyDevice {
213- pin .High ()
209+ func newDevice (pin drivers.Pin , deviceType DeviceType ) * device {
210+ pin .Set (true )
211+ // Pins are configured to maintain backward compatibility,
212+ // When writing new drivers we assume that pins are configured in user code
213+ // so the device initialization could be simplified like this:
214+ // return &device{
215+ // set: pin.Set,
216+ // get: pin.Get,
217+ // ...
218+ // }
219+ isOutput := true
214220 return & device {
215- pin : pin ,
221+ set : func (level bool ) {
222+ if ! isOutput {
223+ legacy .ConfigurePinOut (pin )
224+ isOutput = true
225+ }
226+ pin .Set (level )
227+ },
228+ get : func () bool {
229+ if isOutput {
230+ legacy .ConfigurePinInput (pin )
231+ isOutput = false
232+ }
233+ return pin .Get ()
234+ },
216235 measurements : deviceType ,
217236 initialized : false ,
218237 temperature : 0 ,
219238 humidity : 0 ,
220239 }
221240}
241+
242+ // Constructor function for a DummyDevice implementation.
243+ // This device provides full control to the user.
244+ // It does not do any hidden measurements calls and does not check
245+ // for 2 seconds delay between measurements.
246+ func NewDummyDevice (pin drivers.Pin , deviceType DeviceType ) DummyDevice {
247+ return newDevice (pin , deviceType )
248+ }
0 commit comments