mirror of
https://github.com/kidoman/embd
synced 2024-12-22 04:40:04 +01:00
mcp3008: added package and samples for mcp3008 10-bit 8-channel adc
This commit is contained in:
parent
42033238e2
commit
59958d7dfc
52
convertors/mcp3008/mcp3008.go
Normal file
52
convertors/mcp3008/mcp3008.go
Normal file
@ -0,0 +1,52 @@
|
||||
package mcp3008
|
||||
|
||||
import (
|
||||
"github.com/golang/glog"
|
||||
"github.com/kidoman/embd"
|
||||
|
||||
_ "github.com/kidoman/embd/host/all"
|
||||
)
|
||||
|
||||
type mcp3008 struct {
|
||||
mode int
|
||||
|
||||
bus embd.SPIBus
|
||||
}
|
||||
|
||||
const (
|
||||
SingleMode = int(1)
|
||||
DifferenceMode = int(0)
|
||||
)
|
||||
|
||||
func New(mode, spiChan, speed int) (*mcp3008, error) {
|
||||
if err := embd.InitSPI(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
glog.V(3).Infof("mcp3008: getting spiBus with mode: %v, channel: %v, speed: %v", mode, spiChan, speed)
|
||||
spiBus := embd.NewSPIBus(embd.SpiMode0, byte(spiChan), speed, 0, 0)
|
||||
return &mcp3008{mode, spiBus}, nil
|
||||
}
|
||||
|
||||
func (m *mcp3008) AnalogValueAt(chanNum int) (int, error) {
|
||||
data := make([]uint8, 3)
|
||||
data[0] = 1
|
||||
data[1] = uint8(m.mode)<<7 | uint8(chanNum)<<4
|
||||
data[2] = 0
|
||||
|
||||
if err := m.bus.TransferAndRecieveData(data); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return int(uint16(data[1]&0x03)<<8 | uint16(data[2])), nil
|
||||
}
|
||||
|
||||
func (m *mcp3008) Close() error {
|
||||
glog.V(2).Infoln("mcp3008: performing cleanup")
|
||||
if err := m.bus.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := embd.CloseSPI(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
@ -15,6 +15,8 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"github.com/kidoman/embd"
|
||||
"github.com/kidoman/embd/host/generic"
|
||||
)
|
||||
@ -97,6 +99,7 @@ var ledMap = embd.LEDMap{
|
||||
var spiDeviceMinor = byte(1)
|
||||
|
||||
func ensureFeatureEnabled(id string) error {
|
||||
glog.V(3).Infof("bbb: enabling feature %v", id)
|
||||
pattern := "/sys/devices/bone_capemgr.*/slots"
|
||||
file, err := embd.FindFirstMatchingFile(pattern)
|
||||
if err != nil {
|
||||
@ -108,6 +111,7 @@ func ensureFeatureEnabled(id string) error {
|
||||
}
|
||||
str := string(bytes)
|
||||
if strings.Contains(str, id) {
|
||||
glog.V(3).Infof("bbb: feature %v already enabled", id)
|
||||
return nil
|
||||
}
|
||||
slots, err := os.OpenFile(file, os.O_WRONLY, os.ModeExclusive)
|
||||
@ -115,6 +119,7 @@ func ensureFeatureEnabled(id string) error {
|
||||
return err
|
||||
}
|
||||
defer slots.Close()
|
||||
glog.V(3).Infof("bbb: writing %v to slots file", id)
|
||||
_, err = slots.WriteString(id)
|
||||
return err
|
||||
}
|
||||
|
@ -76,6 +76,10 @@ func NewSPIBus(spiDevMinor, mode, channel byte, speed, bpw, delay int, shouldIni
|
||||
}
|
||||
|
||||
func (b *spiBus) init() error {
|
||||
if b.initialized {
|
||||
return nil
|
||||
}
|
||||
|
||||
if b.shouldInitialize {
|
||||
if err := b.initializer(); err != nil {
|
||||
return err
|
||||
@ -83,14 +87,11 @@ func (b *spiBus) init() error {
|
||||
b.shouldInitialize = false
|
||||
}
|
||||
|
||||
if b.initialized {
|
||||
return nil
|
||||
}
|
||||
|
||||
var err error
|
||||
if b.file, err = os.OpenFile(fmt.Sprintf("/dev/spidev%v.%v", b.spiDevMinor, b.channel), os.O_RDWR, os.ModeExclusive); err != nil {
|
||||
return err
|
||||
}
|
||||
glog.V(3).Infof("spi: sucessfully opened file /dev/spidev%v.%v", b.spiDevMinor, b.channel)
|
||||
|
||||
err = b.setMode()
|
||||
if err != nil {
|
||||
@ -112,6 +113,7 @@ func (b *spiBus) init() error {
|
||||
b.setDelay()
|
||||
|
||||
glog.V(2).Infof("spi: bus %v initialized", b.channel)
|
||||
glog.V(3).Infof("spi: bus %v initialized with spiIocTransfer as %v", b.channel, b.spiTransferData)
|
||||
|
||||
b.initialized = true
|
||||
return nil
|
||||
@ -187,6 +189,10 @@ func (b *spiBus) setDelay() {
|
||||
}
|
||||
|
||||
func (b *spiBus) TransferAndRecieveData(dataBuffer []uint8) error {
|
||||
if err := b.init(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
len := len(dataBuffer)
|
||||
dataCarrier := b.spiTransferData
|
||||
|
||||
@ -194,16 +200,22 @@ func (b *spiBus) TransferAndRecieveData(dataBuffer []uint8) error {
|
||||
dataCarrier.txBuf = uint64(uintptr(unsafe.Pointer(&dataBuffer[0])))
|
||||
dataCarrier.rxBuf = uint64(uintptr(unsafe.Pointer(&dataBuffer[0])))
|
||||
|
||||
glog.V(3).Infof("spi: sending dataBuffer %v with carrier %v", dataBuffer, dataCarrier)
|
||||
_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.file.Fd(), uintptr(spiIocMessageN(1)), uintptr(unsafe.Pointer(&dataCarrier)))
|
||||
if errno != 0 {
|
||||
err := syscall.Errno(errno)
|
||||
glog.V(3).Infof("spi: failed to read due to %v", err.Error())
|
||||
return err
|
||||
}
|
||||
glog.V(3).Infof("spi: read into dataBuffer %v", dataBuffer)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *spiBus) ReceiveData(len int) ([]uint8, error) {
|
||||
if err := b.init(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data := make([]uint8, len)
|
||||
var err error
|
||||
err = b.TransferAndRecieveData(data)
|
||||
@ -214,6 +226,10 @@ func (b *spiBus) ReceiveData(len int) ([]uint8, error) {
|
||||
}
|
||||
|
||||
func (b *spiBus) TransferAndReceiveByte(data byte) (byte, error) {
|
||||
if err := b.init(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
d := make([]uint8, 1)
|
||||
d[0] = uint8(data)
|
||||
err := b.TransferAndRecieveData(d)
|
||||
@ -224,6 +240,10 @@ func (b *spiBus) TransferAndReceiveByte(data byte) (byte, error) {
|
||||
}
|
||||
|
||||
func (b *spiBus) ReceiveByte() (byte, error) {
|
||||
if err := b.init(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
d := make([]uint8, 1)
|
||||
err := b.TransferAndRecieveData(d)
|
||||
if err != nil {
|
||||
|
2
samples/.gitignore
vendored
2
samples/.gitignore
vendored
@ -24,3 +24,5 @@ universalblinker
|
||||
us020
|
||||
watersensor
|
||||
spi
|
||||
mcp3008
|
||||
spimcp3008
|
||||
|
33
samples/mcp3008.go
Normal file
33
samples/mcp3008.go
Normal file
@ -0,0 +1,33 @@
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/kidoman/embd/convertors/mcp3008"
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
fmt.Println("This is a sample code for mcp3008 10bit 8 channel ADC")
|
||||
|
||||
adc, err := mcp3008.New(mcp3008.SingleMode, 0, 1000000)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer adc.Close()
|
||||
|
||||
for i := 0; i < 20; i++ {
|
||||
time.Sleep(1 * time.Second)
|
||||
val, err := adc.AnalogValueAt(0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("Analog value is: %v\n", val)
|
||||
}
|
||||
|
||||
}
|
46
samples/spimcp3008.go
Normal file
46
samples/spimcp3008.go
Normal file
@ -0,0 +1,46 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/kidoman/embd"
|
||||
_ "github.com/kidoman/embd/host/all"
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
if err := embd.InitSPI(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
bus := embd.NewSPIBus(embd.SpiMode0, 0, 1000000, 8, 0)
|
||||
|
||||
defer clean(bus)
|
||||
|
||||
for i := 0; i < 30; i++ {
|
||||
time.Sleep(1 * time.Second)
|
||||
val, _ := getSensorValue(bus)
|
||||
fmt.Printf("value is: %v\n", val)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func clean(bus embd.SPIBus) {
|
||||
bus.Close()
|
||||
embd.CloseSPI()
|
||||
}
|
||||
|
||||
func getSensorValue(bus embd.SPIBus) (uint16, error) {
|
||||
data := make([]uint8, 3)
|
||||
data[0] = 1
|
||||
data[1] = 128
|
||||
data[2] = 0
|
||||
var err error
|
||||
err = bus.TransferAndRecieveData(data)
|
||||
if err != nil {
|
||||
return uint16(0), err
|
||||
}
|
||||
return uint16(data[1]&0x03)<<8 | uint16(data[2]), nil
|
||||
}
|
@ -29,6 +29,7 @@ func (s *spiDriver) Bus(mode, channel byte, speed, bpw, delay int) SPIBus {
|
||||
defer s.busMapLock.Unlock()
|
||||
|
||||
b := s.sbf(s.spiDevMinor, mode, channel, speed, bpw, delay, s.shouldInitialize, s.initializer)
|
||||
s.busMap = make(map[byte]SPIBus)
|
||||
s.busMap[channel] = b
|
||||
return b
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user