- The outside button is next to the outside light, but not the inside button. This moves it beside the light and puts the party button in the middle (on the prototype board)
288 lines
5.3 KiB
Go
288 lines
5.3 KiB
Go
package main
|
|
|
|
import (
|
|
"machine"
|
|
"time"
|
|
)
|
|
|
|
type pwm interface {
|
|
Top() uint32
|
|
Set(uint8, uint32)
|
|
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 {
|
|
red led
|
|
green led
|
|
blue led
|
|
}
|
|
|
|
func (lhw *lighthardware) InitPWM() error {
|
|
var err error
|
|
|
|
err = lhw.red.InitPWM()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = lhw.green.InitPWM()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = lhw.blue.InitPWM()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
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)
|
|
)
|
|
|
|
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)
|
|
|
|
outsidebrightness := make(chan uint32, 2)
|
|
insidebrightness := make(chan uint32, 2)
|
|
|
|
outsidebutton := machine.GP22
|
|
insidebutton := machine.GP20
|
|
partybutton := machine.GP21
|
|
|
|
outsidebutton.Configure(machine.PinConfig{Mode: machine.PinInputPullup})
|
|
insidebutton.Configure(machine.PinConfig{Mode: machine.PinInputPullup})
|
|
partybutton.Configure(machine.PinConfig{Mode: machine.PinInputPullup})
|
|
|
|
outsidebutton.SetInterrupt(machine.PinFalling, func(p machine.Pin) {
|
|
select {
|
|
case outsidepushed_raw <- true:
|
|
default:
|
|
}
|
|
})
|
|
insidebutton.SetInterrupt(machine.PinFalling, func(p machine.Pin) {
|
|
select {
|
|
case insidepushed_raw <- true:
|
|
default:
|
|
}
|
|
})
|
|
partybutton.SetInterrupt(machine.PinFalling, func(p machine.Pin) {
|
|
select {
|
|
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,
|
|
})
|
|
pwm3 := machine.PWM3
|
|
pwm3.Configure(machine.PWMConfig{
|
|
Period: period,
|
|
})
|
|
pwm4 := machine.PWM4
|
|
pwm4.Configure(machine.PWMConfig{
|
|
Period: period,
|
|
})
|
|
pwm5 := machine.PWM5
|
|
pwm5.Configure(machine.PWMConfig{
|
|
Period: period,
|
|
})
|
|
pwm6 := machine.PWM6
|
|
pwm6.Configure(machine.PWMConfig{
|
|
Period: period,
|
|
})
|
|
|
|
insideLight := lighthardware{
|
|
red: led{
|
|
pin: machine.GP11,
|
|
pwm: pwm5,
|
|
},
|
|
green: led{
|
|
pin: machine.GP13,
|
|
pwm: pwm6,
|
|
},
|
|
blue: led{
|
|
pin: machine.GP12,
|
|
pwm: pwm6,
|
|
},
|
|
}
|
|
err := insideLight.InitPWM()
|
|
|
|
if err != nil {
|
|
errs <- err
|
|
} else {
|
|
insideLight2 := lighthardware{
|
|
red: led{
|
|
pin: machine.GP8,
|
|
pwm: pwm4,
|
|
},
|
|
green: led{
|
|
pin: machine.GP10,
|
|
pwm: pwm5,
|
|
},
|
|
blue: led{
|
|
pin: machine.GP9,
|
|
pwm: pwm4,
|
|
},
|
|
}
|
|
err = insideLight2.InitPWM()
|
|
|
|
if err != nil {
|
|
errs <- err
|
|
} else {
|
|
outsideLight := lighthardware{
|
|
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(lights, insidebrightness, outsidebrightness, partypushed)
|
|
}
|
|
}
|
|
}
|
|
|
|
println((<-errs).Error())
|
|
}
|
|
|
|
func delayChan(inchan <-chan bool, outchan chan<- bool) {
|
|
var last time.Time
|
|
|
|
for {
|
|
val := <-inchan
|
|
now := time.Now()
|
|
if now.Sub(last) > pressdelay {
|
|
last = now
|
|
select {
|
|
case outchan <- val:
|
|
default:
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func cycleBrightness(pushchan <-chan bool, brightnesschan chan<- uint32) {
|
|
for {
|
|
for _, b := range brightnessSteps {
|
|
brightnesschan <- b
|
|
<-pushchan
|
|
}
|
|
}
|
|
}
|
|
|
|
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
|
|
// go party(lights)
|
|
// <-partypushed
|
|
partyChange <- true
|
|
lb := <-lastBrightness
|
|
select {
|
|
case insidebrightness <- lb.inside:
|
|
default:
|
|
}
|
|
select {
|
|
case outsidebrightness <- lb.outside:
|
|
default:
|
|
}
|
|
}
|
|
}
|
|
|
|
func normal(lights lightSet, inBrightChange <-chan uint32, outBrightChange <-chan uint32, partyChange <-chan bool, lastBrightness chan<- brightnesses) {
|
|
var brightIn uint32
|
|
var brightOut uint32
|
|
|
|
for {
|
|
select {
|
|
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 setNormal(light *lighthardware, brightness uint32) {
|
|
light.red.set(brightness)
|
|
light.green.set(brightness)
|
|
light.blue.set(brightness)
|
|
}
|