tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/touch/resistive/fourwire.go (about) 1 package resistive 2 3 import ( 4 "machine" 5 6 "tinygo.org/x/drivers/touch" 7 ) 8 9 // FourWire represents a resistive touchscreen with a four-wire interface as 10 // described in http://ww1.microchip.com/downloads/en/Appnotes/doc8091.pdf 11 type FourWire struct { 12 yp machine.ADC 13 ym machine.ADC 14 xp machine.ADC 15 xm machine.ADC 16 17 readSamples int 18 } 19 20 // FourWireConfig is passed to the Configure method. All of the pins must be 21 // specified for this to be a valid configuration. ReadSamples is optional, and 22 // if not set with default to 2. 23 type FourWireConfig struct { 24 25 // Y+ pin, must be capable of analog reads 26 YP machine.Pin 27 28 // Y- pin, must be capable of analog reads 29 YM machine.Pin 30 31 // X+ pin, must be capable of analog reads 32 XP machine.Pin 33 34 // X- pin, must be capable of analog reads 35 XM machine.Pin 36 37 // If set, each call to ReadTouchPoint() will sample the X, Y, and Z values 38 // and average them. This can help smooth out spurious readings, for example 39 // ones that result from the capacitance of a TFT under the touchscreen 40 ReadSamples int 41 } 42 43 // Configure should be called once before starting to read the device 44 func (res *FourWire) Configure(config *FourWireConfig) error { 45 46 res.yp = machine.ADC{Pin: config.YP} 47 res.ym = machine.ADC{Pin: config.YM} 48 res.xp = machine.ADC{Pin: config.XP} 49 res.xm = machine.ADC{Pin: config.XM} 50 51 if config.ReadSamples < 1 { 52 res.readSamples = 2 53 } else { 54 res.readSamples = config.ReadSamples 55 } 56 57 return nil 58 } 59 60 // ReadTouchPoint reads a single touch.Point from the device. If the device 61 // was configured with ReadSamples > 1, each value will be sampled that many 62 // times and averaged to smooth over spurious results of the analog reads. 63 func (res *FourWire) ReadTouchPoint() (p touch.Point) { 64 p.X = int(sample(res.ReadX, res.readSamples)) 65 p.Y = int(sample(res.ReadY, res.readSamples)) 66 p.Z = int(sample(res.ReadZ, res.readSamples)) 67 return 68 } 69 70 // sample the results of the provided function and average the results 71 func sample(fn func() uint16, numSamples int) (v uint16) { 72 sum := 0 73 for n := 0; n < numSamples; n++ { 74 sum += int(fn()) 75 } 76 return uint16(sum / numSamples) 77 } 78 79 // ReadX reads the "raw" X-value on a 16-bit scale without multiple sampling 80 func (res *FourWire) ReadX() uint16 { 81 res.ym.Pin.Configure(machine.PinConfig{Mode: machine.PinInputPulldown}) 82 83 res.xp.Pin.Configure(machine.PinConfig{Mode: machine.PinOutput}) 84 res.xp.Pin.High() 85 86 res.xm.Pin.Configure(machine.PinConfig{Mode: machine.PinOutput}) 87 res.xm.Pin.Low() 88 89 res.yp.Configure(machine.ADCConfig{}) 90 91 return 0xFFFF - res.yp.Get() 92 } 93 94 // ReadY reads the "raw" Y-value on a 16-bit scale without multiple sampling 95 func (res *FourWire) ReadY() uint16 { 96 res.xm.Pin.Configure(machine.PinConfig{Mode: machine.PinInputPulldown}) 97 98 res.yp.Pin.Configure(machine.PinConfig{Mode: machine.PinOutput}) 99 res.yp.Pin.High() 100 101 res.ym.Pin.Configure(machine.PinConfig{Mode: machine.PinOutput}) 102 res.ym.Pin.Low() 103 104 res.xp.Configure(machine.ADCConfig{}) 105 106 return 0xFFFF - res.xp.Get() 107 } 108 109 // ReadZ reads the "raw" Z-value on a 16-bit scale without multiple sampling 110 func (res *FourWire) ReadZ() uint16 { 111 res.xp.Pin.Configure(machine.PinConfig{Mode: machine.PinOutput}) 112 res.xp.Pin.Low() 113 114 res.ym.Pin.Configure(machine.PinConfig{Mode: machine.PinOutput}) 115 res.ym.Pin.High() 116 117 res.xm.Configure(machine.ADCConfig{}) 118 res.yp.Configure(machine.ADCConfig{}) 119 120 z1 := res.xm.Get() 121 z2 := res.yp.Get() 122 123 return 0xFFFF - (z2 - z1) 124 }