Precise & Fast Car
This project is inspired by the science olympiad event "Electric Vehicle", where the goal is to create a car that can travel a certain distance as fast and as precisely as possible.
Created by
zliskovyi
Tier 3
39 views
0 followers
Timeline
CAN ⚡🚀
approved Precise & Fast Car ago
Tickets awarded: 165 tickets
Tier: 3
Nice
CAN ⚡🚀
submitted Precise & Fast Car for review ago
zliskovyi
submitted Precise & Fast Car for review ago
zliskovyi
added to the journal ago
Reflection
What's a project without a reflection?
What I learned/got better at
-wiring & circuits
-coding with Arduino
-3d modelling in fusion
What needs more improvement/future ideas
-I think it would be cool to implement PID to make it more accurate.
-Maybe make an integrated pcb??
Overall, this was a fun and enjoyable project and it definitely taught me a lot.
bye for now :)

zliskovyi
added to the journal ago
Programming
I
hated
this
part.
Here's a general idea of how the code works
- waits for button press
- spins motor(at a very high power first to get momentum)
- encoder reads values until the car is almost at the target distance(variable)
- motor stops just in time.
Took me a crap ton of time and a crap ton of vibecoding to figure out what i was doing.
Anyway, heres the code.
// ==== MOTOR PINS ====
const int ENAPIN = 9;
const int IN1PIN = 8;
const int IN2_PIN = 7;
// ==== BUTTON PIN ====
const int BUTTON_PIN = 11;
// ==== ENCODER PINS ====
const int ENCODERAPIN = 2;
const int ENCODERBPIN = 3;
// ==== WHEEL / ENCODER SETTINGS ====
const float WHEELDIAMETERM = 0.0730; // 73 mm wheel
const int PULSESPERREV = 603; // your encoder value
const float DISTANCETARGETM = 4.0; // meters
// ==== MOTOR SPEED SETTINGS ====
// STRONG START
const int PWMKICK = 255; // full power at start
const long KICKDURATION_MS = 1000; // was 300, now longer
// SHORT BOOST AFTER KICK
const int PWMBOOST = 255; // stronger than normal run
const long BOOSTCOUNTS = 600; // how many encoder counts to use boost
// NORMAL RUN
const int PWM_RUN = 255; // normal running speed
// ==== BRAKE / COMPENSATION ====
// how far BEFORE the real target to start braking
const float BRAKECOMPM = 0.05; // 5 cm
// ==== RUNTIME VARS ====
volatile long encoderCount = 0;
float wheelCircumference = PI * WHEELDIAMETERM;
bool lastButtonState = HIGH;
// ===== Motor helpers =====
void stopMotorCoast() {
analogWrite(ENAPIN, 0);
digitalWrite(IN1PIN, LOW);
digitalWrite(IN2_PIN, LOW);
}
void stopMotorBrake() {
// Strong electric brake
digitalWrite(IN1PIN, HIGH);
digitalWrite(IN2PIN, HIGH);
analogWrite(ENA_PIN, 255);
}
void setMotorForwardPWM(int pwm) {
if (pwm < 0) pwm = 0;
if (pwm > 255) pwm = 255;
digitalWrite(IN1PIN, HIGH);
digitalWrite(IN2PIN, LOW);
analogWrite(ENA_PIN, pwm);
}
// ===== Encoder ISR =====
void encoderISR() {
if (digitalRead(ENCODERBPIN))
encoderCount++;
else
encoderCount--;
}
void runMotorWithStrongStart(long targetCounts, long brakeStartCounts) {
encoderCount = 0; // start counting from 0
long startCount = encoderCount;
unsigned long kickStartTime = millis();
while ((millis() - kickStartTime) < KICKDURATIONMS) {
setMotorForwardPWM(PWM_KICK);
}
// 2) BOOST PHASE (more torque until a minimum encoder count)
long boostEndCount = startCount + BOOSTCOUNTS;
while (encoderCount < boostEndCount && encoderCount < brakeStartCounts) {
setMotorForwardPWM(PWMBOOST);
}
// 3) MAIN RUN at constant PWMRUN until brakeStartCounts
while (encoderCount < brakeStartCounts) {
setMotorForwardPWM(PWMRUN);
}
// 4) HARD BRAKE near the end
stopMotorBrake();
delay(150); // tune: 100–250 ms
stopMotorCoast();
}
// ===== SETUP =====
void setup() {
Serial.begin(9600);
Serial.println("Distance Drive (STRONGER START + HARD BRAKE) — press button on PIN 11.");
pinMode(ENAPIN, OUTPUT);
pinMode(IN1PIN, OUTPUT);
pinMode(IN2_PIN, OUTPUT);
pinMode(BUTTONPIN, INPUTPULLUP);
pinMode(ENCODERAPIN, INPUTPULLUP);
pinMode(ENCODERBPIN, INPUTPULLUP);
attachInterrupt(digitalPinToInterrupt(ENCODERAPIN), encoderISR, RISING);
stopMotorCoast();
}
// ===== MAIN LOOP =====
void loop() {
int buttonState = digitalRead(BUTTON_PIN);
// Detect button press (HIGH -> LOW)
if (lastButtonState == HIGH && buttonState == LOW) {
Serial.println("Button pressed → starting movement.");
encoderCount = 0;
long targetCounts = (long)((DISTANCE_TARGET_M / wheelCircumference) * PULSES_PER_REV);
long brakeStartCounts = (long)(((DISTANCE_TARGET_M - BRAKE_COMP_M) / wheelCircumference) * PULSES_PER_REV);
if (brakeStartCounts < 0) brakeStartCounts = 0;
Serial.print("Target counts: ");
Serial.println(targetCounts);
Serial.print("Brake start counts: ");
Serial.println(brakeStartCounts);
runMotorWithStrongStart(targetCounts, brakeStartCounts);
Serial.print("Final encoderCount = ");
Serial.println(encoderCount);
Serial.println("Movement complete.");
}
lastButtonState = buttonState;
}
I uploaded the code and it worked yay

