Skip to content

Instantly share code, notes, and snippets.

@analogic
Last active May 25, 2017 19:38
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 analogic/1395fff0178258fd31a60a3278ac04d8 to your computer and use it in GitHub Desktop.
Save analogic/1395fff0178258fd31a60a3278ac04d8 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"runtime"
"time"
"bytes"
"strings"
"github.com/kidoman/embd"
_ "github.com/kidoman/embd/host/all"
)
type Pulse struct {
long bool // long/short
invalid bool
at time.Time
reason string
}
func (p *Pulse) String() string {
if p.invalid {
if p.long {
return strings.ToUpper(p.reason)
} else {
return p.reason
}
}
if p.long {
return "█"
} else {
return "▄"
}
}
type Pulses struct {
Pulses []Pulse
}
func (p *Pulses) Add(pulse Pulse) {
p.Pulses = append(p.Pulses, pulse)
}
func (p *Pulses) String() string {
var buffer bytes.Buffer
for _, v := range p.Pulses {
buffer.WriteString(v.String())
}
return buffer.String()
}
var speedPulsesCounter int
var directionPulsesCounter int
func main() {
runtime.GOMAXPROCS(5)
fmt.Println("GPIO Init")
if err := embd.InitGPIO(); err != nil {
panic(err)
}
defer embd.CloseGPIO()
fmt.Println("Starting listening")
// true - long pulse, false - short pulse
rawPulses := make(chan Pulse)
filteredPulsesByTimes := make(chan Pulse)
filteredPulsesByLogic := make(chan Pulse)
go listenDirectionPulses(rawPulses)
go listenSpeedPulses(rawPulses)
go FilterPulsesByTimes(rawPulses, filteredPulsesByTimes)
go FilterPulsesByLogic(filteredPulsesByTimes, filteredPulsesByLogic)
go printResults()
var buffer [36]Pulse
counter := 0
speedPulsesCounter = 0
for p := range filteredPulsesByLogic {
fmt.Print(p.String());
if p.invalid {
continue
}
buffer[counter] = p
speedPulsesCounter++
if counter == 35 {
fmt.Println("\033[1;32m")
directionPulsesCounter = 0
for i := range buffer {
if !buffer[i].long {
directionPulsesCounter++
}
}
fmt.Println("\033[0m")
}
counter = (counter + 1) % 36;
}
}
func printResults() {
for {
time.Sleep(time.Second)
fmt.Println("\033[1;34m")
fmt.Printf("%v pulses, %v direction", speedPulsesCounter, directionPulsesCounter * 10)
fmt.Println("\033[0m")
speedPulsesCounter = 0;
}
}
func FilterPulsesByLogic(inputPulses chan Pulse, outputPulses chan Pulse) {
defer close(outputPulses)
last := Pulse{long: true}
for p := range inputPulses {
if !p.long && !last.long {
p.invalid = true
p.reason = "l"
}
outputPulses <- p
last = p
}
}
func FilterPulsesByTimes(inputPulses chan Pulse, outputPulses chan Pulse) {
defer close(outputPulses)
var buffer []Pulse
for current := range inputPulses {
if len(buffer) == 2 &&
current.long &&
current.at.Sub(buffer[1].at).Nanoseconds() < (buffer[1].at.Sub(buffer[0].at).Nanoseconds() / 10) * 7 {
//fmt.Printf("\ndiff: %v, previous: %v\n", current.at.Sub(buffer[1].at).Nanoseconds() , (buffer[1].at.Sub(buffer[0].at).Nanoseconds() / 10) * 7)
current.invalid = true
current.reason = "t"
}
outputPulses <- current
if current.long && !current.invalid {
if len(buffer) > 1 {
buffer = append(buffer[1:], current)
} else {
buffer = append(buffer, current)
}
}
}
}
func listenDirectionPulses(pulses chan Pulse) {
direction, err := embd.NewDigitalPin(25)
if err != nil {
panic(err)
}
//defer direction.Close()
if err := direction.SetDirection(embd.In); err != nil {
panic(err)
}
direction.ActiveLow(false)
err = direction.Watch(embd.EdgeRising, func(direction embd.DigitalPin) {
pulses <- Pulse{long: false, at: time.Now()}
})
if err != nil {
panic(err)
}
}
func listenSpeedPulses(pulses chan Pulse) {
speed, err := embd.NewDigitalPin(17)
if err != nil {
panic(err)
}
//defer speed.Close()
if err := speed.SetDirection(embd.In); err != nil {
panic(err)
}
speed.ActiveLow(false)
err = speed.Watch(embd.EdgeRising, func(direction embd.DigitalPin) {
pulses <- Pulse{long: true, at: time.Now()}
})
if err != nil {
panic(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment