Автор:dramster
Первая часть /post/arduino-micro-+-clickerman
Не прошло и года, как у меня все-же получилось написать длл для общения с ком портом, а именно с ардуиномикро. По сравнению с командной строкой, работает шустро и незаметно.
При написании никаких дополнительных компонентов для работы с ком не использовал. С ними оказалось намного все сложнее.
Вобщем, пару вечеров, куча статей и форумов, вот первый, и вполне рабочий вариант.
Кто в теме, или вдруг загорится этой темой, код длл делфи10:
Код: Delphi
library micro_com;
uses Windows, SysUtils;
//------------------------------------------------------------------------------
// Основное тело функции, идет на экспорт, вызывается из кликера
function execute( _mas: pInteger; _size: Integer): Integer; export; stdcall;
type
pIntArr = array[0..0] of Integer;
var
DCB : TDCB;
hPort : THandle;
port_num : integer;
param : integer;
byete_res: Cardinal;
str : string;
len : integer;
begin
port_num := pIntArr(_mas^)[0];
param := pIntArr(_mas^)[_size-1];
// 1. Открываем файл
hPort :=
CreateFile(PChar('COM'+IntToStr(port_num)),
GENERIC_READ + GENERIC_WRITE, 0, nil,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
// 2. Контроль ошибок
if hPort = INVALID_HANDLE_VALUE then begin
// Обнаружена ошибка, порт открыть не удалось
result := 1;
exit;
end;
// 3. Чтение текущих настроек порта
if GetCommState(hPort, DCB) then ;
// 4. Настройки:
// Скорость обмена
DCB.BaudRate := 9600;
// Число бит на символ
DCB.ByteSize := 8;
// Стоп-биты
DCB.StopBits := 1;
// Четность
DCB.Parity := 0;
// Какая-то херь непонятная
DCB.Flags := 20625;
// 5. Передача настроек
if not SetCommState(hPort, DCB) then begin{ошибка настройки порта}
result := 2;
exit;
end;
// 6. Настройка буферов порта (очередей ввода и вывода)
if not SetupComm(hPort, 16, 16) then begin{ошибка настройки буферов}
result := 3;
exit;
end;
// 7. Сброс буферов и очередей
if PurgeComm(hPort, PURGE_TXABORT or PURGE_RXABORT or PURGE_TXCLEAR orPURGE_RXCLEAR) then
// 8. Запись в порт
str := intToStr(param);
len := Length(str);
WriteFile(hPort, PChar(str)^, len*2, byete_res, nil);
// 9. Закрытие порта
CloseHandle(hPort);
result := 5;
end;
//------------------------------------------------------------------------------
// список экспорта
exports execute;
begin
end.
Скомпилированная библиотека уверенно отправляет в нужный порт любой текст. Примерно так:
Код: Clickermann
CALL ("micro_com.dll", $com, $val)
Нам же, для управления микрой, нужны только числа. Скетч для контроллера взял старый отсюда /post/arduino-micro-+-clickerman. Немного доработал его:
Код: sketch Arduino
#include <mouse.h>
#include <keyboard.h>
unsigned long par = 0;
String instring = "";
int kmfunct = 0;
int x_cor = 0;
int y_cor = 0;
int mult = 0;
int inchar = 0;
void setup() {
Serial.begin(9600);
Mouse.begin();
Keyboard.begin();
}
void loop() {
while(Serial.available() > 0){
inchar = Serial.read();
if (isDigit(inchar)) {
instring += (char)inchar;
}
}
par = instring.toInt();
instring = "";
if (par > 0) {
kmfunct = par/16777216 ;
switch (kmfunct) {
case 1: //Mouse.click
Mouse.click(par - kmfunct*16777216);
break;
case 2: // Mouse.move
x_cor = (par - kmfunct*16777216)/256;
y_cor = par - x_cor*256 - kmfunct*16777216;
if (x_cor > 127) x_cor = 127 - x_cor;
if (y_cor > 127) y_cor = 127 - y_cor;
Mouse.move(x_cor, y_cor, 0);
break;
case 3: //Mouse.press
Mouse.press(par - kmfunct*16777216);
break;
case 4: //Mouse.release
Mouse.release(par - kmfunct*16777216);
break;
case 5: //Mouse.dblclick
Mouse.click(par - kmfunct*16777216);
delay(50);
Mouse.click(par - kmfunct*16777216);
break;
case 6: //wheel.down.up
mult = par - kmfunct*16777216;
if (mult > 127) mult = 127 - mult;
Mouse.move(0, 0, mult);
case 7: // Keyboard.keydown
Keyboard.press(par - kmfunct*16777216);
break;
case 8: // Keyboard.keyup
Keyboard.release(par - kmfunct*16777216);
break;
case 9: // Keyboard.keypress
Keyboard.write(par - kmfunct*16777216);
break;
}
}
par = 0;
}
</keyboard.h></mouse.h>
Библиотека с подпрограммами для кликермана тут:
Arduino_mouse_keyboard_4.13.cms (4.68 КБ)
Arduino_mouse_keyboard_4.14.cms (3.36 КБ)
Код: Clickermann
$com = 5 //свой порт
//#name "Arduino_mouse&keyboard"
////////////////////////////////////////////////
// Все процедуры с мышью и клавиатурой через ардуино
//micro_move ($x_cor, $y_cor)
//micro_lclick ($x_cor, $y_cor)
//micro_rclick ($x_cor, $y_cor)
//micro_mclick ($x_cor, $y_cor)
//micro_ldown ($x_cor, $y_cor)
//micro_rdown ($x_cor, $y_cor)
//micro_mdown ($x_cor, $y_cor)
//micro_lup ($x_cor, $y_cor)
//micro_rup ($x_cor, $y_cor)
//micro_mup ($x_cor, $y_cor)
//micro_dblclick ($x_cor, $y_cor)
//micro_wheeldown ($mult)
//micro_wheelup ($mult)
// вместо $char_ASCII писать не код клавиши, а символ ASCII.
// в ардуино как-то тупо сделали клавиатурные нажатия :/
//micro_keydown ($char_ASCII)
//micro_keyup ($char_ASCII)
//micro_keypress ($char_ASCII)
//move
SUB(micro_move, $x_cor, $y_cor)
WHILE(DIST($x_cor, $y_cor, $_xmouse, $_ymouse) > 3)
$x_temp = $_xmouse
$y_temp = $_ymouse
$x_dist = $x_cor - $_xmouse
$y_dist = $y_cor - $_ymouse
IF($x_dist < 0)
$x_dist = 127 + int(SQRT(ABS($x_dist*4)))
else
$x_dist = int(SQRT(ABS($x_dist*4)))
END_IF
IF($y_dist < 0)
$y_dist = 127 + int(SQRT(ABS($y_dist*4)))
else
$y_dist = int(SQRT(ABS($y_dist*4)))
END_IF
CALL ("micro_com.dll", $com, 33554432 + $x_dist*256 + $y_dist)
END_CYC
END_SUB
//lclick
SUB(micro_lclick, $x_cor, $y_cor)
micro_move($x_cor, $y_cor)
CALL ("micro_com.dll", $com, 16777217)
END_SUB
//rclick
SUB(micro_rclick, $x_cor, $y_cor)
micro_move($x_cor, $y_cor)
CALL ("micro_com.dll", $com, 16777218)
END_SUB
//mclick
SUB(micro_mclick, $x_cor, $y_cor)
micro_move($x_cor, $y_cor)
CALL ("micro_com.dll", $com, 16777219)
END_SUB
//ldown
SUB(micro_ldown, $x_cor, $y_cor)
micro_move($x_cor, $y_cor)
CALL ("micro_com.dll", $com, 50331649)
END_SUB
//rdown
SUB(micro_rdown, $x_cor, $y_cor)
micro_move($x_cor, $y_cor)
CALL ("micro_com.dll", $com, 50331650)
END_SUB
//mdown
SUB(micro_mdown, $x_cor, $y_cor)
micro_move($x_cor, $y_cor)
CALL ("micro_com.dll", $com, 50331651)
END_SUB
//lup
SUB(micro_lup, $x_cor, $y_cor)
micro_move($x_cor, $y_cor)
CALL ("micro_com.dll", $com, 67108865)
END_SUB
//rup
SUB(micro_rup, $x_cor, $y_cor)
micro_move($x_cor, $y_cor)
CALL ("micro_com.dll", $com, 67108866)
END_SUB
//mup
SUB(micro_mup, $x_cor, $y_cor)
micro_move($x_cor, $y_cor)
CALL ("micro_com.dll", $com, 67108867)
END_SUB
//dblclick
SUB(micro_dblclick, $x_cor, $y_cor)
micro_move($x_cor, $y_cor)
CALL ("micro_com.dll", $com, 83886081)
END_SUB
//wheeldown
SUB(micro_wheeldown, $mult)
CALL ("micro_com.dll", $com, 100663423 + $mult)
END_SUB
//wheelup
SUB(micro_wheelup, $mult)
CALL ("micro_com.dll", $com, 100663296 + $mult)
END_SUB
//keydown
SUB(micro_keydown, $char_ASCII)
CALL ("micro_com.dll", $com, 117440512 + code($char_ASCII))
END_SUB
//keyup
SUB(micro_keyup, $char_ASCII)
CALL ("micro_com.dll", $com, 134217728 + code($char_ASCII))
END_SUB
//keypress
SUB(micro_keypress, $char_ASCII)
CALL ("micro_com.dll", $com, 150994944 + code($char_ASCII))
END_SUB
Даже и не уверен, придумают ли защиту от такого аппаратного управления машиной .
Подключайтесь, проверяйте. Я проверил и использовал лишь в одной защищенной древнючей игре MTA_SA. Не смотря на ее древнючесть, они уже давно впилили защиту от кликеров. Сам контроллер не сильно и дорогой, глянул - от 350р. Я вроде еще за 280 когда-то купил.
Скачать dll для х32 систем: micro_com.dll (133 КБ)
А теперь поподробнее, с чего начинать, что купить, как прошить, как запустить...
1. Нам нужен сам контроллер ардуино. Подойдут только те, которые определяются на ПК как мышь и клавиатура. Те, о которых я в курсе - Arduino Micro, Arduino Pro Micro, Arduino Leonardo.
2. Подключаем наш девайс к ПК в любой USB. Смотрим в диспетчер устройств. Должно появиться три новых устройства - клавиатура HID, HID совместимая мышь, устройство с последовательным интерфейсом USB (COM). Номер COM порта запоминаем.
3. Далее нужно прошить наш контроллер. Для этого нужен софт. Качаем с оффсайта ардуино последнюю версию Arduino IDE https://www.arduino.cc/en/software . Я использую портативную версию для windows - "Windows ZIP file". Она не требует установки, просто распаковать из архива, и готово, можно пользоваться.
4. Настраиваем IDE под наш контроллер. Меню - инструменты - плата: - Arduino Micro, либо Leonardo в зависимости от того что там у вас. Меню - инструменты - порт: - выбираем порт к которому подключен контроллер.
5. Все, можно загружать скетч. Берем тот что я написал, либо пишите свой. Мой:
Код скетча:
#include <mouse.h>
#include <keyboard.h>
unsigned long par = 0;
String instring = "";
int kmfunct = 0;
int x_cor = 0;
int y_cor = 0;
int mult = 0;
int inchar = 0;
void setup() {
Serial.begin(9600);
Mouse.begin();
Keyboard.begin();
}
void loop() {
while(Serial.available() > 0){
inchar = Serial.read();
if (isDigit(inchar)) {
instring += (char)inchar;
}
}
par = instring.toInt();
instring = "";
if (par > 0) {
kmfunct = par/16777216 ;
switch (kmfunct) {
case 1: //Mouse.click
Mouse.click(par - kmfunct*16777216);
break;
case 2: // Mouse.move
x_cor = (par - kmfunct*16777216)/256;
y_cor = par - x_cor*256 - kmfunct*16777216;
if (x_cor > 127) x_cor = 127 - x_cor;
if (y_cor > 127) y_cor = 127 - y_cor;
Mouse.move(x_cor, y_cor, 0);
break;
case 3: //Mouse.press
Mouse.press(par - kmfunct*16777216);
break;
case 4: //Mouse.release
Mouse.release(par - kmfunct*16777216);
break;
case 5: //Mouse.dblclick
Mouse.click(par - kmfunct*16777216);
delay(50);
Mouse.click(par - kmfunct*16777216);
break;
case 6: //wheel.down.up
mult = par - kmfunct*16777216;
if (mult > 127) mult = 127 - mult;
Mouse.move(0, 0, mult);
case 7: // Keyboard.keydown
Keyboard.press(par - kmfunct*16777216);
break;
case 8: // Keyboard.keyup
Keyboard.release(par - kmfunct*16777216);
break;
case 9: // Keyboard.keypress
Keyboard.write(par - kmfunct*16777216);
break;
}
}
par = 0;
}
</keyboard.h></mouse.h>
Копируете и вставляете в редактор arduino. Жмете кнопку "проверить", пойдет компиляция скетча. После завершения в логе будет что-то типа:
Скетч использует 7426 байт (25%) памяти устройства. Всего доступно 28672 байт.
Глобальные переменные используют 265 байт (10%) динамической памяти, оставляя 2295 байт для локальных переменных. Максимум: 2560 байт.
Значит все отлично, жмем кнопку "загрузка" и ждем пока скетч загрузится в контроллер. Если все в норме, то по итогу в логе будет: загрузка завершена, и тоже самое что и после проверки.
6. Контроллер готов и ждет команды из COM порта. Для отправки сообщения в наш порт я написал DLL библиотеку "micro_com.dll". Берем во вложении первого поста, либо вот с ядиска https://disk.yandex.ru/d/YuMXDEFLhWiD6A . Качаем (либо копируем) библиотеку с процедурами мыши и клавиатуры для Clickermann "Arduino_mouse_keyboard.cms" , во вложении, либо код из поста выше, либо с ядиска https://disk.yandex.ru/d/kmqlsabjb4RJvg . Кидаем эти два файла в одну папку. Открываем "Arduino_mouse_keyboard.cms" и прописываем в переменную $com номер порта, к которому подключена ардуина.
7. Создаем наш основной скрипт, либо редактируем уже существующий. Подключаем в него "Arduino_mouse_keyboard.cms".
Код: Clickermann
#include "Arduino_mouse_keyboard.cms"
Все процедуры, которые я пока написал:
Код: Clickermann
//micro_move($x_cor, $y_cor)
//micro_lclick($x_cor, $y_cor)
//micro_rclick($x_cor, $y_cor)
//micro_mclick($x_cor, $y_cor)
//micro_ldown($x_cor, $y_cor)
//micro_rdown($x_cor, $y_cor)
//micro_mdown($x_cor, $y_cor)
//micro_lup($x_cor, $y_cor)
//micro_rup($x_cor, $y_cor)
//micro_mup($x_cor, $y_cor)
//micro_dblclick($x_cor, $y_cor)
//micro_wheeldown($mult)
//micro_wheelup($mult)
// вместо $char_ASCII писать не код клавиши, а символ ASCII.
// в ардуино как-то тупо сделали клавиатурные нажатия :/
// пока поддерживают только печатные символы, в будущем добавлю подпрограмму для клавиш-модификаторов.
//micro_keydown($char_ASCII)
//micro_keyup($char_ASCII)
//micro_keypress($char_ASCII)
Ну и для проверки можно подергать курсором. Пишем к примеру такой код:
Код: Clickermann
#include "Arduino_mouse_keyboard.cms"
WAIT(2)
micro_move(100, 100)
WAIT(2)
micro_move(500, 500)
WAIT(2)
micro_move(500, 100)
WAIT(2)
micro_move(100, 100)
HALT
Жмем "применить" и сохраняем скрипт в папку с "micro_com.dll" и "Arduino_mouse_keyboard.cms". Запускаем и смотрим как курсор двигается по прописанным координатам.
8. Радуемся.
Если курсор не двигается, то ищем где мы накосячили. DLL может помочь в этом. Функция из библиотеки возвращает код, сообщая, на каком моменте остановилась работа по общению с COM портом. Если все в норме, функция должна возвратить "5"
Код: Clickermann
#include "Arduino_mouse_keyboard.cms"
WAIT(2)
micro_move(100, 100)
PRINT($_return1) //должно быть "5", иначе - пишите в этой теме, и подумаем в чем ошибка.
HALT
Подробно о библиотеках Mouse и Keyboard для ардуино тут - https://doc.arduino.ua/ru/prog/MouseKeyboard либо на оффсайте на английском.
Коды клавиш-модификаторов тут - https://doc.arduino.ua/ru/prog/KeyboardModifiers. Для них нужно будет писать отдельную подпрограмму, либо вызывать индивидуально.
DLL написана для х32 систем, соответственно версия кликермана должна быть х32!!!
Вот библиотека для всех версий (кроме х64), включая 4.13 и старше. Написал основные клавиши и клавиши модификаторы. Не достающие клавиши можете дописать сами.
Код: Clickermann
$com = 5 //свой порт
//"Arduino_mouse&keyboard" для версии 4.13 и старше.
////////////////////////////////////////////////
// Все процедуры с мышью и клавиатурой через ардуино
//micro_move ($x_cor, $y_cor)
//micro_lclick ($x_cor, $y_cor)
//micro_rclick ($x_cor, $y_cor)
//micro_mclick ($x_cor, $y_cor)
//micro_ldown ($x_cor, $y_cor)
//micro_rdown ($x_cor, $y_cor)
//micro_mdown ($x_cor, $y_cor)
//micro_lup ($x_cor, $y_cor)
//micro_rup ($x_cor, $y_cor)
//micro_mup ($x_cor, $y_cor)
//micro_dblclick ($x_cor, $y_cor)
//micro_wheeldown ($mult)
//micro_wheelup ($mult)
//micro_keydown (key_)
//micro_keyup (key_)
//micro_keypress (key_)
//коды клавиш, если чегото не хватает, дописывайте сами.
#define key_0:49
#define key_1:50
#define key_2:51
#define key_3:52
#define key_4:53
#define key_5:54
#define key_6:55
#define key_7:56
#define key_8:57
#define key_9:58
#define key_a:97
#define key_b:98
#define key_c:99
#define key_d:100
#define key_e:101
#define key_f:102
#define key_g:103
#define key_h:104
#define key_i:105
#define key_j:106
#define key_k:107
#define key_l:108
#define key_m:109
#define key_n:110
#define key_o:111
#define key_p:112
#define key_q:113
#define key_r:114
#define key_s:115
#define key_t:116
#define key_u:117
#define key_v:118
#define key_w:119
#define key_x:120
#define key_y:121
#define key_z:122
#define KEY_LEFT_CTRL:128
#define KEY_LEFT_SHIFT:129
#define KEY_LEFT_ALT:130
#define KEY_LEFT_GUI:131
#define KEY_RIGHT_CTRL:132
#define KEY_RIGHT_SHIFT:133
#define KEY_RIGHT_ALT:134
#define KEY_RIGHT_GUI:135
#define KEY_UP_ARROW:218
#define KEY_DOWN_ARROW:217
#define KEY_LEFT_ARROW:216
#define KEY_RIGHT_ARROW:215
#define KEY_BACKSPACE:178
#define KEY_TAB:179
#define KEY_RETURN:176
#define KEY_ESC:177
#define KEY_INSERT:209
#define KEY_DELETE:212
#define KEY_PAGE_UP:211
#define KEY_PAGE_DOWN:214
#define KEY_HOME:210
#define KEY_END:213
#define KEY_CAPS_LOCK:193
#define KEY_F1:194
#define KEY_F2:195
#define KEY_F3:196
#define KEY_F4:197
#define KEY_F5:198
#define KEY_F6:199
#define KEY_F7:200
#define KEY_F8:201
#define KEY_F9:202
#define KEY_F10:203
#define KEY_F11:204
#define KEY_F12:205
//move
SUB(micro_move, $x_cor, $y_cor)
WHILE(DIST($x_cor, $y_cor, $_xmouse, $_ymouse) > 3)
$x_temp = $_xmouse
$y_temp = $_ymouse
$x_dist = $x_cor - $_xmouse
$y_dist = $y_cor - $_ymouse
IF($x_dist < 0)
$x_dist = 127 + int(SQRT(ABS($x_dist*4)))
else
$x_dist = int(SQRT(ABS($x_dist*4)))
END_IF
IF($y_dist < 0)
$y_dist = 127 + int(SQRT(ABS($y_dist*4)))
else
$y_dist = int(SQRT(ABS($y_dist*4)))
END_IF
CALL ("micro_com.dll", $com, 33554432 + $x_dist*256 + $y_dist)
END_CYC
END_SUB
//lclick
SUB(micro_lclick, $x_cor, $y_cor)
micro_move($x_cor, $y_cor)
CALL ("micro_com.dll", $com, 16777217)
END_SUB
//rclick
SUB(micro_rclick, $x_cor, $y_cor)
micro_move($x_cor, $y_cor)
CALL ("micro_com.dll", $com, 16777218)
END_SUB
//mclick
SUB(micro_mclick, $x_cor, $y_cor)
micro_move($x_cor, $y_cor)
CALL ("micro_com.dll", $com, 16777219)
END_SUB
//ldown
SUB(micro_ldown, $x_cor, $y_cor)
micro_move($x_cor, $y_cor)
CALL ("micro_com.dll", $com, 50331649)
END_SUB
//rdown
SUB(micro_rdown, $x_cor, $y_cor)
micro_move($x_cor, $y_cor)
CALL ("micro_com.dll", $com, 50331650)
END_SUB
//mdown
SUB(micro_mdown, $x_cor, $y_cor)
micro_move($x_cor, $y_cor)
CALL ("micro_com.dll", $com, 50331651)
END_SUB
//lup
SUB(micro_lup, $x_cor, $y_cor)
micro_move($x_cor, $y_cor)
CALL ("micro_com.dll", $com, 67108865)
END_SUB
//rup
SUB(micro_rup, $x_cor, $y_cor)
micro_move($x_cor, $y_cor)
CALL ("micro_com.dll", $com, 67108866)
END_SUB
//mup
SUB(micro_mup, $x_cor, $y_cor)
micro_move($x_cor, $y_cor)
CALL ("micro_com.dll", $com, 67108867)
END_SUB
//dblclick
SUB(micro_dblclick, $x_cor, $y_cor)
micro_move($x_cor, $y_cor)
CALL ("micro_com.dll", $com, 83886081)
END_SUB
//wheeldown
SUB(micro_wheeldown, $mult)
CALL ("micro_com.dll", $com, 100663423 + $mult)
END_SUB
//wheelup
SUB(micro_wheelup, $mult)
CALL ("micro_com.dll", $com, 100663296 + $mult)
END_SUB
//keydown
SUB(micro_keydown, $key_)
CALL ("micro_com.dll", $com, 117440512 + int($key_))
END_SUB
//keyup
SUB(micro_keyup, $key_)
CALL ("micro_com.dll", $com, 134217728 + int($key_))
END_SUB
//keypress
SUB(micro_keypress, $key_)
CALL ("micro_com.dll", $com, 150994944 + int($key_))
END_SUB
Пример по использованию:
Код: Clickermann
#include "Arduino_mouse_keyboard.cms"
//контроллер выделяет текст активного окна и удаляет его
WAIT(1)
micro_keydown(KEY_RIGHT_CTRL) //зажимает левый контрал
micro_keydown(key_a) //зажимает клавишу"A"
WAITMS(100)
micro_keyup(key_a) //отпускает клавишу"A"
micro_keyup(KEY_RIGHT_CTRL) //отпускает левый контрал
WAITMS(100)
micro_keypr...
Добавленные клавиши:
Код: Text
key_0
key_1
key_2
key_3
key_4
key_5
key_6
key_7
key_8
key_9
key_a
key_b
key_c
key_d
key_e
key_f
key_g
key_h
key_i
key_j
key_k
key_l
key_m
key_n
key_o
key_p
key_q
key_r
key_s
key_t
key_u
key_v
key_w
key_x
key_y
key_z
KEY_LEFT_CTRL
KEY_LEFT_SHIFT
KEY_LEFT_ALT
KEY_LEFT_GUI
KEY_RIGHT_CTRL
KEY_RIGHT_SHIFT
KEY_RIGHT_ALT
KEY_RIGHT_GUI
KEY_UP_ARROW
KEY_DOWN_ARROW
KEY_LEFT_ARROW
KEY_RIGHT_ARROW
KEY_BACKSPACE
KEY_TAB
KEY_RETURN
KEY_ESC
KEY_INSERT
KEY_DELETE
KEY_PAGE_UP
KEY_PAGE_DOWN
KEY_HOME
KEY_END
KEY_CAPS_LOCK
KEY_F1
KEY_F2
KEY_F3
KEY_F4
KEY_F5
KEY_F6
KEY_F7
KEY_F8
KEY_F9
KEY_F10
KEY_F11
KEY_F12
Вот такой прикольный корпус есть для ардуинки