Drag clicking 'mouse' emulator

Hi all, hope you're well! My son who loves playing minecraft asked me yesterday for a new pc mouse so he can drag click. I had to look it up, I'm old :slight_smile:

Anyway, this to me looks like a perfect project for a arduino leonardo, and as it happens, I have one spare.

Just wondered if anyone has tried a project like this? Ideally, a one button momentary push switch connected to the arduino triggers say 20 mouse clicks...?

Your son must have very large hands if the Leonardo looks like a good mouse solution. :slight_smile:

Anyways did you look at this:

https://www.arduino.cc/reference/en/language/functions/usb/mouse/

Looks like you can do this with a few lines of code. Read a button and then call Mouse.click() 20 times. You will likely need to experiment a bit with timing.

Well i built it, a simple joystick and left mouse click! It seems to work but i need some assistance to incorporate a second button that will give me the 20 left clicks i need.. i tried assigning pin 5 as the second switch but i'm a noob at this coding business. Could some please help me finish the sketch?

Here is the sketch so far:

// Define Pins

#include <Mouse.h>

const int startEmulation = 2;      // switch to turn on and off mouse emulation
const int mouseLeftButton = 4;    // input pin for the mouse left Button
const int click20 = 5;                       // input pin for the 20 click mouse left Button
const int joystickX = A1;         // joystick X axis  
const int joystickY = A0;         // joystick Y axis

// parameters for reading the joystick:
int cursorSpeed = 5;               // output speed of X or Y movement
int responseDelay = 5;        // response delay of the mouse, in ms
int threshold = cursorSpeed/4;      // resting threshold
int center = cursorSpeed/2;         // resting position value

boolean mouseIsActive = false;    // whether or not to control the mouse
int lastSwitchState = LOW;        // previous switch state

void setup() 
{
  Serial.begin(9600);
  pinMode(startEmulation, INPUT_PULLUP);   // the switch pin
  pinMode(mouseLeftButton, INPUT_PULLUP);  // the left mouse button pin
  pinMode(click20, INPUT_PULLUP);  // 20 click left mouse button pin 
  
  Mouse.begin();  // take control of the mouse
}

void loop() {
  // read the switch:
  int switchState = digitalRead(startEmulation);
  
  // if it's changed and it's high, toggle the mouse state:
  if (switchState != lastSwitchState) {
    if (switchState == LOW) {
      mouseIsActive = !mouseIsActive;
    }
  }
  
  // save switch state for next loop:
  lastSwitchState = switchState;

  // read and scale the two axes:
  int xReading = readAxis(A1);
  int yReading = readAxis(A0);

  // if the mouse control state is active, move the mouse:
  if (mouseIsActive) {
    Mouse.move(xReading, yReading, 0); // (x, y, scroll mouse wheel)
  }  

  // read the mouse button and click or not click:
  // if the mouse button is pressed:
  if (digitalRead(mouseLeftButton) == HIGH) {
    // if the mouse is not pressed, press it:
    if (!Mouse.isPressed(MOUSE_LEFT)) {
      Mouse.press(MOUSE_LEFT);
      delay(100); // delay to enable single and double-click
    }
  }
  
  // else the mouse button is not pressed:
  else {
    // if the mouse is pressed, release it:
    if (Mouse.isPressed(MOUSE_LEFT)) {
      Mouse.release(MOUSE_LEFT);
    }
  }

  delay(responseDelay);
}

/*
  reads an axis (0 or 1 for x or y) and scales the
 analog input range to a range from 0 to 
 */

int readAxis(int thisAxis) {
  // read the analog input:
  int reading = analogRead(thisAxis);

  // map the reading from the analog input range to the output range:
  reading = map(reading, 0, 1023, 0, cursorSpeed);

  // if the output reading is outside from the
  // rest position threshold,  use it:
  int distance = reading - center;

  if (abs(distance) < threshold) {
    distance = 0;
  }

  // return the distance for this axis:
  return distance;
}

Can you please modify your post to ensure the source code is in a single box. It should look like this.

// Your example source code

You need three ' at the beginning and end in the edit window? When you click on this icon </> you get.

```
type or paste code here
```

This ensures we can get all the source code. Right now if you copy the code there are invisible characters that prevent successful compilation and parts might be missing.

Hi Klaus. Thanks, I have updated with ```

Thanks.

One issue many beginners run into is the use of delay(). It stops the execution of the sketch and wastes processor cycles. This prevents you from extending the sketch without changing what you already have.

Have a look at the following example to learn how to time parts of your code without delay().

File -> Examples -> 02.Digital -> BlinkWithoutDelay

I would separate the parts of the loop into separate functions. I tend to call them tasks e.g. printTask, buttonTask ... . Inside loop should only be calls to tasks.
Inside each task I use the technique from BlinkWithoutDelay to time the task. e.g., read the analog pins 100 times a second by using a 10ms interval. This will also debounce button reads by reading them in an interval.
Change the code you have, so it does not have any delays() anymore. The loop should run as often as possible but the actions happen only as fast as needed.
Then you can add a task that clicks the mouse buttons like a blinking LED in the example. Add a down-counter to stop when the number of clicks is zero. When the click20 button is pushed set the counter to 20 and the mouse will start clicking again.

If you run into any issues please post your new code.