|
|
|
Pilot + Arduino (Hardware clicker) |
|
|
Crocotea |
18.11.2020, 17:30
|
Novice
Сообщений: 51
Регистрация: 30.10.2020 Группа: Пользователи Наличность: 0
Пользователь №: 19.787
|
Цитата(Cockney @ 18.11.2020, 12:50) Версия №4
Код #include <Keyboard.h> #include <stdlib.h>
// Максимальный размер буффера #define MAX_BUFFER_SIZE 20 // Порт #define SERIAL_PORT 9600 // Задержка считывания с порта #define SERIAL_READ_DELAY 5 // Задержка нажатия клавиш по умолчанию #define DEFAULT_SEND_DELAY 0
void setup() { Serial.begin(SERIAL_PORT); Keyboard.begin(); }
void loop() { // буффер под коммандную строку char buffer[MAX_BUFFER_SIZE]; // размер полученного буфера int buffSize = 0; // текущая позиция в буффере int buffPos = 0; // задержка нажатия клавиш int send_delay_value = DEFAULT_SEND_DELAY;
// Собираем информацию из порта while (Serial.available() && buffSize < MAX_BUFFER_SIZE) { buffer[buffSize++] = Serial.read(); delay(SERIAL_READ_DELAY); }
// если данные пришли if (buffSize > 0) { // пытаемся сначала выбрать задержку send_delay_value = parseSendDelay(&buffPos, buffer, buffSize); // разбор и нажатие контрольных клавиш sendControlKeys(&buffPos, buffer, buffSize); // нажатие клавиш while (buffPos < buffSize) { delay(send_delay_value); Keyboard.print(buffer[buffPos++]); };
// очистка Keyboard.releaseAll(); buffPos = 0; buffSize = 0; } }
// парсинг задержки отправки клавиш int parseSendDelay(int* curPos, char* buff, int buffSize) { // идем по полученным данным пока не встретим разделитель while (buff[*curPos] != '|') { ++*curPos; } // далее получаем задержку в числовом виде // не очень красиво, но должно работать.
// заменяем | на символ конца строки buff[*curPos] = '\0'; // получаем задержку int parsedDelay = atoi(buff); // возвращаем если нужно //data[*curPos] = '\|'; // пропуск разделителя ++*curPos;
//возврат return parsedDelay; }
// парсинг клавиши int parseKey(int *curPos, const char *buff, int buffSize) { switch (buff[*curPos]) { case '^': return KEY_LEFT_CTRL; case '@': return KEY_LEFT_ALT; case '~': return KEY_LEFT_SHIFT; default: return -1; } } // нажатие контрольных клавиш void sendControlKeys(int *curPos, const char* buff, int buffSize) { // пока не встретили разделитель while (buff[*curPos] != '|') { // попытка распарсить управляющую клавишу int key = parseKey(curPos, buff, buffSize); // если успешно if (key > 0) { Keyboard.press(key); } // следующий байт ++*curPos; } // пропускаем разделитель ++*curPos; }
Такс, новый видосик теста. нестабильно работает с 1:20
|
|
|
|
DarkMaster |
18.11.2020, 18:15
|
Модератор UOPilot
Сообщений: 9.573
Регистрация: 2.12.2008 Группа: Супермодераторы Наличность: 28549
Пользователь №: 11.279
|
Предлагаю в: Код --lua local function sendKey (symbol) file = io.open("COM7","w") --меняем только номер COM порта, остальное не трогаем file:write(symbol) file:close() end Допилить до Код file:write(symbol .. string.char(0)) И ловить этот 0x0 с чистой совесть и закрывать очередь. Есть еще один коронный вариант - изменить синтаксис до: |задержка| -- для установки задержки. Нафига ее каждый раз отправлять то? Все остальное тупо отправлять и в вызове из пилота указывать только полезную нагрузку. ~@^ заменять на соответсвующие управляющие клавиши. Предыдущий символ хранить в отдельной переменной и если он равен "\" игнорить замену. При таком раскладе оно хотя бы ожидаемо вести себя будет =)
--------------------
Скрипты UOPilot под заказ. Консультации по UOpilot 15$/час. Услуги Lua разработчика (не пилот, проекты, постоянка) Disсоrd: Kov____
|
|
|
|
Crocotea |
18.11.2020, 21:24
|
Novice
Сообщений: 51
Регистрация: 30.10.2020 Группа: Пользователи Наличность: 0
Пользователь №: 19.787
|
Цитата Crocotea, рекомендую на досуге поразвлекаться с SERIAL_READ_DELAY в сторону уменьшения. Это может снизить задержку отправки нажатий, которая зачастую вредит скорости реакции скрипта и его стабильности. sendKey ("1||4") wait(100) sendKey ("1||s") wait(100) sendKey ("1||dddddd") wait(100) sendKey ("1||f") Так работает полностью корректно. Задержка через сам пилот не увеличивается, только через wait()
|
|
|
|
DarkMaster |
19.11.2020, 2:29
|
Модератор UOPilot
Сообщений: 9.573
Регистрация: 2.12.2008 Группа: Супермодераторы Наличность: 28549
Пользователь №: 11.279
|
Цитата А кстати, как нижимать клавиши esc, space, f1,f2...? Скан коды клавиш для этого нужно смотреть. Ну и дальше 0xЦИФЕРКА Цитата Подскажите, при параллельном запуске 2 скриптов возникает такая ошибка 4: attempt to index global 'file' (a nil value) --lua local function sendKey (symbol) file = io.open("COM5","w") --меняем только номер COM порта, остальное не трогаем file:write(symbol) file:close()
А вот с этим уже гораздо сложнее. Насколько я помню открыть ком порт сразу в несколько потоков невозможно. Но даже если мы его откроем в несколько потоков, то в буфер у нас рано или поздо прилетит мешанина из двух команд в произвольном порядке. Правильный вариант тут сделующий и он вам не понравится: Создаем третий скрипт, в нем открываем порт через luasocket, через открытый порт ловим N входящих соединений и создаем очередь отсылок в железку и потом уже отсылаем вот этим третьим скриптом через com. Причем в этом третьем скрипте нужно будет так же сделать парсер, но тут уже проще имхо. Т.е. смысл в том, что это будет делаться все равно в один поток, но скрипта будет два и для них все будет выглядеть прозрачно. Сообщение отредактировал DarkMaster - 19.11.2020, 2:30
--------------------
Скрипты UOPilot под заказ. Консультации по UOpilot 15$/час. Услуги Lua разработчика (не пилот, проекты, постоянка) Disсоrd: Kov____
|
|
|
|
Crocotea |
21.11.2020, 4:23
|
Novice
Сообщений: 51
Регистрация: 30.10.2020 Группа: Пользователи Наличность: 0
Пользователь №: 19.787
|
Цитата(DarkMaster @ 19.11.2020, 2:29) Скан коды клавиш для этого нужно смотреть. Ну и дальше 0xЦИФЕРКА
не работает sendKey ("100||0x1"), пробовал коды 0x1,0x01, 0x1B, 0x76, 0x81 да подскажи пж парсинг для работы в несколько скриптов. в 1 просто ужас как усложняет жизнь И подскажите по есть ли возможность оптимизировать теперь работу?)) есть ряд очень важных моментов, которые хотелось бы как-нибудь по фиксить. т.к. из-за них пользоваться пилотом ну очень сложно. Если можно, то писать сюда?
|
|
|
|
DarkMaster |
21.11.2020, 4:39
|
Модератор UOPilot
Сообщений: 9.573
Регистрация: 2.12.2008 Группа: Супермодераторы Наличность: 28549
Пользователь №: 11.279
|
Цитата sendKey ("100||0x1") sendKey ("100||"..string.char (0x1)) как-то так Цитата да подскажи пж парсинг для работы в несколько скриптов. в 1 просто ужас как усложняет жизнь
Вот прям точно нужно?) Там не только парсер. Там еще клиент-сервер tcp нужно =) Цитата И подскажите по есть ли возможность оптимизировать теперь работу?)) Ну я жду фиксов от Cockney. Что там править еще есть. Если касательно именно оптимизации - я уже говорил, что можно покрутить задержи в сторону уменьшения. Там 5 по умолчанию. Я бы попробовал до 1 уменьшить. Цитата есть ряд очень важных моментов, которые хотелось бы как-нибудь по фиксить. т.к. из-за них пользоваться пилотом ну очень сложно. Если можно, то писать сюда? Если касательно железки - сюда. Другие вопросы - создайте тему, вас никто за это не покусает) Сообщение отредактировал DarkMaster - 21.11.2020, 4:40
--------------------
Скрипты UOPilot под заказ. Консультации по UOpilot 15$/час. Услуги Lua разработчика (не пилот, проекты, постоянка) Disсоrd: Kov____
|
|
|
|
Crocotea |
21.11.2020, 5:18
|
Novice
Сообщений: 51
Регистрация: 30.10.2020 Группа: Пользователи Наличность: 0
Пользователь №: 19.787
|
Цитата(DarkMaster @ 21.11.2020, 4:39) sendKey ("100||"..string.char (0x1)) как-то так
Не работает прямо от слова совсем( подставил все те же цифеки Цитата(DarkMaster @ 21.11.2020, 4:39) Вот прям точно нужно?) Там не только парсер. Там еще клиент-сервер tcp нужно =)
желательно) попытка не пытка. ну пока не так жизненно важно Цитата(DarkMaster @ 21.11.2020, 4:39) Ну я жду фиксов от Cockney. Что там править еще есть. Если касательно именно оптимизации - я уже говорил, что можно покрутить задержи в сторону уменьшения. Там 5 по умолчанию. Я бы попробовал до 1 уменьшить. Если касательно железки - сюда. Другие вопросы - создайте тему, вас никто за это не покусает)
Хорошо я тогда позже распишу. Просто сейчас работать работает, но в некоторый моментах приходится столько лишних действий делать
|
|
|
|
Cockney |
22.11.2020, 2:18
|
Master
Сообщений: 1.402
Регистрация: 22.6.2013 Группа: Пользователи Наличность: 21917
Пользователь №: 16.156
|
Вообще не точно.... Теперь задержка указывается по дефолту в виде [<задержка>] в любом месте. Как только встречаем @,^,~ - зажимаем контрольные кнопки Так же работает экран для них и для скобок через которые указывается задержка. Ну и проверка на \0 присутствует. Версия №5
Код #include <Keyboard.h> #include <stdlib.h>
/* Настройки железки*/ #define MAX_BUFFER_SIZE 20 // Максимальный размер буффера #define SERIAL_PORT 9600 // Порт #define SERIAL_READ_DELAY 5 // Задержка считывания с порта #define DEFAULT_SEND_DELAY 0 // Задержка нажатия клавиш по умолчанию
/* Кастомизация спец. символов */ #define SEND_DELAY_START_CHAR '[' #define SEND_DELAY_END_CHAR ']' #define CONTROL_KEY_CTRL_CHAR '^' #define CONTROL_KEY_ALT_CHAR '@' #define CONTROL_KEY_SHIFT_CHAR '~' #define ESCAPE_CHAR '\\' #define EOF_CHAR '\0'
/* Ввод парсера (для построения матрицы) */ #define SEND_DELAY_START_INPUT 0 #define SEND_DELAY_END_INPUT 1 #define CONTROL_KEY_CTRL_INPUT 2 #define CONTROL_KEY_ALT_INPUT 3 #define CONTROL_KEY_SHIFT_INPUT 4 #define ESCAPE_CHAR_INPUT 5 #define CHAR_INPUT 6 #define DIGIT_INPUT 7 #define EOF_INPUT 8
#define MAX_INPUT_INDEX EOF_INPUT
/* Состояния парсера */ #define SEND_DELAY_INPUT 0 // начат ввод задержки ввода символов #define ESCAPE_INPUT 1 // начат ввод управляющих клавиш #define SEND_INPUT 2 // начат ввод обычных символов #define SEND_END 3 // ввод окончен
#define MAX_STATE_INDEX SEND_END
/* Глобальные переменные */ int SEND_DELAY_VALUE = DEFAULT_SEND_DELAY; // задержка нажатия клавиш char BUFFER[MAX_BUFFER_SIZE]; // буффер под задержку int BUFFER_POS = 0; // позиция в буффере char ESCAPE_CHAR_VALUE = '\0'; // сохраненный экран
// начать ввод задержки int startSendDelayInput(char c) { return SEND_DELAY_INPUT; }
// закончить ввод задержки и распарсить ее int stopSendDelayInput(char c) { BUFFER[BUFFER_POS + 1] = '\0'; SEND_DELAY_VALUE = atoi(BUFFER); BUFFER_POS = 0; return SEND_INPUT; }
// запись в буффер int storeChar(char c) { if (BUFFER_POS < MAX_BUFFER_SIZE - 2) { BUFFER[BUFFER_POS++] = c; }
// возвращаем новое состояние парсера return SEND_DELAY_INPUT; }
// отправка клавиши int sendChar(char c) { delay(SEND_DELAY_VALUE); Keyboard.print(c); return SEND_INPUT; }
// нажатие контрольной клавиши int sendControlKey(char c) { switch (c) { case CONTROL_KEY_CTRL_CHAR: Keyboard.press(KEY_LEFT_CTRL); break; case CONTROL_KEY_ALT_CHAR: Keyboard.press(KEY_LEFT_ALT); break; case CONTROL_KEY_SHIFT_CHAR: Keyboard.press(KEY_LEFT_SHIFT); break; } return SEND_INPUT; }
// обработка экрана int processEscape(char c) { switch (c) { case SEND_DELAY_START_CHAR: sendChar(c); break; case SEND_DELAY_END_CHAR: sendChar(c); break; case CONTROL_KEY_CTRL_CHAR: sendChar(c); break; case CONTROL_KEY_ALT_CHAR: sendChar(c); break; case CONTROL_KEY_SHIFT_CHAR: sendChar(c); break; default: { // не можем экранировать sendChar(ESCAPE_CHAR_VALUE); sendChar(c); } } return SEND_INPUT; }
// сохранение экрана int storeEscapeChar(char c) { ESCAPE_CHAR_VALUE = c; return ESCAPE_INPUT; }
// конец ввода int stopSend(char c) { BUFFER_POS = 0; Keyboard.releaseAll(); return SEND_END; }
// матрица операций парсера int(*PARSE_ACTION_MAP[MAX_STATE_INDEX + 1][MAX_INPUT_INDEX + 1])(char) = { // SEND_DELAY_INPUT -> { NULL, &stopSendDelayInput, NULL, NULL, NULL, NULL, NULL, &storeChar, &stopSend }, // ESCAPE_INPUT -> { &processEscape, &processEscape, &processEscape, &processEscape, &processEscape, &processEscape, &processEscape, &processEscape, &stopSend }, // SEND_INPUT -> { &startSendDelayInput, &sendChar, &sendControlKey, &sendControlKey, &sendControlKey, &storeEscapeChar, &sendChar, &sendChar, &stopSend }, // SEND_END -> { &startSendDelayInput, &sendChar, &sendControlKey, &sendControlKey, &sendControlKey, &storeEscapeChar, &sendChar, &sendChar, &stopSend } };
// классификатор вводимых символов int getInput(char c) { switch (c) { case SEND_DELAY_START_CHAR: return SEND_DELAY_START_INPUT; case SEND_DELAY_END_CHAR: return SEND_DELAY_END_INPUT; case CONTROL_KEY_CTRL_CHAR: return CONTROL_KEY_CTRL_INPUT; case CONTROL_KEY_ALT_CHAR: return CONTROL_KEY_ALT_INPUT; case CONTROL_KEY_SHIFT_CHAR: return CONTROL_KEY_SHIFT_INPUT; case ESCAPE_CHAR: return ESCAPE_CHAR_INPUT; case EOF_CHAR: return EOF_INPUT; default: if (isdigit(c)) return DIGIT_INPUT; else return CHAR_INPUT; } }
void setup() { Serial.begin(SERIAL_PORT); Keyboard.begin(); }
void loop() { // состояние парсера int parserState = SEND_END;
// если буффер не пустой if (Serial.available()) { // читаем байт из потока char curChar = Serial.read(); // определяем что пришло int input = getInput(curChar); // получаем действие int(*action)(char) = PARSE_ACTION_MAP[parserState][input];
// если действие задано if (action != NULL) parserState = action(curChar); } }
|
|
|
|
Crocotea |
22.11.2020, 12:40
|
Novice
Сообщений: 51
Регистрация: 30.10.2020 Группа: Пользователи Наличность: 0
Пользователь №: 19.787
|
Цитата(cirus @ 22.11.2020, 4:34) Неплохо бы проверять открылся ли порт, если не откроется, то попытка закрыть приведёт к ошибке. Код --lua local function sendKey (symbol) local file = io.open("COM7","w") --меняем только номер COM порта, остальное не трогаем if file then file:write(symbol..string.char (0x0)) file:close() end end оба работают исправно Цитата(Cockney @ 22.11.2020, 2:18) Вообще не точно.... Теперь задержка указывается по дефолту в виде [<задержка>] в любом месте. Как только встречаем @,^,~ - зажимаем контрольные кнопки Так же работает экран для них и для скобок через которые указывается задержка. Ну и проверка на \0 присутствует. Версия №5
Код #include <Keyboard.h> #include <stdlib.h> /* Настройки железки*/ #define MAX_BUFFER_SIZE 20 // Максимальный размер буффера #define SERIAL_PORT 9600 // Порт #define SERIAL_READ_DELAY 5 // Задержка считывания с порта #define DEFAULT_SEND_DELAY 0 // Задержка нажатия клавиш по умолчанию /* Кастомизация спец. символов */ #define SEND_DELAY_START_CHAR '[' #define SEND_DELAY_END_CHAR ']' #define CONTROL_KEY_CTRL_CHAR '^' #define CONTROL_KEY_ALT_CHAR '@' #define CONTROL_KEY_SHIFT_CHAR '~' #define ESCAPE_CHAR '\\' #define EOF_CHAR '\0' /* Ввод парсера (для построения матрицы) */ #define SEND_DELAY_START_INPUT 0 #define SEND_DELAY_END_INPUT 1 #define CONTROL_KEY_CTRL_INPUT 2 #define CONTROL_KEY_ALT_INPUT 3 #define CONTROL_KEY_SHIFT_INPUT 4 #define ESCAPE_CHAR_INPUT 5 #define CHAR_INPUT 6 #define DIGIT_INPUT 7 #define EOF_INPUT 8
#define MAX_INPUT_INDEX EOF_INPUT
/* Состояния парсера */ #define SEND_DELAY_INPUT 0 // начат ввод задержки ввода символов #define ESCAPE_INPUT 1 // начат ввод управляющих клавиш #define SEND_INPUT 2 // начат ввод обычных символов #define SEND_END 3 // ввод окончен
#define MAX_STATE_INDEX SEND_END /* Глобальные переменные */ int SEND_DELAY_VALUE = DEFAULT_SEND_DELAY; // задержка нажатия клавиш char BUFFER[MAX_BUFFER_SIZE]; // буффер под задержку int BUFFER_POS = 0; // позиция в буффере char ESCAPE_CHAR_VALUE = '\0'; // сохраненный экран // начать ввод задержки int startSendDelayInput(char c) { return SEND_DELAY_INPUT; }
// закончить ввод задержки и распарсить ее int stopSendDelayInput(char c) { BUFFER[BUFFER_POS + 1] = '\0'; SEND_DELAY_VALUE = atoi(BUFFER); BUFFER_POS = 0; return SEND_INPUT; }
// запись в буффер int storeChar(char c) { if (BUFFER_POS < MAX_BUFFER_SIZE - 2) { BUFFER[BUFFER_POS++] = c; }
// возвращаем новое состояние парсера return SEND_DELAY_INPUT; }
// отправка клавиши int sendChar(char c) { delay(SEND_DELAY_VALUE); Keyboard.print(c); return SEND_INPUT; }
// нажатие контрольной клавиши int sendControlKey(char c) { switch (c) { case CONTROL_KEY_CTRL_CHAR: Keyboard.press(KEY_LEFT_CTRL); break; case CONTROL_KEY_ALT_CHAR: Keyboard.press(KEY_LEFT_ALT); break; case CONTROL_KEY_SHIFT_CHAR: Keyboard.press(KEY_LEFT_SHIFT); break; } return SEND_INPUT; }
// обработка экрана int processEscape(char c) { switch (c) { case SEND_DELAY_START_CHAR: sendChar(c); break; case SEND_DELAY_END_CHAR: sendChar(c); break; case CONTROL_KEY_CTRL_CHAR: sendChar(c); break; case CONTROL_KEY_ALT_CHAR: sendChar(c); break; case CONTROL_KEY_SHIFT_CHAR: sendChar(c); break; default: { // не можем экранировать sendChar(ESCAPE_CHAR_VALUE); sendChar(c); } } return SEND_INPUT; } // сохранение экрана int storeEscapeChar(char c) { ESCAPE_CHAR_VALUE = c; return ESCAPE_INPUT; }
// конец ввода int stopSend(char c) { BUFFER_POS = 0; Keyboard.releaseAll(); return SEND_END; } // матрица операций парсера int(*PARSE_ACTION_MAP[MAX_STATE_INDEX + 1][MAX_INPUT_INDEX + 1])(char) = { // SEND_DELAY_INPUT -> { NULL, &stopSendDelayInput, NULL, NULL, NULL, NULL, NULL, &storeChar, &stopSend }, // ESCAPE_INPUT -> { &processEscape, &processEscape, &processEscape, &processEscape, &processEscape, &processEscape, &processEscape, &processEscape, &stopSend }, // SEND_INPUT -> { &startSendDelayInput, &sendChar, &sendControlKey, &sendControlKey, &sendControlKey, &storeEscapeChar, &sendChar, &sendChar, &stopSend }, // SEND_END -> { &startSendDelayInput, &sendChar, &sendControlKey, &sendControlKey, &sendControlKey, &storeEscapeChar, &sendChar, &sendChar, &stopSend } }; // классификатор вводимых символов int getInput(char c) { switch (c) { case SEND_DELAY_START_CHAR: return SEND_DELAY_START_INPUT; case SEND_DELAY_END_CHAR: return SEND_DELAY_END_INPUT; case CONTROL_KEY_CTRL_CHAR: return CONTROL_KEY_CTRL_INPUT; case CONTROL_KEY_ALT_CHAR: return CONTROL_KEY_ALT_INPUT; case CONTROL_KEY_SHIFT_CHAR: return CONTROL_KEY_SHIFT_INPUT; case ESCAPE_CHAR: return ESCAPE_CHAR_INPUT; case EOF_CHAR: return EOF_INPUT; default: if (isdigit(c)) return DIGIT_INPUT; else return CHAR_INPUT; } } void setup() { Serial.begin(SERIAL_PORT); Keyboard.begin(); }
void loop() { // состояние парсера int parserState = SEND_END;
// если буффер не пустой if (Serial.available()) { // читаем байт из потока char curChar = Serial.read(); // определяем что пришло int input = getInput(curChar); // получаем действие int(*action)(char) = PARSE_ACTION_MAP[parserState][input];
// если действие задано if (action != NULL) parserState = action(curChar); } }
намного лучше работает. и пользоваться удобнее. спасибо Цитата(DarkMaster @ 21.11.2020, 4:39) sendKey ("100||"..string.char (0x1)) как-то так
все также не работает((
|
|
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|