Robot courier Lesson Ф.1 All coursesFor teachersStudy in the app Student Arduino Uno + L298P motor shield
Topic 7 · Lesson F.1

Encoders: counting revolutions and exact distance

The robot counts the revolutions of the wheels and travels the measured distance, and not “how much it can do in time.”

2 × 45 min1–2 students per robotPractice

Lesson result

The program counts wheel revolutions using encoders and drives the measured distance. The number of pulses per revolution is measured, the accuracy is checked with a ruler. Not needed for the final task.

You will learn

  • Explain how an encoder converts wheel rotations into pulses.
  • Measure the number of pulses per wheel revolution.
  • Convert the distance into impulses using the circumference of the wheel.
  • Drive the measured distance and evaluate the accuracy with a ruler.

Need to know

  • 2.1 Motors: driving and stopping
  • 3.2 P-controller: smooth and fast

Will need

Wheel × 2Geared motor × 2USB cable for Arduino

Why this lesson

In lesson 2.1, the robot used timed movement: the motors ran for two seconds. How far it travels in two seconds depends on battery charge, floor surface and weight. Encoder counts wheel revolutions, so the program can select the stopping moment based on wheel rotation, and not just time. You still need to check the accuracy of the path with a ruler.

For the lesson you need an additional module: an encoder for each wheel. It is not included in the main course package; You can't teach a lesson without it. The elective is not needed for the final task.

Warm up · remember
  1. How did the robot drive through a given area in Lesson 2.1?
  2. Why does a robot with dead batteries travel less in the same two seconds?
  3. What is the P-controller from lesson 3.2 in one phrase?
1
Lesson 1 · 45 min
Counting impulses
1

Why time is a bad ruler

8 min

What should a robot do. The robot needs to drive a given distance more accurately than using a stopwatch. To do this, you will need additional encoders: they are not included in the basic kit. They measure the rotation of the wheels, not the distance to the obstacle.

What we use and how it works. The encoder produces pulses when rotating. The counter accumulates them; The number of pulses per revolution relates the count to the wheel revolutions. The circumference relates the revolutions to the intended path. An interrupt allows the counter to be incremented quickly on a pulse, even when the main program is busy with other work.

How to link a dimension to an action. Let's measure the impulses per revolution and use the diameter of our wheel. On an AVR, reading a multibyte counter can be interrupted in the middle by an interrupt, so we copy it with interrupts briefly turned off. Let's check the result with a ruler: when slipping, the wheel rotates, but the body moves less, so the encoder does not give an absolute coordinate.

  1. Remember the program from lesson 2.1, which moves forward in time. Run it twice: at full speed and at half speed. The time is the same.
  2. Mark where the robot stopped both times. Measure both paths with a ruler and write them down in your journal.
It should work

You see: given the same time, the robot travels different distances.

  1. Run the “timed” program from lesson 2.1 three times: speed 100, 150 and 200 at the same time. Measure the paths with a ruler.
  2. Answer in the journal: what, besides the speed in the program, changes the path at the same time? Give at least three reasons.
It should work

Three paths measured, reasons recorded.

  1. Measure the paths “in time” at speeds of 100, 150 and 200. Construct a “speed - path” table in the journal.
  2. Evaluate: is it possible to recalculate the time for 50 cm at a speed of 120 using this table? How much do you trust such a recalculation tomorrow, on a different battery charge? Explain.
  3. Write down what you need measure while driving, so that the path does not depend on these reasons.
It should work

The table, the conversion estimate and the answer are in the journal.

2

How the encoder works

12 min

The encoder is a disk with slots on the wheel axle and a “fork” sensor. Inside the plug there is an LED on one side and a receiver on the other. When a slot passes by, light hits the receiver and the sensor sends impulse. One revolution of the wheel - as many impulses as there are slots on the disk.

  1. Count the slots on the encoder disk. Write it down in a journal.
  2. Find in your robot's wiring table which pins the encoders are connected to. Write down the numbers.
Security

Do not connect encoders while the power is on. If the encoder contacts are not indicated in the wiring table, the connection is made by the teacher.

It should work

In the log - the number of slots and contact numbers of the left and right encoders.

How it works: What is an interrupt

The pulses come quickly - tens per second. If the program is busy with something else, it may skip them. Therefore the score is made interrupt: for each pulse, the Arduino itself postpones the main program, adds 1 to the counter and returns back. On Arduino Uno, only pins 2 and 3 can do this.

