Making potentiometer control mouse and/or keyboard (Bike steering wheel for VR)

Hello. This is my very first post. Let me begin by saying I am a code n0000b, times infinity, but I'm good at learning new things, so you don't necessarily have to dumb things down too much.

I live in Phoenix where half of the year it's too hot to go outside to exorcize. To remedy this, I've built a virtual reality bike (out of a stationary exorcize bike) to ride around in Grand Theft Auto V.

The pedals work fine, implementing a magnetic reed switch. It's the handlebars that I'm stumped with. Stumped, because I'm very bad at code. I've got nothing.

Here's how they work:

[I have an Arduino Uno R3 that I have successfully learned to firmware hack , so that it may be recognized as a keyboard.]

A rubber tread/track (whatever its called) rotates around the handlebar neck (d. A) (images attached)

That, in turn, rotates a linear 10k potentiometer, left to right. (d. B)

What I would like it to do is this:

When the handlebars are straight and the potentiometer is in the middle, I want the Arduino to move the mouse to the very center of the screen, so that I go straight.

When the handlebars are turned left, I'd like the mouse to move left. The further left the potentiometer is turned, the further left it goes, until it hits the end of the screen.

I would like the exact opposite to happen when the handlebars are turned right.

The programs I will be using this code with will be running at a 1920 x 1080 resolution, in full screen.

I'd also like to create a sketch that makes left turns hold the 'A' key and right turns hold the 'D' key, instead of the mouse, just to see what that performance is like also.

So now what do I do? :confused:

Whatever code you help me with, I will be eternally grateful for.
I'm sure that if whatever code you help me with doesn't quite work, I will be able to tweak it as needed and learn from. (I also know there are probably easier ways to go about this, but I really want to try it this way)

Thank you for your time and consideration!

EDIT: I'd post my code so far, but I don't have any. I literally have no idea how to take potentiometer code and convert it into mouse strokes. I'm sorry. Also sorry for the double post of attachments. I don't know what happened there.

I have an Arduino Uno R3

Which can not emulate a mouse. A Leonardo can.

The programs I will be using this code with will be running at a 1920 x 1080 resolution, in full screen.

Not very useful information, since all that the Leonardo-as-mouse can do is make the mouse move relative amounts.

PaulS:
Which can not emulate a mouse. A Leonardo can.
Not very useful information, since all that the Leonardo-as-mouse can do is make the mouse move relative amounts.

Thank you for your response.

What if I recode the Uno's firmware with Arduino-mouse-0.1.hex, as suggested here:

Would that work?

Also, I don't understand your comment about the Leonardo only moving the mouse relative amounts. Are you saying it's unable to determine where the middle of the screen is?

Are you saying it's unable to determine where the middle of the screen is?

Wouldn't "the middle of the screen" be an absolute position? The Leonardo has NO idea where the cursor currently is. It can only tell it to move left, right, up, or down some number of pixels.

By the way, a real mouse can't either. It is the gray matter of the user of the mouse that determines that.

Okay. Thank you.

How about the keyboard idea, making the potentiometer send either 'a' or 'd'? Surely that would be a simpler and more realistic approach?

I'm not sure how it works but I think if you have a drawing tablet connected to a PC you can set things so the tablet positions represent absolute positions on the screen, or with another setting, the movements of the table pointer can be relative, just like a mouse.

I'm wondering if that concept could be adapted to your need.

@PaulS, I think the OP is much cleverer than I am and has converted his Uno to behave like a Leonardo.

@Robobuns, I wonder is it possible to re-program the Usb side of the Arduino so it appears to the PC as a drawing tablet?

...R

I think if you have a drawing tablet connected to a PC you can set things so the tablet positions represent absolute positions on the screen

A tablet has a completely different set of drivers to map stylus motion to position. The Leonardo can not emulate a stylus, though.

