inital commit of PCA9685 backend in go
This commit is contained in:
99
.gitignore
vendored
Normal file
99
.gitignore
vendored
Normal 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
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "proto"]
|
||||||
|
path = proto
|
||||||
|
url = git@github.com:LED-Freaks/LedD-protobuf.git
|
9
config.yaml
Normal file
9
config.yaml
Normal 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
149
main.go
Normal 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
1
proto
Submodule
Submodule proto added at c0b46db0cf
Reference in New Issue
Block a user