INTRODUCERE

03062010728.jpg

Light follower este un robot care reactioneaza la schimbari bruste in lumina ambianta. Imediat ce a detectat schimbari majore intr-o anumita directie, el va merge cateva secunde in acea directie.

Parti Componente

Pentru a-l realiza am folosit:

  • Microcontroller ATMEGA16 montat pe placa de proiect cu programator usb si isp
  • Sasiu cu 2 motoare/ 2 roti independente si suport cu bila
  • circuit integrat L298N pentru a controla/alimenta motoarele
  • 4 fotorezistori montati lateral pentru a masura iluminarea
  • display lcd 2×16 digit NT-C1627A, compatibil pin la pin cu Hitachi 44780 (folosit la debugging)
  • 4 baterii alcaline R14 pentru a alimenta motoarele
  • 4 baterii pentru a alimenta microcontroller-ul, senzorii si display-ul

Hardware Design

Sasiul + trenul de rulare le-am cumparat de la turuga.ro. Desi sunt cam scumpe, sunt de calitate si se monteaza foarte usor.

sdc12183.jpg

sdc12184.jpg

Pentru a alimenta motoarele am folosit un circuit integrat special (L298N) pe care l-am montat direct pe placa.

sdc12192.jpg

Cele 4 fire din stanga alimenteaza motoarele, celelalte 6 le controleaza. Pe dedesubtul placii mai sunt si alte fire care leaga diverse terminale la GND/VCC. Schema de legare este urmatoarea:

Astfel, folosind 4 pini (+ 2 de enable), se pot controla cele 2 motoare in oricare directie. Mare atentie: Pinii SENSA si SENSB ai integratului se leaga la GND si nu se lasa in aer (cum am crezut initial cand am citit datasheet-ul).Altfel portile nu se deschid.

Robotul foloseste 4 senzori de lumina (fotorezistori) pentru a determina intensitatea luminii in fiecare directie (inainte, inapoi, stanga, dreapta). Citirea se face cu ajutorul a 4 din cei 8 pini ai portului A, care sunt si convertoare ADC. Schema de montare este simpla:

Pentru a alege valoarea lui R am masurat rezistenta senzorului la lumina puternica (~ 750 Ω) si la lumina foarte slaba (~ 400 KΩ). Media geometrica (~ 15 KΩ) da o valoare pentru R astfel incat variatia tensiunii masurate de pin sa fie cat mai liniara fata de variatia luminii.

In final, cei 4 senzori sunt dispusi ca in urmatoarea schema:

Pentru a monitoriza permanent valorile masurate de pini am atasat un display LCD cu 16 pini, model NT-C1627A (NellyTech) care are un controller compatibil cu Hitachi 44780, folosit la laboratorul 1. Singurele diferente sunt cei 2 pini in plus (pentru iluminarea ecranului) si modul de conectare al pinului 3 de contrast(direct la masa, desi cand placa este alimentata prin usb, o rezistenta de 2 KΩ inlatura background-ul usor innegrit). Codul sursa de la lab este, deci, potrivit pentru a realiza interfatarea. Schema de conexiune este urmatoarea:

03062010732.jpg

Display-ul indica tot timpul valorile masurate de pini (pe 8 biti). Sub valoarea masurata de fiecare senzor se afla diferenta dintre valoarea curenta si cea precedenta, diferenta care arata eventuala schimbare brusca in luminozitate. Pragul setat este 20. La lumina de neon se observa un oarecare “zgomot” in luminozitate, astfel ca nu este suficient un prag de 20 (ar genera o miscare haotica a robotului), ci de aproximativ 50.

Software Design

Codul sursa este in aceasta arhiva: robo1.rar

Partea esentiala este reprezentata de urmatoarele linii:

