Как обхитрить тайм трекер при помощи Arduino
Здравствуйте!
Вся моя семья работает удалённо. Супруга работает в крупной организации, в которой осуществляется мониторинг рабочего времени. Мониторинг реагирует на нажатие кнопок клавиатуры и колесо прокрутки мыши, с таймаутом 5 минут. Жена переболела COVID-19 и после болезни стала сильно уставать во время работы, поэтому позволяет себе небольшие перерывчики. На время этих перерывчиков она просит меня покрутить колесико мыши, но я бывает так увлекусь работой, что забываю это сделать. В связи с этим у меня возникло желание автоматизировать этот процесс.
Я вспомнил что у меня валяется Arduino Leonardo, а его легко запрограммировать на имитацию клавиатуры и мыши. Покопавшись в ящиках нашел его и запрограммировал на имитацию колесика мыши. Но жена меня раскритиковала, так как у них запрещается пользоваться не зарегистрированными USB устройствами (а Arduino обязательно вызовет вопросы). Поэтому было решено крутить колесико мыши механически, для чего был заказан шаговый двигатель 28BYJ-48 в комплекте с драйвером двигателя на микросхеме ULN2003 и взят из другого «пыльного» ящика Arduino Nano.
Рисунок 1. Шаговый двигатель 28BYJ-48 с драйвером на микросхеме ULN2003.
Подключил двигатель и кнопку к Arduno, двигатель запитывал как напрямую через Arduino, так и через внешний источник питания. Сейчас двигатель запитывается через Arduino (так меньше проводов висит, а Аrduino это терпит). Написал скетч (как смог) имитирующий прокрутку документа человеком при изучении сложного документа. Прокрутка осуществляется группами то в одну, то в другую сторону через разные промежутки времени. Запустить/остановить процесс скроллинга можно нажатием на кнопку или командами «START», «STOP» переданными по последовательному порту.
Рисунок 2. Схема подключения шагового двигателя (через драйвер) с питанием от Arduino.Рисунок 3. Схема подключения шагового двигателя (через драйвер) с внешним питанием.
#include
#include
#define HALFSTEP 8
// Определение пинов для управления двигателем
#define motorPin1 2 // IN1 на 1-м драйвере ULN2003
#define motorPin2 3 // IN2 на 1-м драйвере ULN2003
#define motorPin3 4 // IN3 на 1-м драйвере ULN2003
#define motorPin4 5 // IN4 на 1-м драйвере ULN2003
// Инициализируемся с последовательностью выводов IN1-IN3-IN2-IN4
// для использования AccelStepper с 28BYJ-48
AccelStepper stepper1(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);
String str = "START";
const int buttonPin = 12; // Номер пина кнопки
const int minMaxSpeed = 800;
const int maxMaxSpeed = 1300;
const int minAcceleration = 500;
const int maxAcceleration = 700;
const int minSpeed = 700;
const int maxSpeed = 1000;
const int move = 600; // примерная длина одного перемещения
const int minPause = 1; // Минимальная пауза между группами прокруток (секунды)
const int maxPause = 3*60; // Максимальная пауза между группами прокруток (секунды)
long pos = 0;
int smove = move;
int sMaxSpeed = maxMaxSpeed;
int sAcceleration = maxAcceleration;
int sSpeed = maxSpeed;
unsigned msec = 1000;
bool PREV = false;
int dir = 50;
int count = 5;
void setup(){
pinMode(LED_BUILTIN, OUTPUT); // Светодиод (красный) для сигнализации (светит - стоп, не светит - работа)
Serial.begin(9600);
Serial.println("start");
stepper1.setMaxSpeed(sMaxSpeed);
stepper1.setAcceleration(sAcceleration);
stepper1.setSpeed(sSpeed);
pinMode(buttonPin, INPUT_PULLUP); // Настройка кнопки
stepper1.move(move);
}
int inputHandler(){ // Чтение команд из порта и отслеживание нажатия кнопки
int res = 0;
if (Serial.available() > 0) {
str=Serial.readString();
str.trim();
Serial.println(">>>>>>>>>>>>>>>>>");
Serial.println(str);
res = 1;
}
buttonState = digitalRead(buttonPin);
if (buttonState == LOW && PREV == HIGH ) {
if (str=="START") {
str = "STOP";
Serial.println("Press button to 'STOP'");
stepper1.move(0);
res = 1;
} else {
str = "START";
Serial.println("Press button to 'START'");
res = 1;
}
delay(150);
}
if (str!="START") {
digitalWrite(LED_BUILTIN, HIGH);
} else {
digitalWrite(LED_BUILTIN, LOW);
}
PREV = buttonState;
return res;
}
int delayWithRead(unsigned ms){ // Пауза с обработкой ввода
Serial.print("Delay = ");
Serial.print(ms);
Serial.println(" msec.");
int time = 0;
while (time100){ // Крутить только если чуть ниже стартовой позиции
stepper1.move(smove); // Задать поворот относительно текущей позиции
}
}
void loop(){ // Основной цикл
inputHandler(); // Обработка ввода
if(stepper1.distanceToGo()==0) { // Если поворот закончили
if (str=="START") goNewPosition(); // Получаем следующую позицию
}
if (str=="START"){ // Если нет команды стоять то
stepper1.run(); // Крутим движок
}
}
Из картона сделал футляр для мыши, к которому прикрепил Arduino и двигатель с ведущим колесом которое ложится на колесико мыши и вращает его.
Рисунок 4. Вид гаджета с одной стороны.Рисунок 5. Вид гаджета с другой стороны.Рисунок 6. Гаджет с подопытной мышью:)Рисунок 7. Мышь в гаджете.
Как работает устройство можно посмотреть в видео.
Теперь, когда жене надо отлучиться, она вкладывает мышь в футляр и просто включает этот девайс.