Line sensors: following a line for the first time
The robot “looks” at the floor, distinguishes black from white and follows the line itself.
Lesson result
The robot drives along a black line with a smooth bend, turning according to signals from two sensors. The logbook records sensor readings in white and black.
You will learn
- Read the sensor readings using the analogRead command and output them to the Serial Monitor.
- Distinguish between Serial Monitor lines and telemetry channels with time and units; compare the saved readings of the model and the real robot.
- Measure the readings on white and black and explain why each sensor has different readings.
- Write down the rule “the reading is closer to black, which means there is a line under the sensor.”
- Make two rules for turning and test them first on the stand, then on the track.
Need to know
- 1.1 Assembling the robot and reviving the board
- 2.1 Motors: driving and stopping
Will need
Why this lesson
Until now, the robot only did what you wrote down in advance: drive this way, turn this way. Today he will begin to make decisions himself. Two sensors will look at the floor, and the robot will turn when the line goes to the side.
- What command sets the speed of the motor and what numbers does it accept?
- What does
delay(500)? - Which wheel must be stopped for the robot to turn left?
How can a robot "see" the black line if it doesn't have a camera? Discuss with your partner and record your guess in the logbook. Check at the end of the lesson.
While you are changing the wires, the USB cable is disconnected and the power to the motors is turned off. Experiments with motors - first on a stand: the wheels do not touch the table.
Prepare the path and the robot
5 minWhat should a robot do. To follow the path, the robot needs to notice when the line is under the left or right sensor. To do this, we use two downward-facing reflection sensors; they look at the floor rather than looking for objects in front.
What we use and how it works. The sensor has an emitter and a receiver of reflected light. Surfaces reflect light in different ways, and the receiver converts the reflected light into an electrical signal. analogRead reads it as a number. This is not a ready-made “black” answer: first we measure white and black for each sensor at working height.
How to link a dimension to an action. The program compares the reading with the measured threshold and selects the action of the wheels. Above the line on the left and right you should get different correction commands. Let's check four combinations of cards on the stand, then move along the line. The same readings from both sensors do not yet prove that the robot is standing correctly: both can be on white or black.
The sensor needs a clear picture: a light background and a dark line.
- Take a light matte field with a black line (or stick matte black tape on a white sheet). For starters, a straight line with one smooth bend is enough.
- Prepare two cards: white and black.
- Find the left and right sensors on the robot. They look down and stand on either side of the line when the robot is standing on it.
The track and cards are ready. You can show the left and right sensor.
The sensor needs a clear picture: a light background and a dark line. For intermediate level tasks on the path you will also need an intersection.
- Take a light matte field with a black line or stick black matte electrical tape on a white sheet: straight, smooth bend and one intersection.
- Prepare two cards: white and black.
- Find the left and right sensors on the robot. Put the robot on the line and check: does the line pass between the sensors and not touch any of them?
The path with the intersection and the cards are ready. The line is placed between the sensors.
Prepare a track for your level and check if it suits your robot.
- Make a path: straight, smooth bend, sharp arc and intersection. Prepare white and black cards.
- Using a ruler, measure the width of the line and the distance between the sensors (between the centers of the windows).
- Put the robot on the line. How many millimeters are left from the edge of the line to each sensor? Write in your journal: what happens if the line is wider than the distance between the sensors?
The track is ready, in the log there is the width of the line, the distance between the sensors, the margin on each side and the answer to the question.
Look what the sensor sees
12 minThe sensor shines on the floor and measures how much light has returned. The fee turns it into a number.
To see the number, the board will send it to the computer, and we will open Serial Monitor.
- Create a sketch
L31_Read_Sensorsand type the program. The left sensor is connected toA4, right - toA5.
const int LEFT_SENSOR_PIN = A4;const int RIGHT_SENSOR_PIN = A5; void setup() { Serial.begin(9600);} void loop() { int leftValue = analogRead(LEFT_SENSOR_PIN); int rightValue = analogRead(RIGHT_SENSOR_PIN); Serial.print("L="); Serial.print(leftValue); Serial.print(" R="); Serial.println(rightValue); delay(200);}
- Upload the program. Open up Tools → Port Monitor and select speed 9600.
- Place a white card under the left sensor, then a black one. Keep the card at the same height as the sensor above the floor.
The monitor displays lines like L=… R=…. When you change the card under the sensor, its number changes noticeably.
How it works: What each line means
analogRead(LEFT_SENSOR_PIN)— read the sensor reading: a number from 0 to 1023.int leftValue = …- save the number to a variableleftValue.intis an integer.Serial.begin(9600)- start communication with the computer. 9600 - speed, the same should be selected in the Serial Monitor.Serial.printprints on the same line,Serial.println- prints and moves to a new one.- The text in quotes is printed as is, and the variable name without quotes is replaced with its number.
| What do you see | What to do |
|---|---|
| Strange symbols instead of numbers | In the Serial Monitor, select 9600. |
| The number does not change | Check the S signal wire and the input number in the program. |
| The wrong sensor is being replaced | The left and right sensor wires are mixed up. Swap their places or numbers in the program. |
The sensor shines on the floor and measures how much light has returned. The board turns this into a number, and to see it, the program sends the number to the computer.
| Command | What does |
|---|---|
analogRead(контакт) | Sensor reading: number from 0 to 1023 |
Serial.begin(9600); | Enables communication with the computer, once |
Serial.print(x); | Prints on the same line |
Serial.println(x); | Prints and goes to a new line |
- Create a sketch
L31_Read_Sensorsaccording to the template and write both parts yourself. The left sensor is connected toA4, right - toA5.
// Шаблон среднего уровня. Напиши код в разделе «Твоя часть» по целям в комментариях. const int LEFT_SENSOR_PIN = A4;const int RIGHT_SENSOR_PIN = A5; // ===== Твоя часть: напиши сам ===== void setup() { // Включи связь с компьютером на той же скорости, что в мониторе порта: 9600.} void loop() { // Пять раз в секунду печатай одну строку: L=число левого датчика R=число правого.}
- Upload the program and open the Serial Monitor with speed 9600.
- Place a white card under the left sensor, then a black one. Keep the card at the same height as the sensor above the floor.
What will the monitor print if the variable name is in Serial.print put in quotes?
Hint: Text and number on the same line
The text in quotes is printed as is, and the variable name without quotes is replaced with its number.
The monitor displays lines like L=… R=…. When you change the card under the sensor, its number changes noticeably.
| What do you see | What to do |
|---|---|
| Strange symbols instead of numbers | The speed in the Serial Monitor and in the program must match: 9600. |
| All numbers in one long line | No newline. |
| The wrong sensor is being replaced | The left and right sensor wires are mixed up. |
The sensor shines on the floor and measures how much light has returned. The left sensor is connected to A4, right - to A5.
How it works: Command help
| Command | What does |
|---|---|
analogRead(pin) | Sensor reading: number from 0 to 1023 |
Serial.begin(9600) | Enables communication with the computer, once every setup() |
Serial.print(x) / Serial.println(x) | Prints to the Serial Monitor; println - with line transition |
millis() | How many milliseconds have passed since the board was turned on |
Requirement. Sketch L31_Read_Sensors prints the line five times per second t=… L=… R=…, where t — time in milliseconds since switching on.
Acceptance.
- By numbers
tin the monitor, check that the lines are coming approximately every 200 ms. How many milliseconds does the interval differ from 200 and why? - Place a white card under the left sensor, then a black card at working height. Write down how much the number changes.
Hint: Why is the gap not exactly 200
How long does reading and printing take, except delay(200)?
The program fulfills the requirement. In the logbook there is a real gap between the lines with an explanation and a change in number in white and black.
Check both sensors
8 minWill the left and right sensor numbers be the same over the same white field?
- Place the robot on the white field. Remember the numbers L and R.
- Place the black card only under the left sensor, then only under the right one.
- Move the robot so that the line is exactly between the sensors. What are the numbers now?
You know what number each sensor has on white and how it changes on black. When the line is between the sensors, both show "white".
Will the left and right sensor numbers be the same over the same white field?
- Fill out the table for the four robot positions:
| Position | L | R |
|---|---|---|
| Both over white | ||
| Black only under the left | ||
| Black only under the right | ||
| Line exactly between sensors |
- Why are both numbers “white” in the last line, although the robot is on the line? Write it down.
The table is filled in, the forecast is checked, the answer about the position “between the sensors” is written down.
Take it off profile sensors: how the numbers change while the line passes crosswise under the robot.
- Place the robot across the line so that the line is far to the right of the right sensor.
- Move the robot to the left in 5 mm steps until the line goes beyond the left sensor. Write down L and R at each step.
| Shift, mm | L | R |
|---|---|---|
| 0 | ||
| 5 | ||
| … |
- Draw two graphs in your journal: L and R versus shift. Find on the graph where the line is exactly between the sensors and how many millimeters you can go to the side until the sensor notices it.
Table and two graphs. The log shows the width of the “blind zone” between the sensors in millimeters.
Measure white and black
12 minThe sensors are not the same: even over the same field their numbers are different. Therefore, each sensor needs its own measurements. According to its measurements, such a setting is called calibration.
- Place the robot on the white field. Look at a few lines and write down a typical left gauge number in your logbook: “Left, white.”
- Draw a black line under the left sensor. Write down "Left, black."
- Repeat for the right sensor.
- Test yourself: repeat each measurement again. The numbers should be close to those written down.
| Sensor | White | Black |
|---|---|---|
| Left | ||
| Right |
There are four numbers in the journal. White and black are noticeably different for each sensor.
Hint: White and black are almost the same
The sensor may be too high or the line may be shiny. Lower the sensors closer to the floor and check the line in another area of the field where there is no glare.
How it works: Why is black a large number for some sensors, and a small number for others?
This depends on the sensor design. Some give out a higher number the more light has returned, others - vice versa. Therefore, we do not remember “black is a lot”, but measure our numbers.
The sensors are not the same: even over the same field their numbers are different. Therefore, each sensor needs its own measurements - calibration.
- For each sensor, record three readings on white and three on black, in different places on the track.
- Choose a typical number for each cell and write down why.
| Sensor | White: 3 numbers | White | Black: 3 numbers | Black |
|---|---|---|---|---|
| Left | ||||
| Right |
Hint: Numbers are different in different places
Lighting and field are not the same. They take the number that is close to the others, and not the most successful one.
In the journal there is a table with repetitions and four selected numbers. White and black are noticeably different.
Calibrate the sensors and prove that the calibration can be trusted.
- For each sensor, record 10 readings on white and 10 on black. Find the smallest and largest in each series - this is spread.
- Compare the spread with the difference between white and black. How many times is the difference greater than the spread?
- Repeat white near the window and in the dark corner of the classroom. Do the numbers change more than the spread?
- Write down the conclusion: where the calibration can be trusted and when it needs to be repeated.
| Sensor | White: min-max | Black: min-max | Difference of typical |
|---|---|---|---|
| Left | |||
| Right |
Scatter table, comparison with the difference and conclusion when to repeat the calibration.
Teach the program to notice the line
10 minHow can the program decide that there is a line under the sensor? Let's compare the new reading with our two measurements: if the number is closer to black than to white, there is a line under the sensor.
Example: white - 100, black - 800. The number came 650. To black 150, to white 550. Closer to black - that means a line.
- Create a sketch
L31_Line_Detect. Write your four numbers instead of zeros.
const int LEFT_SENSOR_PIN = A4;const int RIGHT_SENSOR_PIN = A5; // Впиши свои измерения из бортового журнала.const int LEFT_WHITE = 0;const int LEFT_BLACK = 0;const int RIGHT_WHITE = 0;const int RIGHT_BLACK = 0; void setup() { Serial.begin(9600);} void loop() { int leftValue = analogRead(LEFT_SENSOR_PIN); int rightValue = analogRead(RIGHT_SENSOR_PIN); bool leftOnLine = abs(leftValue - LEFT_BLACK) < abs(leftValue - LEFT_WHITE); bool rightOnLine = abs(rightValue - RIGHT_BLACK) < abs(rightValue - RIGHT_WHITE); Serial.print("L="); Serial.print(leftValue); Serial.print(" R="); Serial.print(rightValue); if (leftOnLine) { Serial.print(" слева линия"); } if (rightOnLine) { Serial.print(" справа линия"); } Serial.println(); delay(200);}
- Upload the program, open the Serial Monitor and place the black card under the sensors one by one.
When it is black under the left sensor, “line on the left” appears in the line, “line on the right” appears under the right one.
The neighbor team wrote this:
bool leftOnLine = abs(leftValue - LEFT_BLACK) > abs(leftValue - LEFT_WHITE);
There is a black card under the left sensor, and the “line on the left” is not printed. Find the error and explain what the program is checking now.
How it works: What are abs and bool
abs(число)removes the sign:abs(-150)is equal to 150. So we get distance between two numbers without thinking which one is larger.boolis a variable that stores not a number, but the answer “yes” or “no” (trueorfalse).if (leftOnLine) { … }- if the answer is “yes”, execute the commands in brackets.
The program needs a rule: when to assume that there is a line under the sensor? Compare the new reading with two measurements: if it is closer to black than to white, there is a line under the sensor.
White - 100, black - 800, the number is 650. Is there a line under the sensor or not? Count before launch: how much from 650 to black and how much to white?
- Create a sketch
L31_Line_Detectaccording to the template and enter your four numbers instead of zeros. - Write
loop()myself: deciding "line or not" for each sensor and printing.
// Шаблон среднего уровня. Напиши код в разделе «Твоя часть» по целям в комментариях. const int LEFT_SENSOR_PIN = A4;const int RIGHT_SENSOR_PIN = A5; // Впиши свои измерения из бортового журнала.const int LEFT_WHITE = 0;const int LEFT_BLACK = 0;const int RIGHT_WHITE = 0;const int RIGHT_BLACK = 0; // ===== Твоя часть: напиши сам ===== void loop() { int leftValue = analogRead(LEFT_SENSOR_PIN); int rightValue = analogRead(RIGHT_SENSOR_PIN); // Для каждого датчика реши, линия ли под ним (правило «ближе к чёрному»): leftOnLine и rightOnLine. // Печатай строку L=… R=…, а если под датчиком линия — допиши «слева линия» или «справа линия». // Пять строк в секунду.} // ===== Готовое из прошлого шага — не меняй ===== void setup() { Serial.begin(9600);}
- Upload the program, open the Serial Monitor and place the black card under the sensors one by one.
- Answer in the journal: what will the program start printing if white and black in it are mixed up? Why?
Tip: How to measure the distance between numbers
From 650 to 800 is 800 - 650. But the program does not know in advance which number is greater. Team abs(…) removes the sign: abs(650 - 800) is 150.
Hint: Yes or no
Yes or no response stores type bool. Teams in if (…) { … } are executed only if the answer is "yes".
“left line” and “right line” appear only when there is black under the sensor. The forecast about 650 was correct, the answer about the mixed up numbers was written down.
The neighbor team wrote this:
bool leftOnLine = abs(leftValue - LEFT_BLACK) < abs(leftValue - RIGHT_WHITE);
Sometimes "left line" is printed when there is a white field under the left sensor. Find the error and explain why it does not always appear.
Requirement 1. Function onLine(value, white, black) replies true, when there is a line under the sensor:
- reading is closer to the black dimension than to the white dimension;
- works both when the sensor is black - a large number, and when it is small;
- there are no ready-made threshold numbers inside: only
value,whiteandblack.
Why can't you just write value > 500? Name two cases where this rule would go wrong.
Acceptance. Write onLine in the test sketch, load it and open the Serial Monitor (9600). The test checks eight cases for two types of sensors, including readings outside your measurements.
// Проверка функции onLine. Напиши функцию здесь, загрузи и открой монитор порта.// Когда все строки PASS, перенеси onLine в свою программу. // Требование 1: true, если показание ближе к чёрному, чем к белому.bool onLine(int value, int white, int black) { return false;} int failed = 0; void expect(int value, int white, int black, bool expected) { bool actual = onLine(value, white, black); Serial.print(actual == expected ? "PASS " : "FAIL "); Serial.print("onLine("); Serial.print(value); Serial.print(", "); Serial.print(white); Serial.print(", "); Serial.print(black); Serial.print(") = "); Serial.print(actual ? "true" : "false"); Serial.print(", ожидаем "); Serial.println(expected ? "true" : "false"); if (actual != expected) { failed++; }} void setup() { Serial.begin(9600); // Датчик, у которого чёрное — большое число, а белое — маленькое. expect(780, 120, 780, true); expect(120, 120, 780, false); expect(600, 120, 780, true); expect(300, 120, 780, false); // За пределами измерений. expect(900, 120, 780, true); expect(50, 120, 780, false); // Датчик, у которого наоборот: белое — большое число, чёрное — маленькое. expect(300, 900, 120, true); expect(700, 900, 120, false); if (failed == 0) { Serial.println("Все проверки пройдены"); } else { Serial.print("Ошибок: "); Serial.println(failed); }} void loop() {}
When all lines PASS, add onLine into your program from the “See what the sensor sees” step and save it as L31_Line_Detect. Have her type “line on the left” and “line on the right.” Enter your measurements and check with the card.
Hint: Idea (1 of 3)
Two distances are needed: from the reading to black and from the reading to white. Which one is smaller?
Hint: Plan (2 of 3)
- Distance to black - unsigned difference.
- The distance to white is the same.
- Return the result of comparing two distances.
Hint: Code snippet (3 of 3)
abs(value - black) - distance to black. Why here abs? What will happen to the sensor without it, where the black number is a small number?
The test shows "All checks passed." Your program prints “line on the left” and “line on the right” only when there is black under the sensor.
Figure out how to turn
7 minThe robot moves forward. The line must remain between the sensors. What should I do if the line is under the left sensor? This means that the robot has gone to the right, and it needs to turn left.
The easiest way to turn left is stop left wheel, and let the right one go.
- Place the switched off robot on the line. Move it so that the line is under the left sensor. Show me which wheel needs to be stopped.
- The same for the right sensor.
- Fill out the table in the journal:
| What the sensors see | Left wheel | Right wheel | Where the robot is going |
|---|---|---|---|
| Both white | forward | forward | straight |
| Left - line | ? | ? | ? |
| Right - line | ? | ? | ? |
| Both are a line | ? | ? | ? |
The table is full. Can you explain why stopping one wheel turns the robot?
The robot moves forward and the line must remain between the sensors. If the line was under one sensor, the robot moved to the side. The wheel can only move or stand still. How to return the robot to the line?
- Place the switched off robot on the line. Move it so that the line is under the left sensor. Where did the robot go? Which way should he turn? Which wheel should I stop for this?
- The same for the right sensor.
- Fill out the table in the journal:
| What the sensors see | Left wheel | Right wheel | Where the robot is going |
|---|---|---|---|
| Both white | forward | forward | straight |
| Left - line | ? | ? | ? |
| Right - line | ? | ? | ? |
| Both are a line | ? | ? | ? |
- In your journal, explain in one sentence why stopping one wheel turns the robot.
Hint: Which wheel to stop
Remember lesson 2.2: the left wheel is stationary, the right wheel is moving. Which wheel will the robot turn around and in which direction?
The table is completed, the explanation is written down. You showed both turns with the robot turned off.
The robot moves forward and the line must remain between the sensors. Make up the rules yourself: what the wheels do in each of the four cases and why.
| What the sensors see | Left wheel | Right wheel | Where the robot is going | Why |
|---|---|---|---|---|
| Both white | ||||
| Left - line | ||||
| Right - line | ||||
| Both are a line |
- Check each line with the robot turned off: move it with your hand and show where it should go.
- "Both White" appears in two different robot positions. Which ones? Can the program distinguish between them? Write down what happens to the robot then.
- On a straight track, “both are a line” almost never happens. Where on the final field will this occur and what should the robot do then?
Hint: Two cases of "both white"
Think about where the line could be when no sensor sees it.
Four-line table with explanation. The log records in which position the program does not know where the line is.
Write the rules into the program
10 minLet's put everything together: sensors, our “closer to black” rule and motors from lesson 2.1.
- Create a sketch
L31_First_Line. Transfer your four dimensions.
const int LEFT_SENSOR_PIN = A4;const int RIGHT_SENSOR_PIN = A5; // Впиши свои измерения из бортового журнала.const int LEFT_WHITE = 0;const int LEFT_BLACK = 0;const int RIGHT_WHITE = 0;const int RIGHT_BLACK = 0; 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; int speed = 100; // начальная скорость, подбираем на подставке void setup() { pinMode(LEFT_DIR_PIN, OUTPUT); pinMode(LEFT_SPEED_PIN, OUTPUT); pinMode(RIGHT_DIR_PIN, OUTPUT); pinMode(RIGHT_SPEED_PIN, OUTPUT); analogWrite(LEFT_SPEED_PIN, 0); analogWrite(RIGHT_SPEED_PIN, 0); digitalWrite(LEFT_DIR_PIN, FORWARD); digitalWrite(RIGHT_DIR_PIN, FORWARD); // Без измерений робот не поедет: программа остановится здесь. if (LEFT_WHITE == LEFT_BLACK || RIGHT_WHITE == RIGHT_BLACK) { while (true) { } } delay(2000); // время убрать руки от робота} void loop() { int leftValue = analogRead(LEFT_SENSOR_PIN); int rightValue = analogRead(RIGHT_SENSOR_PIN); bool leftOnLine = abs(leftValue - LEFT_BLACK) < abs(leftValue - LEFT_WHITE); bool rightOnLine = abs(rightValue - RIGHT_BLACK) < abs(rightValue - RIGHT_WHITE); int leftSpeed = speed; int rightSpeed = speed; if (leftOnLine) { leftSpeed = 0; } if (rightOnLine) { rightSpeed = 0; } analogWrite(LEFT_SPEED_PIN, leftSpeed); analogWrite(RIGHT_SPEED_PIN, rightSpeed);}
- Find in
loop()two rules from your table. Explain to your partner what each one does. - Click Check.
How it works: Why the speed is set anew in each repetition
At the beginning loop() both speeds become equal again speed. If we didn't do this, the wheel, once stopped, would remain there even when the sensor sees white again.
How it works: Why the while (true) line
If you forgot to enter the measurements, white and black are equal to zero, and the program cannot distinguish the line. Then it gets “stuck” in an empty infinite loop, and the robot won’t move. This is protection against accidental start.
Let's put everything together: sensors, the “closer to black” rule and motors from lesson 2.1. The wheels will obey the rules from your table.
- Create a sketch
L31_First_Lineaccording to the template. Enter your four dimensions. Motor tuning and protection are already ready. - Write
loop()himself: transfer your conditions fromL31_Line_Detect, set the wheels to speed according to your table of rules and send them to the motors.
// Шаблон среднего уровня. Напиши код в разделе «Твоя часть» по целям в комментариях. const int LEFT_SENSOR_PIN = A4;const int RIGHT_SENSOR_PIN = A5; // Впиши свои измерения из бортового журнала.const int LEFT_WHITE = 0;const int LEFT_BLACK = 0;const int RIGHT_WHITE = 0;const int RIGHT_BLACK = 0;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;int speed = 100; // начальная скорость, подбираем на подставке // ===== Твоя часть: напиши сам ===== void loop() { int leftValue = analogRead(LEFT_SENSOR_PIN); int rightValue = analogRead(RIGHT_SENSOR_PIN); // Реши, линия ли под каждым датчиком, — перенеси свои условия из L31_Line_Detect. // Колёса выполняют твою таблицу правил: линия под датчиком — его колесо стоит. // Колесо, которое правило остановило, снова едет, когда его датчик видит белое.} // ===== Готовое: настройка и защита — не меняй ===== void setup() { pinMode(LEFT_DIR_PIN, OUTPUT); pinMode(LEFT_SPEED_PIN, OUTPUT); pinMode(RIGHT_DIR_PIN, OUTPUT); pinMode(RIGHT_SPEED_PIN, OUTPUT); analogWrite(LEFT_SPEED_PIN, 0); analogWrite(RIGHT_SPEED_PIN, 0); digitalWrite(LEFT_DIR_PIN, FORWARD); digitalWrite(RIGHT_DIR_PIN, FORWARD); // Без измерений робот не поедет: программа остановится здесь. if (LEFT_WHITE == LEFT_BLACK || RIGHT_WHITE == RIGHT_BLACK) { while (true) { } } delay(2000); // время убрать руки от робота}
What happens if you set the wheel speed once every setup(), rather than at the beginning of each repeat loop()?
- Click Check.
Hint: The wheel has stopped and won't move anymore
When does the rule allow the wheel to move again? Where does its speed come from in each repetition?
Hint: Wheel Rule
if (проверка) { … } executes the commands in parentheses only if the check is true. Check your table: which variable to check and which speed to change?
loop() written, Check passes without errors, the response to the forecast is written to the log.
How it works: Why the while (true) line
If you forgot to enter the measurements, white and black are equal to zero, and the program cannot distinguish the line. Then it gets “stuck” in an empty infinite loop, and the robot won’t move. This is protection against accidental start.
Take the frame: it contains contacts, motors and function drive from lesson 2.1. Transfer your measurements and function into it onLine and save as L31_First_Line. You will need this program in lesson 3.2.
// Каркас движения по линии. Требования к программе — в тексте урока.const int LEFT_SENSOR_PIN = A4;const int RIGHT_SENSOR_PIN = A5; // Впиши свои измерения из бортового журнала.const int LEFT_WHITE = 0;const int LEFT_BLACK = 0;const int RIGHT_WHITE = 0;const int RIGHT_BLACK = 0; 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; 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);} // Требование 1: перенеси функцию onLine из тестового скетча.bool onLine(int value, int white, int black) { return false;} void setup() { 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); // Требование 3: защита от запуска без измерений и время убрать руки.} void loop() { // Требование 2: прочитать датчики, решить по своей таблице правил, задать скорости. drive(FORWARD, 0, FORWARD, 0);}
Requirement 2. Wheels follow your rules table:
- in each repetition the program reads both sensors anew and decides anew: the wheel, stopped once, moves again when its sensor sees white;
- your function makes the decision
onLine; - speed - one named variable
speedat the beginning of the sketch.
Requirement 3. The robot is safe:
- without measurements, white and black wheels stand;
- after turning on, you have 2 seconds to remove your hands.
Acceptance - on the stand in the next step: the robot performs every line of your rule table, and without measurements the wheels don’t spin.
What will the robot do if the speeds of both wheels are set once per setup()? Write down your answer before checking.
Hint: Idea (1 of 3)
Each repetition: read sensors → solve → send speeds to motors. The decision starts with “both go”, but the rules change it.
Hint: Plan (2 of 3)
- Read both sensors.
- Ask
onLinefor everyone. - Both speeds -
speed. - The rules from the table change the speeds.
- Send speeds to
drive.
Hint: Code snippet (3 of 3)
if (onLine(leftValue, LEFT_WHITE, LEFT_BLACK)) { leftSpeed = 0; } - and for the right sensor? What about the “both are a line” line from your table?
The program fulfills requirements 2 and 3, Check runs without errors.
Check on the stand
6 minLoad the program when the power to the motors is turned off. The wheels do not touch the table.
- Place the robot on the stand. Upload the program.
- Turn on the power to the motors. Both wheels should turn forward.
- Place the black card under the left sensor: the left wheel will stop. Remove the card: the wheel will start moving again. Check the right sensor.
- Turn off the power to the motors.
Each wheel stops when it is black under its sensor and runs white again.
| What do you see | What to do |
|---|---|
| Wheels don't spin | Check that the measurements are entered and the power to the motors is turned on. |
| The wheel turns backwards | Check FORWARD and connecting the motor. |
| The wrong wheel stops | Sensors or motors are mixed up. Check the Serial Monitor and the L/R labels. |
- Place the robot on the stand, load the program, turn on the power to the motors.
- Check all four rows of your rules table: place the cards so that the sensors see what you need. Write down what the wheels do.
| What the sensors see | Waited | Saw |
|---|---|---|
| Both white | ||
| Left - line | ||
| Right - line | ||
| Both are a line |
- Check your prediction about the speed specified in
setup(). Turn off the power to the motors.
The table is filled, all rows match the rules. The forecast has been verified.
| What do you see | What to do |
|---|---|
| Wheels don't spin | Is it written loop()? Are the measurements included? Is the power to the motors turned on? |
| The wrong wheel stops | Sensors or motors are mixed up. Check the Serial Monitor and the L/R labels. |
Acceptance of requirements 2–3 on a stand.
- Load the program with zeros instead of measurements. The wheels should not spin. Enter the measurements and upload again.
- Check each line of your rules table with cards.
- Note how many seconds after switching on the wheels start moving.
| Check | Waited | Saw |
|---|---|---|
| No measurements | ||
| Both white | ||
| Left - line | ||
| Right - line | ||
| Both are a line | ||
| Pause at the start |
All checks met the requirements. If not, corrected and checked again.
First run along the line
8 min- Turn off the power to the motors, unplug the USB cable.
- Place the robot on a straight line: the line between the sensors.
- Turn on the power and watch. Be prepared to turn off the power if the robot leaves the track.
- Try going through the bend. Write down what happened in your journal.
The robot travels along a line and goes through a smooth bend. It moves jerkily - this is normal for this method.
- Turn off the power to the motors, unplug the USB cable.
- Place the robot on a straight line: the line between the sensors. Turn on the power. Be prepared to turn it off if the robot leaves the path.
- Walk the path three times at
speed = 100, then three times at 80 and at 130. Record how many times the robot went through the bend.
speed | Passed from 3 | What is visible |
|---|---|---|
| 80 | ||
| 100 | ||
| 130 |
- Why does the robot move jerkily? Write it down in one sentence.
Table of races at three speeds and explanation of jerks.
- Turn off the power to the motors, disconnect the USB cable. Be prepared to turn off the power if the robot leaves the track.
- Find the largest
speed, in which the robot goes through a smooth bend three times out of three. Start at 80 and work your way up in 20 steps. - At the highest speed, which the robot could not withstand, look where it loses the line. Explain the reason in the journal through your rule table.
- Write down what needs to be changed in the rules to make the robot keep the line faster. You will check this in lesson 3.2.
The highest reliable speed, the location and reason for the derailment, the idea of improving the rules.
The robot goes through a straight line and a smooth bend according to two rules and does not lose the line.
Now, if both sensors see black, the robot stops. In the middle field, you need to drive straight through intersections. Change the program so that when it is black under both sensors, both wheels move forward. Check on a path with one intersection.
Instead of stopping the wheel, slow it down: for example, up to a third of speed. Compare two options on one bend - “stop” and “slow down”. Which one is smoother? At what speed does each option still hold the line? Record the results in a log: this is the first step to the P-controller, which will be needed on the steep arcs of the advanced field.
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
★ Intermediate level
★★ Advanced level
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 robot learned to choose which wheel to stop based on the readings of two sensors. We did not guess the numbers, but measured them on our field. Jerking when moving is the price of the simple rule “goes or stops.” In lesson 3.2, the robot will learn to turn smoothly: the further the line goes to the side, the stronger it becomes.
Go back to your guess from the beginning of the lesson. Has it been confirmed?
How to confirm the result
For each experiment, save the conditions, program version, observation and conclusion. When comparing attempts, change one reason at a time; unsuccessful attempts also remain in the log. Marking a result refers to actions that have already been completed; there is no need to repeat them for the sake of marking. If the result is not obtained, write down the discrepancy and the next hypothesis to be tested. A model, measurements of a real robot, and an explanation are different types of evidence.
Lesson vocabulary
| line sensor | A sensor that shines light onto the floor and measures how much light is reflected. White reflects a lot, black reflects little. |
| reading | The number that the program receives from the sensor. For our board this number ranges from 0 to 1023. |
| Serial Monitor | The Serial Monitor panel in MyRobotica, where you can see the messages that the board sends to the computer. |
| calibration | Setting up a program to measure your robot and your field. |
| variable | A named location in memory where a program stores a number. |
| condition | If check: commands in curly braces are executed only if the check is true. |
| telemetry | Pass named measurements with time and units to plot and store observations. |
| ADC | Analog-to-digital conversion: the voltage at the input of the board is converted into a number from 0 to 1023. |