inital commit of PCA9685 backend in go

This commit is contained in:
Giovanni Harting 2017-12-12 19:18:31 +01:00
parent 09cf91e638
commit ffe46a0f4b
5 changed files with 261 additions and 0 deletions

99
.gitignore vendored Normal file
View File

@ -0,0 +1,99 @@
# Created by https://www.gitignore.io/api/go,linux,intellij+all
### Go ###
# Binaries for programs and plugins
*.exe
*.dll
*.so
*.dylib
# Test binary, build with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
.glide/
### Intellij+all ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff:
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/dictionaries
# Sensitive or high-churn files:
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.xml
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
# Gradle:
.idea/**/gradle.xml
.idea/**/libraries
# CMake
cmake-build-debug/
# Mongo Explorer plugin:
.idea/**/mongoSettings.xml
## File-based project format:
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Ruby plugin and RubyMine
/.rakeTasks
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
### Intellij+all Patch ###
# Ignores the whole idea folder
# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360
.idea/
### Linux ###
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
# End of https://www.gitignore.io/api/go,linux,intellij+all
bin/
pkg/
src/

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "proto"]
path = proto
url = git@github.com:LED-Freaks/LedD-protobuf.git

9
config.yaml Normal file
View File

@ -0,0 +1,9 @@
name: PCA9685
ledd:
host: "127.0.0.1"
port: 5640
pca9685:
device: "dev/i2c-2"
address: 0x40
minpulse: 0
maxpulse: 1000

149
main.go Normal file
View File

@ -0,0 +1,149 @@
package main
import (
"github.com/op/go-logging"
"golang.org/x/exp/io/i2c"
"gopkg.in/yaml.v2"
"os"
"os/signal"
"syscall"
"io/ioutil"
"net"
"encoding/binary"
"gen/ledd"
"github.com/golang/protobuf/proto"
"github.com/sergiorb/pca9685-golang/device"
"fmt"
)
// CONSTANTS
const VERSION = "0.1"
const RESOLUTION = 4096
const CHANNEL = 16
// STRUCTS
type config struct {
Name string
Ledd struct {
Host string
Port int
}
Pca9685 struct {
Device string
Address int
MinPulse int
MaxPulse int
}
}
type LedD struct {
name string
socket net.Conn
data chan []byte
}
var log = logging.MustGetLogger("LedD")
var ledDaemon = &LedD{}
var pca9685 = device.PCA9685{}
func check(e error) {
if e != nil {
panic(e)
}
}
func (ledd *LedD) receive() {
for {
message := make([]byte, 4096)
length, err := ledd.socket.Read(message)
if err != nil {
ledd.socket.Close()
break
}
if length > 0 {
msgLen := binary.BigEndian.Uint32(message[0:3])
log.Debugf("[%s] Read %d bytes, first protobuf is %d long", ledd.name, length, msgLen)
backendMsg := &ledd.BackendWrapperMessage{}
err = proto.Unmarshal(message[4:msgLen], backendMsg)
if err != nil {
log.Warningf("[%s] Couldn't decode protobuf msg!", backend.niceName())
continue
}
switch msg := backendMsg.Msg.(type) {
case *ledd.BackendWrapperMessage_MLedd:
ledd.name = msg.MLedd.Name
log.Infof("Connection with LedD (%s) etablished and registered", msg.MLedd.Name)
}
}
}
}
func (ledd *LedD) send() {
defer ledd.socket.Close()
for {
select {
case message, ok := <-ledd.data:
if !ok {
return
}
ledd.socket.Write(message)
}
}
}
func main() {
killSignals := make(chan os.Signal, 1)
signal.Notify(killSignals, syscall.SIGINT, syscall.SIGTERM)
log.Info("LedD", VERSION)
config := config{}
content, err := ioutil.ReadFile("config.yaml")
check(err)
err = yaml.Unmarshal(content, &config)
check(err)
i2cDevice, err := i2c.Open(&i2c.Devfs{Dev: config.Pca9685.Device}, config.Pca9685.Address)
check(err)
defer i2cDevice.Close()
pca9685 := device.NewPCA9685(i2cDevice, "PWM Controller", config.Pca9685.MinPulse, config.Pca9685.MaxPulse, log)
pca9685.Init()
conn, err := net.Dial("tcp4", fmt.Sprintf("%s:%d", config.Ledd.Host, config.Ledd.Port))
check(err)
ledDaemon = &LedD{
socket:conn,
data: make (chan []byte),
}
go ledDaemon.send()
go ledDaemon.receive()
wrapperMsg := &ledd.BackendWrapperMessage{
Msg: &ledd.BackendWrapperMessage_MBackend{
MBackend: &ledd.Backend{
Name: config.Name,
Channel: CHANNEL,
Type: "PCA9685",
Resolution: RESOLUTION,
Version: VERSION,
},
},
}
data, err := proto.Marshal(wrapperMsg)
check(err)
ledDaemon.data <- data
<-killSignals
}

1
proto Submodule

@ -0,0 +1 @@
Subproject commit c0b46db0cf38cfd192d6a787c0328cbff8db42fb