package main import ( "machine" "time" ) type pwm interface { Top() uint32 Set(uint8, uint32) Channel(machine.Pin) (uint8, error) } type lighthardware struct { rPin machine.Pin gPin machine.Pin bPin machine.Pin rPwm pwm gPwm pwm bPwm pwm rCh uint8 gCh uint8 bCh uint8 } func (lhw *lighthardware) InitPWM() error { var err error lhw.rCh, err = lhw.rPwm.Channel(lhw.rPin) if err != nil { return err } lhw.gCh, err = lhw.gPwm.Channel(lhw.gPin) if err != nil { return err } lhw.bCh, err = lhw.bPwm.Channel(lhw.bPin) if err != nil { return err } return nil } const ( period = uint64(1e9 / 500) pressdelay = time.Millisecond * 500 brightnesspeak = uint32(255) ) func main() { errs := make(chan error) 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.GP21 partybutton := machine.GP20 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 <- true: default: } }) insidebutton.SetInterrupt(machine.PinFalling, func(p machine.Pin) { select { case insidepushed <- true: default: } }) partybutton.SetInterrupt(machine.PinFalling, func(p machine.Pin) { select { case partypushed <- true: default: } }) pwm1 := machine.PWM5 pwm1.Configure(machine.PWMConfig{ Period: period, }) pwm2 := machine.PWM6 pwm2.Configure(machine.PWMConfig{ Period: period, }) insideLight := lighthardware{ rPin: machine.GP11, gPin: machine.GP13, bPin: machine.GP12, rPwm: pwm1, gPwm: pwm2, bPwm: pwm2, } err := insideLight.InitPWM() if err != nil { errs <- err } else { go cycleBrightness(insidepushed, insidebrightness) go cycleBrightness(outsidepushed, outsidebrightness) go loop(&insideLight, nil, insidebrightness, outsidebrightness) } println((<-errs).Error()) } func cycleBrightness(pushchan chan bool, brightnesschan chan uint32) { brightnesschan <- 0 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) } } func ledset(lpwm pwm, ledch uint8, brightness uint32) { lpwm.Set(ledch, (lpwm.Top()/brightnesspeak)*brightness) } func loop(inside *lighthardware, outside *lighthardware, insidebrightness chan uint32, outsidebrightness chan uint32) { 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: ledset(inside.rPwm, inside.rCh, brightIn) ledset(inside.gPwm, inside.gCh, brightIn) ledset(inside.bPwm, inside.bCh, brightIn) case <-outBrightChange: ledset(outside.rPwm, outside.rCh, brightOut) ledset(outside.gPwm, outside.gCh, brightOut) ledset(outside.bPwm, outside.bCh, brightOut) } } }