mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-08-09 09:23:39 +00:00
Adding driver for four-wire resistive touchscreen (#118)
* resistive: Adding driver for four-wire resistive touchscreen, as used on the Adafruit PyPortal.
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
package touch
|
||||
|
||||
// Pointer is a device that is capable of reading a single touch point
|
||||
type Pointer interface {
|
||||
ReadTouchPoint() Point
|
||||
}
|
||||
|
||||
// Point represents the result of reading a single touch point from a screen.
|
||||
// X and Y are the horizontal and vertical coordinates of the touch, while Z
|
||||
// represents the touch pressure. In general, client code will want to inspect
|
||||
// the value of Z to see if it is above some threshold to determine if a touch
|
||||
// is detected at all.
|
||||
type Point struct {
|
||||
X int
|
||||
Y int
|
||||
Z int
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
package resistive
|
||||
|
||||
import (
|
||||
"machine"
|
||||
|
||||
"tinygo.org/x/drivers/touch"
|
||||
)
|
||||
|
||||
// FourWire represents a resistive touchscreen with a four-wire interface as
|
||||
// described in http://ww1.microchip.com/downloads/en/Appnotes/doc8091.pdf
|
||||
type FourWire struct {
|
||||
yp machine.ADC
|
||||
ym machine.ADC
|
||||
xp machine.ADC
|
||||
xm machine.ADC
|
||||
|
||||
readSamples int
|
||||
}
|
||||
|
||||
// FourWireConfig is passed to the Configure method. All of the pins must be
|
||||
// specified for this to be a valid configuration. ReadSamples is optional, and
|
||||
// if not set with default to 2.
|
||||
type FourWireConfig struct {
|
||||
|
||||
// Y+ pin, must be capable of analog reads
|
||||
YP machine.Pin
|
||||
|
||||
// Y- pin, must be capable of analog reads
|
||||
YM machine.Pin
|
||||
|
||||
// X+ pin, must be capable of analog reads
|
||||
XP machine.Pin
|
||||
|
||||
// X- pin, must be capable of analog reads
|
||||
XM machine.Pin
|
||||
|
||||
// If set, each call to ReadTouchPoint() will sample the X, Y, and Z values
|
||||
// and average them. This can help smooth out spurious readings, for example
|
||||
// ones that result from the capacitance of a TFT under the touchscreen
|
||||
ReadSamples int
|
||||
}
|
||||
|
||||
// Configure should be called once before starting to read the device
|
||||
func (res *FourWire) Configure(config *FourWireConfig) error {
|
||||
|
||||
res.yp = machine.ADC{Pin: config.YP}
|
||||
res.ym = machine.ADC{Pin: config.YM}
|
||||
res.xp = machine.ADC{Pin: config.XP}
|
||||
res.xm = machine.ADC{Pin: config.XM}
|
||||
|
||||
if config.ReadSamples < 1 {
|
||||
res.readSamples = 2
|
||||
} else {
|
||||
res.readSamples = config.ReadSamples
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReadTouchPoint reads a single touch.Point from the device. If the device
|
||||
// was configured with ReadSamples > 1, each value will be sampled that many
|
||||
// times and averaged to smooth over spurious results of the analog reads.
|
||||
func (res *FourWire) ReadTouchPoint() (p touch.Point) {
|
||||
p.X = int(sample(res.ReadX, res.readSamples))
|
||||
p.Y = int(sample(res.ReadY, res.readSamples))
|
||||
p.Z = int(sample(res.ReadZ, res.readSamples))
|
||||
return
|
||||
}
|
||||
|
||||
// sample the results of the provided function and average the results
|
||||
func sample(fn func() uint16, numSamples int) (v uint16) {
|
||||
sum := 0
|
||||
for n := 0; n < numSamples; n++ {
|
||||
sum += int(fn())
|
||||
}
|
||||
return uint16(sum / numSamples)
|
||||
}
|
||||
|
||||
// ReadX reads the "raw" X-value on a 16-bit scale without multiple sampling
|
||||
func (res *FourWire) ReadX() uint16 {
|
||||
res.ym.Pin.Configure(machine.PinConfig{Mode: machine.PinInputPulldown})
|
||||
|
||||
res.xp.Pin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||
res.xp.Pin.High()
|
||||
|
||||
res.xm.Pin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||
res.xm.Pin.Low()
|
||||
|
||||
res.yp.Configure()
|
||||
|
||||
return 0xFFFF - res.yp.Get()
|
||||
}
|
||||
|
||||
// ReadY reads the "raw" Y-value on a 16-bit scale without multiple sampling
|
||||
func (res *FourWire) ReadY() uint16 {
|
||||
res.xm.Pin.Configure(machine.PinConfig{Mode: machine.PinInputPulldown})
|
||||
|
||||
res.yp.Pin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||
res.yp.Pin.High()
|
||||
|
||||
res.ym.Pin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||
res.ym.Pin.Low()
|
||||
|
||||
res.xp.Configure()
|
||||
|
||||
return 0xFFFF - res.xp.Get()
|
||||
}
|
||||
|
||||
// ReadZ reads the "raw" Z-value on a 16-bit scale without multiple sampling
|
||||
func (res *FourWire) ReadZ() uint16 {
|
||||
res.xp.Pin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||
res.xp.Pin.Low()
|
||||
|
||||
res.ym.Pin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||
res.ym.Pin.High()
|
||||
|
||||
res.xm.Configure()
|
||||
res.yp.Configure()
|
||||
|
||||
z1 := res.xm.Get()
|
||||
z2 := res.yp.Get()
|
||||
|
||||
return 0xFFFF - (z2 - z1)
|
||||
}
|
||||
Reference in New Issue
Block a user