ESP32实现iOS模拟点击
相关项目
https://github.com/T-vK/ESP32-BLE-Mouse
https://github.com/sobrinho/ESP32-BLE-Abs-Mouse
实现过程
ESP32-BLE-Mouse是模拟鼠标,iOS设备上可以使用(部分设备需要开启辅助触控,设置-辅助功能-触控-辅助触控)。但不能根据屏幕坐标精准点击。原因是系统在计算鼠标移动时会计算加速度之类的,尝试多次小范围移动,依然无法精确点击。
iOS设备并不支持ESP32-BLE-Abs-Mouse,ESP32-BLE-Abs-Mouse是模拟触控笔,部分安卓设备可以使用,可以精确的点击指定坐标。
ESP32源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
| #include <WiFi.h> #include <WebServer.h> #include <BleMouse.h> #include <math.h>
BleMouse bleMouse; #define LED_BUILTIN 2
const char *ssid = "xxxx"; const char *password = "xxxx";
IPAddress local_IP(192, 168, 31, 112); IPAddress gateway(192, 168, 31, 1); IPAddress subnet(255, 255, 255, 0);
WebServer esp8266_server(80);
void handleRoot() { esp8266_server.send(200, "text/plain", "OK"); }
void handle_click() { esp8266_server.send(200, "text/plain", "OK"); if (bleMouse.isConnected()) { bleMouse.click(MOUSE_LEFT); } } void handle_move3() {
int x = esp8266_server.arg("x").toInt(); int y = esp8266_server.arg("y").toInt();
if (bleMouse.isConnected() && x > -1 && y > -1) { int a = -1000; int b = 1000; signed char xStep = 0; signed char yStep = 0; delay(10); while (a != 0 || b != 0) { xStep = (a > 127) ? 127 : (a < -128) ? -128 : (signed char)a; yStep = (b > 127) ? 127 : (b < -128) ? -128 : (signed char)b;
bleMouse.move(xStep, yStep);
a -= xStep; b -= yStep;
delay(70); }
if (bleMouse.isConnected()) { while (x != 0 || y != 0) { xStep = (x > 1) ? 1 : x; yStep = (y > 1) ? 1 : y;
bleMouse.move(xStep, yStep);
x -= xStep; y -= yStep; delay(1); } } esp8266_server.send(200, "text/plain", "OK"); } }
#define SCREEN_WIDTH 580 #define SCREEN_HEIGHT 1158 #define MOUSE_DPI 500 #define MAX_MOVE_STEP 127 void handle_move() {
int x = esp8266_server.arg("x").toInt(); int y = esp8266_server.arg("y").toInt();
int targetX = esp8266_server.arg("x").toInt(); int targetY = esp8266_server.arg("y").toInt();
if (bleMouse.isConnected() && x > -1 && y > -1) { int a = -1000; int b = 1000; signed char xStep = 0; signed char yStep = 0; signed char max_move_step = 16; delay(10); while (a != 0 || b != 0) { xStep = (a > 127) ? 127 : (a < -128) ? -128: (signed char)a; yStep = (b > 127) ? 127 : (b < -128) ? -128: (signed char)b;
bleMouse.move(xStep, yStep);
a -= xStep; b -= yStep;
delay(70); }
delay(100); while (1) { if (y == 0) { break; } yStep = (y > max_move_step) ? max_move_step : (signed char)y;
bleMouse.move(0, yStep * -1); y -= yStep; delay(10); } delay(100); while (1) { if (x == 0) { break; } xStep = (x > max_move_step) ? max_move_step : (signed char)x; bleMouse.move(xStep, 0); x -= xStep; delay(10); } } esp8266_server.send(200, "text/plain", "OK"); }
void handle_movex() {
int x = esp8266_server.arg("x").toInt(); int y = esp8266_server.arg("y").toInt();
int targetX = esp8266_server.arg("x").toInt(); int targetY = esp8266_server.arg("y").toInt();
if (bleMouse.isConnected() && x > -1 && y > -1) { int a = -1000; int b = 1000; signed char xStep = 0; signed char yStep = 0; signed char max_move_step = 16; delay(10); while (a != 0 || b != 0) { xStep = (a > 127) ? 127 : (a < -128) ? -128: (signed char)a; yStep = (b > 127) ? 127 : (b < -128) ? -128: (signed char)b;
bleMouse.move(xStep, yStep);
a -= xStep; b -= yStep;
delay(70); }
delay(100); while (1) { if (x == 0 && y == 0) { break; }
xStep = (x > max_move_step) ? max_move_step : (signed char)x; yStep = (y > max_move_step) ? max_move_step : (signed char)y;
bleMouse.move(xStep, yStep * -1); x -= xStep; y -= yStep; delay(10); } } esp8266_server.send(200, "text/plain", "OK"); }
void handleNotFound() { esp8266_server.send(404, "text/plain", "404: Not found"); }
void setup() { Serial.begin(115200); pinMode(LED_BUILTIN, OUTPUT); bleMouse.begin();
WiFi.config(local_IP, gateway, subnet); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); int i = 0; while (WiFi.status() != WL_CONNECTED) { delay(1000); }
esp8266_server.begin(); esp8266_server.on("/", handleRoot); esp8266_server.on("/click", handle_click); esp8266_server.on("/move", handle_move); esp8266_server.onNotFound(handleNotFound); }
void loop() { esp8266_server.handleClient(); if (bleMouse.isConnected()) { digitalWrite(LED_BUILTIN, HIGH); } else { digitalWrite(LED_BUILTIN, LOW); } }
|
为了尽可能精确的点击,我尝试先移动Y方向,再移动X方向,并采集鼠标移动距离与实际移动距离的数据。
采集数据需要创建一个PWA应用,这样可以几乎采集全屏的点击事件(状态栏等位置无法采集点击事件)。
每个不同的设备采集一份数据,就可以通过计算得到点击屏幕坐标映射后的鼠标坐标,勉强实现“精准”点击。
为了实现自动化脚本,需要借助爱思助手的投屏功能,PC端采集并检测屏幕数据,再用python脚本发送点击事件,即可实现iOS自动化脚本。