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: } }) 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{ rPin: machine.GP11, gPin: machine.GP13, bPin: machine.GP12, rPwm: pwm5, gPwm: pwm6, bPwm: pwm6, } err := insideLight.InitPWM() if err != nil { errs <- err } else { insideLight2 := lighthardware{ rPin: machine.GP8, gPin: machine.GP10, bPin: machine.GP9, rPwm: pwm4, gPwm: pwm5, bPwm: pwm4, } err = insideLight2.InitPWM() if err != nil { errs <- err } else { outsideLight := lighthardware{ rPin: machine.GP5, gPin: machine.GP7, bPin: machine.GP6, rPwm: pwm2, gPwm: pwm3, bPwm: pwm3, } err = outsideLight.InitPWM() if err != nil { errs <- err } else { go cycleBrightness(insidepushed, insidebrightness) go cycleBrightness(outsidepushed, outsidebrightness) go loop(&insideLight, &insideLight2, &outsideLight, 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, inside2 *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: normal(inside, brightIn) normal(inside2, brightIn) case <-outBrightChange: normal(outside, brightOut) } } } func normal(light *lighthardware, brightness uint32) { ledset(light.rPwm, light.rCh, brightness) ledset(light.gPwm, light.gCh, brightness) ledset(light.bPwm, light.bCh, brightness) }