From 10db8f6d89b93b564907f006eff1a93b6c27469b Mon Sep 17 00:00:00 2001 From: Drew Bowering Date: Wed, 3 Apr 2024 00:57:50 -0600 Subject: [PATCH] implement party mode --- main.go | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 138 insertions(+), 12 deletions(-) diff --git a/main.go b/main.go index c2dd758..04051ab 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "machine" + "runtime" "time" ) @@ -73,8 +74,11 @@ var ( const ( period = uint64(1e9 / 500) - pressdelay = time.Millisecond * 500 - brightnesspeak = uint32(255) + pressdelay = time.Millisecond * 300 + brightnesspeak = uint32(256) + defaultrng = uint32(time.Millisecond * 250) + maxrng = uint32(time.Millisecond * 500) + minrng = uint32(time.Millisecond * 50) ) func main() { @@ -247,18 +251,17 @@ func loop(lights lightSet, insidebrightness chan uint32, outsidebrightness chan for { go normal(lights, insidebrightness, outsidebrightness, partyChange, lastBrightness) <-partypushed - // go party(lights) - // <-partypushed partyChange <- true lb := <-lastBrightness - select { - case insidebrightness <- lb.inside: - default: - } - select { - case outsidebrightness <- lb.outside: - default: - } + insidebrightness <- lb.inside + outsidebrightness <- lb.outside + + go party(lights, insidebrightness, outsidebrightness, partyChange, lastBrightness) + <-partypushed + partyChange <- true + lb = <-lastBrightness + insidebrightness <- lb.inside + outsidebrightness <- lb.outside } } @@ -285,3 +288,126 @@ func setNormal(light *lighthardware, brightness uint32) { light.green.set(brightness) light.blue.set(brightness) } + +func party(lights lightSet, inBrightChange <-chan uint32, outBrightChange <-chan uint32, partyChange <-chan bool, lastBrightness chan<- brightnesses) { + var brightIn uint32 + var brightOut uint32 + inBright := make(chan uint32, 1) + in2Bright := make(chan uint32, 1) + outBright := make(chan uint32, 1) + partysOver := make(chan bool, 3) + partysDone := make(chan bool, 3) + + go partyLight(lights.inside, inBright, partysOver, partysDone) + go partyLight(lights.inside2, in2Bright, partysOver, partysDone) + go partyLight(lights.outside, outBright, partysOver, partysDone) + runtime.Gosched() + + for { + select { + case brightIn = <-inBrightChange: + inBright <- brightIn + in2Bright <- brightIn + case brightOut = <-outBrightChange: + outBright <- brightOut + case <-partyChange: + partysOver <- true + partysOver <- true + partysOver <- true + runtime.Gosched() + <-partysDone + <-partysDone + <-partysDone + lastBrightness <- brightnesses{inside: brightIn, outside: brightOut} + return + } + } +} + +func partyLight(light *lighthardware, brightChange <-chan uint32, endParty <-chan bool, partyEnded chan<- bool) { + rBright := make(chan uint32, 1) + gBright := make(chan uint32, 1) + bBright := make(chan uint32, 1) + partysOver := make(chan bool, 3) + partysDone := make(chan bool, 3) + + go partyColour(light.red, rBright, partysOver, partysDone) + go partyColour(light.green, gBright, partysOver, partysDone) + go partyColour(light.blue, bBright, partysOver, partysDone) + runtime.Gosched() + + for { + select { + case brightness := <-brightChange: + rBright <- brightness + gBright <- brightness + bBright <- brightness + case <-endParty: + partysOver <- true + partysOver <- true + partysOver <- true + runtime.Gosched() + <-partysDone + <-partysDone + <-partysDone + partyEnded <- true + return + } + } +} + +func partyColour(light led, brightChange <-chan uint32, endParty <-chan bool, partyEnded chan<- bool) { + brightness := <-brightChange + +LOOP: + for { + if brightness > 0 { + r, err := machine.GetRNG() + if err != nil { + r = defaultrng + } + + r = (r % maxrng) + minrng + + delaytime := time.Duration(r / brightness) + for i := brightness; i > 0; i-- { + light.set(i) + runtime.Gosched() + time.Sleep(delaytime) + + select { + case brightness = <-brightChange: + continue LOOP + case <-endParty: + partyEnded <- true + return + default: + } + } + + for i := uint32(0); i <= brightness; i++ { + light.set(i) + runtime.Gosched() + time.Sleep(delaytime) + + select { + case brightness = <-brightChange: + continue LOOP + case <-endParty: + partyEnded <- true + return + default: + } + } + } else { + light.set(0) + select { + case brightness = <-brightChange: + continue + case <-endParty: + partyEnded <- true + return + } + } + } +}