Pages: 1 [2]   Go Down
Author Topic: Arduino Leonardo mouse emulator using a potentiometer  (Read 1850 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 56
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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;
 }
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
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.
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 56
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
  int yReading = readAxis(A1);
to
Code:
  int yReading = 0;
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 56
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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);
   } 
 
 }
 
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 56
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 56
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am open to any suggestions and insightful comments.
Logged

UK
Offline Offline
Shannon Member
****
Karma: 222
Posts: 12520
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Offline Offline
Jr. Member
**
Karma: 0
Posts: 56
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks, Peter.
Logged

Offline Offline
Full Member
***
Karma: 5
Posts: 181
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 56
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi laadams85,

Thank you.
Logged

Pages: 1 [2]   Go Up
Jump to: