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  }