Çizgi İzleyen Robot

Tasarım ve ağırlık açısından diğer örneklerinden ayrılan bu çizgi izleyen robot kendi klasmanında rakipsiz sayılabilir.Piyasada hazır satın alabileceğiniz çizgi izleyenler hem tasarım olarak sizi yansıtmayacak hemde bazı rakiplerinizle aynı koşullarda yarışıyor olacaksınız.Ama bu çizgi izleyen robot ile rakiplerinizden bir adım öndesiniz.Ayrıca kontrol kartını da kendiniz hazırlayacağınız için yerden de tasarruf sağlamış oluyorsunuz.

Projemizde motor sürücü olarak tb752a1 kartı kullanılmış.Ayrıca atmega328 işlemcisi ile hızınıza hız katacak.Robotta güç kaynağı olarak 3.7volt lipo kullanılmış , hem küçük hemde hafif olması ayrı bir avantaj.Ama 3.7 volt gerilimi robot için yetersiz olduğundan voltajı yükseltmek için DC-DC dönüştürücü kullanılmış.

Malzemelerimiz

1- Baby Orangutan B-328
2- Pololu 10:1 Redüktörlü Motor x2
3-QTR-8A çizgi izleyen sensörü
4- Pololu 32×7 mm tekerlek
5- 3/8″ sarhoş tekerlek
6-  2.5-9.5 V konventör
7- 3.7 volt lipo batarya

Devre elemanları : C1 ve C2 = 22uF kondansatör , R1 R2 ve R4 = 470 Ohms direnç, R10 R7 ve R8 = 330 Ohmsdirenç, R3 R5 ve R6 = 15K direnç, Robotun kaynak kodları C alt yapısı ile programlanmış projenin kodlarını ve robot çizimlerini konu sonundaki linkten indirebilirsiniz.Robotun ortalama ağırlığı 108 gr civarında bu size extra bir avantaj sağlıyor.

Bileşenler smd olduğundan çok hafifler.Robot programlanırken PID kullanılmış bu sayede çizgi üzerinde herhangi bir yalpalama yapmamakta.PID nedir diyorsanız.Projenin çizimlerini ve kaynak kodlarını bu linkten indirebilirsiniz.