while(1){
	
	disp += 1;						//contor folositor pentru refresh-ul LCD-ului
	i = getFromADC(PA0);					//citeste senzorul fata
	if(i-p1 > m1) m1 = i-p1;				//actualizeaza maximul (cea mai mare diferenta gasita)
	p1 = i;							//valoarea precedenta = cea actuala (pentru urmatoarea masuratoare)
	if(disp % 200 == 0){					//afisez doar 0.5% din conversii insa toate se iau in calcul
		LCD_writeInstruction(LCD_INSTR_returnHome);
		LCD_printDecimal2u(i);
	}
	
	i = getFromADC(PA1);					//ceteste senzorul spate
	if(i-p2 > m2) m2 = i-p2;
	p2 = i;
	if(disp % 200 == 0) LCD_printDecimal2u(i);
	
	i = getFromADC(PA2);					//citeste senzorul stanga
	if(i-p3 > m3) m3 = i-p3;
	p3 = i;
	if(disp % 200 == 0) LCD_printDecimal2u(i);
	i = getFromADC(PA3);					//citeste senzorul dreapta
	if(i-p4 > m4) m4 = i-p4;
	p4 = i;
	if(disp % 100 == 0){					//afiseaza diferentele gasite fata de masuratorile precedente, 
								//pe randul de jos al ecranului
	
		LCD_printDecimal2u(i);
		LCD_writeInstruction(LCD_INSTR_nextLine);
		LCD_printDecimal2u(m1);
		LCD_printDecimal2u(m2);
		LCD_printDecimal2u(m3);
		LCD_printDecimal2u(m4);
	}
	if(disp == 2000) {m1 = m2 = m3 = m4 = 0; disp = 0;}
	if(m1 > 15 && m1 < 250) {					//daca s-a detectat lumina in fata
		LCD_writeInstruction(LCD_INSTR_clearDisplay);		//afiseaza info
		LCD_print("F = ");LCD_printDecimal2u(m1);		//activez motoarele inainte 3 secunde
		PORTD |= (1<<1) | (1<<2);				//activez motoarele inainte 3 secunde
		for(i = 0; i < 15; ++i) _delay_ms(200);
		PORTD &= ~((1<<1) | (1<<2));				//opresc motoarele
		m1 = m2 = m3 = m4 = 255;				//resetez masuratorile
	}
	else if(m2 > 15 && m2 < 250) {					//daca s-a detectat lumina in spate
		LCD_writeInstruction(LCD_INSTR_clearDisplay);		//afiseaza info
		LCD_print("B = ");LCD_printDecimal2u(m2);
		PORTD |= (1<<1) | (1<<3);				//activez motoarele intr-o miscare de rotatie de 180 grade
		for(i = 0; i < 13; ++i) _delay_ms(50);
		PORTD &= ~((1<<1) | (1<<3));				//opresc motoarele
		PORTD |= (1<<1) | (1<<2);				//merg inainte 3 secunde
		for(i = 0; i < 15; ++i) _delay_ms(200);
		PORTD &= ~((1<<1) | (1<<2));				//opresc motoarele
		m1 = m2 = m3 = m4 = 255;				//resetez masuratorile
	}
	else if(m3 > 15 && m3 < 250) {					//daca s-a detectat lumina la senzorul din stanga
		LCD_writeInstruction(LCD_INSTR_clearDisplay);		//afiseaza info
		LCD_print("L = ");LCD_printDecimal2u(m3);
		PORTD |= (1<<0) | (1<<2);				//activez motoarele intr-o miscare de rotatie de -90 grade
		for(i = 0; i < 4; ++i) _delay_ms(100);
		PORTD &= ~((1<<0) | (1<<2));				//opresc motoarele
		PORTD |= (1<<1) | (1<<2);				//merg inainte 3 secunde
		for(i = 0; i < 15; ++i) _delay_ms(200);
		PORTD &= ~((1<<1) | (1<<2));				//opresc motoarele
		m1 = m2 = m3 = m4 = 255;				//resetez masuratorile
	}
	else if(m4 > 15 && m4 < 250) {					//daca s-a detectat lumina la senzorul din stanga
		LCD_writeInstruction(LCD_INSTR_clearDisplay);		//afiseaza info
		LCD_print("R = ");LCD_printDecimal2u(m4);
		PORTD |= (1<<1) | (1<<3);				//activez motoarele intr-o miscare de rotatie de 90 grade
		for(i = 0; i < 4; ++i) _delay_ms(100);
		PORTD &= ~((1<<1) | (1<<3));				//opresc motoarele
		PORTD |= (1<<1) | (1<<2);				//merg inainte 3 secunde
		for(i = 0; i < 15; ++i) _delay_ms(200);
		PORTD &= ~((1<<1) | (1<<2));				//opresc motoarele
		m1 = m2 = m3 = m4 = 255;				//resetez masuratorile
	}
}

Resurse

– datasheet ATMEGA16 - 1773.pdf

– datasheet L298N - 1773.pdf

– datasheet LCD - NT-C1627A_Nely.pdf.html

– laboratoare pm 1 si 3

– google

pm/prj2010/pgp/light_follower.txt · Last modified: 2021/04/14 17:07 (external edit)
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0