Для построения машинки, способной двигаться по черной линии, необходимо определиться с основными элементами. Мы использовали следующие:
- Микроконтроллер 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 действительно крутая штука для создания любительских устройств.
- Машинка получилась не самая лучшая, но с задачей справляется.
Над проектом работали:
Стукалов А. И
Рынкевич Е.С.
ссылка на оригинал статьи https://geektimes.ru/post/270316/
Добавить комментарий