tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/examples/touch/resistive/pyportal_touchpaint/main.go (about) 1 package main 2 3 import ( 4 "image/color" 5 "machine" 6 "math" 7 8 "tinygo.org/x/drivers/ili9341" 9 "tinygo.org/x/drivers/touch" 10 "tinygo.org/x/drivers/touch/resistive" 11 ) 12 13 var ( 14 resistiveTouch = &resistive.FourWire{} 15 16 display = ili9341.NewParallel( 17 machine.LCD_DATA0, 18 machine.TFT_WR, 19 machine.TFT_DC, 20 machine.TFT_CS, 21 machine.TFT_RESET, 22 machine.TFT_RD, 23 ) 24 25 white = color.RGBA{255, 255, 255, 255} 26 black = color.RGBA{0, 0, 0, 255} 27 red = color.RGBA{255, 0, 0, 255} 28 green = color.RGBA{0, 255, 0, 255} 29 blue = color.RGBA{0, 0, 255, 255} 30 magenta = color.RGBA{255, 0, 255, 255} 31 yellow = color.RGBA{255, 255, 0, 255} 32 cyan = color.RGBA{0, 255, 255, 255} 33 34 oldColor color.RGBA 35 currentColor color.RGBA 36 ) 37 38 const ( 39 penRadius = 3 40 boxSize = 30 41 42 Xmin = 750 43 Xmax = 325 44 Ymin = 840 45 Ymax = 240 46 ) 47 48 func main() { 49 50 // configure backlight 51 machine.TFT_BACKLIGHT.Configure(machine.PinConfig{machine.PinOutput}) 52 53 // configure touchscreen 54 machine.InitADC() 55 resistiveTouch.Configure(&resistive.FourWireConfig{ 56 YP: machine.TOUCH_YD, 57 YM: machine.TOUCH_YU, 58 XP: machine.TOUCH_XR, 59 XM: machine.TOUCH_XL, 60 }) 61 62 // configure display 63 display.Configure(ili9341.Config{}) 64 65 // fill the background and activate the backlight 66 width, height := display.Size() 67 display.FillRectangle(0, 0, width, height, black) 68 machine.TFT_BACKLIGHT.High() 69 70 // make color selection boxes 71 display.FillRectangle(0, 0, boxSize, boxSize, red) 72 display.FillRectangle(boxSize, 0, boxSize, boxSize, yellow) 73 display.FillRectangle(boxSize*2, 0, boxSize, boxSize, green) 74 display.FillRectangle(boxSize*3, 0, boxSize, boxSize, cyan) 75 display.FillRectangle(boxSize*4, 0, boxSize, boxSize, blue) 76 display.FillRectangle(boxSize*5, 0, boxSize, boxSize, magenta) 77 display.FillRectangle(boxSize*6, 0, boxSize, boxSize, black) 78 display.FillRectangle(boxSize*7, 0, boxSize, boxSize, white) 79 80 // set the initial color to red and draw a box to highlight it 81 oldColor = red 82 currentColor = red 83 display.DrawRectangle(0, 0, boxSize, boxSize, white) 84 85 last := touch.Point{} 86 87 // loop and poll for touches, including performing debouncing 88 debounce := 0 89 for { 90 91 point := resistiveTouch.ReadTouchPoint() 92 touch := touch.Point{} 93 if point.Z>>6 > 100 { 94 rawX := mapval(point.X>>6, Xmin, Xmax, 0, 240) 95 rawY := mapval(point.Y>>6, Ymin, Ymax, 0, 320) 96 touch.X = rawX 97 touch.Y = rawY 98 touch.Z = 1 99 } else { 100 touch.X = 0 101 touch.Y = 0 102 touch.Z = 0 103 } 104 105 if last.Z != touch.Z { 106 debounce = 0 107 last = touch 108 } else if math.Abs(float64(touch.X-last.X)) > 4 || 109 math.Abs(float64(touch.Y-last.Y)) > 4 { 110 debounce = 0 111 last = touch 112 } else if debounce > 1 { 113 debounce = 0 114 HandleTouch(last) 115 } else if touch.Z > 0 { 116 debounce++ 117 } else { 118 last = touch 119 debounce = 0 120 } 121 122 } 123 } 124 125 // based on Arduino's "map" function 126 func mapval(x int, inMin int, inMax int, outMin int, outMax int) int { 127 return (x-inMin)*(outMax-outMin)/(inMax-inMin) + outMin 128 } 129 130 func HandleTouch(touch touch.Point) { 131 132 if int16(touch.Y) < boxSize { 133 oldColor = currentColor 134 x := int16(touch.X) 135 switch { 136 case x < boxSize: 137 currentColor = red 138 case x < boxSize*2: 139 currentColor = yellow 140 case x < boxSize*3: 141 currentColor = green 142 case x < boxSize*4: 143 currentColor = cyan 144 case x < boxSize*5: 145 currentColor = blue 146 case x < boxSize*6: 147 currentColor = magenta 148 case x < boxSize*7: 149 currentColor = black 150 case x < boxSize*8: 151 currentColor = white 152 } 153 154 if oldColor == currentColor { 155 return 156 } 157 158 display.DrawRectangle((x/boxSize)*boxSize, 0, boxSize, boxSize, white) 159 switch oldColor { 160 case red: 161 x = 0 162 case yellow: 163 x = boxSize 164 case green: 165 x = boxSize * 2 166 case cyan: 167 x = boxSize * 3 168 case blue: 169 x = boxSize * 4 170 case magenta: 171 x = boxSize * 5 172 case black: 173 x = boxSize * 6 174 case white: 175 x = boxSize * 7 176 } 177 display.FillRectangle(int16(x), 0, boxSize, boxSize, oldColor) 178 179 } 180 181 if (int16(touch.Y) - penRadius) > boxSize { 182 display.FillRectangle( 183 int16(touch.X), int16(touch.Y), penRadius*2, penRadius*2, currentColor) 184 } 185 }