Encoder - a disk with slots on the wheel axle and an optical gap sensor: the slot passes by the sensor - the sensor gives impulse. The pulses will be counted interrupt: The Arduino itself calls a short function on every pulse, no matter what the main program does.

  1. Count the slots on the disk, write down the encoder contact numbers from the wiring table.
Predict

Wheel with a diameter of 45 mm, 20 slots on the disk. How many millimeters does the wheel travel between two pulses? Do the math before you launch.

  1. Answer in the journal: why the pulse counter cannot be increased by loop() after delay(200)?
Security

Do not connect encoders while the power is on. Contacts are not listed in the table - the teacher connects.

Hint: How much does a wheel travel per revolution?

In one revolution, the wheel covers the length of its circumference: π × diameter.

It should work

Number of slots, contacts, mm per impulse forecast and answer about delay - in the journal.

  1. Count the slots, write down the encoder contacts from the wiring table.
  2. Estimate the pulse frequency: 45 mm wheel, 20 slots, robot travels 0.3 m/s. How many pulses per second does each encoder produce?
  3. Explain in the journal why counting is done as an interrupt and why on the Arduino Uno only pins 2 and 3 are suitable for this.
Security

Do not connect encoders while the power is on. Contacts are not listed in the table - the teacher connects.

Hint: Pulse frequency

First, how many revolutions per second does the wheel make at 300 mm/s.

It should work

Frequency estimates and explanation are in the journal.

3

Pulses per revolution

22 min
  1. Create a sketch LF1_Count. Enter the encoder contact numbers.
Pulse countingLF1_Count.ino.ino
// Контакты энкодеров: впиши номера из таблицы проводки своего робота.// На Arduino Uno счёт по прерыванию работает только на контактах 2 и 3.const int LEFT_ENCODER_PIN = -1;const int RIGHT_ENCODER_PIN = -1; // Счётчики импульсов. volatile: их меняет прерывание.volatile long leftTicks = 0;volatile long rightTicks = 0; // Arduino вызывает её сама на каждый импульс левого энкодера.void countLeft() {  leftTicks++;} // То же для правого энкодера.void countRight() {  rightTicks++;} void setupEncoders() {  // Без контактов энкодеров программа дальше не пойдёт.  if (LEFT_ENCODER_PIN < 0 || RIGHT_ENCODER_PIN < 0) {    Serial.println("Впиши контакты энкодеров");    while (true) {    }  }  pinMode(LEFT_ENCODER_PIN, INPUT);  pinMode(RIGHT_ENCODER_PIN, INPUT);  attachInterrupt(digitalPinToInterrupt(LEFT_ENCODER_PIN), countLeft, RISING);  attachInterrupt(digitalPinToInterrupt(RIGHT_ENCODER_PIN), countRight, RISING);} void setup() {  Serial.begin(9600);  setupEncoders();} void loop() {  // Читаем оба счётчика, пока прерывания выключены: число не изменится посередине чтения.  noInterrupts();  long left = leftTicks;  long right = rightTicks;  interrupts();   Serial.print("Левое: ");  Serial.print(left);  Serial.print("  правое: ");  Serial.println(right);  delay(200);}
  1. Upload and open the Serial Monitor. Turn the wheel with your hand: the number should increase.
  2. Make a mark on the wheel with chalk or a marker. Spin the wheel by hand exactly 10 turns by label. Divide the number of pulses by 10 - this is pulses per revolution.
  3. Repeat for the second wheel. Write both numbers in your journal.
It should work

In the log - impulses per revolution for each wheel. This is usually the number of slots on the disc.

If it doesn't work
What do you seeWhat to do
“Enter the encoder contacts”Enter the contact numbers instead of −1
The number is not growingCheck the wires and that the disc fits through the sensor slot
The number increases when the wheel is stationaryThe wheel has stopped at the edge of the slot: move it a little
  1. Create a sketch LF1_Count according to the template. Enter your contacts, write your part.
