3
3
open System
4
4
open System.Threading .Tasks
5
5
open FSharp.Control .Tasks .ContextInsensitive
6
+ open System.Device .Gpio
6
7
7
- open Unosquare.RaspberryIO
8
- open Unosquare.WiringPi
9
- open Unosquare.RaspberryIO .Abstractions
10
-
11
-
12
- let init () =
13
- Pi.Init< BootstrapWiringPi>()
14
-
15
- type LED ( pin : IGpioPin ) =
8
+ type LED ( controller : GpioController , log : log4net.ILog , pin : int ) =
16
9
let mutable active = false
10
+ let mutable blinking = false
17
11
do
18
- pin.PinMode <- GpioPinDriveMode .Output
19
- pin .Write false
12
+ controller.OpenPin ( pin , PinMode .Output)
13
+ controller .Write( pin , PinValue.Low )
20
14
21
15
with
22
16
member __.IsActive = active
23
17
24
18
member __.Activate () =
25
- pin.Write true
19
+ controller.Write( pin, PinValue.High)
20
+ blinking <- false
26
21
active <- true
27
22
28
23
member __.Deactivate () =
29
- pin.Write false
24
+ controller.Write( pin, PinValue.Low)
25
+ blinking <- false
30
26
active <- false
31
27
32
28
member this.Blink ( times : int ) = task {
29
+ blinking <- false
33
30
for _ in 0 .. times-1 do
34
31
this.Activate()
35
32
do ! Task.Delay( 300 )
36
33
this.Deactivate()
37
34
do ! Task.Delay( 300 )
38
35
}
39
36
40
- type Button ( pin : IGpioPin , onPress ) =
41
- let mutable lastChangedState = DateTime.MinValue
42
- let bounceTimeSpan = TimeSpan.FromMilliseconds 30.
43
- let mutable lastState = false
37
+ member this.StartBlinking () = task {
38
+ blinking <- true
39
+ while blinking do
40
+ this.Activate()
41
+ do ! Task.Delay( 300 )
42
+ this.Deactivate()
43
+ do ! Task.Delay( 300 )
44
+ }
45
+
46
+ member this.StopBlinking () = this.Deactivate()
47
+
48
+ type CableConnection ( controller : GpioController , log : log4net.ILog , pin : int ) =
49
+ let mutable onConnected = None
50
+ let mutable onDisconnected = None
51
+ let mutable lastState = None
52
+
53
+ let execute expectedState f =
54
+ match lastState with
55
+ | Some s ->
56
+ let state = controller.Read( pin) = PinValue.High
57
+ if state = expectedState && s <> state then
58
+ f()
59
+ lastState <- Some state
60
+ | None ->
61
+ let state = controller.Read( pin) = PinValue.High
62
+ if state = expectedState then
63
+ f()
64
+ lastState <- Some state
65
+
44
66
do
45
- pin.PinMode <- GpioPinDriveMode.Input
46
- pin.InputPullMode <- GpioPinResistorPullMode.PullUp
47
- lastState <- pin.Read()
48
- pin.RegisterInterruptCallback(
49
- EdgeDetection.FallingAndRisingEdge,
50
- fun () ->
51
- let state = pin.Read()
52
- let time = DateTime.UtcNow
53
- let bounceTimeReached = lastChangedState.Add bounceTimeSpan < time
54
- if bounceTimeReached && ( not state) && lastState then
55
- ()
56
- if bounceTimeReached && state && not lastState then
57
- onPress()
58
- if lastState <> state then
59
- lastChangedState <- time
60
- lastState <- state)
61
-
62
- let d =
63
- { new IDisposable with
64
- member __.Dispose () = () }
65
-
66
- interface IDisposable with
67
- member __.Dispose () = d.Dispose()
68
-
69
- let waitForButtonPress ( pin : IGpioPin ) = task {
70
- let pressed = ref false
71
- use _button = new Button( pin,( fun _ -> pressed := true ))
72
- while not ! pressed do
73
- do ! Task.Delay( 100 )
74
- }
67
+ controller.OpenPin( pin, PinMode.InputPullUp)
68
+
69
+ let rising ( _sender : obj ) ( _e : PinValueChangedEventArgs ) =
70
+ log.InfoFormat( " Rising - unconnected" )
71
+ match onDisconnected with
72
+ | None -> ()
73
+ | Some f -> execute true f
74
+
75
+ let falling ( _sender : obj ) ( _e : PinValueChangedEventArgs ) =
76
+ log.InfoFormat( " Falling - connected" )
77
+ match onConnected with
78
+ | None -> ()
79
+ | Some f -> execute false f
80
+
81
+ controller.RegisterCallbackForPinValueChangedEvent(
82
+ pin,
83
+ PinEventTypes.Rising,
84
+ PinChangeEventHandler rising)
85
+
86
+ controller.RegisterCallbackForPinValueChangedEvent(
87
+ pin,
88
+ PinEventTypes.Falling,
89
+ PinChangeEventHandler falling)
90
+
91
+ member __.SetOnConnected f =
92
+ onConnected <- Some f
93
+ execute false f
94
+
95
+ member __.SetOnDisConnected f =
96
+ onDisconnected <- Some f
97
+ execute true f
98
+
99
+ type Button ( controller : GpioController , log : log4net.ILog , pin : int , onPress ) =
100
+ let mutable lastState = None
101
+
102
+ let execute () =
103
+ match lastState with
104
+ | Some s ->
105
+ let state = controller.Read( pin) = PinValue.High
106
+ if not state && s <> state then
107
+ lastState <- Some state
108
+ | None ->
109
+ let state = controller.Read( pin) = PinValue.High
110
+ if not state then
111
+ onPress()
112
+ lastState <- Some state
113
+
114
+ do
115
+ controller.OpenPin( pin, PinMode.InputPullUp)
116
+
117
+ let falling ( _sender : obj ) ( _e : PinValueChangedEventArgs ) =
118
+ log.InfoFormat( " Falling - pressed" )
119
+ execute ()
120
+
121
+ controller.RegisterCallbackForPinValueChangedEvent(
122
+ pin,
123
+ PinEventTypes.Falling,
124
+ PinChangeEventHandler falling)
125
+
126
+
127
+ type Controller ( log : log4net.ILog ) =
128
+ let controller = new GpioController( PinNumberingScheme.Logical)
129
+
130
+ with
131
+ member __.NewLED ( pin ) =
132
+ LED( controller, log, pin)
133
+
134
+ member __.NewCableConnection ( pin : int ) =
135
+ CableConnection( controller, log, pin)
136
+
137
+ member __.NewButton ( pin : int , onPress ) =
138
+ Button( controller, log, pin, onPress)
139
+
140
+ interface IDisposable with
141
+ member __.Dispose () = controller.Dispose()
0 commit comments