The Leonardo CAN also emulate a keyboard, but I'm not sure how sending 'a' or 'd' would happen. What event would cause the 'a' to be sent? What event would cause the 'd' to be sent? The only event I see that is relevant is moving the handle bars. Does some amount of movement in one direction cause the Arduino to send a letter? How much movement?

Robin2:
I'm not sure how it works but I think if you have a drawing tablet connected to a PC you can set things so the tablet positions represent absolute positions on the screen, or with another setting, the movements of the table pointer can be relative, just like a mouse.

I'm wondering if that concept could be adapted to your need.

@PaulS, I think the OP is much cleverer than I am and has converted his Uno to behave like a Leonardo

Good looking out. My wacom was one of the first things that popped into my mind when trying to resolve the mouse issue, but alas, as PaulS is getting at, the amount of coding and reverse engineering required to pull something like that off would mean I'm smart enough to find simpler solutions. :frowning: I can't code at all. Not yet, at least.

And more or less, yes, I have hacked the Uno to behave this way. How accurately it behaves like a Leonardo, I have no idea, but I imagine it's not as good. I have to keep flashing the firmware back and forth to get it to read as an Arduino or a keyboard. I'm just glad I've gotten what I have out of it. :smiley:

PaulS:
The Leonardo CAN also emulate a keyboard, but I'm not sure how sending 'a' or 'd' would happen. What event would cause the 'a' to be sent? What event would cause the 'd' to be sent? The only event I see that is relevant is moving the handle bars. Does some amount of movement in one direction cause the Arduino to send a letter? How much movement?

Basically, the way I imagined it is with the potentiometer pointed in the approximate center, between it's highest and lowest available values. When it is turned any degree clockwise from this position, it holds the 'D' key down, releasing it only when the potentiometer is moved back to the approximate center, OR any degree counter-clockwise from the approximate center.

When the potentiometer is turned counter-clockwise, any degree from the the aproximate center, it holds the 'A' key, releasing it only when the potentiometer is moved back to the approximate center, OR any degree clockwise from the approximate center.

I think that will work. It seems simple enough, but I have no idea how to tell the Arduino to do this stuff. I've looked through so much code and I'm none the closer to figuring this out.

Thanks again for your time, folks. It means the world to me.

Robobuns:
When it is turned any degree clockwise from this position, it holds the 'D' key down, releasing it only when the potentiometer is moved back to the approximate center, OR any degree counter-clockwise from the approximate center.

What you describe is to send a keyDown (for D) when the potentiometer moves clockwise and send a keyUp when it gets back to centre.

I think what you need is to
send a keyDown (for D) when the potentiometer moves clockwise
send a D up when the potentiometer stops moving
send an A down when the pot starts moving anti-clockwise (from wherever it is)
etc

HOWEVER - what will be PC be doing in response to the keyDown - if it keeps moving the screen you will have no idea how far it gets so you can bring it back by the same amount when you centre the pot.

...R

Robin2:
HOWEVER - what will be PC be doing in response to the keyDown - if it keeps moving the screen you will have no idea how far it gets so you can bring it back by the same amount when you centre the pot.

With the mouse, we could vary how sharply the game's handlebars turn, but I've given up on that. A binary 'turn right' 'turn left' 'yes' and 'no' is fine, at this point, which is all the keyboard can accomplish. In the game, GTA, pressing 'A' or 'B' makes you turn left or right, flat out. The longer you hold it, the longer the player keeps turning their handlebars, in game. When you release the key, the character in the game automatically straightens his handlebars back and rides straight. Therefore, I do not want to release the key until I straighten my handlebars out, in real life.

I've never connected a potentiometer to anything before. Is it possible I am misunderstanding how they work?

Thanks.

The longer you hold it, the longer the player keeps turning their handlebars, in game.

So, sending one value when the turn starts (key pressed) and another when the turn stops (key released) matters. And, you're not planning on doing that. Oh, well.

PaulS:
So, sending one value when the turn starts (key pressed) and another when the turn stops (key released) matters. And, you're not planning on doing that. Oh, well.

