Skip to content

Commit e9f29d7

Browse files
committed
Bumping version to 1.8.0
1 parent f6387c3 commit e9f29d7

8 files changed

+310
-284
lines changed

RELEASE_NOTES.md

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Release Notes
22

3+
## 1.8.0 - 2019-10-30
4+
* Use GPIO from .NET Core 3
5+
36
## 1.7.8 - 2019-10-30
47
* .NET Core 3
58

paket.dependencies

+1-2
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,4 @@ group Pi
5454
nuget Thoth.Json
5555
nuget log4net
5656
nuget Elmish
57-
nuget Unosquare.Raspberry.IO strategy:min
58-
nuget Unosquare.WiringPi strategy:min
57+
nuget System.Device.Gpio

paket.lock

+143-190
Large diffs are not rendered by default.

src/Client/ReleaseNotes.fs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
module internal ReleaseNotes
22

3-
let Version = "1.7.8"
3+
let Version = "1.8.0"
44

55
let IsPrerelease = false
66

77
let Notes = """
88
# Release Notes
99
10+
## 1.8.0 - 2019-10-30
11+
* Use GPIO from .NET Core 3
12+
1013
## 1.7.8 - 2019-10-30
1114
* .NET Core 3
1215

src/PiServer/GeneralIO.fs

+114-47
Original file line numberDiff line numberDiff line change
@@ -3,72 +3,139 @@
33
open System
44
open System.Threading.Tasks
55
open FSharp.Control.Tasks.ContextInsensitive
6+
open System.Device.Gpio
67

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) =
169
let mutable active = false
10+
let mutable blinking = false
1711
do
18-
pin.PinMode <- GpioPinDriveMode.Output
19-
pin.Write false
12+
controller.OpenPin(pin, PinMode.Output)
13+
controller.Write(pin, PinValue.Low)
2014

2115
with
2216
member __.IsActive = active
2317

2418
member __.Activate() =
25-
pin.Write true
19+
controller.Write(pin, PinValue.High)
20+
blinking <- false
2621
active <- true
2722

2823
member __.Deactivate() =
29-
pin.Write false
24+
controller.Write(pin, PinValue.Low)
25+
blinking <- false
3026
active <- false
3127

3228
member this.Blink(times:int) = task {
29+
blinking <- false
3330
for _ in 0..times-1 do
3431
this.Activate()
3532
do! Task.Delay(300)
3633
this.Deactivate()
3734
do! Task.Delay(300)
3835
}
3936

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+
4466
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()

src/PiServer/PiServer.fs

+16-8
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,8 @@ open System.Reflection
1313
open GeneralIO
1414
open Elmish
1515
open Elmish.Audio
16-
open Unosquare.RaspberryIO.Abstractions
1716

1817

19-
GeneralIO.init()
2018

2119
let runIn (timeSpan:TimeSpan) successMsg errorMsg =
2220
let t() = task {
@@ -36,6 +34,14 @@ let log =
3634
log
3735

3836

37+
let controller =
38+
try
39+
new GeneralIO.Controller(log)
40+
with
41+
| exn ->
42+
log.ErrorFormat("Error during GPIO init: {0}", exn.Message)
43+
reraise()
44+
3945
type MediaFile = {
4046
FileName : string
4147
}
@@ -72,12 +78,12 @@ type Msg =
7278
let rfidLoop (dispatch,nodeServices:INodeServices) = task {
7379
log.InfoFormat("Connecting all buttons")
7480

75-
use _nextButton = new Button(Unosquare.RaspberryIO.Pi.Gpio.[BcmPin.Gpio04], fun () -> dispatch NextMediaFile)
76-
use _previousButton = new Button(Unosquare.RaspberryIO.Pi.Gpio.[BcmPin.Gpio18], fun () -> dispatch PreviousMediaFile)
77-
use _volumeDownButton = new Button(Unosquare.RaspberryIO.Pi.Gpio.[BcmPin.Gpio26], fun () -> dispatch VolumeDown)
78-
use _volumeUpButton = new Button(Unosquare.RaspberryIO.Pi.Gpio.[BcmPin.Gpio12], fun () -> dispatch VolumeUp)
79-
let blueLight = GeneralIO.LED(Unosquare.RaspberryIO.Pi.Gpio.[BcmPin.Gpio20])
80-
let yellowLight = GeneralIO.LED(Unosquare.RaspberryIO.Pi.Gpio.[BcmPin.Gpio21])
81+
let _nextButton = controller.NewButton(4, fun () -> dispatch NextMediaFile)
82+
let _previousButton = controller.NewButton(18, fun () -> dispatch PreviousMediaFile)
83+
let _volumeDownButton = controller.NewButton(26, fun () -> dispatch VolumeDown)
84+
let _volumeUpButton = controller.NewButton(12, fun () -> dispatch VolumeUp)
85+
let blueLight = controller.NewLED(20)
86+
let yellowLight = controller.NewLED(21)
8187
let allLights = [| blueLight; yellowLight|]
8288

8389
let! _ = allLights |> Array.map (fun l -> l.Blink(2)) |> Task.WhenAll
@@ -306,4 +312,6 @@ let t = task { while true do do! Task.Delay 10000 }
306312

307313
t |> Async.AwaitTask |> Async.RunSynchronously
308314

315+
(controller :> IDisposable).Dispose()
316+
309317
log.InfoFormat("PiServer {0} is shutting down.", ReleaseNotes.Version)

src/PiServer/PiServer.fsproj

+28-33
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,29 @@
1-
<?xml version="1.0" encoding="utf-8"?>
2-
<Project Sdk="Microsoft.NET.Sdk">
3-
<PropertyGroup>
4-
<OutputType>Exe</OutputType>
5-
<TargetFramework>netcoreapp3.0</TargetFramework>
6-
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
7-
</PropertyGroup>
8-
<ItemGroup>
9-
<Compile Include="..\Client\ReleaseNotes.fs" />
10-
<Compile Include="..\Shared\Shared.fs" />
11-
<Compile Include="..\Server\Utils.fs" />
12-
<Compile Include="SemVer.fs" />
13-
<Compile Include="FirmwareUpdate.fs" />
14-
<Compile Include="Elmish.Audio.fs" />
15-
<Compile Include="GeneralIO.fs" />
16-
<Compile Include="PiServer.fs" />
17-
</ItemGroup>
18-
<ItemGroup>
19-
<None Include="read-tag.js">
20-
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
21-
</None>
22-
23-
<None Include="package.json">
24-
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
25-
</None>
26-
<None Include="log4net.config">
27-
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
28-
</None>
29-
<None Include="PiServer">
30-
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
31-
</None>
32-
</ItemGroup>
33-
<Import Project="..\..\.paket\Paket.Restore.targets" />
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>netcoreapp3.0</TargetFramework>
5+
</PropertyGroup>
6+
<ItemGroup>
7+
<Compile Include="../Client/ReleaseNotes.fs" />
8+
<Compile Include="../Shared/Shared.fs" />
9+
<Compile Include="../Server/Utils.fs" />
10+
<Compile Include="SemVer.fs" />
11+
<Compile Include="FirmwareUpdate.fs" />
12+
<Compile Include="Elmish.Audio.fs" />
13+
<Compile Include="GeneralIO.fs" />
14+
<Compile Include="PiServer.fs" />
15+
<None Include="read-tag.js">
16+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
17+
</None>
18+
<None Include="package.json">
19+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
20+
</None>
21+
<None Include="log4net.config">
22+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
23+
</None>
24+
<None Include="PiServer">
25+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
26+
</None>
27+
</ItemGroup>
28+
<Import Project="..\..\.paket\Paket.Restore.targets" />
3429
</Project>

src/PiServer/paket.references

+1-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,5 @@ group Pi
55
Thoth.Json.Net
66
Thoth.Json
77
log4net
8-
Unosquare.Raspberry.IO
8+
System.Device.Gpio
99
Elmish
10-
Unosquare.WiringPi
11-

0 commit comments

Comments
 (0)