Engineering

Outreach

Resources

Enrichment

Green Engineers

Mechatronics Studio

Contact Us

Mechatronics Learning Studio

 

 

The Auto-Bike Gear Selecting System 

Stefano Mazza and Patrick Gall, Department of Mechanical Engineering, University of Ottawa

 

 

First year

 

 

The following year

 

Description

                This report outlines the design steps and operation of the Auto-Bike bolt-on electronic gear selecting package.

Reasons for System

This system is meant to create a more user friendly interface with the bicycle. There are electronic group sets available for bicycles, however they are very expensive and are only compatible with certain frames types. The Auto-Bike bolt-on package will be able to mount to almost any bicycle. Electronic gear selecting is not only more accurate, but also puts less pressure on the cyclist to monitor and maintain proper chain lines and gear settings.

Design Goals

                The following points are design features that were selected for this project. They outline a specific application for this system.

·         The system must remain general enough to be able to bolt onto any bicycle.

·         The system should display to the user which gear the bicycle is currently in.

Using the System

                The system is switched on simply by plugging in the batteries located on the main mount, on the down tube of the bicycle. The system will always initialize thinking that it is in the highest gear, i.e. the gear with the fewest teeth. For this reason it is important to shift the bicycle to this gear before switching it off. In the case of the demonstration bicycle, it is an 8 speed bicycle, and so the system starts in 8th gear, and should be returned to 8th gear before shut down.

                User input is done via three buttons located on the handle bars. In the normal operating mode, signified by the unlit warning LED, the ‘+’ and ‘-’ buttons will control the gear selecting. Once pressed, either button will cause a gear change. Keystrokes during a change are ignored. If a button is pressed and the warning LED flashes, then the shift requested in not possible since there is no gear in that direction. On the demonstration bike for instance, while in 8th gear, pressing ‘+’ will result in the warning LED flashing as there is no 9th gear. The same will occur in 1st except when ‘-’ is pressed.

Set mode is entered by pressing the ‘Set’ button on the interface. Set mode is signified by the warning LED being constantly lit. In this mode, the ‘+’ and ‘-’ buttons will simply move the step motor in the direction specified for as long as they are held. This can be used to fine tune a gear during riding, or to first setup the system on the bicycle. Exiting set mode is simply done by pressing the ‘Set’ button again.

 Discussion of Construction

                The entire system has two main output streams and one input stream. The input comes in the form of 3 buttons actuated by the user to perform specific tasks. The output streams go to the step motor and to the screen.

Figure 1: The general outline of the gear selector.

Mechanical System

Lead Screw

Figure 2: A model of the lead screw.

                The lead screw transforms the rotational input of the step motor to a linear translation of the cable. The step motor’s shaft is retained into the lead screw coupler by a single M4 set screw. The lead screw itself uses a M6 threaded rod that rotates on ball bearings and is threaded into a sliding block that holds the cable. The sliding block fits into a square piece of aluminum tube which absorbs the torque generated by the step motor while still allowing the block to slide.

                An approximation for the torque required to pull the cable can be found using the following equation:

Where, f is the friction coefficient of the material, W is the load carried (the cable tension in this case), is the mean diameter of the thread, L is the Lead (which is equal to the thread pitch in this case), is the contact angle of the thread (which is 60 degrees as this is an ISO thread). The above equation ignores the friction of the ball bearings and only considers the friction from thread contact; however the friction of the ball bearings is very low to begin with, thus it can be neglected. Therefore the torque can be found as follows:

                It is important to note that the cable tension (W) is a variable between different derailleurs. It is therefore possible that, when implemented on some other bicycles, the system would require a greater or lower torque to accomplish the gear changing.

The Step Motor

                The step motor used on the demonstration bike was from a common printer. Very little information could be found pertaining to its operating voltages and maximum torque. Future versions of this system will utilize specifically built step motors. Therefore, more accurate predictions and calculations can be made.

