Compare commits
10 Commits
aab533caaf
...
10db8f6d89
Author | SHA1 | Date | |
---|---|---|---|
10db8f6d89 | |||
4a29e0c600 | |||
69042cbe9c | |||
972b395f5d | |||
772ac6a8d8 | |||
67607347e4 | |||
3c4b177360 | |||
bbd231b2eb | |||
856a6e2d88 | |||
32d03ddd05 |
361
main.go
361
main.go
@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"machine"
|
||||
"runtime"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -11,32 +12,44 @@ type pwm interface {
|
||||
Channel(machine.Pin) (uint8, error)
|
||||
}
|
||||
|
||||
type led struct {
|
||||
pin machine.Pin
|
||||
pwm pwm
|
||||
channel uint8
|
||||
}
|
||||
|
||||
func (l *led) InitPWM() error {
|
||||
var err error
|
||||
|
||||
l.channel, err = l.pwm.Channel(l.pin)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (l *led) set(brightness uint32) {
|
||||
l.pwm.Set(l.channel, (l.pwm.Top()/brightnesspeak)*brightness)
|
||||
}
|
||||
|
||||
type lighthardware struct {
|
||||
rPin machine.Pin
|
||||
gPin machine.Pin
|
||||
bPin machine.Pin
|
||||
rPwm pwm
|
||||
gPwm pwm
|
||||
bPwm pwm
|
||||
rCh uint8
|
||||
gCh uint8
|
||||
bCh uint8
|
||||
red led
|
||||
green led
|
||||
blue led
|
||||
}
|
||||
|
||||
func (lhw *lighthardware) InitPWM() error {
|
||||
var err error
|
||||
|
||||
lhw.rCh, err = lhw.rPwm.Channel(lhw.rPin)
|
||||
err = lhw.red.InitPWM()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
lhw.gCh, err = lhw.gPwm.Channel(lhw.gPin)
|
||||
err = lhw.green.InitPWM()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
lhw.bCh, err = lhw.bPwm.Channel(lhw.bPin)
|
||||
err = lhw.blue.InitPWM()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -44,15 +57,36 @@ func (lhw *lighthardware) InitPWM() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type lightSet struct {
|
||||
inside *lighthardware
|
||||
inside2 *lighthardware
|
||||
outside *lighthardware
|
||||
}
|
||||
|
||||
type brightnesses struct {
|
||||
inside uint32
|
||||
outside uint32
|
||||
}
|
||||
|
||||
var (
|
||||
brightnessSteps = []uint32{0, 255, 100, 20}
|
||||
)
|
||||
|
||||
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() {
|
||||
errs := make(chan error)
|
||||
|
||||
outsidepushed_raw := make(chan bool)
|
||||
insidepushed_raw := make(chan bool)
|
||||
partypushed_raw := make(chan bool)
|
||||
outsidepushed := make(chan bool)
|
||||
insidepushed := make(chan bool)
|
||||
partypushed := make(chan bool)
|
||||
@ -61,8 +95,8 @@ func main() {
|
||||
insidebrightness := make(chan uint32, 2)
|
||||
|
||||
outsidebutton := machine.GP22
|
||||
insidebutton := machine.GP21
|
||||
partybutton := machine.GP20
|
||||
insidebutton := machine.GP20
|
||||
partybutton := machine.GP21
|
||||
|
||||
outsidebutton.Configure(machine.PinConfig{Mode: machine.PinInputPullup})
|
||||
insidebutton.Configure(machine.PinConfig{Mode: machine.PinInputPullup})
|
||||
@ -70,23 +104,27 @@ func main() {
|
||||
|
||||
outsidebutton.SetInterrupt(machine.PinFalling, func(p machine.Pin) {
|
||||
select {
|
||||
case outsidepushed <- true:
|
||||
case outsidepushed_raw <- true:
|
||||
default:
|
||||
}
|
||||
})
|
||||
insidebutton.SetInterrupt(machine.PinFalling, func(p machine.Pin) {
|
||||
select {
|
||||
case insidepushed <- true:
|
||||
case insidepushed_raw <- true:
|
||||
default:
|
||||
}
|
||||
})
|
||||
partybutton.SetInterrupt(machine.PinFalling, func(p machine.Pin) {
|
||||
select {
|
||||
case partypushed <- true:
|
||||
case partypushed_raw <- true:
|
||||
default:
|
||||
}
|
||||
})
|
||||
|
||||
go delayChan(outsidepushed_raw, outsidepushed)
|
||||
go delayChan(insidepushed_raw, insidepushed)
|
||||
go delayChan(partypushed_raw, partypushed)
|
||||
|
||||
pwm2 := machine.PWM2
|
||||
pwm2.Configure(machine.PWMConfig{
|
||||
Period: period,
|
||||
@ -109,12 +147,18 @@ func main() {
|
||||
})
|
||||
|
||||
insideLight := lighthardware{
|
||||
rPin: machine.GP11,
|
||||
gPin: machine.GP13,
|
||||
bPin: machine.GP12,
|
||||
rPwm: pwm5,
|
||||
gPwm: pwm6,
|
||||
bPwm: pwm6,
|
||||
red: led{
|
||||
pin: machine.GP11,
|
||||
pwm: pwm5,
|
||||
},
|
||||
green: led{
|
||||
pin: machine.GP13,
|
||||
pwm: pwm6,
|
||||
},
|
||||
blue: led{
|
||||
pin: machine.GP12,
|
||||
pwm: pwm6,
|
||||
},
|
||||
}
|
||||
err := insideLight.InitPWM()
|
||||
|
||||
@ -122,12 +166,18 @@ func main() {
|
||||
errs <- err
|
||||
} else {
|
||||
insideLight2 := lighthardware{
|
||||
rPin: machine.GP8,
|
||||
gPin: machine.GP10,
|
||||
bPin: machine.GP9,
|
||||
rPwm: pwm4,
|
||||
gPwm: pwm5,
|
||||
bPwm: pwm4,
|
||||
red: led{
|
||||
pin: machine.GP8,
|
||||
pwm: pwm4,
|
||||
},
|
||||
green: led{
|
||||
pin: machine.GP10,
|
||||
pwm: pwm5,
|
||||
},
|
||||
blue: led{
|
||||
pin: machine.GP9,
|
||||
pwm: pwm4,
|
||||
},
|
||||
}
|
||||
err = insideLight2.InitPWM()
|
||||
|
||||
@ -135,21 +185,33 @@ func main() {
|
||||
errs <- err
|
||||
} else {
|
||||
outsideLight := lighthardware{
|
||||
rPin: machine.GP5,
|
||||
gPin: machine.GP7,
|
||||
bPin: machine.GP6,
|
||||
rPwm: pwm2,
|
||||
gPwm: pwm3,
|
||||
bPwm: pwm3,
|
||||
red: led{
|
||||
pin: machine.GP5,
|
||||
pwm: pwm2,
|
||||
},
|
||||
green: led{
|
||||
pin: machine.GP7,
|
||||
pwm: pwm3,
|
||||
},
|
||||
blue: led{
|
||||
pin: machine.GP6,
|
||||
pwm: pwm3,
|
||||
},
|
||||
}
|
||||
err = outsideLight.InitPWM()
|
||||
|
||||
if err != nil {
|
||||
errs <- err
|
||||
} else {
|
||||
lights := lightSet{
|
||||
inside: &insideLight,
|
||||
inside2: &insideLight2,
|
||||
outside: &outsideLight,
|
||||
}
|
||||
|
||||
go cycleBrightness(insidepushed, insidebrightness)
|
||||
go cycleBrightness(outsidepushed, outsidebrightness)
|
||||
go loop(&insideLight, &insideLight2, &outsideLight, insidebrightness, outsidebrightness)
|
||||
go loop(lights, insidebrightness, outsidebrightness, partypushed)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -157,66 +219,195 @@ func main() {
|
||||
println((<-errs).Error())
|
||||
}
|
||||
|
||||
func cycleBrightness(pushchan chan bool, brightnesschan chan uint32) {
|
||||
brightnesschan <- 0
|
||||
func delayChan(inchan <-chan bool, outchan chan<- bool) {
|
||||
var last time.Time
|
||||
|
||||
for {
|
||||
<-pushchan
|
||||
brightnesschan <- 255
|
||||
time.Sleep(pressdelay)
|
||||
<-pushchan
|
||||
brightnesschan <- 120
|
||||
time.Sleep(pressdelay)
|
||||
<-pushchan
|
||||
brightnesschan <- 30
|
||||
time.Sleep(pressdelay)
|
||||
<-pushchan
|
||||
brightnesschan <- 0
|
||||
time.Sleep(pressdelay)
|
||||
val := <-inchan
|
||||
now := time.Now()
|
||||
if now.Sub(last) > pressdelay {
|
||||
last = now
|
||||
select {
|
||||
case outchan <- val:
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ledset(lpwm pwm, ledch uint8, brightness uint32) {
|
||||
lpwm.Set(ledch, (lpwm.Top()/brightnesspeak)*brightness)
|
||||
func cycleBrightness(pushchan <-chan bool, brightnesschan chan<- uint32) {
|
||||
for {
|
||||
for _, b := range brightnessSteps {
|
||||
brightnesschan <- b
|
||||
<-pushchan
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func loop(inside *lighthardware, inside2 *lighthardware, outside *lighthardware, insidebrightness chan uint32, outsidebrightness chan uint32) {
|
||||
func loop(lights lightSet, insidebrightness chan uint32, outsidebrightness chan uint32, partypushed <-chan bool) {
|
||||
partyChange := make(chan bool)
|
||||
lastBrightness := make(chan brightnesses)
|
||||
|
||||
for {
|
||||
go normal(lights, insidebrightness, outsidebrightness, partyChange, lastBrightness)
|
||||
<-partypushed
|
||||
partyChange <- true
|
||||
lb := <-lastBrightness
|
||||
insidebrightness <- lb.inside
|
||||
outsidebrightness <- lb.outside
|
||||
|
||||
go party(lights, insidebrightness, outsidebrightness, partyChange, lastBrightness)
|
||||
<-partypushed
|
||||
partyChange <- true
|
||||
lb = <-lastBrightness
|
||||
insidebrightness <- lb.inside
|
||||
outsidebrightness <- lb.outside
|
||||
}
|
||||
}
|
||||
|
||||
func normal(lights lightSet, inBrightChange <-chan uint32, outBrightChange <-chan uint32, partyChange <-chan bool, lastBrightness chan<- brightnesses) {
|
||||
var brightIn uint32
|
||||
var brightOut uint32
|
||||
inBrightChange := make(chan bool)
|
||||
outBrightChange := make(chan bool)
|
||||
|
||||
go func() {
|
||||
for {
|
||||
brightIn = <-insidebrightness
|
||||
select {
|
||||
case inBrightChange <- true:
|
||||
default:
|
||||
}
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
for {
|
||||
brightOut = <-outsidebrightness
|
||||
select {
|
||||
case outBrightChange <- true:
|
||||
default:
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-inBrightChange:
|
||||
normal(inside, brightIn)
|
||||
normal(inside2, brightIn)
|
||||
case <-outBrightChange:
|
||||
normal(outside, brightOut)
|
||||
case brightIn = <-inBrightChange:
|
||||
setNormal(lights.inside, brightIn)
|
||||
setNormal(lights.inside2, brightIn)
|
||||
case brightOut = <-outBrightChange:
|
||||
setNormal(lights.outside, brightOut)
|
||||
case <-partyChange:
|
||||
lastBrightness <- brightnesses{inside: brightIn, outside: brightOut}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func normal(light *lighthardware, brightness uint32) {
|
||||
ledset(light.rPwm, light.rCh, brightness)
|
||||
ledset(light.gPwm, light.gCh, brightness)
|
||||
ledset(light.bPwm, light.bCh, brightness)
|
||||
func setNormal(light *lighthardware, brightness uint32) {
|
||||
light.red.set(brightness)
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user