Differential Steering Car With Arduino

About: I am a fan of arduino, and I like to make some of my favorite robots.

Hey, everyone, I'm wsurging, and I'm sending out my new car tutorial again. This is almost the same structure as the previous steering gear, but the rear wheel has added a RC model differential. Unfortunately, there is no With the addition of a shock absorber system, this car model has been ready for a long time, but it has not been sent out and it is here today.

The car model is also the rear drive structure. The front wheel is responsible for steering and the rear wheel is driven. Compared with the previous one, the car with the differential has a quicker steering, and the car model also uses the high-speed motor RS380. This car model can also be used directly. RC accessories to control, add electronic governor and remote control.

Let's take a look at how to install it. I will list the parts used in detail, let us look at it:

Step 1: Accessories

The required accessories are:

Frame

Arduino UNO R3 motherboard

Expanding board

Motor drive module

PS2 wireless controller SONY (model remote control or gun remote control)

lithium polymer battery(Li-Po 2S)

Step 2: Steering Cup and Transmission Shaft

Each of the accessories is 2 sets, 2 sets can be assembled, and subsequent installation on the chassis.

  1. Black steering cup x 2
  2. Rotary axis x 2
  3. Bearing x 4 (inside 4 outside 8mm, inner 8 outside 12mm)
  4. Pin x 2
  5. Hexagon x 2
  6. Wheels x 2
  7. M4 locknut x 2
  8. 65mm wheel x 2

Step 3: Install Servo Accessories

Fix the L-bracket to the servo, pay attention to the length of the bracket (red circle). Before installing the steering angle on the steering gear, please center it at 90° (1500μs) to facilitate subsequent installation and commissioning.

  1. M2.5 x 10mm screw x 1
  2. M3 x 6mm screw x 1
  3. M3 x 8mm screws x 4
  4. M2.5 locknut x 1
  5. M3 nuts x 4
  6. MG996R servo x 1
  7. Ball head lever (short) x 1
  8. Rudder angle x 1
  9. L type bracket x 1
  • Name :MG996R
  • Voltage: 4.8-7.2V
  • Current :400-800MA
  • Steering gear torque: 10kg.cm
  • Extreme angle: 180°
  • Wire length: 30CM
  • Gear material: metal
  • Control system: change pulse width

Servo wiring: digital port I/O4

Step 4: Connecting 2 Side Steering Cups

The long connecting rod is in the upper hole and connects the 2 side steering cups; the short connecting rod is in the lower hole, the steering cup is connected on one side, the rudder angle is connected on the other side, and the long and short connecting rods are not in the same hole position.

Long link hole spacing 65mm, short link hole spacing 46mm, fine adjustment if deviation.

  1. M2.5 x 10mm screw x 3
  2. Long and short connecting rod x 2

Step 5: Flat Front Part

Before installation, make sure that the chassis is facing forward and backward, bend upwards, and fix the previously equipped steering gear and steering cup to the chassis. The steering cup is fixed on both sides by the copper column support, and the plastic cylinder is placed under the steering cup (the front and rear heights are consistent) , the steering cup fixing screw can not be tightened to ensure flexible steering.

  1. Chassis x 1
  2. M3 x 26mm copper pillars x 4
  3. M2.5 x 8mm screws x 2 (UP)
  4. M2.5 x 12mm screw x 2 (DOWN)
  5. M3 x 8mm screw x 12
  6. M3 nut x 4
  7. Black cylindrical x 2 (red box)

Step 6: Rear Wheel Differential Section

The rear wheel seat needs to be fixed lastly. The drive shaft is fixed to the output shaft firstly. The rear wheel is installed similarly to the front wheel; the rear wheel seat is installed in the left and right,*the top R is installed on the left side, and the standard L is installed on the right side.

