Go Down

Topic: Arduino Leonardo mouse emulator using a potentiometer (Read 2291 times) previous topic - next topic

33chen

Hi Paul,

Thanks. I see what you mean by range. My current observation is  that even when I turn the pot knob one direction, the cursor moves to the ends of screen back and forth. I have no clue what happens. You mention about the configuration of mouse. Should I check the properties of mouse on my laptop.Thanks

The following is the updated code.

// set pin numbers for switch, and LED:
const int switchPin = 2;      // switch to turn on and off mouse control
const int xAxis = A0;         // joystick X axis 
const int ledPin = 13;         // Mouse control LED

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

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

void setup() {
   pinMode(switchPin, INPUT);       // the switch pin
   pinMode(ledPin, OUTPUT);         // the LED pin 
  // take control of the mouse:
   Mouse.begin();
}

void loop() {
   // read the switch:
   int switchState = digitalRead(switchPin);
   // if it's changed and it's high, toggle the mouse state:
   if (switchState != lastSwitchState) {
     if (switchState == HIGH) {
       mouseIsActive = !mouseIsActive;
       // turn on LED to indicate mouse state:
       digitalWrite(ledPin, mouseIsActive);
     }
  }
   // save switch state for next comparison:
   lastSwitchState = switchState;

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

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



  delay(responseDelay);
}

/*
   reads an axis (0 for x) and scales the
analog input range to a range from 0 to <range>
  */

int readAxis(int thisAxis) {
  //int distance = 0; //distance from center of the output range
  // 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, range);

  // 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;
return reading;
}

PaulS

Code: [Select]
return distance;
return reading;

One return statement per function is the general recommendation.

Your threshold is 1/4 of the screen. Is that really a valid distance?

Perhaps what you need to do is quit trying to be a mouse, until you get the code debugged. Use Serial.begin() (in setup()) and Serial.print(ln)() in other functions, to see what is going on.

33chen

Sorry for the confusing. I removed the very last line of my code (return reading), the problem is still there. I feel a little lost. As you said, the joystick is essentially two pots. I saw other people use pretty much same code as I have used to make mouse control. Why can I use this code ( with removing whatever code lines for vertical axis) to just achieve the horizontal mouse control. In their code for mouse control, the range they use are all 12.  For example, this is an example: http://idea-dev-storage.de/?p=211#more-211.

PaulS

Quote
In their code for mouse control, the range they use are all 12.

They are splitting the potentiometer reading into 12 ranges.

What happens if you run that code, but change:
Code: [Select]
  int yReading = readAxis(A1);
to
Code: [Select]
  int yReading = 0;

33chen

Thanks, Paul. I tried it. The cursor still swings back and forth. But this following code seems working for my purpose. Again, I still use the relative movement input instead of absolute movement. Any suggestion for improvement or any comments on flaws. Here the range I put is 2000 (although x y coordinates of screen is 1366*766). I tried 1366 for the range,but the cursor can not movement from one end of screen to the other (from 0v to 5v). The range of 2000, however, works fine. Any thoughts on why it happens like this way. Thanks a lot, Paul. You are a great helper.

const int switchPin = 2;      // switch to turn on and off mouse control
const int xAxis = A0;         // joystick X axis 
const int ledPin = 13;         // Mouse control LED

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

int prevXreading = 0;

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

void setup() {
   pinMode(switchPin, INPUT);       // the switch pin
   pinMode(ledPin, OUTPUT);         // the LED pin 
   // take control of the mouse:
   Mouse.begin();
}

void loop() {
   // read the switch:
   int switchState = digitalRead(switchPin);
   // if it's changed and it's high, toggle the mouse state:
   if (switchState != prevSwitchState) {
     if (switchState == HIGH) {
       mouseIsActive = !mouseIsActive;
       // turn on LED to indicate mouse state:
       digitalWrite(ledPin, mouseIsActive);
     }
  }

  // save switch state for next comparison:
   prevSwitchState = switchState;

int currXreading = analogRead(xAxis);

int currXreading1 = map (currXreading, 0, 1023, 0, range);

int xReading = prevXreading - currXreading1;

// xReading = map(xReading, 0, 1023, 0, 20);

  prevXreading = currXreading1;


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

}


33chen

Paul,

thanks again. Why do you think I can do from there according to my previous post. I am very interested in your suggestions.

Best,

Ji

33chen

I am open to any suggestions and insightful comments.

PeterH

I suggest that you do the mapping from the min/max range of values that you actually get from the joystick rather than 0-1023, and do the mapping to the distance in pixels that you want to be able to move the mouse in one operation i.e. without using the button to 'disconnect' the joystick from the mouse.
I only provide help via the forum - please do not contact me for private consultancy.


laadams85

I think you would be better served using a rotary encoder, so that you aren't limited by the pot, and mapping the angle change to a number of pixels.  Just my 2 cents.
http://playground.arduino.cc/Main/RotaryEncoders


Go Up