Template: pulse countingLF1_Count_Gaps.ino.ino
// Шаблон среднего уровня. Напиши код в разделе «Твоя часть» по целям в комментариях. // Контакты энкодеров: впиши номера из таблицы проводки своего робота.// На Arduino Uno счёт по прерыванию работает только на контактах 2 и 3.const int LEFT_ENCODER_PIN = -1;const int RIGHT_ENCODER_PIN = -1; // Счётчики импульсов. volatile: их меняет прерывание.volatile long leftTicks = 0;volatile long rightTicks = 0; // ===== Твоя часть: напиши сам ===== void countLeft() {  // Каждый импульс левого энкодера увеличивает его счётчик на 1.} void countRight() {  // То же для правого энкодера.} void loop() {  long left = 0;  long right = 0;  // Скопируй оба счётчика в left и right так, чтобы прерывание не изменило их посередине чтения.   Serial.print("Левое: ");  Serial.print(left);  Serial.print("  правое: ");  Serial.println(right);  delay(200);} // ===== Готовое: подключение энкодеров — не меняй ===== void setupEncoders() {  // Без контактов энкодеров программа дальше не пойдёт.  if (LEFT_ENCODER_PIN < 0 || RIGHT_ENCODER_PIN < 0) {    Serial.println("Впиши контакты энкодеров");    while (true) {    }  }  pinMode(LEFT_ENCODER_PIN, INPUT);  pinMode(RIGHT_ENCODER_PIN, INPUT);  attachInterrupt(digitalPinToInterrupt(LEFT_ENCODER_PIN), countLeft, RISING);  attachInterrupt(digitalPinToInterrupt(RIGHT_ENCODER_PIN), countRight, RISING);} void setup() {  Serial.begin(9600);  setupEncoders();}
  1. Spin each wheel by hand exactly 10 revolutions along the mark and count the pulses per revolution.
  2. Compare with the number of slots. Coincidence? If not, find the reason.
Hint: How not to spoil a number when reading

Counter - long, these are 4 bytes, and the Arduino reads them one at a time. An interruption in the middle will give a mixture of the old and new number. There are a couple of commands that temporarily disable interrupts.

It should work

The counting works, the pulses per revolution of both wheels are recorded and compared with the number of slots.

Requirement 1. The program counts the pulses of each wheel as an interrupt and prints both counters to the Serial Monitor; The counters are read in such a way that an interrupt does not spoil the number. Without entered contacts, the program does not proceed further.

  1. Write the program yourself.
How it works: Command help
CommandWhat does
attachInterrupt(digitalPinToInterrupt(pin), f, RISING)Call a function f for each edge of the pulse on the contact pin
volatile long xVariable that is changed by the interrupt
noInterrupts() / interrupts()Turn interrupts off and on again
  1. Measure the pulses per revolution: spin the wheel 10 revolutions along the mark, then 20 turns. How different are the two results? Which one is more accurate and why?
  2. Find the position of the wheel at which the score increases without moving. Explain in the log what is happening in the sensor.
Hint: Idea (1 of 2)

Interrupt functions should be short: only increment the counter.

Hint: Counting without moving (2 of 2)

At the edge of the slot, the light hits the receiver “halfway”, and the signal trembles near the threshold.

It should work

The program fulfills requirement 1, the pulses per revolution are measured twice, the explanation of the jitter is recorded.

2
Lesson 2 · 45 min
Exact distance
4

Millimeters to pulses

15 min

In one revolution the wheel covers the circumference: π × диаметр. Wheel diameter - 45 mm. To travel 500 mm, you need 500 / (π × 45) revolutions, and pulses - in TICKS_PER_REV times more.

  1. Count on paper: how many pulses per 500 mm, if there are 20 pulses per revolution?
  2. Create a sketch LF1_Distance, enter the contacts and your number of pulses per revolution.
