Main Page | File List | Globals

robotu.c

Go to the documentation of this file.
00001 //
00002 // C Implementation: robotu
00003 //
00004 // Description: helper routines for robot.c
00005 //
00006 //
00007 // Author: Leonhard Klein <leoklein@gmx.net>, (C) 2004
00008 
00009 #include <avr/io.h>
00010 #include <avr/interrupt.h>
00011 #include <avr/signal.h>
00012 #include <avr/pgmspace.h>
00013 #include <avr/eeprom.h>
00014 #include "robotu.h"
00015 
00016 
00017 const s08 graytab[]= {0,-1,1,0, 1,0,0,-1, -1,0,0,1, 0,1,-1,0};
00018 
00019 #define IRON     (PORTB |=  _BV(PB4))  
00020 #define IROFF    (PORTB &= ~_BV(PB4))  
00021 #define IRTOGGLE (PORTB ^=  _BV(PB4))  
00023 u16 irtime;
00024 s16 irbit;
00025 
00026 irdatatype irbuf;
00027 
00028 #ifdef SINUS
00029 const s08 __ATTR_PROGMEM__ sinetab[] = {
00030                                          0,3,6,9,12,16,19,22,25,28,31,34,37,40,43,46,49,51,54,57,60,63,65,68,71,
00031                                          73,76,78,81,83,85,88,90,92,94,96,98,100,102,104,106,107,109,110,112,113,
00032                                          115,116,117,118,120,121,122,122,123,124,125,125,126,126,126,127,127,127
00033                                        }
00034                                        ;  /* sine_tab [0..63]-> [0..127] */
00035 
00036 s08 sine(u08 in) {
00037   if (in < 64) return pgm_read_byte_near(sinetab[in]);
00038   else if (in < 128) return pgm_read_byte_near(sinetab[127-in]);
00039   else if (in < 192) return -pgm_read_byte_near(sinetab[in-128]);
00040   else return -pgm_read_byte_near(sinetab[255-in]);
00041 }
00042 #endif
00043 
00044 void decode_position() {                   /* decode angle sensors */
00045   static s16 posoldl, posoldr, temppos;
00046   static u08 positioncount, positionl_code, positionr_code;
00047   positionl_code = positionl_code >> 2;
00048   if (PIND & _BV(PD2)) positionl_code |=4;
00049   if (PIND & _BV(PD3)) positionl_code |=8;
00050   positionl -= graytab[positionl_code];
00051   positionr_code = positionr_code >> 2;
00052   if (PIND & _BV(PD0)) positionr_code |=4;
00053   if (PIND & _BV(PD1)) positionr_code |=8;
00054   positionr += graytab[positionr_code];
00055   heading = (positionr-positionl);
00056   while (heading < 0) heading+=POS360;
00057   heading = heading % POS360;
00058   if (!positioncount++) {
00059     /*        temppos = ((positionl-posoldl)+(positionr-posoldr)) >> 1;
00060             posx += temppos * sine(heading*255/POS360);
00061             posy += temppos * COSINE(heading*255/POS360);       not used */
00062     if ((positionl>10000)|(positionl<-10000)|(positionl>10000)|(positionl<-10000)) {
00063       l_to -= positionl;
00064       r_to -= positionr - heading;
00065       positionr = heading;
00066       positionl = 0;
00067     }
00068     posoldl = positionl;
00069     posoldr = positionr;
00070   }
00071 }
00072 u16 abs(s16 val) {
00073   if (val<0) return -val;
00074   else return val;
00075 }
00076 void drive() {                             /* set PWM according to l_to, r_to and calculate speed and direction */
00077   static s16 tempspeed;
00078   s16 l,r;
00079   if (direction > 0) {
00080     l_to += (tempspeed * (64-direction)) / DIVSPEED;
00081     r_to += (tempspeed * 64) / DIVSPEED;
00082   } else {
00083     r_to += (tempspeed * (64+direction)) / DIVSPEED;
00084     l_to += (tempspeed * 64) / DIVSPEED;
00085   }
00086   l = (l_to - positionl);
00087   r = (r_to - positionr);
00088   d_pos = abs(l)+abs(r);
00089   if ((l > 255)|(l < -255)|(r > 255)|(r < -255)) {
00090     if (l>255) l=255;   if (l<-255) l=-255;
00091     if (r>255) r=255;   if (r<-255) r=-255;
00092     tempspeed = 0;
00093   } else tempspeed = speed;
00094   if ((l < MINSPEED)&(l>-MINSPEED)) l=0;
00095   if ((r < MINSPEED)&(r>-MINSPEED)) r=0;   /* TODO: Delay to avoid sliding */
00096   if (l>=0) {
00097     PORTB &= ~_BV(PB0);
00098     OCR1A = l;
00099   } else {
00100     PORTB |= _BV(PB0);
00101     OCR1A = 255+l;
00102   }
00103   if (r>=0) {
00104     OCR1B = r;
00105     PORTD &= ~_BV(PD7);
00106   } else {
00107     PORTD |= _BV(PD7);
00108     OCR1B = 255+r;
00109   }
00110 }
00111 void drive_to_pos(s16 l2, s16 r2) {       /* not additive! */
00112   l_to = positionl + l2;
00113   r_to = positionr + r2;
00114 }
00115 
00116 void start_radar() {
00117   oldmodus = modus;                                /* save old modus */
00118   modus = radar;
00119   radar_value = -1400;                             /* delay before INIT */
00120   TCCR0 = _BV(CS00);                               /* set TIMER0 frequency to 15,6kHz 1Tick = 1,92cm */
00121   PORTD &= ~_BV(PD6);                              /* switch radar on */
00122 }
00123 void start_ad(enum admodtype adm) {
00124   if (admodus == none) {
00125     admodus = adm;
00126     switch (adm) {
00127     case irpos:
00128       ADMUX = _BV(REFS0) + 1;                                     /* external AREF Channel 1 */
00129       ADCSRA = _BV(ADEN)|_BV(ADSC)|_BV(ADFR)|_BV(ADIE) + 6;       /* enable freerunning /64 */
00130       return;
00131     case irstation:
00132       ADMUX = _BV(REFS0) + 1;                                     /* external AREF Channel 1 */
00133       break;
00134     case light:
00135       ADMUX = _BV(REFS0) + 0;                                     /* light sensor */
00136       break;
00137     case vcc:
00138       ADMUX = _BV(REFS0) + 5;                                     /* internal bandgap 1.23V */
00139       break;
00140     case vcco:
00141       ADMUX = _BV(REFS0) + 4;                                     /* voltage of "feeler" */
00142       break;
00143     }
00144     ADCSRA = _BV(ADEN)|_BV(ADSC)|_BV(ADIE) + 3;                   /* enable single mode */
00145   } else START_BEEP(5);
00146 }
00147 u08 atoi(u08 *str) {
00148   u08 i,i2;
00149   i = str[0];
00150   i2= str[1];
00151   if ((i2 == ' ')|(i2 == 0)) {
00152     i2 = i;
00153     i = '0';
00154   }
00155   if (i>='A') i -= 'A'-'9'-1;
00156   if (i2>='A') i2 -= 'A'-'9'-1;
00157   return ((i-'0') << 4) + (i2-'0');
00158 }
00159 void ir_int_send(u16 val) {
00160   static u08 intstr[6];
00161   u08 i;
00162   i = 0;
00163   while (i++ < 5) {
00164     intstr[5-i] = val%10 + '0';
00165     val /= 10;
00166   }
00167   intstr[5] = 0;
00168   ir_string_send(intstr);
00169 }

Generated on Wed Feb 2 20:03:50 2005 for Robot by doxygen 1.3.6