62 lines
1.3 KiB
Go
62 lines
1.3 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// adc is an abstract ADC-based analog input.
|
|
type adc interface {
|
|
// Read returns the ADC value in volts.
|
|
Read() (float32, error)
|
|
}
|
|
|
|
// bbADC implements adc using a BeagleBone's built-in ADC.
|
|
type bbADC struct {
|
|
path string
|
|
}
|
|
|
|
// newBBADC returns a BeagleBone ADC for a given channel number.
|
|
func newBBADC(num int) (*bbADC, error) {
|
|
path := fmt.Sprintf("/sys/bus/iio/devices/iio:device0/in_voltage%d_raw", num)
|
|
if _, err := os.Stat(path); err != nil {
|
|
return nil, fmt.Errorf("could not access: %w", err)
|
|
}
|
|
return &bbADC{
|
|
path: path,
|
|
}, nil
|
|
}
|
|
|
|
func (b *bbADC) Read() (float32, error) {
|
|
by, err := os.ReadFile(b.path)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
d := strings.TrimSpace(string(by))
|
|
v, err := strconv.ParseUint(d, 10, 64)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
// The ADC Vref/Vdd is at 1.8V and is 10-bit (0-4095).
|
|
vadc := float32(v) * 1.8 / 4096.0
|
|
// The ADC is connected through a resistor divider.
|
|
r1 := float32(1000.0)
|
|
r2 := float32(4698.0)
|
|
vin := vadc / (r1 / (r1 + r2))
|
|
return vin, nil
|
|
}
|
|
|
|
// fakeADC implements an adc that outputs a sine wave. This is used for testing.
|
|
type fakeADC struct {
|
|
}
|
|
|
|
func (b *fakeADC) Read() (float32, error) {
|
|
t := float64(time.Now().UnixMilli()) / 1000
|
|
v := (math.Sin(t/10)+1)*(6.5/2) + 2
|
|
return float32(v), nil
|
|
}
|