Skip to content

Instantly share code, notes, and snippets.

@kidoman
Last active December 28, 2015 22:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kidoman/7569937 to your computer and use it in GitHub Desktop.
Save kidoman/7569937 to your computer and use it in GitHub Desktop.
package main
import (
"github.com/gorilla/mux"
rpio "github.com/stianeikeland/go-rpio"
"log"
"net/http"
"os"
"os/signal"
"time"
)
const (
gameTime = 4
startBlinkDelay = 50
)
func main() {
log.Print("Starting up...")
err := rpio.Open()
if err != nil {
panic(err)
}
defer func() {
log.Print("Cleaning up...")
rpio.Close()
}()
pin := rpio.Pin(10)
pin.Output()
defer func() {
log.Print("Setting pin 10 to low")
pin.Low()
}()
r := mux.NewRouter()
r.HandleFunc("/current", func(resp http.ResponseWriter, req *http.Request) {
defer pin.Output()
pin.Input()
state := pin.Read()
var output string
if state == rpio.Low {
output = "Low"
} else {
output = "High"
}
resp.Write([]byte(output))
}).
Methods("GET")
saved := make(chan bool)
r.HandleFunc("/save", func(resp http.ResponseWriter, req *http.Request) {
saved <- true
}).
Methods("POST")
go func() {
log.Print("Starting web server")
http.ListenAndServe(":8080", r)
}()
resetBlinking, stopBlinking := blinker(pin)
timeout := time.After(gameTime * time.Second)
quit := make(chan bool, 1)
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, os.Kill)
go func() {
<-c
quit <- true
}()
for {
select {
case <-saved:
log.Print("Saved by the bell")
timeout = time.After(gameTime * time.Second)
resetBlinking <- true
log.Printf("You got another %v seconds", gameTime)
case <-timeout:
log.Print("You couldnt save the LED")
quit <- true
case <-quit:
stoppedBlinking := make(chan bool)
stopBlinking <- stoppedBlinking
<-stoppedBlinking
return
}
}
}
func blinker(pin rpio.Pin) (chan<- bool, chan<- chan bool) {
resetBlinking := make(chan bool)
stopBlinking := make(chan chan bool)
go func() {
var everySecond <-chan time.Time
resetTimer := func() { everySecond = time.Tick(1 * time.Second) }
resetTimer()
blinkDelay := startBlinkDelay
printBlinkDelay := func() { log.Printf("Blink delay now %v", blinkDelay) }
for {
select {
case <-resetBlinking:
blinkDelay = startBlinkDelay
printBlinkDelay()
resetTimer()
case <-everySecond:
blinkDelay *= 2
printBlinkDelay()
case stoppedBlinking := <-stopBlinking:
everySecond = nil
stoppedBlinking <- true
default:
time.Sleep(time.Duration(blinkDelay) * time.Millisecond)
pin.High()
time.Sleep(10 * time.Millisecond)
pin.Low()
}
}
}()
return resetBlinking, stopBlinking
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment