Transforming an Old Exercise Bike Into a Controller for a Game

by andrewhyun in Workshop > Repair

1120 Views, 9 Favorites, 0 Comments

Transforming an Old Exercise Bike Into a Controller for a Game

5568323f7e3998813ac2bec463c472f3d0ff5d5b-1.jpg

I love to make fun games for my friends and my family to play. My games are often 3D, and I use virtual reality in most of them to create a realness effect. I wanted to combine real life objects into VR. Later, my dad said that his friend had an exercise bike that didn't work. *Cue lightbulb over my head* You don't see an exercise bike as a controller that often, right? You can exercise while playing video games!! So, I took the exercise bike, and got to work!


There are two parts to this game I'm making.


The first part is that I need to make the exercise bike work as a controller. That shouldn't be too hard. I just have to find out how the bike knows when and how fast I move the pedals. Then, I hook it up to an Arduino and make it so that when I go a certain speed, it would act as if typing a button on the keyboard. Then I can easily use that input in my actual game. I could also make it so that you have 2 vertical handles on the bike that you can move back and forth to turn.


The second part, you guessed it, is making the actual game! I had this idea of making a game where the main character is a submarine, and they are... swimming? running? around the sea trying to go through rings to score points while optionally trying to dodge an enemy. When I start pedaling on the exercise bike, I'd move forward in the actual game.


So now that we have the idea in mind, let's get to work!

Supplies

  1. Exercise Bike(I used a Nordictrack GX 2.7 exercise bike, but you can use any exercise bike that uses a reed switch to measure speed)
  2. Oculus Quest 2 Headset and Controllers + Link Cable
  3. 3D printer
  4. Arduino Micro
  5. 10k Ohm resistor
  6. Wires
  7. 3/4 inch PVC pipe, PVC 3-way joints, and 3/4 inch x 2 ft plastic coil pipe

Take Off Exercise Bike Pedal Cover

Capturey.JPG
Captureyes.JPG
bbc49e829860bc23c6245bea59805dab0a933fed-1.jpg

First, we want to see what's measuring the bike pedaling speed. To do that, we have to take apart the exercise bike. On my bike, there were a few screws that were holding the bike pedal cover on. I also had to remove the cranks using a crank removal tool. Once I removed those, I was able to get the bike cover off. Once the bike covers are off, it should look like the first 2 pictures.


If you take a close look, you'll see something called a reed switch next to the pedals. The 3rd picture shows it. If you watch the reed switch as you start pedaling, you'll notice a magnet passes by it once in a while. My bike has two magnets that are equally spaced. When the reed switch detects the magnet, it closes a circuit. This is how the bike knows when and how fast the person is pedaling.

Speed = distance/time.

The distance is always a constant, because the distance between the two magnets are the same. So, speed is a function of time that it takes to close the switch as the pedal goes around.


In the next step, we'll connect it to the computer.

Hook Up the Arduino With the Bike and Computer

8a7a84a61829c1a7daa6f213ed50a4f7bf579565-1.jpg


You should use one of the following Arduinos: the Leonardo, Micro, Zero and Due (or any 32U4 based board) for this step. The reason for this is because we can only use Arduinos that are HID-compatible to use it as a keyboard. Important Note: The Arduino Uno and Mega will not work. I chose the Micro because it's small and fits nicely on my bread board. The Arduino Micro will look like the first picture.


Now go to this Instructables page that shows you how to make an exercise bike speedometer using an Arduino. If you look at the first step, it tells you the schematic that you need to use to hook up the bike with the Arduino.

I disconnected the reed switch and used jumper cables to connect the switch output to the A0 and the 5V per the Instructables instructions. You should also put a 10k Ohm resistor between A0 and ground.


We've just connected the bike to the Arduino. Now, we have to connect the Arduino with the computer! Hook up a USB cable from the Arduino to your computer. If you go to the instructables page's link, it will show you the original Arduino code. This is how I modified the code so that it types the letters q, w, e, and r depending on how fast you are pedaling:


//arduino bike speedometer w serial.print()
//by Amanda Ghassaei 2012
//https://www.instructables.com/id/Arduino-Bike-Speedometer/


/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
*/


