Здравствуйте, гость ( Вход | Регистрация )

8 страниц V < 1 2 3 4 > »   
Ответить в эту темуОткрыть новую тему
> Pilot + Arduino (Hardware clicker)
Crocotea
сообщение 18.11.2020, 17:30
Сообщение #21


***

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
[+]

Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
DarkMaster
сообщение 18.11.2020, 18:15
Сообщение #22


***********

Модератор UOPilot
Сообщений: 9.462
Регистрация: 2.12.2008
Группа: Супермодераторы
Наличность: 27674
Пользователь №: 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____
Пользователь в онлайне!Delete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
Cockney
сообщение 18.11.2020, 18:35
Сообщение #23


********

Master
Сообщений: 1.395
Регистрация: 22.6.2013
Группа: Пользователи
Наличность: 21043
Пользователь №: 16.156



Оно и сейчас себя ожидаемо ведет. Мы прочитали первый буффер, где задержка, управляющие клавиши и начали исполнять нажатия. А тем временем в буффер пришли другие данные, которые мы считаем просто символами.


Можно попробовать ловить \0, но мне кажется что не все так очевидно.
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
DarkMaster
сообщение 18.11.2020, 18:56
Сообщение #24


***********

Модератор UOPilot
Сообщений: 9.462
Регистрация: 2.12.2008
Группа: Супермодераторы
Наличность: 27674
Пользователь №: 11.279



Оно просто в буффер накидывает быстрее, чем ты считываешь и по фактку получается буфере строка:
"100||4100||s"
и так далее. Он и ведет себя соответственно. Без флагов завершения ты никак это не отловишь нормально имхо.
Ну хотя бы получив такую бяку в буфер где ты будешь разбивать на куски? Ладно еще 4100, а если там будет 1234? Сколько задержка? 234? 34? 4?
Одиночные 4 и s он отправляет корректно просто потому, что там есть магический wait(100) внутри цикла и железка просто успевает выгрести весь буфер.

Crocotea, рекомендую на досуге поразвлекаться с SERIAL_READ_DELAY в сторону уменьшения. Это может снизить задержку отправки нажатий, которая зачастую вредит скорости реакции скрипта и его стабильности.

Сообщение отредактировал DarkMaster - 18.11.2020, 18:57


--------------------
Скрипты UOPilot под заказ.
Консультации по UOpilot 15$/час.
Услуги Lua разработчика (не пилот, проекты, постоянка)
Disсоrd:
Kov____
Пользователь в онлайне!Delete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
Cockney
сообщение 18.11.2020, 19:15
Сообщение #25


********

Master
Сообщений: 1.395
Регистрация: 22.6.2013
Группа: Пользователи
Наличность: 21043
Пользователь №: 16.156



Я вроде примерно тоже самое и описал. Мои соображения: сделать набор состояний и при считывании нового байта определять что с ним делать. Конечный автомат в общем. там и буффер тогда не потребуется. Ну если только под задержку. А дальше на лету будем отправлять все.
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
DarkMaster
сообщение 18.11.2020, 19:21
Сообщение #26


***********

Модератор UOPilot
Сообщений: 9.462
Регистрация: 2.12.2008
Группа: Супермодераторы
Наличность: 27674
Пользователь №: 11.279



Ну дык и я о том же.
Едиственное экран на всяких случай сделать - все равно примитив.


--------------------
Скрипты UOPilot под заказ.
Консультации по UOpilot 15$/час.
Услуги Lua разработчика (не пилот, проекты, постоянка)
Disсоrd:
Kov____
Пользователь в онлайне!Delete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
Crocotea
сообщение 18.11.2020, 21:24
Сообщение #27


***

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()
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
DarkMaster
сообщение 18.11.2020, 21:45
Сообщение #28


***********

Модератор UOPilot
Сообщений: 9.462
Регистрация: 2.12.2008
Группа: Супермодераторы
Наличность: 27674
Пользователь №: 11.279



Цитата
Задержка через сам пилот не увеличивается, только через wait()

ибо луа


--------------------
Скрипты UOPilot под заказ.
Консультации по UOpilot 15$/час.
Услуги Lua разработчика (не пилот, проекты, постоянка)
Disсоrd:
Kov____
Пользователь в онлайне!Delete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
Crocotea
сообщение 19.11.2020, 0:50
Сообщение #29


***

Novice
Сообщений: 51
Регистрация: 30.10.2020
Группа: Пользователи
Наличность: 0
Пользователь №: 19.787



Подскажите, при параллельном запуске 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()

Как ее исправить?

А кстати, как нижимать клавиши esc, space, f1,f2...?
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
DarkMaster
сообщение 19.11.2020, 2:29
Сообщение #30


***********

Модератор UOPilot
Сообщений: 9.462
Регистрация: 2.12.2008
Группа: Супермодераторы
Наличность: 27674
Пользователь №: 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____
Пользователь в онлайне!Delete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
Crocotea
сообщение 21.11.2020, 4:23
Сообщение #31


***