Exact distanceLF1_Distance.ino.ino
// Контакты энкодеров: впиши номера из таблицы проводки своего робота.// На Arduino Uno счёт по прерыванию работает только на контактах 2 и 3.const int LEFT_ENCODER_PIN = -1;const int RIGHT_ENCODER_PIN = -1; const int LEFT_DIR_PIN = 7;const int LEFT_SPEED_PIN = 6;const int RIGHT_DIR_PIN = 4;const int RIGHT_SPEED_PIN = 5;const int FORWARD = HIGH; const int TICKS_PER_REV = 0; // импульсов на оборот колеса: измерь и впишиconst int WHEEL_DIAMETER_MM = 45;const int DISTANCE_MM = 500; // сколько проехатьint speed = 100; volatile long leftTicks = 0;volatile long rightTicks = 0; void countLeft() {  leftTicks++;} void countRight() {  rightTicks++;} // Сколько импульсов нужно, чтобы проехать mm миллиметров.long ticksFor(int mm, int ticksPerRev, int diameterMm) {  float revolutions = mm / (PI * diameterMm);  return (long)(revolutions * ticksPerRev + 0.5);} // Сколько импульсов в среднем насчитали оба колеса.long averageTicks() {  noInterrupts();  long sum = leftTicks + rightTicks;  interrupts();  return sum / 2;} void drive(int leftDir, int leftSpeed, int rightDir, int rightSpeed) {  digitalWrite(LEFT_DIR_PIN, leftDir);  digitalWrite(RIGHT_DIR_PIN, rightDir);  analogWrite(LEFT_SPEED_PIN, leftSpeed);  analogWrite(RIGHT_SPEED_PIN, rightSpeed);} void setupEncoders() {  // Без контактов энкодеров программа дальше не пойдёт.  if (LEFT_ENCODER_PIN < 0 || RIGHT_ENCODER_PIN < 0) {    Serial.println("Впиши контакты энкодеров");    while (true) {    }  }  pinMode(LEFT_ENCODER_PIN, INPUT);  pinMode(RIGHT_ENCODER_PIN, INPUT);  attachInterrupt(digitalPinToInterrupt(LEFT_ENCODER_PIN), countLeft, RISING);  attachInterrupt(digitalPinToInterrupt(RIGHT_ENCODER_PIN), countRight, RISING);} void setup() {  Serial.begin(9600);  pinMode(LEFT_DIR_PIN, OUTPUT);  pinMode(LEFT_SPEED_PIN, OUTPUT);  pinMode(RIGHT_DIR_PIN, OUTPUT);  pinMode(RIGHT_SPEED_PIN, OUTPUT);  drive(FORWARD, 0, FORWARD, 0);  setupEncoders();   // Без числа импульсов на оборот робот не поедет.  if (TICKS_PER_REV <= 0) {    Serial.println("Впиши число импульсов на оборот");    while (true) {    }  }  delay(2000); // время убрать руки от робота   long target = ticksFor(DISTANCE_MM, TICKS_PER_REV, WHEEL_DIAMETER_MM);  drive(FORWARD, speed, FORWARD, speed);  while (averageTicks() < target) {  }  drive(FORWARD, 0, FORWARD, 0);  delay(1000); // робот докатывается   Serial.print("Цель, импульсов: ");  Serial.println(target);  Serial.print("Насчитано после остановки: ");  Serial.println(averageTicks());} void loop() {}
  1. Place the robot on the floor at the start mark, turn on the power to the motors. The robot will pass and stop. Measure the path with a ruler from the mark to the same point on the body.
It should work

You did the math: about 71 pulses. The robot traveled approximately 50 cm, the path was measured.

  1. Create a sketch LF1_Distance according to the template, write the contacts and pulses on the back.
  2. Write ticksFor and averageTicks by goals.
Template: exact distanceLF1_Distance_Gaps.ino.ino
// Шаблон среднего уровня. Напиши код в разделе «Твоя часть» по целям в комментариях. // Контакты энкодеров: впиши номера из таблицы проводки своего робота.// На Arduino Uno счёт по прерыванию работает только на контактах 2 и 3.const int LEFT_ENCODER_PIN = -1;const int RIGHT_ENCODER_PIN = -1; const int LEFT_DIR_PIN = 7;const int LEFT_SPEED_PIN = 6;const int RIGHT_DIR_PIN = 4;const int RIGHT_SPEED_PIN = 5;const int FORWARD = HIGH; const int TICKS_PER_REV = 0; // импульсов на оборот колеса: измерь и впишиconst int WHEEL_DIAMETER_MM = 45;const int DISTANCE_MM = 500; // сколько проехатьint speed = 100; volatile long leftTicks = 0;volatile long rightTicks = 0; // ===== Твоя часть: напиши сам ===== long ticksFor(int mm, int ticksPerRev, int diameterMm) {  // Сколько оборотов колеса нужно на mm миллиметров: один оборот — длина окружности колеса.  // Сколько это импульсов, округлённо до целого. Число PI в Arduino уже есть.  return 0;} long averageTicks() {  // Среднее двух счётчиков. Читай их так, чтобы прерывание не изменило число посередине.  return 0;} // ===== Готовое: энкодеры, моторы и поездка — не меняй ===== void countLeft() {  leftTicks++;} void countRight() {  rightTicks++;} void drive(int leftDir, int leftSpeed, int rightDir, int rightSpeed) {  digitalWrite(LEFT_DIR_PIN, leftDir);  digitalWrite(RIGHT_DIR_PIN, rightDir);  analogWrite(LEFT_SPEED_PIN, leftSpeed);  analogWrite(RIGHT_SPEED_PIN, rightSpeed);} void setupEncoders() {  // Без контактов энкодеров программа дальше не пойдёт.  if (LEFT_ENCODER_PIN < 0 || RIGHT_ENCODER_PIN < 0) {    Serial.println("Впиши контакты энкодеров");    while (true) {    }  }  pinMode(LEFT_ENCODER_PIN, INPUT);  pinMode(RIGHT_ENCODER_PIN, INPUT);  attachInterrupt(digitalPinToInterrupt(LEFT_ENCODER_PIN), countLeft, RISING);  attachInterrupt(digitalPinToInterrupt(RIGHT_ENCODER_PIN), countRight, RISING);} void setup() {  Serial.begin(9600);  pinMode(LEFT_DIR_PIN, OUTPUT);  pinMode(LEFT_SPEED_PIN, OUTPUT);  pinMode(RIGHT_DIR_PIN, OUTPUT);  pinMode(RIGHT_SPEED_PIN, OUTPUT);  drive(FORWARD, 0, FORWARD, 0);  setupEncoders();   // Без числа импульсов на оборот робот не поедет.  if (TICKS_PER_REV <= 0) {    Serial.println("Впиши число импульсов на оборот");    while (true) {    }  }  delay(2000); // время убрать руки от робота   long target = ticksFor(DISTANCE_MM, TICKS_PER_REV, WHEEL_DIAMETER_MM);  drive(FORWARD, speed, FORWARD, speed);  while (averageTicks() < target) {  }  drive(FORWARD, 0, FORWARD, 0);  delay(1000); // робот докатывается   Serial.print("Цель, импульсов: ");  Serial.println(target);  Serial.print("Насчитано после остановки: ");  Serial.println(averageTicks());} void loop() {}
Predict