//calculations
//tire radius ~ 13.5 inches
//circumference = pi*2*r =~85 inches
//max speed of 35mph =~ 616inches/second
//max rps =~7.25
#include <Keyboard.h>


#define reed A0//pin connected to read switch


//storage variables
int reedVal;
long timer;// time between one full rotation (in ms)
float mph;
float radius = 13.5;// tire radius (in inches)
float circumference;


int maxReedCounter = 220;//min time (in ms) of one rotation (for debouncing)
int reedCounter;




void setup(){
  
  reedCounter = maxReedCounter;
  circumference = 2*3.14*radius;
  pinMode(reed, INPUT);
  
  // TIMER SETUP- the timer interrupt allows precise timed measurements of the reed switch
  //for more info about configuration of arduino timers see http://arduino.cc/playground/Code/Timer1
  cli();//stop interrupts


  //set timer1 interrupt at 1kHz
  TCCR1A = 0;// set entire TCCR1A register to 0
  TCCR1B = 0;// same for TCCR1B
  TCNT1  = 0;
  // set timer count for 1khz increments
  OCR1A = 1999;// = (1/1000) / ((1/(16*10^6))*8) - 1
  // turn on CTC mode
  TCCR1B |= (1 << WGM12);
  // Set CS11 bit for 8 prescaler
  TCCR1B |= (1 << CS11);   
  // enable timer compare interrupt
  TIMSK1 |= (1 << OCIE1A);
  
  sei();//allow interrupts
  //END TIMER SETUP
  
  Serial.begin(9600);
}




ISR(TIMER1_COMPA_vect) {//Interrupt at freq of 1kHz to measure reed switch
  reedVal = digitalRead(reed);//get val of A0
  if (reedVal){//if reed switch is closed
    if (reedCounter == 0){//min time between pulses has passed
      mph = (56.8*float(circumference))/float(timer);//calculate miles per hour
      timer = 0;//reset timer
      reedCounter = maxReedCounter;//reset reedCounter
    }
    else{
      if (reedCounter > 0){//don't let reedCounter go negative
        reedCounter -= 1;//decrement reedCounter
      }
    }
  }
  else{//if reed switch is open
    if (reedCounter > 0){//don't let reedCounter go negative
      reedCounter -= 1;//decrement reedCounter
    }
  }
  if (timer > 2000){
    mph = 0;//if no new pulses from reed switch- tire is still, set mph to 0
  }
  else{
    timer += 1;//increment timer
  } 
}


void displayMPH(){
  Serial.println(mph);
  if (mph >= 20.0){
    Keyboard.write('r');
  }else {
    if (mph >= 15){
      Keyboard.write('e');
    }else {
      if (mph >= 10){
          Keyboard.write('w');
      }else {
        if (mph >= 5){
            Keyboard.write('q');
        }
      }
    }
  }
}


void loop(){
  //print mph once a second
  displayMPH();
  delay(1000);
}


Upload the code to your Arduino. Open up notepad and start pedaling. Depending on how fast you are pedaling, you should see the Arduino type out q, w, e, and r.

Make Handle Controllers

20220521_162824.jpg
20220521_163327.jpg
20220521_163320.jpg

I sawed off the original handles of the electric bike, and took off the monitor screen. Then, I put the 3/4 in x 2 ft PVC pipe through what remained of the handlebar. Since it was kind of a loose fit, I taped the pipe to the handlebar so that it wouldn't move. I put the 3-way PVC joints through the pipe, one on each side, and I put the other 2 3/4 inch PVC pipes into the joints. We now have handlebars that can move back and forth. See picture above.


I used Openscad to model an Oculus Controller Holder, which you can find at this Thingiverse page. Once you have printed all files out for each oculus controller, assemble the holder so that it looks like the Thingiverse picture. I slipped each holder onto each handlebar. It was a loose fit, so I drilled a hole through the holder and the PVC pipe and put a bolt through the hole to keep it in place. I did this for both oculus controllers. The holder kept slipping out, so I duct them in place.


Once you are done with this, look at my end result and compare it to yours.

Connect It to the Game!

Capture.JPG

If you already have unity downloaded, skip this paragraph. However, if you don't, go to the unity website and download unity hub. Once that's done installing, go to the "Installs" tab, and then install the newest version of unity. Where it says "add modules", you don't need to add anything besides visual studio code.


