From c9dc844d840957721607059808c040abc8d3cc01 Mon Sep 17 00:00:00 2001 From: Drew Bowering Date: Sat, 30 Mar 2024 13:53:19 -0600 Subject: [PATCH] initial implementation - Single "inside" light, with inside brightness button. Cycles through the brightness settings, white light only. --- .vscode/settings.json | 8 ++ main.go | 179 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 187 insertions(+) create mode 100644 .vscode/settings.json create mode 100644 main.go diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..1b4896c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "go.toolsEnvVars": { + "GOOS": "linux", + "GOARCH": "arm", + "GOROOT": "/home/drew/.cache/tinygo/goroot-9c236da82c2ce16303d51dc7635261f33d2c6bc8180628c7b6806ae789ca6c8b", + "GOFLAGS": "-tags=cortexm,baremetal,linux,arm,rp2040,rp,pico,tinygo,purego,math_big_pure_go,gc.conservative,scheduler.tasks,serial.usb" + } +} \ No newline at end of file diff --git a/main.go b/main.go new file mode 100644 index 0000000..ca91bf9 --- /dev/null +++ b/main.go @@ -0,0 +1,179 @@ +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) + } + } +}