Derailleur Modifications

                The derailleur had to be modified to allow the step motor to be increased in leverage over the derailleur return spring. This was accomplished by increasing the length of the lever arms used to actuate the derailleur. Doing this would of course increase the cable travel required to get to the next gear. The system was designed with a copious amount of cable to travel. Under no circumstances, on any bike, should the cable run out.

Figure 3: The derailleur modifications to allow more leverage.

System Mounting

                The system is comprised of two main mountings.

                The main mount holds the microcontroller, motor driver, lead-screw, step motor, and batteries. All these components mount onto an aluminum bracket that bolts to the bottle cage bolts on the bicycle frame.

Figure 4: The main mount of the system on the down tube of the bicycle

                The Interface mount holds the screen, the selecting buttons, and the warning LED. All these components are on one small circuit board mounted somewhere on the handle bars of the bicycle. Signal Cables run back from the interface board to the main mount to communicate with the Arduino.

Figure 5: The user interface of the system

Electrical System

                The main concern in designing the electrical system was to not overload the Arduino Microcontroller. The input and output ports of the Arduino have very clear restraints on how much current can be sourced or absorbed and at what voltages those ports can operate at.

Motor Driver

                Due to the fact that the Arduino cannot generate enough power by itself to operate the step motor, a motor driver is required. The motor driver consists of 4 identical sections, 1 for each motor pole. Each section has two circuits, the signaling circuit and the power circuit. The signaling circuit takes the 5V output from the Arduino and uses it to drive a transistor which switches the power circuit. The power circuit simply has the battery and the step motor linked to the transistor. The transistor used by the driver is an ECG263, which is an NPN type transistor.

                The signaling circuit also contains a resistor and a diode. The resistor acts simply to limit the current in the signaling circuit as to not exceed the limits of the Arduino. The Arduino can only sustain an output of less than 0.040A at 5V. The size of resistor was chosen so that even in the worst case scenario, a shorted circuit past the resistor, the Arduino would still be okay. The resulting calculation is therefore very simple:

                Therefore resistors greater than  would sufficiently limit the current being emitted from the Arduino to below the max rated current.

                The diode in the circuit protects the Arduino from reverse currents that could be generated when the pin goes from being high, to being low. There is a certain back voltage generated by the motor windings, and the transistor, that must be prevented from getting to the Arduino. The magnitude of these back pulses could not be predicted with current knowledge. Thus the diodes were installed in case they were dangerous.

CIRCUIT DIAGRAM:

Figure 6: Motor driver circuit for 1 pole

 

User Interface

Screen Driver

                The 7 segments common anode display is driven by a 74LS47 screen decoder. It uses 4 Arduino outputs which sent a BCD (binary coded decimal) to the decoder would actuate the required screen LEDs. Summary diagrams of the chip and screen can be seen below:

Figure 7: The 74LS47 screen decoder and common anode display.

                When supplying the chip with 5V and a BCD across pins A, B, C, and D (where D is the least significant bit) the corresponding outputs a, b, c, d, e, f, and g will form the correct digit for the screen.

                The Arduino output pins that go to the screen decoder also needed to be current limited in the same manner that the motor output pins had to be. The same base calculation applied and so any resistor above  would suffice.

CIRCUIT DIAGRAM

                Figure 8: Decoder Circuit for 1 pin

Both the chip and the screen require separate power apart from the signals to operate. This is done through the onboard Arduino power supply. The 74LS47 chip used runs at the TTL standard, which is signified by an operating voltage of 5V. Thankfully the Arduino power supply can produce both 3.3V and 5V, so 5V is supplied directly to the chip. The screen is simply a set of LEDs with a common anode. The LEDs themselves operate at less than 5V and so a resistor needs to be used reduce the voltage (and therefore the current) going to the resistors. The manufacturer of the screen states that the diodes should not be exposed to more than 0.050A. For ease of construction, and to save materials, it was decided that only the input to the screen would be resisted. The alternative, resisting the 7 signal pins, would require 6 more resistors and much more room on the circuit board. The negative side effect of the single resistor is that the digit 1 would appear brighter than the digit 8. This is caused by the current becoming more divided when more screen elements are active, and so each element is not as bright. Without more knowledge of how to predict the resistance of LEDs, it was decided to build both configurations and test them. The single resistor method was found to be adequate; the difference in luminosity was not as considerable as expected. To not exceed 0.050A when 1 lamp is lit would require a resistor of size  as a minimum.