Projenin Dosyasını İndir

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
//Robot Zero
#define F_CPU 20000000UL    // Baby Orangutan frequency (20MHz)
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
//Leds. Salidas.
#define LEDR PORTB1
#define LEDV PORTB2
//Interruptores. Entradas.
#define PULSADOR PORTB0
//Sensores. Entradas y salidas.
#define D3 PORTD7
#define D2 PORTC5
#define D1 PORTC4
#define D0 PORTC3
#define I0 PORTC2
#define I1 PORTC1
#define I2 PORTC0
#define I3 PORTD4
#define LED_ON PORTD2
void inicializar_puertos(void);
void reset(void);
void M1_forward(unsigned char pwm);
void M1_reverse(unsigned char pwm);
void M2_forward(unsigned char pwm);
void M2_reverse(unsigned char pwm);
void motors_init(void);
int obtener_errorp(void);
void inicializar_timer1(void);
int obtener_errord(void);
/*********** Ajuste comportamiento robot *********/
//Constantes Regulador PD.
int Kp = 50;  // 
int Kd = 2500; //
volatile int velocidad = 160;    
/*************************************************/
int main( void )
{
    char pulsador = 1;
    inicializar_puertos();
    motors_init();
    reset();
    while(pulsador != 0 )
    {
        pulsador = PINB & (1<<PULSADOR);
    }
    _delay_ms(500);
    inicializar_timer1();
    PORTD |= (1<<LED_ON); //Encendemos Sensores.
    
    M1_forward(0);      //Motor derecho.
    M2_forward(0);      //Motor izquierdo.
                
    while ( 1 )
    {  
    }
    return 0;
}
void inicializar_puertos(void)
{
   DDRD=0x6C;     //0110 1100 
   PORTD=0x00;  
   DDRB=0x26;     //0010 0110 
   PORTB=0x00;
   DDRC=0x00;     //0000 0000
   PORTC=0x00; 
}
void reset(void)
{
    
    PORTB &= ~(1<<LEDV);
    PORTB &= ~(1<<LEDR);
    _delay_ms(300);
    PORTB |= (1<<LEDV);
    PORTB |= (1<<LEDR);
    _delay_ms(300);
    PORTB &= ~(1<<LEDV);
    PORTB &= ~(1<<LEDR);
    _delay_ms(300);
    PORTB |= (1<<LEDV);
    PORTB |= (1<<LEDR);
    _delay_ms(300);
    PORTB &= ~(1<<LEDV);
    PORTB &= ~(1<<LEDR);
    _delay_ms(300);
    PORTB |= (1<<LEDV);
    PORTB |= (1<<LEDR);
}
//Funciones para controlar la velocidad y dirección de los
//motores. PWM controla la velocidad, valor entre 0-255.
void M1_reverse(unsigned char pwm)
{
    OCR0A = 0;
    OCR0B = pwm;
}
void M1_forward(unsigned char pwm)
{
    OCR0B = 0;
    OCR0A = pwm;
}
void M2_forward(unsigned char pwm)
{
    OCR2A = pwm;
    OCR2B = 0;
}
void M2_reverse(unsigned char pwm)
{
    OCR2B = pwm;
    OCR2A = 0;
}
//Configuración del hardware del micro que controla los motores.
void motors_init(void)
{
    // configure for inverted PWM output on motor control pins:
    // set OCxx on compare match, clear on timer overflow
    // Timer0 and Timer2 count up from 0 to 255
    TCCR0A = TCCR2A = 0xF3;
    // use the system clock/8 (=2.5 MHz) as the timer clock
    TCCR0B = TCCR2B = 0x02;
    // initialize all PWMs to 0% duty cycle (braking)
    OCR0A = OCR0B = OCR2A = OCR2B = 0;
    // set PWM pins as digital outputs (the PWM signals will not
    // appear on the lines if they are digital inputs)
    DDRD |= (1 << PORTD3) | (1 << PORTD5) | (1 << PORTD6);
    DDRB |= (1 << PORTB3);
}
void inicializar_timer1(void) //Configura el timer y la interrupción.
{
    OCR1A= 0x0138; // 1 ms. 0C35 10ms, 0x0271 2ms.
    TCCR1B |=((1<<WGM12)|(1<<CS11)|(1<<CS10));    //Los bits que no se tocan a 0 por defecto
    TIMSK1 |= (1<<OCIE1A);
    sei();
}
int obtener_errorp(void)
{
    char errorp=0;
    static char ultimo_errorp=0;
    char contador_sensor=0;
    if(((PINC & 0x04) != 0) && ((PINC & 0x08) != 0))
    {
        errorp=0;
        return(0);
     }
    if((PIND & 0x10) != 0) //I3 PD4 -7
    {
        errorp = errorp - 0x07;
        contador_sensor++;
    }
    if((PINC & 0x01) != 0) //I2 PC0 -5
    {
        errorp = errorp - 0x05;
        contador_sensor++;
    }
    if((PINC & 0x02) != 0) //I1 PC1 -3
    {
        errorp = errorp - 0x03;
        contador_sensor++;
    }
    if((PINC & 0x04) != 0) //I0 PC2 -1
    {
        errorp = errorp - 0x01;
        contador_sensor++;
    }
    if((PINC & 0x08) != 0) //D0 PC3 +1
    {
        errorp = errorp + 0x01;
        contador_sensor++;
    }
    if((PINC & 0x10) != 0) //D1 PC4 +3
    {
        errorp = errorp + 0x03;
        contador_sensor++;
    }
    if((PINC & 0x20) != 0) //D2 PC5 +5
    {
        errorp = errorp + 0x05;
        contador_sensor++;
    }
    if((PIND & 0x80) != 0) //D3 PD7 +7
    {
        errorp = errorp + 0x07;
        contador_sensor++;
    }
    if(contador_sensor != 0)
    {
        errorp = errorp / contador_sensor;
        ultimo_errorp = errorp;
        return(Kp * (int)errorp);
    }
    else
    {
        if(ultimo_errorp < 0)
            errorp = -0x09;
        else
            errorp = 0x09;
        ultimo_errorp = errorp;
        return((int)errorp * Kp);
    }      
}
int obtener_errord(void)
{
    int error = 0;
    static int error_old = 0;
    static int errord=0;
    static int errord_old = 0;
    static int tic = 1;  // 1
    static int tic_old = 1; //
    int diferencia = 0;
    if(((PINC & 0x04) != 0) && ((PINC & 0x08) != 0))
        error=0;
    else if((PINC & 0x08) != 0) //D0 PC3 +1
        error = 1;
    else if((PINC & 0x04) != 0) //I0 PC2 -1
        error = -1;
    else if((PINC & 0x10) != 0) //D1 PC4 +3
        error = 3;
    else if((PINC & 0x02) != 0) //I1 PC1 -3
        error = -3;
    else if((PINC & 0x20) != 0) //D2 PC5 +5
        error = 5;
    else if((PINC & 0x01) != 0) //I2 PC0 -5
        error = -5;
    else if((PIND & 0x80) != 0) //D3 PD7 +7
        error = 7;
    else if((PIND & 0x10) != 0) //I3 PD4 -7
        error = -7;
    else
        {
            if (error_old < 0) error = -9; else if(error_old > 0)
                error = 9;
        }
    //Cálculo de la velocidad media del error.
    if (error == error_old)
    {
        tic = tic + 1;
        if(tic > 30000)
            tic = 30000;
        if(tic > tic_old)
            errord = errord_old/tic;
//      if(tic > tic_old)
//          errord = (errord_old*tic_old)/tic;
    }
    else
    {
        tic++;
        diferencia = error - error_old;
        errord = Kd*(diferencia)/tic; //error medio
        errord_old = errord;
        tic_old=tic;
        tic=0;
    }
    error_old = error;
    return(errord);
}
ISR(TIMER1_COMPA_vect)
{
    int errort=0;
    int proporcional = obtener_errorp();
    int derivativo = obtener_errord();
    errort = proporcional + derivativo;
    if(errort > velocidad)
        errort = velocidad;
    else if(errort < - velocidad) errort = - velocidad; if(errort>0)
    {
        M1_forward(velocidad - errort);     //Motor derecho.
        M2_forward(velocidad);              //Motor izquierdo.
        PORTB |= (1<<LEDV);
        PORTB &= ~(1<<LEDR);
    }
    else if(errort<0)
    {
        M1_forward(velocidad);              //Motor derecho. 
        M2_forward(velocidad + errort);     //Motor izquierdo.
        PORTB |= (1<<LEDR);
        PORTB &= ~(1<<LEDV);
    }
    else
    {
        M2_forward(velocidad);      
        M1_forward(velocidad);
        PORTB &= ~(1<<LEDR);
        PORTB &= ~ (1<<LEDV);
    }
    TIFR1 |= (1<<OCF1A);
}

YAZAR : Admin

Elektronik Mühendisi / E.Üni. Kalibrasyon Lab. Sorumlusu / Biyomedikal Kalibrasyon Laboratuvarı Sorumlu Müdürü (Sağ.Bak.) / X-Işınlı Görüntüleme Sistemleri Test Kontrol ve Kalibrasyon Uzmanı (Sağ.Bak.) / Ultrason-Doppler Sistemleri Test Kontrol ve Kalibrasyon Uzmanı (Sağ.Bak.) - Hatalı veya kaldırılmasını istediğiniz sayfaları diyot.net@gmail.com bildirin

BU YAZIYI DA İNCELEDİNİZ Mİ ?

Buzzer

BUZZER uyarı sesleri çıkarabilmek amacı ile kullanılan mini hoparlördür. Hoparlörler kadar yüksek ve detaylı ses …

Bir cevap yazın