- PVSM.RU - https://www.pvsm.ru -
Для построения машинки, способной двигаться по черной линии, необходимо определиться с основными элементами. Мы использовали следующие:
После проведения самых первых тестов, выявилась одна проблема. Плата Arduino не запускала загруженный код, если подавать питающее напряжение не от компьютера, а от внешнего источника.
Решение проблемы нашлось не сразу. Есть два возможных пути. Первый описан на официальном сайте [1]. Мы же воспользовались вторым: на вход Reset подали 5 вольт. В этом случае при записи скетча на плату, необходимо размыкать цепь. В качестве источников питания используем две батарейки «Крона». Плата Arduino, драйвер двигателя и датчики линий питаются от одной, а двигатели от второй. Основой для машинки будет служить пластинка из оргстекла. Далее просверливаем в оргстекле необходимые отверстия и закрепляем на нём все составляющие.
Закрепляем макетную плату и собираем всю схему до конца следующим образом:
Как работать с драйвером двигателя L298N можно почитать вот тут [2].
Вот что получилось:
Теперь нужно определиться как машинка будет ориентироваться с помощью датчиков. Поскольку есть только два датчика, сделаем так: один будет следить за черной линией, а второй за белым пространством. Для описания работы двигателей в зависимости от показаний датчиков составим машину состояний:
L( R) – соответствует единичному уровню сигнала с левого (правого) датчика.
~L (~R) – нулевому уровню.
Вот собственно код:
int RightSensor = 4;
int LeftSensor = 11;
int ENB = 5;
int In4 = 6;
int In3 = 7;
int In2 = 8;
int In1 = 9;
int ENA = 10;
int prevState = 0;
int curState;
void turnOnRightEngine(int val, boolean Direction){
if(Direction){
digitalWrite(In2, LOW);
digitalWrite(In1, HIGH);
}
else{
digitalWrite(In2, HIGH);
digitalWrite(In1, LOW);
}
analogWrite(ENA, val);
}
void turnOnLeftEngine(int val, boolean Direction){
if(Direction){
digitalWrite(In3, LOW);
digitalWrite(In4, HIGH);
}
else{
digitalWrite(In3, HIGH);
digitalWrite(In4, LOW);
}
analogWrite(ENB, val);
}
void turnOffRightEngine(){
digitalWrite(In2, LOW);
digitalWrite(In1, LOW);
analogWrite(ENA,0);
}
void turnOffLeftEngine(){
digitalWrite(In3, LOW);
digitalWrite(In4, LOW);
analogWrite(ENB,0);
}
void setup()
{
pinMode(RightSensor, INPUT);
pinMode(LeftSensor, INPUT);
pinMode(ENA, OUTPUT);
pinMode(ENB, OUTPUT);
pinMode(In1, OUTPUT);
pinMode(In2, OUTPUT);
pinMode(In3, OUTPUT);
pinMode(In4, OUTPUT);
}
void changeState(int state){
switch(state){
case 0:
{
turnOffLeftEngine();
turnOffRightEngine();
break;
}
case 1:
{
turnOffLeftEngine();
turnOnRightEngine(150, true);
break;
}
case 2:
{
turnOffRightEngine();
turnOnLeftEngine(150, true);
break;
}
case 3:
{
turnOnLeftEngine(150, true);
turnOnRightEngine(150, true);
break;
}
}
}
void loop()
{
int rs = digitalRead(RightSensor);
int ls = digitalRead(LeftSensor);
int state = prevState;
switch(state){
case 0:
{
if(ls == 1 && rs == 0)
curState = 3;
else
curState = 0;
break;
}
case 1:
{
if(ls == 0 && rs == 0)
curState = 1;
else if(rs == 1)
curState = 2;
else if(ls == 1 && rs == 0)
curState = 3;
break;
}
case 2:
{
if(ls == 0 && rs == 0)
curState = 2;
else if(rs == 1)
curState = 2;
else if(ls == 1 && rs == 0)
curState = 3;
break;
}
case 3:
{
if(ls == 0 && rs == 0)
curState = 1;
else if(rs == 1)
curState = 2;
else if(ls == 1 && rs == 0)
curState = 3;
break;
}
}
changeState(curState);
prevState = curState;
}
В результате машинка едет по черной линии, однако недолго – батарейки хватает на минуты 3.
Итоги:
Над проектом работали:
Стукалов А. И
Рынкевич Е.С.
Автор: StukalovAI
Источник [3]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/arduino/111088
Ссылки в тексте:
[1] официальном сайте: http://arduino.ua/ru/guide/Troubleshooting#toc5
[2] тут: http://zelectro.cc/Motor_shield_L298N_Arduino
[3] Источник: https://geektimes.ru/post/270316/
Нажмите здесь для печати.