Proiectul propune realizarea unui robot ,alimentat cu baterii, ce urmărește o linie.
Un robot line follower este o masina autonoma, ce poate urmari o anumita traiectorie. Traiectoria este redata prin intermediul unei linii negre pe un fundal alb.
Initial, robotul se va deplasa in linie dreapta. Detectarea pozitiei traiectoriei se face pe baza informatiei primite de la 4 senzori. Microcontroller-ul ATmega16 este cel care va controla functiile motoarelor si va monitoriza senzorii.
Robotul este proiectat pornind de la o masina controlata prin telecomanda, a carei placi a fost inlocuita.
Cu ajutorul senzorilor (ce detecteaza alb sau negru) situati in partea din fata a robotului, cu o distanta de 2 cm intre ei, se pot lua decizii referitoare la pozitionarea fata de traseul de urmat. Senzorii vor prelucra lumina reflectata de traiectorie si vor indica un anumit voltaj. Microcontroller-ul Atmega16, citind valorile de pe senzori, va decide daca masina trebuie sa urmeze o linie dreapta sau sa faca o curba.
La placuta din prima etapa la care am cuplat un driver de motor pentru comanda celor doua motoare de curent continuu. Driverul este prevazut cu patru intrari si patru iesiri permitand comanda in paralel a doua motoare. In faza urmatoare cele doua motoare sunt actionate in functie de semnalele primate de la cei doi senzori.
Iesirile spre motoare (pinii PC 0,1 si PC 5,6) sunt 4 biti pentru codificarea directiilor iar pinii PD 4 si 5 sunt pentru turatia motoarelor. Motoarele sunt conectate direct la circuitul L298.
Lista piese:
- Placa de baza de la etapa 1
- 4 senzori linie IR QRE1113 ANALOG
- Controller motoare L298N L298N
- masina cu 2 motoare
Cod:
void move_forward() {
PWM_channelA(MOTOR2, MAX); // sTANGA FATA PWM_channelA(MOTOR2, MIN); PWM_channelB(MOTOR1, MIN); // DREAPTA FATA PWM_channelB(MOTOR1, MAX);
PORTB = SET; PORTA = SET; OCR1A = 2000; OCR1B = 1000; }
int main(void) {
DDRC &= ~_BV(PC6); // intrari senzori DDRC &= ~_BV(PC4); DDRC &= ~_BV(PC5); DDRC &= ~_BV(PC7); PINC = _BV(PC4) | _BV(PC5) | _BV(PC6) | _BV(PC7); DDRD &= ~_BV(PD6); PORTD |= _BV(PD6); DDRD |= _BV(PD7); PORTD |= _BV(PD7);
while((PIND & (1 << PD6)) == (1 << PD6)); init_timer(); _delay_ms(1000); DDRB = 0xFF; DDRA = 0xFF; // la nesfarsit while(1) {
// in functie de miscare apelez functia care o realizeaza if (((PINC&_BV(PC5))==0)&&((PINC&_BV(PC4))!=0)){// dreapta interior dreapta sta PWM_channelA(MOTOR2, MAX); PWM_channelA(MOTOR2, MIN); PORTA = SET; OCR1A = 2000; }else if((PINC&_BV(PC4))==0){ // dreapta exterior dreapta = MERGE INAPOI PWM_channelB(MOTOR1, MAX); PWM_channelB(MOTOR1, MIN); PORTB = SET; OCR1B = 2000; PWM_channelA(MOTOR2, MAX); PWM_channelA(MOTOR2, MIN); PORTA = SET; OCR1A = 2000; }else{//motorul drept merge inainte PWM_channelB(MOTOR1, MIN); PWM_channelB(MOTOR1, MAX); PWM_channelA(MOTOR2, MAX); PWM_channelA(MOTOR2, MIN); PORTB = SET; PORTA = SET; OCR1A = 2000; OCR1B = 1000; } if (((PINC&_BV(PC7))==0)&&((PINC&_BV(PC6))!=0)) { //stanga interior stanga = sta PWM_channelB(MOTOR1, MIN); PWM_channelB(MOTOR1, MAX); PORTB = SET; OCR1B = 1000; } else if((PINC&_BV(PC6))==0) { //stanga exterior stanga = MERGE INAPOI PWM_channelA(MOTOR2, MIN); PWM_channelA(MOTOR2, MAX); PWM_channelB(MOTOR1, MIN); PWM_channelB(MOTOR1, MAX); PORTA = SET; OCR1A = 1000; PORTB = SET; OCR1B = 1000; } else { PWM_channelB(MOTOR1, MIN); PWM_channelB(MOTOR1, MAX); PWM_channelA(MOTOR2, MAX); PWM_channelA(MOTOR2, MIN); PORTB = SET; PORTA = SET; OCR1A = 2000; OCR1B = 1000; } move_forward(); }
Construirea robotilor este un lucru destul de fascinant si care cu siguranta ar fi meritat mai mult timp alocat.