Buttons

                The buttons located on the interface are also resisted to limit the current that will flow through the Arduino. The main difference in their implementation is that the input pin on the Arduino is placed in parallel with the resistor. The switch is outside of this section of the parallel circuit. This means that when the switch is open the pin is ‘pulled down’ by the resistor (which is connected to ground). When the switch is closed, current is divided between the resistor and the Arduino as to not overload the Arduino input pin.

CIRCUIT DIAGRAM

Figure 9: Circuit for 1 Button

Arduino Program

                The program operates in two main modes, normal, and set mode. In normal mode the program runs the loop() method and calls various other methods to update the screen and advance the gears. The loop() method continually checks if any of the buttons have been pressed, and then calls the required methods to complete the task. As soon as the methods have been called the program stops looking at the buttons creating the behavior, noted above, that the program ignores keystrokes when changing gears.

                In set mode, the code is restricted to a method called calibrate() by a ‘while’ loop that waits for the set button to open again. In this calibrate() method, the program looks at the input buttons and simply moves the step motor in that direction 1 cycle (about 7.2 degrees) every time it sees the button pressed. Pressing and holding the button moves the step motor continuously.

                Originally the program was to use the two built-in interrupts on the Arduino, but there was an issue with anti-bouncing. So the plan was scrapped in favor of the current arrangement.

                To implement the system onto another bicycle, two constants in the program would have to be changed. The first is a variable called ‘maxGear’ which specifies the number of gears on the bicycle. The second is a made-up index called ‘spacing’, which describes the number of cycles the motor has to go through to get to the next gear. Changing these two constants to the appropriate values would allow the system to be implemented on almost any bicycle.

  The entire code is attached.

 Arduino Code

//Screen Pins

const int D = 7;

const int C = 6;

const int B = 5;

const int A = 4;

 

//Motor Pins

const int MA = 0;

const int MB = 1;

const int MC = 2;

const int MD = 3;

 

//buttons

const int UP = 8;

const int DOWN = 9;

const int SET = 10;

//warning LED

const int OUTLED = 11;

 

//The gear spacing of the bicycle

const int spacing = 94;

 

//the gear that the bike arbitrarily starts in.

volatile int gear = 8;

 

void setup() {

  //screen pins

  pinMode(A,OUTPUT);

  pinMode(B,OUTPUT);

  pinMode(C,OUTPUT);

  pinMode(D,OUTPUT);

  digitalWrite(A,LOW);

  digitalWrite(B,LOW);

  digitalWrite(C,LOW);

  digitalWrite(D,LOW);

  //motor pins

  pinMode(MA,OUTPUT);

  pinMode(MB,OUTPUT);

  pinMode(MC,OUTPUT);

  pinMode(MD,OUTPUT);

  pinMode(OUTLED, OUTPUT);

  updateDisplay();

}

 

void loop() {

  if(digitalRead(UP)==HIGH)

  {

    up();

  }

  if(digitalRead(DOWN)==HIGH)

  {

    down();

  }

  if(digitalRead(SET)==HIGH)

  {

    digitalWrite(OUTLED,HIGH);

    calibrate();

  }

  if(digitalRead(SET)==LOW)

  {

    digitalWrite(OUTLED,LOW);

  }

}

void updateDisplay()

{

   if((gear/8)%2 > 0)

     digitalWrite(A,HIGH);

   else

     digitalWrite(A,LOW);

   if((gear/4)%2 > 0)

     digitalWrite(B,HIGH);

   else

     digitalWrite(B,LOW);

   if((gear/2)%2 > 0 )

     digitalWrite(C,HIGH);

   else

     digitalWrite(C,LOW);

   if((gear/1)%2 > 0)

     digitalWrite(D,HIGH);

   else

     digitalWrite(D,LOW);

}

