Drobnicky

Drobničky 006 – Klikimouse aneb volím si tebe, Klikaču!

Spousta her, zvláště na internetu, vyžaduje natolik intenzivní klikání myší, že mám až podezření, že za nimi stojí (z důvodu omezeného počtu sepnutí spínačů) nějaká lobby prodejců myší. Nebo doktorů specializujících se na karpální tunely. Přitom autorepeat jsme měli u laciných joysticků už před více než 20 lety.

Naštěstí pokud do počítače zapojím víc myší, tak se chovají jako jedna kolektivní velemyš = lze například jednou hýbat a druhou klikat a funguje to.

Takže jsem si zrobil myš, kde lze nastavovat rychlost opakování a jedním stiskem tlačítka zapnout zběsilé klikání a druhým stiskem ho zase vypnout – viz obrázky dole:

Materiálová náročnost: Arduino Micro z číny, tři tlačítka a obligátní dioda s odporem.

Nechal jsem to trápit jednu gamesu pár nocí a docela to mělo grády – zásahů cíle asi 50.000.000, úspěšnost odhadem asi 1/5, takže zatím nějakých 250 miliónů kliknutí – která laciná myš to spolehlivě dá?




/*
	Klikimouse aneb Volim si tebe, Klikacu!
	3 tlacitka a LED+330 Ohm odpor proti zemi
	AutoFire for Mouse (ArduinoMicro)
	
	Based on:
	
	ButtonMouseControl
	For Leonardo and Due boards only.
	http://www.arduino.cc/en/Tutorial/ButtonMouseControl
*/

#include "Mouse.h"

// set pin numbers for the buttons and led:
const int speedUpButton = 2;
const int speedDownButton = 3;
const int pushButton = 4;
const int led = 8;


unsigned long long responseDelay = 16;	// repepeat rate of the mouse, in ms between up/down and down/up
unsigned long long debounceDelay = 400;	// debounce delay of the button, in ms
bool MouseDown=false;
bool somePressed=true;	// pressed any button => digitalRead()==0
bool debouncing=false;
bool active=false;

unsigned long milsDebounce;
unsigned long milsMouse;
unsigned long currentMillis;
void setup() {
	// initialize the buttons' inputs:
	pinMode(speedUpButton, INPUT_PULLUP);
	pinMode(speedDownButton, INPUT_PULLUP);
	pinMode(pushButton, INPUT_PULLUP);
	pinMode(led, OUTPUT);
	// initialize mouse control:
	Mouse.begin();
	milsDebounce=millis();
	milsMouse=millis();
}

void loop() {
	currentMillis=millis();
	bool speedUp= ! digitalRead(speedUpButton);
	bool speedDown= ! digitalRead(speedDownButton);
	bool push= ! digitalRead(pushButton);
	
	if (debouncing and ((currentMillis-milsDebounce) >= debounceDelay)) {
		debouncing = false;
	};
	if (! debouncing) {	// {{{ check for change
		if ( (speedUp || speedDown || push) != somePressed){	// {{{ somePressed changed !
			// {{{ start debouncing
			milsDebounce=currentMillis;
			somePressed=(speedUp || speedDown || push);
			debouncing=true;
			// }}}
			if (speedUp) {	// speedUp if possible
				if (responseDelay >2) responseDelay=responseDelay>>1;
			};
			if (speedDown) {	// speedDown
				responseDelay=responseDelay<<1; }; if (push) { milsMouse=currentMillis; active = ! active; }; }; // }}} }; // }}} ! debouncing if (active) { if ((currentMillis-milsMouse) >= responseDelay){
			milsMouse=currentMillis;
			MouseDown = ! MouseDown;
			digitalWrite(led,MouseDown);
			
			if ( MouseDown ) {
				Mouse.press(MOUSE_LEFT);
			} else  {
				Mouse.release(MOUSE_LEFT);
			};
		};
	} else {	// not active:
		if (MouseDown){		// release mouse ...
			if ((currentMillis-milsMouse) >= responseDelay){	// ... at the right time
				MouseDown = ! MouseDown;	// = false
				digitalWrite(led,MouseDown);
				
				Mouse.release(MOUSE_LEFT);
			};
		};
	};
}