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:
Sasiul + trenul de rulare le-am cumparat de la turuga.ro. Desi sunt cam scumpe, sunt de calitate si se monteaza foarte usor.
Pentru a alimenta motoarele am folosit un circuit integrat special (L298N) pe care l-am montat direct pe placa.
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:
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.
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
} }
– datasheet ATMEGA16 - 1773.pdf
– datasheet L298N - 1773.pdf
– datasheet LCD - NT-C1627A_Nely.pdf.html
– laboratoare pm 1 si 3