void up()

{

  //check gear range

  if(gear ==8)

  {

    flashThree();

  }

  else

  {

    //change gear number for screen

    gear += 1;

    //update display

    updateDisplay();

    //advance motor

    for(int i = 0; i<spacing ;i++)

    {

      for(int j = 0; j<8; j++)

      {

        if(j==0||j==1||j==7)

          digitalWrite(0,HIGH);

        else

          digitalWrite(0,LOW);

        if(j==1||j==2||j==3)

          digitalWrite(1,HIGH);

        else

          digitalWrite(1,LOW);

        if(j==3||j==4||j==5)

          digitalWrite(2,HIGH);

        else

          digitalWrite(2,LOW);

        if(j>4)

          digitalWrite(3,HIGH);

        else

          digitalWrite(3,LOW);

          delay(4);

      }

    }

    clearmotor();

}

}

void calibrate()

{

  //allows the user to fine tune a gear for as long as the set mode is active

  while(digitalRead(SET) == HIGH)

  {

    if(digitalRead(UP)==HIGH)

    {

      for(int j = 0; j<8; j++)

      {

        if(j==0||j==1||j==7)

          digitalWrite(0,HIGH);

        else

          digitalWrite(0,LOW);

        if(j==1||j==2||j==3)

          digitalWrite(1,HIGH);

        else

          digitalWrite(1,LOW);

        if(j==3||j==4||j==5)

          digitalWrite(2,HIGH);

        else

          digitalWrite(2,LOW);

        if(j>4)

          digitalWrite(3,HIGH);

        else

          digitalWrite(3,LOW);

        delay(5);

        digitalWrite(0,LOW);

        digitalWrite(1,LOW);

        digitalWrite(2,LOW);

        digitalWrite(3,LOW);

      }

    }

    if(digitalRead(DOWN)==HIGH)

    {

      for(int j = 7; j>0; j--)

      {

        if(j==0||j==1||j==7)

          digitalWrite(MA,HIGH);

        else

          digitalWrite(MA,LOW);

        if(j==1||j==2||j==3)

          digitalWrite(MB,HIGH);

        else

          digitalWrite(MB,LOW);

        if(j==3||j==4||j==5)

          digitalWrite(MC,HIGH);

        else

          digitalWrite(MC,LOW);

        if(j>4)

          digitalWrite(MD,HIGH);

        else

          digitalWrite(MD,LOW);

        delay(5);

        digitalWrite(0,LOW);

        digitalWrite(1,LOW);

        digitalWrite(2,LOW);

        digitalWrite(3,LOW);

      }

    }

  }

  clearmotor();

}

void down()

{

  //check gear range

  if(gear ==1)

  {

    flashThree();

  }

  else

  {

    //advance gear for screen

    gear -= 1;

    //update display

    updateDisplay();

    //advance motor

    for(int i = 0; i<spacing ;i++)

    {

      for(int j = 7; j>0; j--)

      {

        if(j==0||j==1||j==7)

          digitalWrite(MA,HIGH);

        else

          digitalWrite(MA,LOW);

        if(j==1||j==2||j==3)

          digitalWrite(MB,HIGH);

        else

          digitalWrite(MB,LOW);

        if(j==3||j==4||j==5)

          digitalWrite(MC,HIGH);

        else

          digitalWrite(MC,LOW);

        if(j>4)

          digitalWrite(MD,HIGH);

        else

          digitalWrite(MD,LOW);

          delay(4);

      }

    }

    clearmotor();

  }

}

//warning flash for out of bounds gear

void flashThree()

{

  for(int i = 0;i<5;i++)

  {

    digitalWrite(OUTLED,HIGH);

    delay(50);

    digitalWrite(OUTLED,LOW);

    delay(50);

  }

}

//clears the motor to save power

void clearmotor()

{

  for(int i = 0; i<4; i++)

  {

    digitalWrite(i,LOW);

  }