|
|
|
Pilot + Arduino (Hardware clicker) |
|
|
cirus |
27.11.2020, 2:58
|
Elder
Сообщений: 3.480
Регистрация: 18.8.2014 Группа: Пользователи Наличность: 26707
Пользователь №: 16.971
Возраст: 29
|
Цитата некоторую табличку перемещений? При включённой галке 'Включить повышенную точность установки указателя' на сколько пикселей переместится курсор зависит от заданной скорости курсора и на сколько пикселей смещать курсор. Скорость перемещения курсора мыши в винде от 1 до 20. К примеру, сместить курсор на 100 пикселей по X и на 100 по Y. При минимальной скорости, т. е. 1 сместит от 14 до 17 пикселей. Если увеличить скорость до 2, то сместит от 30 до 34. При 3 от 45 до 51. и т. д. При скорости 20 вместо 100 пикселей сместит от 310 до 342. При смещение на 50 пикселей, а не на 100 цифры будут примерно вдвое меньше. Т. е. при минимальной скорости сместит на 7-8 пикселей, вместо 50. Тут ещё надо учитывать что функции мыши принимают char, т. е. сместить курсор за раз можно максимум на -128...127 пикселей. Как вариант можно отключать эту функцию перед перемещением курсора и включать обратно. Если верить описанию ****, на это уходит 12 мсек. Сообщение отредактировал DarkMaster - 27.11.2020, 3:18
|
|
|
|
DarkMaster |
27.11.2020, 3:29
|
Модератор UOPilot
Сообщений: 9.467
Регистрация: 2.12.2008 Группа: Супермодераторы Наличность: 27722
Пользователь №: 11.279
|
Цитата Тут ещё надо учитывать что функции мыши принимают char, т. е. сместить курсор за раз можно максимум на -128...127 пикселей. Забавно. Т.е. получается в винде макс скорость перемещения мыши существует и зависит от герцовки мыша. Цитата Как вариант можно отключать эту функцию перед перемещением курсора и включать обратно. Дерганье туда-сюда имхо не есть хорошо и уж точно не есть правильно. Имхо куда разумнее потроить обратную функцию (в смысле k(x)) и исходить из нее. На самом деле не так много вариантов получается - можно и вовсе таблицу использовать. 5120 значений - смех. Собрать тем же пилотом можно. Из-за ограничений макс дистанции все равно делать функцию разбиения движения на несколько вызовов, в рамках нее реализовать добор значений. Про добор поясню, например, нам нужно переместить на 100 пикселей, но из-за включенной акселерации у нас есть только 98 и 105 пикселей, соотвественно придется двигать на 98, потом на 2 ну или другие слогаемые. Насколько последняя версия стабильна? В шапку выкладываю? В таблицу enter все предлагаю все-таки вернуть. Я понимаю, что "по правильному" это "return", но вот ты когда последний раз его так называл? А при попытке клика чисто интуитивно, как бы начал писать? По поводу _return и _end вопрос более спорный, прошу помощь зала =)
--------------------
Скрипты UOPilot под заказ. Консультации по UOpilot 15$/час. Услуги Lua разработчика (не пилот, проекты, постоянка) Disсоrd: Kov____
|
|
|
|
cirus |
27.11.2020, 4:42
|
Elder
Сообщений: 3.480
Регистрация: 18.8.2014 Группа: Пользователи Наличность: 26707
Пользователь №: 16.971
Возраст: 29
|
arduino.zip ( 2,81 килобайт )
Кол-во скачиваний: 118В архиве скетч и модуль lua. Исправлено export_array["return"] = 0xB0 на Код export_array.enter = 0xB0 Добавлен скролл - перемещает курсор в указанные координаты и выполняет скролл на нужное количество щелчков, если количество не указано то сделает 1 щелчок вниз. Код hw.mouse.wheel(200, 100) -- переместить курсор в координаты 200 100 и сделать 1 щелчок вниз hw.mouse.wheel(200, 100, 3) -- на 3 щелчка вверх hw.mouse.wheel(200, 100, -2) -- на 2 вниз Добавлен drag - перемещает курсор в указанные координаты, зажимает левую кнопку мыши, перемещает курсор в указанные координаты. Код hw.mouse.drag(200, 100, 500, 300) Функция text() теперь принимает строку любой длины, т. к. размер буфера ограничен, то строка будет напечатана частями по 60 символов. Цитата В шапку выкладываю? Да.
|
|
|
|
Crocotea |
27.11.2020, 11:46
|
Novice
Сообщений: 51
Регистрация: 30.10.2020 Группа: Пользователи Наличность: 0
Пользователь №: 19.787
|
Цитата Насколько последняя версия стабильна? В шапку выкладываю? сегодня постараюсь сделать полный тест всех функций, край завтра Извиняюсь, я упустил момент, добавлялись ли спец символы !@^ для использования key('@~2') или они будут через keydown(KEY_LEFT_CTRL) keydown(KEY_LEFT_SHIFT) key('2') keyup(KEY_LEFT_SHIFT) keyup(KEY_LEFT_CTRL) как было решено оставить? Цитата Можешь дать некоторую табличку перемещений? Перемещал на 1 - прыгнуло на 2, перемещал на 10, прыгнуло на 15 и т.д.? вместе с тестом, так получается через get_mousepos? как им считывать относительные координаты?
|
|
|
|
Crocotea |
27.11.2020, 15:19
|
Novice
Сообщений: 51
Регистрация: 30.10.2020 Группа: Пользователи Наличность: 0
Пользователь №: 19.787
|
Цитата(cirus @ 27.11.2020, 4:42)
arduino.zip ( 2,81 килобайт )
Кол-во скачиваний: 118В архиве скетч и модуль lua. не отпускает клавиши в указанных координатах. Так со всеми кнопками мыши где есть _up (правая,левая,центральная). Зажимает в нужных Код hw.mouse.left_down (740, 426) hw.mouse.left_up (740, 326) все остальное работает Цитата Можешь дать некоторую табличку перемещений? Перемещал на 1 - прыгнуло на 2, перемещал на 10, прыгнуло на 15 и т.д.? тест Код --lua local hw = require'arduino' hw.com = 8 -- Номер порта hw.set_delay_key(20) -- установка пауз hw.set_delay_mouse(1000)
wait(3000) local a,b,x,y = 752, 420, 0, 0
::mt1:: hw.mouse.move(a, b) local x, y = mouse_pos ("abs") log(x,y) goto mt1 результат Код 15:16:53 12 (autosaved_12.txt, 0): 95 353 15:16:54 12 (autosaved_12.txt, 0): 1738 520 15:16:55 12 (autosaved_12.txt, 0): 0 268 15:16:56 12 (autosaved_12.txt, 0): 1904 653 15:16:58 12 (autosaved_12.txt, 0): 0 75 15:16:59 12 (autosaved_12.txt, 0): 1835 912 15:17:00 12 (autosaved_12.txt, 0): 0 0 15:17:01 12 (autosaved_12.txt, 0): 1919 1075 15:17:03 12 (autosaved_12.txt, 0): 0 0 15:17:04 12 (autosaved_12.txt, 0): 1919 1075 15:17:05 12 (autosaved_12.txt, 0): 0 580 15:17:06 12 (autosaved_12.txt, 0): 1139 689 15:17:07 12 (autosaved_12.txt, 0): 282 97 15:17:09 12 (autosaved_12.txt, 0): 1351 820 15:17:10 12 (autosaved_12.txt, 0): 0 0 15:17:11 12 (autosaved_12.txt, 0): 1919 1075 15:17:12 12 (autosaved_12.txt, 0): 1364 58 15:17:13 12 (autosaved_12.txt, 0): 0 896 15:17:15 12 (autosaved_12.txt, 0): 1919 0 15:17:16 12 (autosaved_12.txt, 0): 0 1065 15:17:17 12 (autosaved_12.txt, 0): 1916 5 15:17:18 12 (autosaved_12.txt, 0): 0 1015 15:17:20 12 (autosaved_12.txt, 0): 1919 0 15:17:21 12 (autosaved_12.txt, 0): 0 1065 15:17:22 12 (autosaved_12.txt, 0): 1919 0 15:17:23 12 (autosaved_12.txt, 0): 0 1064 15:17:24 12 (autosaved_12.txt, 0): 1919 0 15:17:26 12 (autosaved_12.txt, 0): 0 1064 15:17:27 12 (autosaved_12.txt, 0): 1919 0
|
|
|
|
Crocotea |
27.11.2020, 15:28
|
Novice
Сообщений: 51
Регистрация: 30.10.2020 Группа: Пользователи Наличность: 0
Пользователь №: 19.787
|
Цитата(cirus @ 27.11.2020, 15:27) Увеличить паузу между нажатием и отпускание кнопок мыши.
параметры теста: Код --lua local hw = require'arduino' hw.com = 8 -- Номер порта hw.set_delay_key(20) -- установка пауз hw.set_delay_mouse(1000) целая секунда стоит
|
|
|
|
Cockney |
28.11.2020, 18:00
|
Master
Сообщений: 1.395
Регистрация: 22.6.2013 Группа: Пользователи Наличность: 21061
Пользователь №: 16.156
|
Цитата(cirus @ 28.11.2020, 3:17) Исправил. Исправил drag. Убрал паузу при чтении из буфера, теперь должно работать даже при небольших паузах. Убрал паузу при перемещении мыши.
arduino.zip ( 2,81 килобайт )
Кол-во скачиваний: 117Убрана вся магия Выброшен String text, substring() и прочие. Развернуть
Код #include <Mouse.h> #include <Keyboard.h> #include <stdlib.h>
// hardware int KEYBOARD_DELAY = 20; int MOUSE_DELAY = 20; const int SERIAL_PORT = 9600; const int SERIAL_DELAY = 1; #define MAX_BUFFER_SIZE 65 //null-terminated
// protocol #define SET_DELAY '0' #define SET_KEYBOARD_DELAY '0' #define SET_MOUSE_DELAY '1' #define PRESS_KEY '1' #define PRINT_STRING '2' #define KEY_DOWN '3' #define KEY_UP '4' #define MOUSE_MOVE '5' #define MOUSE_CLICK '6' #define MOUSE_DOWN '7' #define MOUSE_UP '8' #define MOUSE_SCROLL '9'
void setup() { Serial.begin(SERIAL_PORT); Mouse.begin(); Keyboard.begin(); }
void loop() { char buffer[MAX_BUFFER_SIZE]; int buffPos = 0;
while (!Serial.available()) { delay(SERIAL_DELAY); }
while (Serial.available()) { if (buffPos <= MAX_BUFFER_SIZE - 2) { buffer[buffPos++] = Serial.read(); buffer[buffPos] = '\0'; } }
switch (buffer[0]) { case SET_DELAY: // установки паузы для клавиш клавиутуры и мыши { switch (buffer[1]) { case SET_KEYBOARD_DELAY: KEYBOARD_DELAY = atoi(&buffer[2]); break; case SET_MOUSE_DELAY: MOUSE_DELAY = atoi(&buffer[2]); break; } break; } case PRESS_KEY: // нажатие клавиши { char key = buffer[1]; Keyboard.press(key); delay(KEYBOARD_DELAY); Keyboard.release(key); delay(KEYBOARD_DELAY); break; } case PRINT_STRING: // напечатать строку { for (int i = 1; i < MAX_BUFFER_SIZE - 1; i++) { Keyboard.write(buffer[i]); delay(KEYBOARD_DELAY); } break; } case KEY_DOWN: // зажать клавишу { Keyboard.press(buffer[1]); delay(KEYBOARD_DELAY); break; } case KEY_UP: // отпустить клавишу { Keyboard.release(buffer[1]); delay(KEYBOARD_DELAY); break; } case MOUSE_MOVE: // переместить курсор мыши { long coordinate = atoi(&buffer[3]); // x и y на сколько пикселей нужно сместить курсор long x = coordinate / 65535; long y = coordinate % 65535;
// нужно двигать влево/вправо вверх/вниз if (buffer[1] == '-') x = -x; if (buffer[2] == '-') y = -y;
// сколько нужно сделать шагов int count_step; int stepX = 127, stepY = 127; // шаг int remainsX, remainsY; // сколько останется в конце
if (abs(x) > abs(y)) // если по X больше двигать курсор чем по Y { count_step = abs(x) / 127; if (count_step > 0) { if (x < 0)stepX = -127;
if (y > 0)stepY = abs(y) / count_step; else stepY = y / count_step;
if (abs(stepY) > 127) { if (stepY > 0)stepY = 127; else stepY = -127; } } remainsX = x % stepX; remainsY = y % stepY; } else { count_step = abs(y) / 127; if (count_step > 0) { if (y < 0)stepY = -127; if (x > 0)stepX = abs(x) / count_step; else stepX = x / count_step;
if (abs(stepX) > 127) { if (stepX > 0)stepX = 127; else stepX = -127; } } remainsX = x % stepX; remainsY = y % stepY; }
for (int i = 0; i < count_step; i++) // перемещение курсора { Mouse.move(stepX, stepY, 0); }
Mouse.move(remainsX, remainsY, 0); // перемещение в конечную точку delay(MOUSE_DELAY); break; } case MOUSE_CLICK: // клик кнопкой мыши { Mouse.click(buffer[1]); delay(MOUSE_DELAY); break; } case MOUSE_DOWN: // зажать кнопку мыши { Mouse.press(buffer[1]); delay(MOUSE_DELAY); break; } case MOUSE_UP: // отпустить кнопку мыши { Mouse.release(buffer[1]); delay(MOUSE_DELAY); break; } case MOUSE_SCROLL: // скролл мыши { char wheel = atoi(&buffer[1]); Mouse.move(0, 0, wheel); delay(MOUSE_DELAY); break; } default: break; }
}
|
|
|
|
Crocotea |
29.11.2020, 21:20
|
Novice
Сообщений: 51
Регистрация: 30.10.2020 Группа: Пользователи Наличность: 0
Пользователь №: 19.787
|
Цитата(cirus @ 28.11.2020, 20:03) Исправил ошибки. Скетч
Код #include <Mouse.h> #include <Keyboard.h> #include <stdlib.h>
// hardware int KEYBOARD_DELAY = 20; int MOUSE_DELAY = 20; const int SERIAL_PORT = 9600; const int SERIAL_DELAY = 1; #define MAX_BUFFER_SIZE 64
// protocol #define SET_DELAY '0' #define SET_KEYBOARD_DELAY '0' #define SET_MOUSE_DELAY '1' #define PRESS_KEY '1' #define PRINT_STRING '2' #define KEY_DOWN '3' #define KEY_UP '4' #define MOUSE_MOVE '5' #define MOUSE_CLICK '6' #define MOUSE_DOWN '7' #define MOUSE_UP '8' #define MOUSE_SCROLL '9'
void setup() { Serial.begin(SERIAL_PORT); Mouse.begin(); Keyboard.begin(); }
void loop() { char buffer[MAX_BUFFER_SIZE]; int buffPos = 0;
while (!Serial.available()) { delay(SERIAL_DELAY); }
while (Serial.available()) { if (buffPos < MAX_BUFFER_SIZE - 1) { buffer[buffPos++] = Serial.read(); buffer[buffPos] = '\0'; } }
switch (buffer[0]) { case SET_DELAY: // установки паузы для клавиш клавиутуры и мыши { switch (buffer[1]) { case SET_KEYBOARD_DELAY: KEYBOARD_DELAY = atoi(&buffer[2]); break; case SET_MOUSE_DELAY: MOUSE_DELAY = atoi(&buffer[2]); break; } break; } case PRESS_KEY: // нажатие клавиши { char key = atoi(&buffer[1]); Keyboard.press(key); delay(KEYBOARD_DELAY); Keyboard.release(key); delay(KEYBOARD_DELAY); break; } case PRINT_STRING: // напечатать строку { for (int i = 1; i < buffPos; i++) { Keyboard.write(buffer[i]); delay(KEYBOARD_DELAY); } break; } case KEY_DOWN: // зажать клавишу { Keyboard.press(atoi(&buffer[1])); delay(KEYBOARD_DELAY); break; } case KEY_UP: // отпустить клавишу { Keyboard.release(atoi(&buffer[1])); delay(KEYBOARD_DELAY); break; } case MOUSE_MOVE: // переместить курсор мыши { long coordinate = atol(&buffer[3]);
// x и y на сколько пикселей нужно сместить курсор long x = coordinate / 65535; long y = coordinate % 65535;
// нужно двигать влево/вправо вверх/вниз if (buffer[1] == '-') x = -x; if (buffer[2] == '-') y = -y;
// сколько нужно сделать шагов int count_step; int stepX = 127, stepY = 127; // шаг int remainsX, remainsY; // сколько останется в конце
if (abs(x) > abs(y)) // если по X больше двигать курсор чем по Y { count_step = abs(x) / 127; if (count_step > 0) { if (x < 0)stepX = -127;
if (y > 0)stepY = abs(y) / count_step; else stepY = y / count_step;
if (abs(stepY) > 127) { if (stepY > 0)stepY = 127; else stepY = -127; } } remainsX = x % stepX; remainsY = y % stepY; } else { count_step = abs(y) / 127; if (count_step > 0) { if (y < 0)stepY = -127; if (x > 0)stepX = abs(x) / count_step; else stepX = x / count_step;
if (abs(stepX) > 127) { if (stepX > 0)stepX = 127; else stepX = -127; } } remainsX = x % stepX; remainsY = y % stepY; }
for (int i = 0; i < count_step; i++) // перемещение курсора { Mouse.move(stepX, stepY, 0); }
Mouse.move(remainsX, remainsY, 0); // перемещение в конечную точку delay(MOUSE_DELAY); break; } case MOUSE_CLICK: // клик кнопкой мыши { Mouse.click(buffer[1]); delay(MOUSE_DELAY); break; } case MOUSE_DOWN: // зажать кнопку мыши { Mouse.press(buffer[1]); delay(MOUSE_DELAY); break; } case MOUSE_UP: // отпустить кнопку мыши { Mouse.release(buffer[1]); delay(MOUSE_DELAY); break; } case MOUSE_SCROLL: // скролл мыши { char wheel = atoi(&buffer[1]); Mouse.move(0, 0, wheel); delay(MOUSE_DELAY); break; } default: break; } } комбинации с _up работают корректно
|
|
|
|
cirus |
29.11.2020, 23:12
|
Elder
Сообщений: 3.480
Регистрация: 18.8.2014 Группа: Пользователи Наличность: 26707
Пользователь №: 16.971
Возраст: 29
|
Crocotea, проверьте этот код: Узнать номер com порта, в котором arduino
Код --lua local ffi = require('ffi') local setupapi = ffi.load('SetupAPI.dll') local advapi32 = ffi.load('Advapi32.dll')
local DIGCF_ALLCLASSES = 4 local DIGCF_PRESENT = 2 local SPDRP_HARDWAREID = 1 local DICS_FLAG_GLOBAL = 1 local DIREG_DEV = 1 local KEY_READ = 131097 local BUFF_LEN = 20 local ERROR_SUCCESS = 0 local REG_SZ = 1
ffi.cdef[[ struct HWND__ { int unused; }; typedef struct HWND__ *HWND; struct HKEY__ { int unused; }; typedef struct HKEY__ *HKEY; typedef HKEY *PHKEY; typedef unsigned long ULONG; typedef unsigned long DWORD; typedef DWORD *LPDWORD; typedef long LONG; typedef DWORD *PDWORD; typedef unsigned char BYTE; typedef BYTE *PBYTE, *LPBYTE; typedef wchar_t WCHAR; typedef const char *LPCSTR, *PCSTR; typedef unsigned long ULONG_PTR, *PULONG_PTR; typedef void *PVOID; typedef PVOID HDEVINFO; typedef ULONG DEVPROPTYPE; typedef LONG LSTATUS; typedef DWORD ACCESS_MASK; typedef ACCESS_MASK REGSAM;
typedef struct _GUID {unsigned long Data1; unsigned short Data2; unsigned short Data3; unsigned char Data4[8];} GUID; typedef struct _SP_DEVINFO_DATA {DWORD cbSize; GUID ClassGuid; DWORD DevInst; ULONG_PTR Reserved;} SP_DEVINFO_DATA, *PSP_DEVINFO_DATA;
HDEVINFO SetupDiGetClassDevsA(const GUID *ClassGuid, PCSTR Enumerator, HWND hwndParent, DWORD Flags); bool SetupDiDestroyDeviceInfoList(HDEVINFO DeviceInfoSet); bool SetupDiEnumDeviceInfo(HDEVINFO DeviceInfoSet, DWORD MemberIndex, PSP_DEVINFO_DATA DeviceInfoData); bool SetupDiGetDeviceRegistryPropertyA(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property, PDWORD PropertyRegDataType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, PDWORD RequiredSize); HKEY SetupDiOpenDevRegKey(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Scope, DWORD HwProfile, DWORD KeyType, REGSAM samDesired); LSTATUS RegCloseKey(HKEY hKey); LSTATUS RegQueryValueExA(HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType,LPBYTE lpData, LPDWORD lpcbData); ]]
function get_port(vid, pid) if vid == nil then return -1 end if pid == nil then return -2 end
local com local DeviceInfoSet = ffi.new('HDEVINFO') local DeviceIndex = 0 local DeviceInfoData = ffi.new('SP_DEVINFO_DATA', 0) local DevEnum = ffi.new('PCSTR', "USB") local ExpectedDeviceId = 'VID_' .. tostring(vid) .. '&PID_' .. tostring(pid) local szBuffer = ffi.new('unsigned char[1024]', 0) local ulPropertyType = ffi.new('DEVPROPTYPE[1]') local dwSize = ffi.new('PDWORD') DeviceInfoSet = setupapi.SetupDiGetClassDevsA(nil, DevEnum, nil, bit.bor(DIGCF_ALLCLASSES, DIGCF_PRESENT)) DeviceInfoData.cbSize = ffi.sizeof(DeviceInfoData)
while setupapi.SetupDiEnumDeviceInfo(DeviceInfoSet, DeviceIndex, DeviceInfoData) do DeviceIndex = DeviceIndex + 1 if (setupapi.SetupDiGetDeviceRegistryPropertyA(DeviceInfoSet, DeviceInfoData, SPDRP_HARDWAREID, ulPropertyType, szBuffer, ffi.sizeof(szBuffer), dwSize)) then if ffi.string(szBuffer):match(ExpectedDeviceId) then local hDeviceRegistryKey = ffi.new('HKEY') hDeviceRegistryKey = setupapi.SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); local pszPortName = ffi.new('char[?]', BUFF_LEN) local dwSize = ffi.new('DWORD[1]', ffi.sizeof(pszPortName)) local dwType = ffi.new('DWORD[1]') if advapi32.RegQueryValueExA(hDeviceRegistryKey, "PortName", nil, dwType, pszPortName, dwSize) == ERROR_SUCCESS and dwType[0] == REG_SZ then com = tonumber(ffi.string(pszPortName):match('%d+')) end end advapi32.RegCloseKey(hDeviceRegistryKey) end end setupapi.SetupDiDestroyDeviceInfoList(DeviceInfoSet) if com then return com end return 0 end
-- узнать номер порта, передавать vid, pid local COM = get_port(2341, 8036) -- указать нужные vid и pid log(COM) vid и pid можно узнать в Arduino IDE, в меню 'Инструменты', 'Получить информацию о плате'.
|
|
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|