-
• #2
When I created the touch directly w/o a controller on an Espruino Pico - see Resistive Touchscreen directly (no touch controller) - I for sure did not have this issue. I picked a scan rate suitable for the ui application - AND - for Espruino's way of doing things. That was 10+ years ago... Nowadays, almost all displays show up with a controller that makes live - for the most part - easier an for sure code for sure shorter. Looking at the handling of the XPT2046 in Espruino 2V25.40 build for CYD ESP32-2432S028 2.8 LCD board it is on the high side when a lot of JS should run between events. Also, picking up a noise free - or low noise - event stream seems to be an issue, nature of the type of resistive touch screen.
For certain applications you may like the controller hot, and for others just nicely humming. To get to that without global configuration of the XPT2046 as one-size-fits-all, envision a configurable pip - or filter - that also can take care of other things, like:
- Filter (drag/move) events that look like jitter... touch point events with little movement - just a few pixels around the initial touch - can be ignored in a smart way, so that small changes still come true when disired.
- Do a calibrated mapping of the device signals to accurate as possible x/y coordinates - current implementation is very loos and shows erorrs - bigger towards x/y = 0/0 corner, small x y values - and less noticeable along borders.
In a 1st as a 1st step, I want to explore the short and longer touching of a point - no move / drag, like hovering. In a seconds step, I want to explore the impact of a tamed event stream.
The filter 'ignores' small moves - up to (configurable) 5 pixels - but counts them and lets one pass after incurring (configurable) 20 of them. With that, a move of 'the center' is still passed on to the application when trying to adjust the touch position slowly.
These are the results for hovering with untamed, tamed, untamed, etc. touch value streams.
For the first untamed sequence I show all values - with max deviation of 4 - for the subsequent I did cut some out to save space, since it is most of the time also just + or - one pixel around the initial touch value. Notice the the time between the events, the xy change, and finally compare the first x/y with the last x/y: even though there are streaks in one or the other direction, the overall difference in the end is a fraction of it.
Untamed begins and ends
123/138
to123/140
--->0/+2
127/147
to124/148
--->-3/+1
118/158
to116/160
--->+2/+2
compared to the tamed begins and ends:
123/138
to123/140
--->0/+2
120/153
to119/155
--->-1/+2
117/162
to116/160
--->-1/-1
with a reduction of more than 90%:
45, 54
and46
vs.3, 4
and4
events /sand
48, 64
and40
vs.6, 7
and2
'moved';'moved' is though a bit apples vs. orages, because it is not normalized against the time spent touching, but is still well in the 90%+ / 10%- range (despite the 'Parkinson effect'):
0.9, 1.0
and0.75
vs.1.0, 0.9
and0.9
seconds.Noteworthy is the fact that the sum of the ignored small moves - the number in square bracket [n] minus 1 when > 0 - are the same as for untamed. These small moves that anyway only run around in circles do not need to be handled by a potentially complex and lengthy application logic... such as figuring in which graphical object or ui element the hover point lays, perform actions tied to this object/element, recalculating and redrawing, all repeatedly with not relevant difference as, for example, for a slider. Such savings are for the benefit of other JS 'threads' started by events that show up in the event queue.
` .-------------------- event (1001,1002,...-1000) | .---------------x/y touch | | .---------- 0/1=un/touched | | | | .----- ignored small events (-1 when 21) | | | | | .--- delta x y (moved) compared to 1st V V V V V V time [s] between events ---- ---/--- - --- -/- ------------- 1001 123 138 1 [0] <--- beg 1st untamed 1002 123 139 1 [0] 0 1 (0.01531910896) 1003 123 140 1 [0] 0 1 (0.02776908874) 1004 123 139 1 [0] 0 1 (0.01628279685) 1005 123 138 1 [0] 0 1 (0.02150797843) 1006 123 139 1 [0] 0 1 (0.01629805564) 1007 123 138 1 [0] 0 1 (0.02665996551) 1008 123 139 1 [0] 0 1 (0.01616621017) 1009 123 140 1 [0] 0 1 (0.02230596542) 1010 123 139 1 [0] 0 1 (0.01875686645) 1011 124 139 1 [0] 1 0 (0.02144408226) 1012 123 139 1 [0] 1 0 (0.01607990264) 1013 123 138 1 [0] 0 1 (0.01588702201) 1014 123 139 1 [0] 0 1 (0.01696300506) 1015 123 140 1 [0] 0 1 (0.08504104614) 1016 123 139 1 [0] 0 1 (0.01670098304) 1017 123 138 1 [0] 0 1 (0.02869606018) 1018 123 139 1 [0] 0 1 (0.01759099960) 1019 123 143 1 [0] 0 4 (0.02132105827) <--- max 4 1020 123 139 1 [0] 0 4 (0.01694297790) <--- max 4 1021 123 138 1 [0] 0 1 (0.04373693466) 1022 123 139 1 [0] 0 1 (0.01703596115) 1023 123 138 1 [0] 0 1 (0.03567790985) 1024 123 139 1 [0] 0 1 (0.01621818542) 1025 123 140 1 [0] 0 1 (0.02796101570) 1026 123 139 1 [0] 0 1 (0.01660084724) 1027 123 138 1 [0] 0 1 (0.02174711227) 1028 123 139 1 [0] 0 1 (0.01654601097) 1029 123 138 1 [0] 0 1 (0.01900291442) 1030 123 139 1 [0] 0 1 (0.01687908172) 1031 123 137 1 [0] 0 2 (0.03798103332) 1032 123 139 1 [0] 0 2 (0.01607990264) 1033 123 138 1 [0] 0 1 (0.01726007461) 1034 123 139 1 [0] 0 1 (0.01693391799) 1035 123 140 1 [0] 0 1 (0.02277493476) 1036 123 139 1 [0] 0 1 (0.01781010627) 1037 123 138 1 [0] 0 1 (0.03011298179) 1038 123 139 1 [0] 0 1 (0.01818299293) 1039 123 138 1 [0] 0 1 (0.02060008049) 1040 123 139 1 [0] 0 1 (0.01865196228) 1041 123 140 1 [0] 0 1 (0.01846098899) 1042 123 140 0 [0] 0 0 (0.01568007469) <--- end 1st untamed 0/+2 <---u1 11 :untamed: 41 events, 0.91629600524 s, 45 /s, 48 moved 1043 130 141 1 [0] | 1st tamed beg 1044 129 140 1 [21] 1 1 (0.36120200157) | 1045 128 141 1 [21] 1 1 (0.30423212051) | 1046 128 143 0 [17] 0 2 (0.34888005256) | ...end --------- -2/+2 <--- t1 12 : tamed: 3 events, 1.01089406013 s, 3 /s, 6 moved 1047 127 147 1 [0] <--- beg 2nd untamed 1048 128 145 1 [0] 1 2 (0.01464605331) 1049 128 144 1 [0] 0 1 (0.02041387557) ... 1061 127 145 1 [0] 1 0 (0.01671099662) 1062 127 142 1 [0] 0 3 (0.01643610000) <--- max 3 1063 127 145 1 [0] 0 3 (0.01597404479) <--- max 3 1064 127 144 1 [0] 0 1 (0.01821804046) 1099 124 148 1 [0] 0 1 (0.01611399650) 1100 124 148 0 [0] 0 0 (0.01936197280) <--- end 2nd untamed -3/+1 <---u2 13 :untamed: 53 events, 0.99068808555 s, 54 /s, 64 moved 1101 120 153 1 [0] | 2nd tamed beg... 1102 120 155 1 [21] 0 2 (0.33901095390) | 1103 120 153 1 [21] 0 2 (0.35639715194) | 1104 119 155 0 [8] 1 2 (0.22670388221) | ...end -------- -1/+2 <--- t2 14 : tamed: 3 events, 0.91868901252 s, 4 /s, 7 moved 1105 118 158 1 [0] <--- beg 3rd untamed 1106 118 157 1 [0] 0 1 (0.01460504531) 1107 119 156 1 [0] 1 1 (0.01930594444) ... 1138 116 160 1 [0] 0 1 (0.01970911026) 1139 116 160 0 [0] 0 0 (0.01907181739) <--- end 3rd untamed -2/+2 <--- u3 15 :untamed: 34 events, 0.74815177917 s, 46 /s, 40 moved 1140 117 162 1 [0] | 3rd tamed beg... 1141 117 161 1 [21] 0 1 (0.31535387039) | 1142 116 161 1 [21] 1 0 (0.41444993019) | 1143 116 161 0 [6] 0 0 (0.15343713760) | ...end -------- -1/-1 <--- t3 16 : tamed: 3 events, 0.87734198570 s, 4 /s, 2 moved `
- Filter (drag/move) events that look like jitter... touch point events with little movement - just a few pixels around the initial touch - can be ignored in a smart way, so that small changes still come true when disired.
-
• #3
2nd, looking at the RED - untamed - and BLUE - tamed - drawings, we notice practically no difference in the 'quality' of the line in regard of steadiness or jaggedness. The reason is that the
number of events
are not that far apart from each other, and themoved
numbers are are even closer to one another - the measurable and comparable value for quality. The same is for theignored small
moves: not many are ignored in the tamed drawings.rn=1
In console enables again multi-interval operation.Absolute comparison could be achieved by a robot... I'm definitively not one, even though I tried to do the same movements twice or four (4) times, as the attached pictures in Post #1 show.
Conclusion: Even simple filter as above can greatly contribute to the smooth operation of a Espruino JS application by taming the touch event rate that makes it to the application and this saving a lot of cycles for what is more pressing.***
This is the data that goes with the 1st attached picture :
` 1001 59 196 1 [0] begin UNTAMED RED 1002 57 197 1 [0] 2 1 (0.01512312889) upside down 1003 55 197 1 [0] 2 0 (0.01950287818) check mark 1004 55 194 1 [0] 0 3 (0.01612114906) 1005 55 193 1 [0] 0 1 (0.01827287673) 1006 56 190 1 [0] 1 3 (0.01632499694) 1007 57 186 1 [0] 1 4 (0.01704096794) 1008 61 182 1 [0] 4 4 (0.01617503166) 1009 66 175 1 [0] 5 7 (0.02005600929) 1010 75 165 1 [0] 9 10 (0.01708793640) 1011 86 156 1 [0] 11 9 (0.01607298851) 1012 98 145 1 [0] 12 11 (0.01709699630) 1013 115 131 1 [0] 17 14 (0.01613712310) 1014 134 112 1 [0] 19 19 (0.01635384559) 1015 160 90 1 [0] 26 22 (0.01998305320) 1016 177 78 1 [0] 17 12 (0.01613402366) 1017 190 70 1 [0] 13 8 (0.01719713211) 1018 204 62 1 [0] 14 8 (0.01616096496) 1019 217 56 1 [0] 13 6 (0.01603198051) 1020 229 50 1 [0] 12 6 (0.01743888854) 1021 238 47 1 [0] 9 3 (0.01877903938) 1022 244 45 1 [0] 6 2 (0.01696610450) 1023 246 45 1 [0] 2 0 (0.01629400253) 1024 247 46 1 [0] 1 1 (0.01608395576) 1025 248 46 1 [0] 1 0 (0.01956200599) 1026 249 44 1 [0] 1 2 (0.01642799377) 1027 254 44 1 [0] 5 0 (0.01932406425) 1028 258 42 1 [0] 4 2 (0.01667499542) 1029 260 41 1 [0] 2 1 (0.01617789268) 1030 260 42 1 [0] 0 1 (0.02322602272) 1031 258 43 1 [0] 2 1 (0.01620888710) 1032 258 44 1 [0] 0 1 (0.01910519599) 1033 258 45 1 [0] 0 1 (0.01725888252) 1034 259 45 1 [0] 1 0 (0.03020906448) 1035 259 47 1 [0] 0 2 (0.01701593399) 1036 260 50 1 [0] 1 3 (0.01616191864) 1037 261 57 1 [0] 1 7 (0.01844120025) 1038 261 73 1 [0] 0 16 (0.01854395866) 1039 260 94 1 [0] 1 21 (0.01632189750) 1040 263 109 1 [0] 3 15 (0.01701998710) 1041 265 116 1 [0] 2 7 (0.01608514785) 1042 268 119 1 [0] 3 3 (0.01693892478) 1043 268 120 1 [0] 0 1 (0.01875090599) 1044 267 119 1 [0] 1 1 (0.02097105979) 1045 266 118 1 [0] 1 1 (0.01707911491) 1046 264 117 1 [0] 2 1 (0.01605200767) 1047 264 116 1 [0] 0 1 (0.01638793945) 1048 264 117 1 [0] 0 1 (0.01697802543) 1049 264 117 0 [0] 0 0 (0.01828384399) untamed RED checkm 11 :untamed: 48 events, 0.84429478645 s, 57 /s, 470 moved 1050 61 197 1 [0] begin TAMED BLUE 1051 61 190 1 [3] 0 7 (0.05082583427) upside down 1052 62 185 1 [3] 1 5 (0.04750108718) check mark 1053 64 180 1 [1] 2 5 (0.02709603309) 1054 68 175 1 [0] 4 5 (0.01733803749) 1055 74 168 1 [0] 6 7 (0.01696085929) 1056 87 155 1 [0] 13 13 (0.02001500129) 1057 100 144 1 [0] 13 11 (0.01653599739) 1058 111 135 1 [0] 11 9 (0.01768112182) 1059 125 123 1 [0] 14 12 (0.01666188240) 1060 140 110 1 [0] 15 13 (0.01653194427) 1061 156 94 1 [0] 16 16 (0.01888704299) 1062 174 79 1 [0] 18 15 (0.01819205284) 1063 184 71 1 [0] 10 8 (0.01687598228) 1064 193 64 1 [0] 9 7 (0.01771306991) 1065 201 58 1 [0] 8 6 (0.01656508445) 1066 208 54 1 [0] 7 4 (0.01750588417) 1067 216 50 1 [0] 8 4 (0.01926302909) 1068 224 46 1 [0] 8 4 (0.01821804046) 1069 230 43 1 [0] 6 3 (0.01770401000) 1070 235 41 1 [0] 5 2 (0.01691102981) 1071 242 38 1 [1] 7 3 (0.02646493911) 1072 247 36 1 [0] 5 2 (0.01718306541) 1073 252 35 1 [0] 5 1 (0.01996779441) 1074 257 33 1 [5] 5 2 (0.07298803329) 1075 262 30 1 [0] 5 3 (0.01898598670) 1076 268 29 1 [1] 6 1 (0.02689409255) 1077 265 35 1 [3] 3 6 (0.04518604278) 1078 269 40 1 [9] 4 5 (0.10440492630) 1079 268 47 1 [0] 1 7 (0.01691412925) 1080 267 64 1 [0] 1 17 (0.02047991752) 1081 268 79 1 [0] 1 15 (0.01711487770) 1082 271 93 1 [0] 3 14 (0.01757311820) 1083 274 101 1 [0] 3 8 (0.01681995391) 1084 275 106 1 [0] 1 5 (0.01686906814) 1085 273 103 0 [11] 2 3 (0.13009786605) tamed BLUE checkm 12 : tamed: 35 events, 0.98949193954 s, 36 /s, 474 moved 1086 161 70 1 [0] begin untamed 1087 159 69 1 [0] 2 1 (0.01593708992) RED cirle 1088 158 67 1 [0] 1 2 (0.01636791229) 1089 157 66 1 [0] 1 1 (0.01783299446) 1090 156 64 1 [0] 1 2 (0.01820111274) 1091 156 63 1 [0] 0 1 (0.01610183715) 1092 155 62 1 [0] 1 1 (0.01657795906) 1093 154 62 1 [0] 1 0 (0.01658010482) 1094 150 62 1 [0] 4 0 (0.01608800888) 1095 146 64 1 [0] 4 2 (0.01885795593) 1096 140 67 1 [0] 6 3 (0.01732802391) 1097 134 71 1 [0] 6 4 (0.01631402969) 1098 128 78 1 [0] 6 7 (0.01684999465) 1099 121 80 1 [0] 7 2 (0.01598501205) 1100 117 83 1 [0] 4 3 (0.01633596420) 1101 114 86 1 [0] 3 3 (0.01915812492) 1102 113 90 1 [0] 1 4 (0.01782393455) 1103 112 94 1 [0] 1 4 (0.01709294319) 1104 111 102 1 [0] 1 8 (0.01635789871) 1105 109 108 1 [0] 2 6 (0.01605820655) 1106 108 115 1 [0] 1 7 (0.01703882217) 1107 108 122 1 [0] 0 7 (0.01815819740) 1108 108 129 1 [0] 0 7 (0.01740598678) 1109 110 136 1 [0] 2 7 (0.01701498031) 1110 111 143 1 [0] 1 7 (0.01631879806) 1111 112 151 1 [0] 1 8 (0.01605916023) 1112 115 158 1 [0] 3 7 (0.01695394515) 1113 119 164 1 [0] 4 6 (0.01779890060) 1114 124 170 1 [0] 5 6 (0.01822113990) 1115 130 176 1 [0] 6 6 (0.01634788513) 1116 136 183 1 [0] 6 7 (0.01609802246) 1117 142 191 1 [0] 6 8 (0.01691007614) 1118 150 196 1 [0] 8 5 (0.01715803146) 1119 157 198 1 [0] 7 2 (0.01749205589) 1120 166 195 1 [0] 9 3 (0.01826786994) 1121 173 192 1 [0] 7 3 (0.01626706123) 1122 180 190 1 [0] 7 2 (0.01635694503) 1123 187 187 1 [0] 7 3 (0.01671504974) 1124 192 184 1 [0] 5 3 (0.01644492149) 1125 198 180 1 [0] 6 4 (0.01690506935) 1126 206 174 1 [0] 8 6 (0.01903700828) 1127 212 168 1 [0] 6 6 (0.01624393463) 1128 217 162 1 [0] 5 6 (0.01696896553) 1129 220 156 1 [0] 3 6 (0.01612997055) 1130 223 149 1 [0] 3 7 (0.01671600341) 1131 226 141 1 [0] 3 8 (0.01684617996) 1132 229 132 1 [0] 3 9 (0.01897192001) 1133 230 124 1 [0] 1 8 (0.01772308349) 1134 230 118 1 [0] 0 6 (0.01614284515) 1135 228 114 1 [0] 2 4 (0.01617097854) 1136 223 110 1 [0] 5 4 (0.01957106590) 1137 219 105 1 [0] 4 5 (0.01843714714) 1138 216 100 1 [0] 3 5 (0.01747083663) 1139 212 95 1 [0] 4 5 (0.01635599136) 1140 208 89 1 [0] 4 6 (0.01606893539) 1141 204 86 1 [0] 4 3 (0.01695823669) 1142 199 84 1 [0] 5 2 (0.01647496223) 1143 194 81 1 [0] 5 3 (0.01931595802) 1144 188 78 1 [0] 6 3 (0.01670885086) 1145 183 73 1 [0] 5 5 (0.01623415946) 1146 178 67 1 [0] 5 6 (0.01689887046) 1147 173 64 1 [0] 5 3 (0.01613903045) 1148 167 64 1 [0] 6 0 (0.01708102226) 1149 162 66 1 [0] 5 2 (0.01948404312) 1150 158 69 1 [0] 4 3 (0.01650595664) 1151 157 72 1 [0] 1 3 (0.01624393463) 1152 157 72 0 [0] 0 0 (0.01677703857) untamed RED circle 13 :untamed: 66 events, 1.12202405929 s, 59 /s, 534 moved 1153 182 70 1 [0] begin tamed 1154 181 65 1 [2] 1 5 (0.03417015075) BLUE circle 1155 180 59 1 [1] 1 6 (0.02991580963) 1156 175 56 1 [1] 5 3 (0.02599906921) 1157 169 56 1 [0] 6 0 (0.01737499237) 1158 161 59 1 [0] 8 3 (0.01728916168) 1159 154 60 1 [0] 7 1 (0.01943087577) 1160 149 63 1 [0] 5 3 (0.01761007308) 1161 144 65 1 [0] 5 2 (0.01659893989) 1162 139 67 1 [0] 5 2 (0.01779794692) 1163 134 72 1 [0] 5 5 (0.01669001579) 1164 129 76 1 [0] 5 4 (0.01654696464) 1165 124 82 1 [0] 5 6 (0.01986718177) 1166 118 89 1 [0] 6 7 (0.01687693595) 1167 113 95 1 [0] 5 6 (0.01659297943) 1168 111 101 1 [0] 2 6 (0.01869797706) 1169 109 106 1 [0] 2 5 (0.01680207252) 1170 111 111 1 [0] 2 5 (0.01778697967) 1171 110 123 1 [0] 1 12 (0.01932191848) 1172 109 137 1 [0] 1 14 (0.01761507987) 1173 109 153 1 [0] 0 16 (0.01782703399) 1174 110 168 1 [0] 1 15 (0.01684594154) 1175 114 177 1 [0] 4 9 (0.01769590377) 1176 119 184 1 [0] 5 7 (0.01686215400) 1177 128 189 1 [0] 9 5 (0.02009797096) 1178 137 191 1 [0] 9 2 (0.01672887802) 1179 148 190 1 [0] 11 1 (0.01701307296) 1180 160 188 1 [0] 12 2 (0.01745605468) 1181 170 186 1 [0] 10 2 (0.01667189598) 1182 179 184 1 [0] 9 2 (0.01680994033) 1183 191 179 1 [0] 12 5 (0.02048301696) 1184 201 175 1 [0] 10 4 (0.01663899421) 1185 209 170 1 [0] 8 5 (0.01791810989) 1186 215 165 1 [0] 6 5 (0.01673603057) 1187 220 160 1 [0] 5 5 (0.01738190650) 1188 223 153 1 [0] 3 7 (0.02028107643) 1189 225 145 1 [0] 2 8 (0.01712489128) 1190 226 135 1 [0] 1 10 (0.01786208152) 1191 226 124 1 [0] 0 11 (0.01697206497) 1192 224 116 1 [0] 2 8 (0.01681399345) 1193 223 109 1 [0] 1 7 (0.01784205436) 1194 220 103 1 [0] 3 6 (0.01916480064) 1195 216 95 1 [0] 4 8 (0.01699018478) 1196 212 89 1 [0] 4 6 (0.01809096336) 1197 209 84 1 [0] 3 5 (0.01679587364) 1198 202 78 1 [1] 7 6 (0.02666711807) 1199 196 74 1 [0] 6 4 (0.01917505264) 1200 187 71 1 [0] 9 3 (0.02043294906) 1201 179 73 1 [0] 8 2 (0.01711487770) 1202 172 69 1 [0] 7 4 (0.01728105545) 1203 164 70 1 [0] 8 1 (0.01673698425) 1204 158 68 1 [0] 6 2 (0.01676702499) 1205 151 66 1 [0] 7 2 (0.01997590065) 1206 145 66 1 [0] 6 0 (0.01705002784) 1207 140 67 1 [1] 5 1 (0.02669501304) 1208 145 69 1 [2] 5 2 (0.03549313545) 1209 145 69 0 [0] 0 0 (0.01866602897) tamed BLUE circle 14 : tamed: 56 events, 1.06269502639 s, 53 /s, 568 moved 1210 153 126 1 [0] begin RED hover / 1211 153 125 1 [0] 0 1 (0.01460194587) point (no move) 1212 153 126 1 [0] 0 1 (0.02797102928) 1213 153 124 1 [0] 0 2 (0.01610517501) 1214 152 125 1 [0] 1 1 (0.01820588111) 1215 152 122 1 [0] 0 3 (0.01941895484) 1216 153 126 1 [0] 1 4 (0.01618409156) 1217 153 127 1 [0] 0 1 (0.02172493934) 1218 153 128 1 [0] 0 1 (0.03227305412) 1219 153 127 1 [0] 0 1 (0.01700901985) 1220 152 127 1 [0] 1 0 (0.02249693870) 1221 153 127 1 [0] 1 0 (0.01769590377) 1222 153 128 1 [0] 0 1 (0.04150915145) 1223 152 128 1 [0] 1 0 (0.01670289039) 1224 152 129 1 [0] 0 1 (0.01865696907) 1225 152 128 1 [0] 0 1 (0.01712203025) 1226 152 127 1 [0] 0 1 (0.03233408927) 1227 152 128 1 [0] 0 1 (0.01674294471) 1228 152 129 1 [0] 0 1 (0.02026009559) 1229 152 128 1 [0] 0 1 (0.01976704597) 1230 152 129 1 [0] 0 1 (0.01916193962) 1231 153 128 1 [0] 1 1 (0.01724600791) 1232 153 128 0 [0] 0 0 (0.01590394973) RED hover / point 15 :untamed: 22 events, 0.45567607879 s, 49 /s, 30 moved 1233 155 129 1 [0] Begin BLUE hover / 1234 154 129 1 [21] 1 0 (0.44625902175) point 1235 155 130 0 [9] 1 1 (0.19742083549) BLUE hover / point 16 : tamed: 2 events, 0.64026784896 s, 4 /s, 3 moved >rn=0 =0 > `
Last but not least the code that produced the numbers and pictures.
It uses the the espruino.com/ILI9341.js module's initialization code to get the display properly working for the hardware at hand. It waits for the very first event to start the
2 second
and3
secondmeasuring
anddrawing intervals
with timing help for the operator when to touch and draw and stop there of. Interval begin and end are visualized by a back light outage 'reverse flash' (line# 55...
). Turning the RED LED1 on 300ms into the interval and leave it on for 1000ms less than the interval (line#s 51+57
) tells about touching and drawing time. All values at configurable at the beginning. A few attempts got me trained enough to have decent repeatability and staying within the time boundaries.Watching and recordingof events keeps going until
rn = 0
is entered in the console. After completion of the current interval, the drawing happens. Double the amount of drawing or intervals is possible, but going beyond that is 'honored' with the panic messageshort on memory
and a final exception with exceptional execution death... ;-). After the initial multi-interval phase, subsequent touching and drawings start just one such interval before auto-drawing.// touchTamerExploration.js // v20250201_ao // // E.on("touch",...); delivers A LOT of event due to jitter // due to the nature of touch screen being resistive. This // code cuts back to forward only essential calls and with // that calming downt the touch and prevent overloading by // ui processing. var rn = 1; // run (rn = 0; in console will stop nicely and draw moves on display) function tameTest(cd,ic) { cd=(cd==undefined)? 5:cd; // ignorable change <---- small change conditionally ignored ic=(ic==undefined)?20:ic; // ignore overflow <---- ingore only ic small changes var cu = [] // coords untamed , ct = [] // coords tamed , cc = [] // coords collector / work storage , el = 1000 // event line # , sl = 10 // summary line # , ma = 0 // measuring deactivated (using ID returned from setInterval() , t0 = 0 // time 1st touch in measuring interval , t1 = 0 // time last untouch in measuring interval (if no spanning touch) , ec = 0 // event count , md = 0 // dragged distance , ta = 0 // tamer deactived , tl = {x:0,y:0,b:0,c:0,t:getTime()} // last touch , t8 = getTime()-10 // to get 'low absolute' time numbers , mi = 2000 // ms measuring interval (3000 when drawing) , ot = 300 // ms inot mi LED1 turns on , st = 1000 // ms 'safety' time LED1 off in; must: ot+(mi-st)<mi , th=E.on("touch",(t)=>{ // listen to touch t.xd=Math.abs(t.x-tl.x); t.yd=Math.abs(t.y-tl.y); if (ta) { if (t.b==tl.b) { // no change in touch/untouch state if (t.xd<cd && t.yd<cd) { // small change in coord state if (t.xd+t.yd>0) tl.c++; // count small change if (tl.c<=ic) return; // ignore ic small changes } } } if (ma) { // measuring and recording /intervals activ(ated) // handle change large and small t.c=0; t.t=getTime(); if (ec) { print(++el,t.x,t.y,t.b,"["+tl.c+"]", t.xd, t.yd, " ("+(t.t-tl.t)+")"); md+=t.xd+t.yd; // moved (drag distance) } else { print(++el, t.x,t.y,t.b,"["+tl.c+"]"); t0=getTime(); } tl=t; // last touch cc.push(t.x); cc.push(t.y); // record ec++; // count event } else { // measuring not (yet) activated: activate cc=(ta)?ct:cu; // set initial collector LED1.set(); setTimeout(()=>LED1.reset(),mi-st); // signal timing ma=setInterval(()=>{ // starts measuring and its intervalls // signal times / interval: w/ backlite off-on, LED1-on-off analogWrite(cydIni.C.bl,0.1,{freq:100}); setTimeout(()=>{ analogWrite(cydIni.C.bl,0.9,{freq:100}); },50); setTimeout(()=>{LED1.set(); setTimeout(()=>LED1.reset(),mi-st);},ot); if (ec) { t1=tl.t-t0; print( ++sl, (ta)?": tamed:":":untamed:" , ec-1, " events,", t1, "s, ",Math.ceil((ec-1)/t1), "/s," , md, "moved"); print(""); } cc.push(-1); cc.push(t.b); // mark end of drawing / interval ta=!ta; // flip taming/not taming cc=(ta)?ct:cu; // record tamed/not tamed ec=0; // rest event count md=0; // reset moved (drag distance) t0=0; // reset to take time on 1st touch in interval if (!rn) { // stopped? (not running (anymore)): now draw records cc = cu; ec = 2; g.setColor(1,0,0); while (ec<cc.length) { g.drawLine(cc[ec-2],cc[ec-1],cc[ec++],cc[ec++]); if (cc[ec]<0) { ec+=4; } } cc = ct; ec = 2; g.setColor(0,0,1); while (ec<cc.length) { g.drawLine(cc[ec-2],cc[ec-1],cc[ec++],cc[ec++]); if (cc[ec]<0) { ec+=4; } } cc=[];cu=[];ct=[]; ec=0; } },2000); } }); } function cydIni(callback, bl, spi, ce, dc, rst) { // derived from espruino.com/ILI9341.js module var C= { callback:callback||undefined // CYD ESP32-2432S028 board specifics for ILI9341 LCD Display / controller , bl : bl || D21 // backlit (PWM) , spi: spi||SPI1 // SPI , ce : ce || D15 // Chip Enable , dc : dc || D2 // Data/Command , rst: rst||undefined // hardwired to board rst (reset) button (no sw reset) }; cydIni.C = C; // hold on to running config let wCMD=(d) =>{ C.ce.write(0); C.spi.write(d,C.dc); }; let wCD =(c,d)=>{ C.ce.write(0); C.spi.write(c,C.dc); C.spi.send(d); C.ce.write(1); }; C.ce.write(1); C.dc.write(1); if (C.rst) C.rst.write(0); setTimeout(function(){ if (C.rst) C.rst.write(1); setTimeout(function(){ wCMD(0x01); setTimeout(function(){ wCMD(0x28); C.ce.write(1); wCD(0xCF,[0x00,0x83,0x30]); wCD(0xED,[0x64,0x03,0x12,0x81]); wCD(0xE8 ,[0x85,0x01,0x79]); wCD(0xCB,[0x39,0x2C,0x00,0x34,0x02]); wCD(0xF7,0x20); wCD(0xEA,[0x00,0x00]); wCD(0xC0,0x26); wCD(0xC1,0x11); wCD(0xC5,[0x35,0x3E]); wCD(0xC7,0xBE); // wCD(0x36,0x48); // wCD(0x36,0x60); // portrait RGB wCD(0x36,0x00); // landscape RGB compatible default (no rotatiom) wCD(0x3A,0x55); wCD(0xB1,[0x00,0x1B]); wCD(0xF2,0x08); wCD(0x26,0x01); wCD(0xE0,[0x1F,0x1A,0x18,0x0A,0x0F,0x06,0x45,0x87,0x32,0x0A,0x07,0x02,0x07,0x05,0x00]); wCD(0xE1,[0x00,0x25,0x27,0x05,0x10,0x09,0x3A,0x78,0x4D,0x05,0x18,0x0D,0x38,0x3A,0x1F]); wCD(0xB7,0x07); wCD(0xB6,[0x0A,0x82,0x27,0x00]); wCMD(0x11); C.ce.write(1); setTimeout(()=>{ wCMD(0x29); C.ce.write(1); setTimeout(()=>{ g.clear(); if (C.callback !== undefined) C.callback(); },100); },100); },5); },5); },1); } function onInit() { cydIni(tameTest); } setTimeout(onInit,555);
-
• #4
Wow, thanks for sharing! This should go to c-source code (line 30-36).
-
• #5
thanks for pointing out that the low level code that creates the system-to-JS event queue entry is of type
idle
... I did not notice that when looking at the board code where the JS event is created. Looks like I did not dig deep enough. :Yes, in deed: these few lines should go into the system layer, and the
E.on("touch",callback,...)
could have options to configure that... thecounter (overflow) for ignoring idle
(that would make it conditional not only on idle, but occurrence of the user trying to tell the app and system thru the touch ui about an escape hatch/break/cancel or a like), thedelta xy to identify small events
(ignorable events), andcounter (overflow) for ignoring small events
...).That's very good news, and I hope it is not absolute, same as my ignoring is not absolute. To throttle on busy JS engine is good... A good JS application should take advantage of setTimeout() to allow break-ins of events that can influence the execution. It would be nice to have something like a JS-CPU-usage-in% (range 1..10, or 0.1....1.0, or...) made available to the application so that the application can adjust... (since we do not have processes w/ different priorities... haha).
-
• #6
forgot to mention that the
E.on("touch",...)
should have an options parameter for an optional, overriding calibration/correction function. The calculations on CYD are quite off, especially for x/y-s close to 0/0.When challenged 10+ years ago by the implementation of touch directly in Espruino, I did some calibrations w/ multiple units... and for the type of unit it was pretty constant... but across types, it is different...
The touch controller xy calculation from raw xy code is something like that:
// setup touch screen and connect it to ui SPI1.setup({sck:A5, miso:A6, mosi:A7, baud: 2000000}); // spi, cs, irq, callback, calc (calibrated) touch = touchMod.connect(SPI1, A3, A2, function(x,y){ ui.evt(x,y);} , function(yr, xr, d) { return [ Math.round(xr / -121.44 + 259.70685111989) , Math.round(yr / 88.90357142857 + -19.78130398103) ]; }).listen();
where the espruino.com/modules/XPT2046.js delivers the raw values rx and ry. The low-level implementation does not have to do all what XPT2046 module does (of which a lot has already been implemented into the Espruino binary).
-
• #7
Here is a small test sequence to check if the touch is working as expected.
// ESP32_CYD_touch_grid_test.js function drawGridLines(gridX, gridY) { var xm = g.getWidth()-1, ym = g.getHeight()-1, x, y; // h-lines for (y = gridY; y < ym; y += gridY) g.drawLine(0, y, xm, y); // v-lines for (x = gridX; x < xm; x += gridX) g.drawLine(x, 0, x, ym); } var gridX = 20 ,gridY = 20; g.clear(); drawGridLines(gridX,gridY); grid = new Array(g.getWidth()/gridX).fill(new Array(g.getHeight()/gridY).fill(0)); var tl = {x:0,y:0,b:0,c:0,t:getTime()}, cd = 5, ic = 20; E.on("touch",(t)=>{ t.xd=Math.abs(t.x-tl.x); t.yd=Math.abs(t.y-tl.y); if (t.b==tl.b) { // no change in touch/untouch state if (t.xd<cd && t.yd<cd) { // small change in coord state if (t.xd+t.yd>0) tl.c++; // count small change if (tl.c<=ic) return; // ignore ic small changes } else xg = (t.x / gridX)|0; yg = (t.y / gridY)|0; //print(xg,yg); c = (grid[xg][yg] == 0) ? "#fff" : "#000"; grid[xg][yg] = +!grid[xg][yg]; x = xg * gridX; y = yg * gridY; g.setColor(c).fillRect(x+1,y+1,x+gridX-1,y+gridY-1); } });
2 Attachments
-
• #8
@MaBe, nice work...
going for the corners of the dislplay as well as the corner of critical squares helps to find the formula. Unfortunately also the parallax-error comes into play, because a display is never looked at perpendicularly.
For that reason, it is usually a user function - as you may remember from the first palm tops... (with the gray LCD display and touch screen with pen). I have done that in this post Resistive Touchscreen directly (no touch controller).
-
• #9
@MaBe, attached pic shows a circle where I touched with the pen and an arrow with the tip at the coordinates that the the touch controller delivered, and the pixel is made red. To be as accurate as possible, I intentionally made sure that the parallax-error is not the issue.
With taking the most bottom right touch as an outlier, the error decreases on the x-axis (horizontal) more than on the y-axis (vertical).
1 Attachment
An XPT2046 - controlling a touch screen - can be setup hot and floods the Espruino System-to-JS event queue to the point of drowning and failing of the application(s). Quickly can lagging behind turn into drowned. The flurry of events can have negative effect in an applications, but slowing it down in general (by re-configuring the controller) makes it lame for the application(s) or part(s) thereof that need them speedy... or an application that needs multiple, different speeds at times. Btw, it is not just CYD's touch challenge, but any
touchable
device raises the same concerns.In this conversation I explore options for handling touch with a tamer - like a tiller tamer - and make the event stream suitable for a ui application, and, I show the effect - or non-effect - on free hand drawings.
Bottom line, a good (configured) tamer filters out a lot of noise - up to 90+% - without impacting free hand drawing fidelity. In attached picture you seer RED and BLUE drawings:
Both show about the same line quality, the blue - filtered one -is in some areas even a bit smoother, counter intuitively, because less data points lead to less smooth lines (below a certain limit for sure).
Btw, don't get blind sided by the number of lines of code you find in Post #3... The relevant code is in lines # 30..35. Also, take a look at Post #5.
2 Attachments