The lower support is a Z-shaped structure. The installation needs to pay attention to the direction, close to the differential box width, and the wheel base is narrow. If it is unclear, it can be consistent with the viewing angle in the figure.Upper support fixation requires removal of screws for installation.

    1. Differential x 1
    2. Transmission shaft x 2
    3. Triangle bracket x 4
    4. Z type bracket x 4
    5. Rear wheel seat x 2
    6. Bearings x 4
    7. Hexagonal adapter x 2
    8. Pin x 2
    9. Aluminum cylinder x 2(Fixed between the upper support (triangle) and rear wheel seat)
    10. 65mm wheel x 2
    11. M2 x 12mm screw x 2
    12. M2 locknut x 2
    13. M2.5 x 16mm screws x 4
    14. M2.5 x 25mm screw x 2
    15. M2.5 x 30mm screws x 2
    16. M2.5 Locknut x 8
    17. M4 Locknut x 2

    Step 7: Differential Box Fixed to Chassis

    Fit the copper gear to the input shaft of the reduction gear box, fix the locking screw to the D type plane, fix it tightly with an L-type wrench, and fix the differential box on the chassis

    1. M2.5 x 8mm screw x 4
    2. Bull gear 0.5 die 54 teeth x 1

    Step 8: Motor Fixing

    The motor is first fixed to the large bracket, and then fixed to the chassis. The bracket is fixed with M3 screws. The motor is fixed on the bracket and the left and right positions of the motor can be adjusted to set the tightness of the gear.

    1. M2.5 x 5mm screws x 2 (flat head screws)
    2. M3 x 6mm screw x 3 (with gasket)
    3. L type motor bracket
    4. RS380 DC motor

    parameter:

    1. Operating voltage range: 3.0-9.0V
    2. Rated voltage: 7.2V
    3. No load speed: 16200rpm
    4. No load current: 0.50A
    5. Rated speed: 14000rpm
    6. Maximum current: 3.29A
    7. Rated torque: 110g.cm
    8. Rated power: 15.8W
    9. Starting torque: 840g.cm

    The red dot of the electrode is positive.

    Step 9: Upper Chassis Mounting (Acrylic)

    Upper chassis is made of acrylic material, with Arduino UNO and Raspberry Pi holes integrated,Rocker switch installed in rectangular hole

    1. M3 x 8mm screws x 9
    2. M3 x 35mm copper pillars x 5
    3. Rocker Switch x 1
    4. Acrylic x 1

    Step 10: Anti-collision Cotton

    The red circle is the copper column fixing hole, and the bumper cotton is pressed with a gasket

    1. M3 x 8mm screw x 8
    2. M3 gasket x 4
    3. M3 x 16mm copper column x 4
    4. Anti-collision cotton x 1

    Step 11: Motor Drive Module

    The MD01 motor driver consists of a single H-bridge driver IC plus four external N-channel MOS transistors. Its compact size (L*W: 3.3*2cm), the motherboard supports 5.9V to 30V wide voltage input, continuous current can reach 17A, support 100% pulse width modulation. The module realizes forward, reverse and speed control of the motor through the direction DIR pin and the speed control PWM pin.

    The control terminal supports 1.8V-5V logic input, and the driver IC integrates PWM current regulation function, which limits the motor surge current. The low level of the SLP pin allows the MD01 driver module to enter a low-power mode, resulting in a low quiescent current consumption of approximately 9uA.

    Note: SLP low-power mode, the default low level, needs to keep the SLP pin high when in use, and can directly connect +5V if you do not need to use the low-power mode.

    1. Working voltage: 5.9-13V
    2. Working current: 17A
    3. Logic input: 1.8V, 3.3V, 5V (max)
    4. PWM frequency: 100kHz
    5. Current detection: 50mV/A (only valid when forward or reverse)
    6. Reflected voltage protection: none (VM and GND must not be reversed)

    Step 12: Remote Control (2.4Ghz)

    2.4Ghz remote control We use Sony's PS2, you can also use the RC model controller; if you have an electronic governor, you probably don't need Arduino UNO to join in, but we are learning to use Arduino.

    The handle is equipped with an adapter plate for easy wiring and reverse connection protection. The interface is up to the bottom:GND VCC DAT CMD CS CLK

    /****************************************************************************
    * The program controls the forward and backward * movement of the motor through the Y-axis of the left joystick, * the X-axis of the right joystick controls the left and right of the servo, * the button part also writes forward and backward, * and the right button controls the left and right. *****************************************************************************/ #include <Servo.h>

    #include <PS2X_lib.h>

    //for v1.6 PS2X ps2x; Servo myservo;

    #define PS2_DAT A0 #define PS2_CMD A1 //PS2 #define PS2_SEL A2 #define PS2_CLK A3 #define PWM 5 //Motor A's pin #define DIR 6 //Motor A's pin #define SERVOPIN 4 //servo's pin

    #define SERVOMIN 40 //the angle of servo #define SERVOMID 90 #define SERVOMAX 130 #define TURNLEFT myservo.write(SERVOMIN) //turn left #define TURNMID myservo.write(SERVOMID) //turn middle #define TURNRIGHT myservo.write(SERVOMAX) //turn right #define MOTORFOWARD setMotor(100) //motor forward PWM #define MOTORBACK setMotor(-100) //motor back PWM #define MOTORSTOP setMotor(0) //motor stop PWM

    bool EnableRockerR = 1; bool EnableRockerL = 1; int RMid = 0 ; int LStop = 0 ;

    #define pressures false #define rumble false int error = 0; byte type = 0; byte vibrate = 0; void(* resetFunc) (void) = 0;

    void setup() { Serial.begin(57600); pinMode(PWM, OUTPUT); pinMode(DIR, OUTPUT); myservo.attach(SERVOPIN); SERVOMID; delay(300); error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, pressures, rumble);

    if (error == 0) { Serial.print("Found Controller, configured successful "); Serial.print("pressures = "); if (pressures) Serial.println("true "); else Serial.println("false"); Serial.print("rumble = "); if (rumble) Serial.println("true)"); else Serial.println("false"); Serial.println("Try out all the buttons, X will vibrate the controller, faster as you press harder;"); Serial.println("holding L1 or R1 will print out the analog stick values."); Serial.println("Note: Go to www.billporter.info for updates and to report bugs."); } else if (error == 1) Serial.println("No controller found, check wiring, see readme.txt to enable debug. visit www.billporter.info for troubleshooting tips");

    else if (error == 2) Serial.println("Controller found but not accepting commands. see readme.txt to enable debug. Visit www.billporter.info for troubleshooting tips");

    else if (error == 3) Serial.println("Controller refusing to enter Pressures mode, may not support it. ");

    type = ps2x.readType(); switch (type) { case 0: Serial.print("Unknown Controller type found "); break; case 1: Serial.print("DualShock Controller found "); break; case 2: Serial.print("GuitarHero Controller found "); break; case 3: Serial.print("Wireless Sony DualShock Controller found "); break; } }

    void loop() { if (error == 1) //skip loop if no controller found resetFunc(); ps2x.read_gamepad(false, vibrate); //read controller and set large motor to spin at 'vibrate' speed

    if (ps2x.Button(PSB_START)) //will be TRUE as long as button is pressed Serial.println("Start is being held"); if (ps2x.Button(PSB_SELECT)) Serial.println("Select is being held");

    if (ps2x.ButtonPressed(PSB_PAD_UP)) { Serial.println("PAD_UP just pressed"); MOTORFOWARD; EnableRockerL = 0; }else if(ps2x.ButtonReleased(PSB_PAD_UP)) { Serial.println(" PAD_UP just released"); MOTORSTOP; EnableRockerL = 1; LStop = 0; }

    if (ps2x.ButtonPressed(PSB_PAD_DOWN)) { Serial.println("PAD_DOWN just pressed"); MOTORBACK; EnableRockerL = 0; }else if(ps2x.ButtonReleased(PSB_PAD_DOWN)) { Serial.println(" PAD_DOWN just released"); MOTORSTOP; EnableRockerL = 1; LStop = 0; }

    if (EnableRockerL) { //Forward and Back if (0 <= ps2x.Analog(PSS_LY) && ps2x.Analog(PSS_LY) <= 110) { digitalWrite(DIR, HIGH); analogWrite(PWM, map(ps2x.Analog(PSS_LY), 0, 110, 255,0)); LStop = 0; } else if (255 >= ps2x.Analog(PSS_LY) && ps2x.Analog(PSS_LY) >= 140) { digitalWrite(DIR, LOW); analogWrite(PWM, map(ps2x.Analog(PSS_LY), 140, 255, 0,255)); LStop = 0; } else { if(LStop == 0){ MOTORSTOP; LStop ++; } } }

    if (ps2x.ButtonPressed(PSB_CIRCLE)) { //will be TRUE if button was JUST pressed Serial.println("Circle just pressed"); TURNRIGHT; EnableRockerR = 0; } else if (ps2x.ButtonReleased(PSB_CIRCLE)) { Serial.println("Circle just released"); TURNMID; EnableRockerR = 1; RMid = 0; } if (ps2x.ButtonPressed(PSB_SQUARE)) { //will be TRUE if button was JUST released Serial.println("Square just pressed"); TURNLEFT; EnableRockerR = 0; } else if (ps2x.ButtonReleased(PSB_SQUARE)) { //will be TRUE if button was JUST released Serial.println("Square just released"); TURNMID; EnableRockerR = 1; RMid = 0; } if (EnableRockerR) { //Left and Right if (0 <= ps2x.Analog(PSS_RX) && ps2x.Analog(PSS_RX) <= 110) { myservo.write(map(ps2x.Analog(PSS_RX), 0, 110, 40,90)); RMid = 0; } else if (255 >= ps2x.Analog(PSS_RX) && ps2x.Analog(PSS_RX) >= 140) { myservo.write(map(ps2x.Analog(PSS_RX), 140, 255, 90,130)); RMid = 0; }else { if(RMid == 0){ TURNMID; RMid ++; } } }

    if (ps2x.NewButtonState(PSB_CROSS)) { //will be TRUE if button was JUST pressed OR released Serial.println("X just changed"); MOTORSTOP; } delay(50); }

    void setMotor(int Speed) //Motor drive function { if (Speed > 0) { digitalWrite(DIR, HIGH); analogWrite(PWM, Speed); } else if(Speed < 0){ digitalWrite(DIR, LOW); analogWrite(PWM, -Speed); }else{ digitalWrite(PWM, LOW); digitalWrite(DIR, LOW); } }

    Step 13: RC Receiver(FS-TH9X)

    If you are using a model remote, you can control your robot as follows. I simply wrote some code with the interrupt, and if you need it, you can improve it and make it better.I am using the FS-TH9X. I am using the left and right throttles. In order to return, I use the right joystick to control the forward and backward movement of the robot. When I center, I stop. The left joystick controls the left and right steering. For me, it may be used. Not used to it, if you need FS-TH9X information, please Google.

    I use CH3 (throttle) and CH4 (direction). It is easy to use when wiring. It is OK to supply the receiver with 5v and GND. Use the 5V pin on the Arduino UNO. Maybe UNO may not provide enough. The current is used to maintain the normal operation of the receiver and servo. At this time, you need an external power supply to supply power to the servo or receiver. Of course, you need to supply the ground.

    Wiring:
    CH3>>Arduino I/O2

    CH4>>Arduino I/O3

    //The two channels of the receiver are connected to the
    //digital port 2 and 3 of the arduino respectively. int ppm1 = 2; int ppm2 = 3;

    unsigned long rc1_PulseStartTicks,rc2_PulseStartTicks; volatile int rc1_val, rc2_val;

    void setup() { Serial.begin(9600); pinMode(ppm1, INPUT); //PPM inputs from RC receiver pinMode(ppm2, INPUT); attachInterrupt(0, rc1, CHANGE); // Level change trigger interrupt attachInterrupt(1, rc2, CHANGE); }

    void rc1(){ // did the pin change to high or low? if (digitalRead( ppm1 ) == HIGH) rc1_PulseStartTicks = micros(); // store the current micros() value else rc1_val = micros() - rc1_PulseStartTicks; }

    void rc2(){ // did the pin change to high or low? if (digitalRead( ppm2 ) == HIGH) rc2_PulseStartTicks = micros(); else rc2_val = micros() - rc2_PulseStartTicks; }

    void loop() { Serial.print("CH1: ");Serial.print(rc1_val); Serial.print(" ");//print values Serial.print("CH2: ");Serial.println(rc2_val); delay(200); }

    Remember to turn on the transmitter first when controlling

    #include <Servo.h>

    Servo myservo; //The two channels of the receiver are connected to the digital port 2 and 3 of the arduino respectively. int ppm1 = 2; int ppm2 = 3;

    int servo = 4; //Servo pin int PWM = 5; //Motor pin int DIR = 6; //Motor pin

    unsigned long rc1_PulseStartTicks,rc2_PulseStartTicks; volatile int rc1_val, rc2_val;

    void setup() { Serial.begin(9600); pinMode(DIR ,OUTPUT); pinMode(PWM ,OUTPUT); myservo.attach(servo); pinMode(ppm1, INPUT); //PPM inputs from RC receiver pinMode(ppm2, INPUT); attachInterrupt(0, rc1, CHANGE); // Level change trigger interrupt attachInterrupt(1, rc2, CHANGE); }

    void rc1(){ // did the pin change to high or low? if (digitalRead( ppm1 ) == HIGH) rc1_PulseStartTicks = micros(); // store the current micros() value else rc1_val = micros() - rc1_PulseStartTicks; }

    void rc2(){ // did the pin change to high or low? if (digitalRead( ppm2 ) == HIGH) rc2_PulseStartTicks = micros(); else rc2_val = micros() - rc2_PulseStartTicks; }

    void loop() { if(rc1_val < 1100){ rc1_val = 1100; } if(rc1_val > 1900){ rc1_val = 1900; } if(rc2_val < 1100){ rc2_val = 1100; } if(rc2_val > 1850){ rc2_val = 1850; } if(rc1_val >= 1100 && rc1_val <= 1490) { digitalWrite(DIR ,LOW); analogWrite(PWM,map(rc1_val,1100,1490,255,0)); } else if(rc1_val >= 1510 && rc1_val <= 1900) { digitalWrite(DIR ,HIGH); analogWrite(PWM,map(rc1_val,1510,1900,0,255)); }else{ digitalWrite(PWM, LOW); digitalWrite(DIR, LOW); } if(rc2_val >= 1100 && rc2_val <= 1490) { myservo.write(map(rc2_val,1100,1490,40,89)); } else if(rc2_val >= 1510 && rc2_val <= 1850) { myservo.write(map(rc2_val,1510,1850,91,130)); } delay(15); }

    Share

      Recommendations

      • Sweet Treats Challenge

        Sweet Treats Challenge
      • Organization Contest

        Organization Contest
      • Warm and Fuzzy Contest

        Warm and Fuzzy Contest

      Discussions