Для построения машинки, способной двигаться по черной линии, необходимо определиться с основными элементами. Мы использовали следующие:
- Микроконтроллер Arduino UNO.
- Драйвер двигателя L298N.
- Цифровой датчик линии AMP-B018 (2 шт).
После проведения самых первых тестов, выявилась одна проблема. Плата Arduino не запускала загруженный код, если подавать питающее напряжение не от компьютера, а от внешнего источника.
Решение проблемы нашлось не сразу. Есть два возможных пути. Первый описан на официальном сайте. Мы же воспользовались вторым: на вход Reset подали 5 вольт. В этом случае при записи скетча на плату, необходимо размыкать цепь. В качестве источников питания используем две батарейки «Крона». Плата Arduino, драйвер двигателя и датчики линий питаются от одной, а двигатели от второй. Основой для машинки будет служить пластинка из оргстекла. Далее просверливаем в оргстекле необходимые отверстия и закрепляем на нём все составляющие.
Закрепляем макетную плату и собираем всю схему до конца следующим образом:
Как работать с драйвером двигателя L298N можно почитать вот тут.
Вот что получилось:
Теперь нужно определиться как машинка будет ориентироваться с помощью датчиков. Поскольку есть только два датчика, сделаем так: один будет следить за черной линией, а второй за белым пространством. Для описания работы двигателей в зависимости от показаний датчиков составим машину состояний:
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.
Итоги:
- Arduino действительно крутая штука для создания любительских устройств.
- Машинка получилась не самая лучшая, но с задачей справляется.
Над проектом работали:
Стукалов А. И
Рынкевич Е.С.
Автор: StukalovAI