Table of Contents

LineFollower

Introducere

Proiectul constă într-o mașinuță care urmează traseul dat de o linie neagră, iar pe ecranul LCD se vor afișa mesaje sugestive.

Implementarea se bazează pe concepte de bază ale roboticii, folosirea senzorilor pentru detecția drumului și controlul motoarelor.

Se dorește crearea unui sistem autonom care nu necesită intervenție umană odată finalizat.

Descriere generală

În următoarea schemă bloc se pot observa modulele principale ale proiectului, cât și modul în care interacționează:

Hardware Design

În schema de mai jos se poate observa modul de conectare al pinilor pentru proiect. Componentele sunt următoarele:

Mod conectare baterie: pentru motor driver o conectăm la pinii GND și VCC, iar pentru microcontroller o conectăm direct la Power Jack.

Aspect Final

Software Design

Ca și mediu de dezvoltare am foloist Arduino IDE, iar bibliotecile folosite sunt:

Din punct de vedere al logicii proiectul nu este extrem de complicat; avem 2 senzori în partea din față a mașinii și următoarele 4 scenarii:

  1. niciun senzor nu detectează negru în față: mașina își continuă drumul drept, linia neagră se află între senzori
  2. senzorul din dreapta detectează negru: linia neagră o ia spre dreapta, iar mașina trebuie să vireze în acea parte
  3. senzorul din stânga detectează negru: linia neagră o ia spre stânga, iar mașina trebuie să vireze în acea parte
  4. ambii senzori detectează negru: oprim mașina

Pentru toate aceste scenarii am definit funcții ajutătoare. Roata va merge înainte dacă pinul 1 de input este pe HIGH, pinul 2 de input este pe LOW, iar pinul de enable are o valoare potrivită setată; roata se oprește când pinii enumerați adineauri sunt toți setați pe LOW. Pentru a vira la stânga/dreapta vom lăsa să meargă doar roata din acea parte (cu o viteză mai mică pentru a nu lua curbele prea brusc).

Pentru citirea datelor de la senzori am folosit funcția readLineBlack() aceasta întoarce un număr cuprins între 0 și 1000 (0: reflectanța este maximă, 1000: reflectanța este minimă) și am concluzionat că valorile mai mari de 700 indică culoarea neagră.

void forward() {
  digitalWrite(IN1_R, HIGH);
  digitalWrite(IN2_R, LOW);
  analogWrite(EN_R, motor_speed);
  digitalWrite(IN1_L, HIGH);
  digitalWrite(IN2_L, LOW);
  analogWrite(EN_L, motor_speed);
}

void left() {
  digitalWrite(IN1_R, HIGH);
  digitalWrite(IN2_R, LOW);
  analogWrite(EN_R, cornering_speed);
  digitalWrite(IN1_L, LOW);
  digitalWrite(IN2_L, LOW);
  analogWrite(EN_L, LOW);
}

void right() {
  digitalWrite(IN1_R, LOW);
  digitalWrite(IN2_R, LOW);
  analogWrite(EN_R, LOW);
  digitalWrite(IN1_L, HIGH);
  digitalWrite(IN2_L, LOW);
  analogWrite(EN_L, cornering_speed);
}

void stop() {
  lcd.print("Orbesc!! Vad   "); 
  lcd.setCursor(0, 1);  
  lcd.print("negru in fata!!"); 
  lcd.setCursor(0, 0);  

  PORTB &= ~(1 << PORTB1);
  PORTB &= ~(1 << PORTB0);
  PORTB &= ~(1 << PORTB3);
  PORTD &= ~(1 << PORTD7);
  PORTD &= ~(1 << PORTD6);
  PORTB &= ~(1 << PORTB2);
}

void loop()
{
  int SensorRight, SensorLeft;

  qtr1.readLineBlack(sensorValues1);
  if(sensorValues1[0] > 700) {
    SensorRight = 1;
  } else {
    SensorRight = 0;
  }

  qtr2.readLineBlack(sensorValues2);
  if(sensorValues2[0] > 700) {
    SensorLeft = 1;
  } else {
    SensorLeft = 0;
  }

  if(SensorRight == 0 && SensorLeft == 0) {
    forward();
  }

  if(SensorRight == 1 && SensorLeft == 0) {
    right();
  }

  if(SensorRight == 0 && SensorLeft == 1) {
    left();
  }

  if(SensorRight == 1 && SensorLeft == 1) {
    stop();
  }
}

Proiectul a fost mult mai dificil decât mă așteptam deoarece senzorii nu citeau bine valorile, nu făceau diferența între partea închisă și cea deschisă, deși îi calibram conform documenției. Înainte de a îi putea folosi (corect) aceștia trebuie să treacă prin etapa de calibrare: să fie expuși celei mai închise (în cazul nostru linia neagră) și celei mai deschise părți din traseu, iar dacă etapa nu este îndeplinită corect și în timp util valorile citite ajung să fie irelevante. În cele din urmă am reușit să găsesc varianta de cod (după multe măsurători) și să poziționez senzorii pe mașină în așa fel încât să citească datele cât mai bine (am observat că aceștia sunt foarte sensibili și la umbre). De asemenea, pentru a putea distinge când începe și când se oprește etapa menționată anterior aprind și sting un led pe plăcuță.

Rezultate Obţinute

Am făcut tot ce mi-am propus, mașina urmează traiectoria dată de o linie neagră și se oprește atunci când întâlnește o linie neagră perpendiculară pe traseu. De asemenea, pe ecranul LCD sunt afișate mesaje corespunzătoare.

Video

Concluzii

A fost un proiect interesant, diferit față de ce am mai avut de făcut până acum la facultate. Am avut ocazia să pun în practică lucruri învățate la laboratoare sau știute doar în teorie, de exemplu, atunci când nu mergea o componentă putea fi un bug în soft și/sau în hardware: identificarea problemelor, testarea componentelor și fixarea bug-urilor într-un astfel de proiect a considerat în sine o etapă. Deoarece nu am mai lucrat în trecut în acest mod cu un microcontroller mi-a luat uneori mult să mă prind ce greșeam (începuse să se restarteze plăcuță random și credeam că este un bug în cod, dar se consumaseră bateriile m(; al căror număr a fost cu mult mai mare decât anticipasem, cred că am trecut prin 4 seturi).

Download

LineFollower

Jurnal

Bibliografie/Resurse

Documentație Senzori

Motor Driver