Hi, I'm fairly new to this. I have a disability where I have limited use of my hands which makes researching a little challenging so I'm hoping to get some assistance.
This project is intended to create a custom switch which can operate as the left click button of a computer mouse using my foot. (I am aware there are commercial options available, however for a multitude of reasons, none of them function in a way that is suited to my body.) I want the switch to operate in the same manner as a computer mouse, e.g being able to hold the click down to drag. I tried to achieve this in the code with the Mouse.release() action.
I have already had the mouse built and wired. It does work but not in the same way a normal mouse would. This is the last code which I tried (there have been several). It mostly seems to behave as follows:
Click acts as click and hold (no release)
second click will either release or continue to be held down.
I'm using Arduino Leonardo
Any help or advice would be greatly appreciated
// Include the Mouse library
#include <Mouse.h>
// Define the pin for the momentary switch
const int switchPin = 3; // changed from 2 to 3
// Define the variables for the switch state
bool switchState = false; // current state of the switch
bool lastSwitchState = false; // previous state of the switch
bool mouseState = false; // current state of the mouse
void setup() {
// Initialize the switch pin as an input with pullup resistor
pinMode(switchPin, INPUT_PULLUP);
// Initialize the Mouse library
Mouse.begin();
// Initialize the serial monitor
Serial.begin(9600);
}
void loop() {
// Read the switch state
switchState = digitalRead(switchPin) == LOW;
// Check if the switch state has changed
if (switchState != lastSwitchState) {
// If the switch is pressed, toggle the mouse state
if (switchState) {
mouseState = !mouseState;
// If the mouse state is true, send a mouse press
if (mouseState) {
Mouse.press();
Serial.println("Left click"); // added to print left click
}
// If the mouse state is false, send a mouse release
else {
Mouse.release();
Serial.println("Mouse Release");
}
}
// Update the last switch state
lastSwitchState = switchState;
}
// Add a delay of 350 milliseconds
delay(350); // added to the code
}
Hi Angelo; I built something similar for a client, around a micro pro. She could not hold the mouse still and click at the same time.
I provided a set of three buttons with different actions - (sadly due to dementia she could never remember what they did)
Hope you find this useful.
sorry this is long but for convenience I've put the code here
/*
Example program mousebuttons for Arduino Micro Pro 23 Jan 2022
to provide mouse clicks for disabled lady
produces time-controlled clicks as follows:
left button (L_Mouse) single left click (& hold - ie not released until button released)
middle button (L2_Mouse) double left click & hold
right button - R_Mouse single RIght click & hold
debounce time and dleay between button clicks adjustable.
When testing can uncomment serial prints and comment out calls to click routines.
*/
#include "Mouse.h"
//pin assignments
const byte L_Mouse = 7; //buttons to GROUND & pulled HIGH so active low
const byte L2_Mouse = 6; //double left click
const byte R_Mouse = 5;
const byte Yel = 8; //LED_L leds on 8 & 9 via resistors to GROUND so active HIGH
const byte Red = 9; //LED_R
bool L_State, L2_State, R_State;
int tRepeat; //diagnostic; used in debugging tDelay
unsigned long tDebounce = 200; //time switch state must be continuous to count as stable
unsigned long tDelay = 1000; //delay before a new stable switch condition can cause a click
unsigned long tNow;
unsigned long tLastChange; //time of the most recent change on ANY button
struct condition { //declares a type named "condition"
int switchPin; // pin to read for this switch
bool lastState; //condition when last read
bool stableVal; // last stable value
unsigned long changeTime; //time of last change
};
condition sw[3] = { //array of three variables of type "condition"
{L_Mouse, 1, 1, 0}, //switch on pin 5
{L2_Mouse, 1, 1, 0}, //switch on pin 6
{R_Mouse, 1, 1, 0} //switch on pin 7
};
void setup() {
Serial.begin(57600);
delay(500);
pinMode(L_Mouse, INPUT_PULLUP);
pinMode(L2_Mouse, INPUT_PULLUP);
pinMode(R_Mouse, INPUT_PULLUP);
pinMode(Yel, OUTPUT);
pinMode(Red, OUTPUT);
digitalWrite(Red, LOW);
digitalWrite(Yel, LOW);
tLastChange = millis();
//Serial.println("Setup complete");
}
void loop() {
//has s1 changed?
L_State = digitalRead(sw[0].switchPin);
if (L_State != sw[0].lastState) { //s1 has changed
sw[0].lastState = L_State; //record current state to look for new changes
//flashLeft(1); //diagnostic
//now - has it been stable for > tDebounce?
tNow = millis();
if ((tNow - sw[0].changeTime) > tDebounce) {
//its a valid change
sw[0].stableVal = L_State;
//here stableVal represents the true condition of the S1 button
digitalWrite(Yel, !sw[0].stableVal);
LClick(sw[0].stableVal); //only executes a press or release if not already set
tLastChange = tNow;
//Serial.print(" Lbutton tLastChange is: ");
//Serial.println(tLastChange);
}
else {
//not a valid change so not stable; update time of last change
sw[0].changeTime = tNow;
}
}
//has s2 changed?
L2_State = digitalRead(sw[1].switchPin);
if (L2_State != sw[1].lastState) { //s1 has changed
sw[1].lastState = L2_State; //record current state to look for new changes
flashLeft(1);
//now - has it been stable for > tDebounce?
tNow = millis();
if ((tNow - sw[1].changeTime) > tDebounce) {
//its a valid change
sw[1].stableVal = L2_State;
//here stableVal represents the true condition of the S1 button
digitalWrite(Yel, !sw[1].stableVal);
L2Click(sw[1].stableVal); //only executes a press or release if not already set
tLastChange = tNow;
//Serial.print(" L2button tLastChange is: ");
//Serial.println(tLastChange);
}
else {
//not a valid change so not stable; update time of last change
sw[1].changeTime = tNow;
}
}
R_State = digitalRead(sw[2].switchPin);
if (R_State != sw[2].lastState) { //s3 has changed
sw[2].lastState = R_State; //record current state to look for new changes
//now - has it been stable for > tDebounce?
tNow = millis();
if ((tNow - sw[2].changeTime) > tDebounce) {
//its a valid change
sw[2].stableVal = R_State;
//here stableVal represents the true condition of the S3 button
digitalWrite(Red, !sw[2].stableVal);
RClick(sw[2].stableVal); //only executes a press or release if not already set
tLastChange = tNow;
//Serial.print(" Rbutton tLastChange is: ");
//Serial.println(tLastChange);
}
else {
//not a valid change so not stable; update time of last change
sw[2].changeTime = tNow;
}
}
//if any state has changed, AND all buttons released, delay before next is allowed
if (sw[0].stableVal && sw[1].stableVal && sw[2].stableVal) {
while ((millis() - tLastChange) <= tDelay) {
//tRepeat = millis() - tLastChange;
//Serial.print(" tRepeat is: ");
//Serial.println(tRepeat);
delay(100);
}
}
} // loop
and the functions
void flashLeft(int count){
for(int i = 0; i<count; i++){
//flash LEFT LED
digitalWrite(Yel, HIGH);
delay(50);
digitalWrite(Yel, LOW);
delay(100);
}
}
void LClick(bool valueL) {
if (valueL == 0) { //button is depressed
if (!Mouse.isPressed(MOUSE_LEFT)) {
Mouse.press(MOUSE_LEFT);
}
}
else { //button released
if (Mouse.isPressed(MOUSE_LEFT)) {
Mouse.release(MOUSE_LEFT);
}
}
}
void L2Click(int valueL) {
if (valueL == 0) { //button is depressed
if (!Mouse.isPressed(MOUSE_LEFT)) {
Mouse.press(MOUSE_LEFT);
delay(50);
Mouse.release(MOUSE_LEFT);
delay(50);
Mouse.press(MOUSE_LEFT);
delay(50);
}
}
else { //button released
if (Mouse.isPressed(MOUSE_LEFT)) {
Mouse.release(MOUSE_LEFT);
}
}
}
void RClick(int valueR) {
if (valueR == LOW) {
if (!Mouse.isPressed(MOUSE_RIGHT)) {
Mouse.press(MOUSE_RIGHT);
}
}
else { //button released
if (Mouse.isPressed(MOUSE_RIGHT)) {
Mouse.release(MOUSE_RIGHT);
}
}
}
#include <Mouse.h>// Include the Mouse library
const byte switchPin = 3; // Define the pin for the momentary switch
bool switchState = false; // current state of the switch
bool lastSwitchState = false; // previous state of the switch
void setup() {
pinMode(switchPin, INPUT_PULLUP);
Mouse.begin();
Serial.begin(9600);
}
void loop() {
if (digitalRead(switchPin) != lastSwitchState) { // Check if the switch state has changed
lastSwitchState = !lastSwitchState;
if (lastSwitchState) { // If the switch is pressed, toggle the mouse state
Mouse.release();
Serial.println("Mouse Release");
}
else {
Mouse.press();
Serial.println("Left click"); // added to print left click
}
}
delay(50); // Add a delay of 350 milliseconds // 350is too many
}