Как обхитрить тайм трекер при помощи Arduino

55383c4e405a5930e081f92941a3b809.jpg

Здравствуйте!
Вся моя семья работает удалённо. Супруга работает в крупной организации, в которой осуществляется мониторинг рабочего времени. Мониторинг реагирует на нажатие кнопок клавиатуры и колесо прокрутки мыши, с таймаутом 5 минут. Жена переболела COVID-19 и после болезни стала сильно уставать во время работы, поэтому позволяет себе небольшие перерывчики. На время этих перерывчиков она просит меня покрутить колесико мыши, но я бывает так увлекусь работой, что забываю это сделать. В связи с этим у меня возникло желание автоматизировать этот процесс.

Я вспомнил что у меня валяется Arduino Leonardo, а его легко запрограммировать на имитацию клавиатуры и мыши. Покопавшись в ящиках нашел его и запрограммировал на имитацию колесика мыши. Но жена меня раскритиковала, так как у них запрещается пользоваться не зарегистрированными USB устройствами (а Arduino обязательно вызовет вопросы). Поэтому было решено крутить колесико мыши механически, для чего был заказан шаговый двигатель 28BYJ-48 в комплекте с драйвером двигателя на микросхеме ULN2003 и взят из другого «пыльного» ящика Arduino Nano.

Рисунок 1. Шаговый двигатель 28BYJ-48 с драйвером на микросхеме ULN2003.Рисунок 1. Шаговый двигатель 28BYJ-48 с драйвером на микросхеме ULN2003.

Подключил двигатель и кнопку к Arduno, двигатель запитывал как напрямую через Arduino, так и через внешний источник питания. Сейчас двигатель запитывается через Arduino (так меньше проводов висит, а Аrduino это терпит). Написал скетч (как смог) имитирующий прокрутку документа человеком при изучении сложного документа. Прокрутка осуществляется группами то в одну, то в другую сторону через разные промежутки времени. Запустить/остановить процесс скроллинга можно нажатием на кнопку или командами «START», «STOP» переданными по последовательному порту.

Рисунок 2. Схема подключения шагового двигателя (через драйвер) с питанием от Arduino.Рисунок 2. Схема подключения шагового двигателя (через драйвер) с питанием от Arduino.Рисунок 3. Схема подключения шагового двигателя (через драйвер) с внешним  питанием.Рисунок 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. Вид гаджета с одной стороны.Рисунок 4. Вид гаджета с одной стороны.Рисунок 5. Вид гаджета с другой стороны.Рисунок 5. Вид гаджета с другой стороны.Рисунок 6. Гаджет с подопытной мышью:)Рисунок 6. Гаджет с подопытной мышью:)Рисунок 7. Мышь в гаджете.Рисунок 7. Мышь в гаджете.

Как работает устройство можно посмотреть в видео.

 Теперь, когда жене надо отлучиться, она вкладывает мышь в футляр и просто включает этот девайс.

© Habrahabr.ru