Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pcf8591: add ADC only implementation for I2C ADC/DAC #690

Merged
merged 1 commit into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions examples/pcf8591/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Connects to a pcf8591 ADC via I2C.
package main

import (
"machine"
"time"

"tinygo.org/x/drivers/pcf8591"
)

var (
i2c = machine.I2C0
)

func main() {
i2c.Configure(machine.I2CConfig{})
adc := pcf8591.New(i2c)
adc.Configure()

// get "CH0" aka "machine.ADC" interface to channel 0 from ADC.
p := adc.CH0

for {
val := p.Get()
println(val)
time.Sleep(50 * time.Millisecond)
}
}
84 changes: 84 additions & 0 deletions pcf8591/pcf8591.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Package pcf8591 implements a driver for the PCF8591 Analog to Digital/Digital to Analog Converter.
//
// Datasheet: https://www.nxp.com/docs/en/data-sheet/PCF8591.pdf
package pcf8591 // import "tinygo.org/x/drivers/pcf8591"

import (
"machine"

"errors"

"tinygo.org/x/drivers"
)

// Device wraps PCF8591 ADC functions.
type Device struct {
bus drivers.I2C
Address uint16
CH0 ADCPin
CH1 ADCPin
CH2 ADCPin
CH3 ADCPin
}

// ADCPin is the implementation of the ADConverter interface.
type ADCPin struct {
machine.Pin
d *Device
}

// New returns a new PCF8591 driver. Pass in a fully configured I2C bus.
func New(b drivers.I2C) *Device {
d := &Device{
bus: b,
Address: defaultAddress,
}

// setup all channels
d.CH0 = d.GetADC(0)
d.CH1 = d.GetADC(1)
d.CH2 = d.GetADC(2)
d.CH3 = d.GetADC(3)

return d
}

// Configure here just for interface compatibility.
func (d *Device) Configure() {
}

// Read analog data from channel
func (d *Device) Read(ch int) (uint16, error) {
if ch < 0 || ch > 3 {
return 0, errors.New("invalid channel for pcf8591 Read")
}

return d.GetADC(ch).Get(), nil
}

// GetADC returns an ADC for a specific channel.
func (d *Device) GetADC(ch int) ADCPin {
return ADCPin{machine.Pin(ch), d}
}

// Get the current reading for a specific ADCPin.
func (p ADCPin) Get() uint16 {
// TODO: also implement DAC
tx := make([]byte, 2)
tx[0] = byte(p.Pin)

rx := make([]byte, 2)

// The result from the measurement triggered by the first write,
// however, the second write is required to get the result.
// See section 8.4 "A/D Conversion" in the datasheet for more info
p.d.bus.Tx(p.d.Address, tx, rx)
p.d.bus.Tx(p.d.Address, tx, rx)

// scale result to 16bit value like other ADCs
return uint16(rx[1] << 8)
}

// Configure here just for interface compatibility.
func (p ADCPin) Configure() {
}
7 changes: 7 additions & 0 deletions pcf8591/registers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package pcf8591

// PCF8591 Default Address
const defaultAddress = 0x48

// control bit for DAC
const PCF8591_ENABLE_DAC = 0x40
1 change: 1 addition & 0 deletions smoketest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ tinygo build -size short -o ./build/test.hex -target=xiao ./examples/pcf8563/clk
tinygo build -size short -o ./build/test.hex -target=xiao ./examples/pcf8563/time/
tinygo build -size short -o ./build/test.hex -target=xiao ./examples/pcf8563/timer/
tinygo build -size short -o ./build/test.hex -target=pico ./examples/qmi8658c/main.go
tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/pcf8591/
tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/ina260/main.go
tinygo build -size short -o ./build/test.hex -target=nucleo-l432kc ./examples/aht20/main.go
tinygo build -size short -o ./build/test.hex -target=feather-m4 ./examples/sdcard/console/
Expand Down
Loading