Now I'm getting confused. What do you mean I don't plan on sending a (key pressed) and (key released) when the turn stops? I thought I just discussed how I want to go about doing this very thing in my previous post.

Very confusing. What am I missing, here?

PaulS:
...And, you're not planning on doing that. Oh, well.

Is there anybody who doesn't have an "oh well" attitude who would like to help me? This is the exact reason why I avoid forums, is people treating each other like that. This is supposed to be a place to ask questions and learn-- not talk down to people. I said I'm 100% new and I'm trying my best to understand. What more could I be doing to not be talked to this way? Maybe I don't understand how things work around here, but that seems like a rude thing to say, especially from somebody with 56,000+ posts...

Robobuns:
I've never connected a potentiometer to anything before. Is it possible I am misunderstanding how they work?

I think you need to do some experimenting rather than expect a complete solution straight off.

Write a short program that reads values from a pot and displays them on the Serial Monitor.
Then extend that program so it sends messages to the Serial Monitor that represent the keystrokes you will eventually send to ypur game. By messages I mean something like "Ldown" or "Lup" that let you see what is happening in response to the movement of the pot and allow you to think about how the game will respond.

I still think the system I suggested in Reply #8 is broadly correct.

...R

I thought I just discussed how I want to go about doing this very thing in my previous post.

Robobuns:
Is there anybody who doesn't have an "oh well" attitude who would like to help me? This is the exact reason why I avoid forums, is people treating each other like that. This is supposed to be a place to ask questions and learn-- not talk down to people. I said I'm 100% new and I'm trying my best to understand. What more could I be doing to not be talked to this way? Maybe I don't understand how things work around here, but that seems like a rude thing to say, especially from somebody with 56,000+ posts...

I apologize. I read your previous post too hastily. I missed where you were not planning to send the release event until the bars were returned to center.

Although, I think the time to send the release event is when the bars start moving back to center.

[EDIT: To simplify things, I purchased a Leonardo clone]
[EDIT: The pedal code seems to be broken. Once initiated, it reverses it's function and sends a HIGH signal until the magnetic reed passes in front of it. Whether I use the pullup resistor or not, it does this. It's peculiar.]
[EDIT: Pedals work again. I connected the ground cable going into the reed switch from N.C. to N.O.]

I did it!

I misunderstood how potentiometers worked. It turned out the answer was as easy as I hoped it might be and I am frankly shocked and astounded.

Here's my code I hacked together:

const int buttonPin = 7;
const int ledpin =  8;

int buttonState = 0;

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(14400);
  Keyboard.begin();
  pinMode(ledpin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  buttonState = digitalRead(buttonPin);
  int sensorValue = analogRead(A0);
  // print out the value you read:
  Serial.println(sensorValue);
  delay(1);        // delay in between reads for stability
  if (sensorValue < 481)
  {Keyboard.press('a');
  }
  else
  Keyboard.release('a');
  if (sensorValue > 539)
  {Keyboard.press('d');
  }
  else
  {
  Keyboard.release('d');
  }
  if ((sensorValue < 513) && (sensorValue > 509))
  digitalWrite(ledpin, HIGH);
  else
  digitalWrite(ledpin, LOW);
  
  if (buttonState == HIGH)
  {Keyboard.press('g');
  }
  else
  {Keyboard.release('g');}
  {

}
}
//

This code uses a reed switch on pin08 to detect when the wheel makes a rotation. It in turn sends the 'g' key, which makes the player pedal on screen.

I've also included a snippet that turns an LED on when the potentiometer is in the approximate center, to calibrate on the fly. The only problem is that the harsh turning contradicts what my muscle memory expects. It's intolerable, really. I'm now going to attempt to break the potentiometers range into pieces and make each piece move the mouse at different speeds, to create varying degrees of turning IRL. As it would turn out, the game automatically moves the mouse back to the center of the screen for you, when steering with it.

Thanks for your help, folks.