How many pulses will return ticksFor(500, 20, 45)? Do the math before you launch.

  1. Start the trip from the mark, measure the path with a ruler. Compare with the Serial Monitor: how much more “counted after stopping” than the target?
Hint: Round to the nearest whole number

If you add 0.5 and discard the fractional part, you will get rounding to the nearest integer.

It should work

The forecast was correct: 71. The robot traveled about 50 cm, the roll after stopping is visible in the Serial Monitor.

Requirement 2. Function long ticksFor(int mm, int ticksPerRev, int diameterMm) converts millimeters to pulses, rounded to the nearest integer and does not overflow on the Arduino Uno.

Acceptance. Write a function in a test sketch. When all the lines PASS, transfer it to your program.

Test of the ticksFor functionLF1_Ticks_Test.ino.ino
// Проверка функции ticksFor. Напиши функцию здесь, загрузи и открой монитор порта.// Когда все строки PASS, перенеси ticksFor в свою программу. // Требование 2: сколько импульсов нужно, чтобы проехать mm миллиметров (округлённо).long ticksFor(int mm, int ticksPerRev, int diameterMm) {  return 0;} int failed = 0; void expect(int mm, int ticksPerRev, int diameterMm, long expected) {  long actual = ticksFor(mm, ticksPerRev, diameterMm);  Serial.print(actual == expected ? "PASS " : "FAIL ");  Serial.print("ticksFor(");  Serial.print(mm);  Serial.print(", ");  Serial.print(ticksPerRev);  Serial.print(", ");  Serial.print(diameterMm);  Serial.print(") = ");  Serial.print(actual);  Serial.print(", ожидаем ");  Serial.println(expected);  if (actual != expected) {    failed++;  }} void setup() {  Serial.begin(9600);   expect(0, 20, 45, 0);  expect(141, 20, 45, 20);   // почти ровно один оборот  expect(500, 20, 45, 71);   // 70.7 округляется вверх  expect(1000, 20, 65, 98);  // другое колесо  expect(1000, 40, 45, 283);  expect(2000, 40, 45, 566); // 2000 × 40 не помещается в int   if (failed == 0) {    Serial.println("Все проверки пройдены");  } else {    Serial.print("Ошибок: ");    Serial.println(failed);  }} void loop() {}

Requirement 3. The program moves forward until average of two counters does not reach the target, stops and prints the target and counted after stopping. Without the entered number of pulses per revolution, the robot stands still.

  1. Fulfill requirements 2 and 3, drive 500 mm from the mark and measure the path.
Hint: Idea (1 of 2)

Pulses = revolutions × pulses per revolution, revolutions = path / circumference.

Hint: Test fails at 2000 mm (2 of 2)

2000 * 40 - 80,000, more than it can hold int. Count in float or long before multiplication.

It should work