Novice
Сообщений: 51
Регистрация: 30.10.2020
Группа: Пользователи
Наличность: 0
Пользователь №: 19.787



Цитата(DarkMaster @ 19.11.2020, 2:29) *

Скан коды клавиш для этого нужно смотреть. Ну и дальше 0xЦИФЕРКА


не работает sendKey ("100||0x1"), пробовал коды 0x1,0x01, 0x1B, 0x76, 0x81

да подскажи пж парсинг для работы в несколько скриптов. в 1 просто ужас как усложняет жизнь

И подскажите по есть ли возможность оптимизировать теперь работу?))
есть ряд очень важных моментов, которые хотелось бы как-нибудь по фиксить. т.к. из-за них пользоваться пилотом ну очень сложно. Если можно, то писать сюда?
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
DarkMaster
сообщение 21.11.2020, 4:39
Сообщение #32


***********

Модератор UOPilot
Сообщений: 9.462
Регистрация: 2.12.2008
Группа: Супермодераторы
Наличность: 27674
Пользователь №: 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____
Пользователь в онлайне!Delete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
Crocotea
сообщение 21.11.2020, 5:18
Сообщение #33


***

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 уменьшить.
Если касательно железки - сюда. Другие вопросы - создайте тему, вас никто за это не покусает)

Хорошо я тогда позже распишу. Просто сейчас работать работает, но в некоторый моментах приходится столько лишних действий делать
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
Cockney
сообщение 22.11.2020, 2:18
Сообщение #34


********

Master
Сообщений: 1.395
Регистрация: 22.6.2013
Группа: Пользователи
Наличность: 21043
Пользователь №: 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);
    }
}

Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
DarkMaster
сообщение 22.11.2020, 4:17
Сообщение #35


***********

Модератор UOPilot
Сообщений: 9.462
Регистрация: 2.12.2008
Группа: Супермодераторы
Наличность: 27674
Пользователь №: 11.279



Ну и предвосхищая возможные вопросы/проблемы рекомендую обновить функцию пилота:
Код
--lua
local function sendKey (symbol)
    file = io.open("COM7","w")  --меняем только номер COM порта, остальное не трогаем
    file:write(symbol..string.char (0x0))
    file:close()
end



--------------------
Скрипты UOPilot под заказ.
Консультации по UOpilot 15$/час.
Услуги Lua разработчика (не пилот, проекты, постоянка)
Disсоrd:
Kov____
Пользователь в онлайне!Delete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
cirus
сообщение 22.11.2020, 4:34
Сообщение #36


**********

Elder
Сообщений: 3.480
Регистрация: 18.8.2014
Группа: Пользователи
Наличность: 26689
Пользователь №: 16.971
Возраст: 29



Неплохо бы проверять открылся ли порт, если не откроется, то попытка закрыть приведёт к ошибке.
Код
--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
Пользователь в онлайне!Delete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
DarkMaster
сообщение 22.11.2020, 4:37
Сообщение #37


***********

Модератор UOPilot
Сообщений: 9.462
Регистрация: 2.12.2008
Группа: Супермодераторы
Наличность: 27674
Пользователь №: 11.279



Цитата
Неплохо бы проверять открылся ли порт, если не откроется, то попытка закрыть приведёт к ошибке.

Тогда надо и возвращать ошибку и мониторить возврат на каждом вызове и останавливать скрипт, если была ошибка. Имхо уж пусть лучше сразу кританет, чем писать доп обвязку с теми же самыми еррорами.

Самое забавное будет с проверкой порта, когда человек будет отсылать и не пониммать а чего оно ваще не работает и что с этим делать) оно же тупо молчит, ерроров не пишет)


--------------------
Скрипты UOPilot под заказ.
Консультации по UOpilot 15$/час.
Услуги Lua разработчика (не пилот, проекты, постоянка)
Disсоrd:
Kov____
Пользователь в онлайне!Delete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
cirus
сообщение 22.11.2020, 4:46
Сообщение #38


**********

Elder
Сообщений: 3.480
Регистрация: 18.8.2014
Группа: Пользователи
Наличность: 26689
Пользователь №: 16.971
Возраст: 29



Цитата
Самое забавное будет с проверкой порта, когда человек будет отсылать и не пониммать а чего оно ваще не работает и что с этим делать) оно же тупо молчит, ерроров не пишет)

На плате лампочки мигают когда что-то приходит в порт или отправляется с него.
Пользователь в онлайне!Delete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
Crocotea
сообщение 22.11.2020, 12:40
Сообщение #39


***

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))
как-то так


все также не работает((
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
Cockney
сообщение 22.11.2020, 13:31
Сообщение #40


********

Master
Сообщений: 1.395
Регистрация: 22.6.2013
Группа: Пользователи
Наличность: 21043
Пользователь №: 16.156



что именно не так работает ?
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения

8 страниц V < 1 2 3 4 > » 
Ответить в эту темуОткрыть новую тему
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 

- Текстовая версия | Версия для КПК Сейчас: 16.4.2024, 14:26
Designed by Nickostyle