tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/mcp3008/mcp3008.go (about) 1 // Package mcp3008 implements a driver for the MCP3008 Analog to Digital Converter. 2 // 3 // Datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/21295d.pdf 4 package mcp3008 // import "tinygo.org/x/drivers/mcp3008" 5 6 import ( 7 "errors" 8 "machine" 9 10 "tinygo.org/x/drivers" 11 ) 12 13 // Device wraps MCP3008 SPI ADC. 14 type Device struct { 15 bus drivers.SPI 16 cs machine.Pin 17 tx []byte 18 rx []byte 19 CH0 ADCPin 20 CH1 ADCPin 21 CH2 ADCPin 22 CH3 ADCPin 23 CH4 ADCPin 24 CH5 ADCPin 25 CH6 ADCPin 26 CH7 ADCPin 27 } 28 29 // ADCPin is the implementation of the ADConverter interface. 30 type ADCPin struct { 31 machine.Pin 32 d *Device 33 } 34 35 // New returns a new MCP3008 driver. Pass in a fully configured SPI bus. 36 func New(b drivers.SPI, csPin machine.Pin) *Device { 37 d := &Device{bus: b, 38 cs: csPin, 39 tx: make([]byte, 3), 40 rx: make([]byte, 3), 41 } 42 43 // setup all channels 44 d.CH0 = d.GetADC(0) 45 d.CH1 = d.GetADC(1) 46 d.CH2 = d.GetADC(2) 47 d.CH3 = d.GetADC(3) 48 d.CH4 = d.GetADC(4) 49 d.CH5 = d.GetADC(5) 50 d.CH6 = d.GetADC(6) 51 d.CH7 = d.GetADC(7) 52 53 return d 54 } 55 56 // Configure sets up the device for communication 57 func (d *Device) Configure() { 58 d.cs.Configure(machine.PinConfig{Mode: machine.PinOutput}) 59 } 60 61 // Read analog data from channel 62 func (d *Device) Read(ch int) (uint16, error) { 63 if ch < 0 || ch > 7 { 64 return 0, errors.New("invalid channel for MCP3008 Read") 65 } 66 67 return d.GetADC(ch).Get(), nil 68 } 69 70 // GetADC returns an ADC for a specific channel. 71 func (d *Device) GetADC(ch int) ADCPin { 72 return ADCPin{machine.Pin(ch), d} 73 } 74 75 // Get the current reading for a specific ADCPin. 76 func (p ADCPin) Get() uint16 { 77 p.d.tx[0] = 0x01 78 p.d.tx[1] = byte(8+p.Pin) << 4 79 p.d.tx[2] = 0x00 80 81 p.d.cs.Low() 82 p.d.bus.Tx(p.d.tx, p.d.rx) 83 84 // scale result to 16bit value like other ADCs 85 result := uint16((p.d.rx[1]&0x3))<<(8+6) + uint16(p.d.rx[2])<<6 86 p.d.cs.High() 87 88 return result 89 } 90 91 // Configure here just for interface compatibility. 92 func (p ADCPin) Configure() { 93 }