Test passed, 500mm trip done and measured.

5

Why does the robot drive further

15 min

After the “stop” command, the robot rolls a little more - like a bicycle if you stop pedaling.

  1. Do three runs of 500 mm. Record the paths in a journal.
  2. Reduce speed to 70 and do three more runs. Has it become more accurate?
speedHeat 1Heat 2Heat 3
100
70
It should work

The table is full. You see at what speed the robot is more accurate.

  1. Do three runs of 500mm. For each, write down the path with a ruler and the “roll” in pulses from the Serial Monitor.
  2. Add an amendment to the program: stop at OVERSHOOT pulses before the target, where OVERSHOOT - average roll of three runs. Do three more runs.
  3. Answer in the journal: will this correction be correct at a different speed? Why?
It should work

Six races in the log, the correction has been checked, the answer about speed has been written down.

Requirement 4. For SLOW_TICKS impulses to the target, the robot slows down in order to roll less after stopping.

  1. Complete requirement 4 and pick up SLOW_TICKS and reduced speed.
  2. Compare three runs without slowing down and three with slowing down: average error and spread.
  3. Explain in the journal why deceleration is better than the “stop N pulses earlier” correction.
It should work

Requirement 4 is met, the comparison of the two methods and the conclusion are in the journal.

6

Quests by level

12 min
Basic · Exactly 50 cm

Drive 500 mm with an error of no more than 2 cm in three out of three runs.

Intermediate level · Right on the meter

Drive 1 m, aligning the wheels according to the difference in impulses: if the left one counts more, slow down the left one and speed up the right one, like the P-controller from lesson 3.2. The robot moves away from the straight line no more than 3 cm.

Advanced · Exactly 90 degrees

Turn 90° in place: the wheels turn in opposite directions, and each travels a quarter-circle whose diameter equals the robot’s track width — 90 mm. Calculate the pulse counts and check the angle with a set square. The error must not exceed 10°.

Test yourself

Test yourself

Select answers to prepare. They are not stored or evaluated on the site. Take the knowledge test in the course syllabus or discuss the answers with your instructor.

● Basic

1.What does the encoder count?
2.There are 20 slots on the disk, each with one pulse. How many pulses are there in 3 revolutions of the wheel?
3.How far does a wheel with a diameter of 45 mm travel in one revolution?
4.Why is driving “on time” inaccurate?
5.Why does the robot go a little further than the target after stopping?

★ Intermediate level

1.20 pulses per revolution, 45 mm wheel. How many pulses are needed for 500 mm?
2.Why is the pulse counter declared as a volatile long?
3.At one time, the left wheel counted 300 impulses, the right wheel counted 270. Where is the robot going?
4.How to more accurately measure the number of pulses per revolution?
5.Why does the “stop 5 pulses earlier” correction stop working at other speeds?

★★ Advanced level

1.The robot turns 90° in place and has a track width of 90 mm. How far does each wheel travel?
2.The function is correct at 500 mm, but for 2000 mm and 40 pulses per revolution it gives the wrong number. What's wrong?
long ticksFor(int mm, int ticksPerRev, int diameterMm) {  int ticks = mm * ticksPerRev / (3.14 * diameterMm);  return ticks;}
3.The wheel stands on the edge of the slot, and the counter grows. What's happening?
4.Why is the target compared to the middle of the two counters, and not to the left one?
5.The long counter is read in loop() without noInterrupts(). What could happen?

Answer questions at your level. Correct answers needed: Beginner - 4 out of 5; Average - 4 out of 5; Advanced - 4 out of 5. Answers will be checked by the teacher or course program.

Summary

The encoder turns wheel revolutions into impulses, and impulses into distance traveled. The robot travels not “as long as it can”, but as long as necessary, regardless of the battery charge.

How to confirm the result

The result of the experiment relates the conditions, program version, observation and conclusion. Comparing attempts with one change helps verify the cause, including failed attempts. The mark refers to practice already completed; repetition for the sake of marking is not necessary. The discrepancy with the forecast sets the next hypothesis to be tested. A model, measurements of a real robot, and an explanation are different types of evidence.

Lesson vocabulary

encoderRPM sensor: a disc with slots on the wheel axle and a sensor that gives an impulse to each slot.
impulseShort encoder signal: the slot has passed the sensor.
interruptArduino postpones the main program and immediately executes a short function when a pulse arrives at the pin.
volatileMarking the variable that is changed by the interrupt: the program reads it again each time.
circumferenceWheel path per revolution: π × diameter.