Go to this GitHub page, then clone this repository. After that, go back into unity hub, and press "Open" and locate the place where you saved the GitHub file. Then open the unity project by clicking on it in the list of unity games.


Your game should look like the picture in the end. If instead of seeing "Game Scene", you see "Untitled", Then you should go to the scenes folder under "Assets" and double click the left icon that says, "Game Scene."

Unity Game Challenges

This isn't actually a step, it's more like just a section telling the challenges I had to go through to get to the final end product for my game.


Making the submarine turn

The submarine will turn based on how you move the handles back and forth. At first, we considered using the rotation (orientation) of the controllers to turn. But, the problem with that is that the rotation gets messed up based on how the exercise bike itself is oriented. So, we decided to go with position of the controller. We used the y-position(Or in other words, the vertical axis) to find out where the handle is.


Using trigonometry, we figured out the Unity units of how far the controllers go up and down on the Y axis when the controllers are parallel to the ground, and when the controllers are sticking straight up.. We assumed that distance is also the length of the PVC pipes (radius of the circle).

In our game, we found that the hypotenuse was .3 units. We configured the highest point (max(y)) that the controllers go and put it in variables leftHigh and rightHigh

if (leftHigh < leftController.localPosition.y)
        {
            leftHigh = leftController.localPosition.y;
        }


        if (rightHigh < rightController.localPosition.y)
        {
            rightHigh = rightController.localPosition.y;
        }


Then we used the trigonometric formulas to figure out the angles of the controllers.

Sin theta = opposite/hypotenuse ==> theta = Inverse Sin (opposite/hypotenuse)

leftAngle = Mathf.Asin((leftController.localPosition.y - (leftHigh - .3f)) / .3f) * 180 / Mathf.PI;
rightAngle = Mathf.Asin((rightController.localPosition.y - (rightHigh - .3f)) / .3f) * 180 / Mathf.PI;


Using these angles, we made the submarine turn. There are two parts to this.

The first part is that I have to make it so that you go up and down if the handles are pulled up or pulled down together. It would be kind of like an airplane yoke. We made a function which detects the angle based on the y-position:


float surfaceSpeed = (leftAngle + rightAngle - 90)/90;


The second part, is making the ship turn (barrel roll) if the controllers aren't parallel. I made another code that will do that function. The best part about this is that it won't affect my first function:


float angleDiff = ((rightAngle - 45) - (leftAngle-45))/90;


And those are my main functions for finding out the rotation of the controllers! The actual part where is rotates the submarine is down below:


this.transform.Rotate(surfaceSpeed*vertRotSpeed, 0, angleDiff*horzRotSpeed);



Making the Underwater Scene

This part is easy. If you go to the unity asset store, you will find this asset for $25. I plopped it into my game and the submarine floated around in the underwater environment.

Getting Oculus Ready

First, you need to download the oculus software onto your pc. Plug the oculus link cable into your Oculus Quest 2 Headset, and inside your headset, enable Oculus Link. This mode will basically connect you to your computer, if the oculus app is downloaded. If the enable Oculus Link pop-up isn't showing up, either disable Air Link if it's on, or try restarting the oculus or the oculus app.

Let's Play!

Exercise Bike End Result

Here is how to play the game:

Press trigger on the oculus controller to fire a bullet.

Depending on how fast you pedal on the bike, your submarine will change speed in the game.(No way to go backwards)

Depending on how you move the handles back and forth, the submarine will turn that specific way.(You'll get used to it)

Try to control your submarine into the yellow hoops to increase your score!

If you want an extra challenge, enable the enemy in hierarchy. To do this, click on the enemy in the hierarchy, and in the inspector window, enable the checkmark box to the left of the name. Try to destroy the enemy(Red submarine). If it hits you once, you die, and have to restart.


In the unity editor, hit play. If everything works correctly, as long as you are still in oculus link mode, you will go inside of the game, and the exercise bike will be connected.


You can play the game without an Oculus controller by using the keyboard, also. We did this so that we can test some of the game features without having to hop on the bike every time. It's not nearly as fun.

...


I hope you had fun reading about this project! Here is my final result. Thank you for taking the time to read it! Show this project to your friends and family! If you know how to use unity well, you could even network the enemy so that a friend could control it! Go crazy! Have fun!