Still needs some tuning of variables depending on distance but works pretty well :D
zliskovyi
added to the journal ago
Assembling & wiring the vehicle
My favorite part yay!
This went pretty smoothly as I already had the circuit ready; I just had to put everything in its place.
I screwed in the encoder and motor to the printed mounts with m3 screws.
I taped the battery using double sided tape and did the same with the arduino and the L298N(BTW, I rewired some junctions using lever connectors, but the schematic did not change.)
I put in the axles using 8mm od/4mm id bearings and attached BaneBots 2 7/8 in diameter wheels to the outside. I attached gears to connect the encoder and motor on the axle using shaft collars screwed to connect to the gears.

The zipties in the picture are not necessary, but I dropped the vehicle while carrying it and a bearing holder (below) fell off so I ziptied everything for peace of mind.


** in a future redesign I would definitely reinforce everything as right now some parts are flimsy.
zliskovyi
added to the journal ago
Printing and test circuit
While I was waiting for the car to print on my A1, I started wiring the circuit just as a test. Due to the nature of the parts I was using, trying to create a schematic on TinkerCad or Kicad was simply not viable. I just had to go straight to wiring and try to figure everything out.
With that being said, here is the wiring.
Both motor wires - L298N out1&out2
button - any arduino pwm pin
battery - split between arduino jack and l298n.
L298N IN1 → Arduino D8
L298N IN2 → Arduino D9
L298N ENA → Arduino D10 (PWM pin)
Encoder +5V → Arduino 5V
Encoder GND → Arduino GND
Encoder A → Arduino D pin
Encoder B → Arduino D pin
i friggin hate wiring i wish i could test all of this online or smth
While wiring I put a gnd wire to +5v breadboard rail and the arduino caught fire.
not good.

encoder is just out of the picture but you can see it wired
here is the finished print BTW, came out pretty well!

zliskovyi
added to the journal ago
CAD
spent a couple of hours cading the car in fusion.
Has a space to slide a 2x4 AA battery pack in, has mounts for the motor and encoder(each will be connected on a separate axle),and has an iron-sight (primitive) aiming device.
These Pictures show just the model that will be 3d printed. It is designed to be a single body and fits a 256x256mm print bed(just barely).



The pictures below are some renders with all of the physical parts included. These will hopefully resemble the future final build.
note: wheels are missing as I haven't decided which ones to get :/


boy do i love rendering
Finding good models of hardware took a bit.
everything else was pretty straightforward but tedious.
zliskovyi
added to the journal ago
Brainstorming & Gathering parts
Note: This project will not request any funding because I already have most of the items needed, and, if I don't, I will buy them on my own.
brainstorming
my plan is to make the vehicle using just one motor connected through gears to an axle. Moreover, I will use a rotary encoder to determine the distance traveled by the car.
gathering parts
encoder - 600ppr rotary encoder
https://www.amazon.com/Photoelectric-Incremental-Encoder-DC5-24V-Optical/dp/B0DS5Q5649/ref=sr_1_4?sr=8-4
motor driver(to control the motor) - L298N
board(to control everything) - Arduino Uno R4 Wifi
misc- m3 screws, button, jumper wires, lever connectors, 8x AA battery pack, etc

zliskovyi
started Precise & Fast Car ago