jueves, 1 de marzo de 2012

Wii-Robot


Este es un proyecto creado en el colegio Don Bosco de Renteria por los alumnos Lander Del Rio y Belai Irazabal que cursan el ciclo superior de electronica, el proyecto consiste en un juego de baloncesto, para meter las canastas un brazo robot es controlado por un Nunchuk (mando de la nintendo wii), esperamos que os guste.







/*******************************************************************************

                              WII-ROBOT
                              
Programa honek esku baten forma duen robota kontrolatzeko balio du, robotak
5 motor ditu 5 artikulazio ezberdin mugitu ahal izateko, motor bakoitzak bi
zentzuetan biratzen du, mugimenduak kontrolatzeko nintendo wii konsolaren mandoa
erabiltzen da, nunchuk izenekoa, hau erabili ahal izateko i2c protokoloa
erabiltzea derrigorrezkoa da.                              
Honetaz gain, jolasaren menuko aukera guztiak erakutsiko dituen LCD bat erabili
dugu, bertan, denbora atzera kontua eta kanasta kopurua adierazteko.
Minutu kopurua aukeratu daiteke.
Menuan zehar nabegatzeko botoien eginkizuna lcd-an erakusten da botoien parean

PORT A
   MOTOR 5  (A0,A1)
   ARGIA    (A2)   
   BOTOIAK  (A3 MARKAK,A4 JOKATU)
   SENSOREA (A5)            

PORT B
   LCD
      B0 --> enable  -  B1 --> rs   -  B2 --> rw   -  B4 --> D4   -  B5 --> D5
      B6 --> D6      -  B7 --> D7
   SOINUA
      B3 --> Soinua sortzeko uhina ateratzeko
      
PORT C
   MOTOR 1  (C0,C1)
   MOTOR 2  (C2,C3)
   MOTOR 3  (C4,C5)
   MOTOR 4  (C6,C7)

PORT D
   I2C      (D0=SDA,D1=SCL)
   
     
lcd_init()--> funtzio hau erabiltzen dugu LCD-a hasieratzeko
lcd_gotoxy(x,y) --> funtzio hau erabiltzen dugu LCD-aren posizioa aukeratzeko

*******************************************************************************/

#include <16F877A.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock= 4000000)
#include "lcd.c"
#use i2c(Master,sda=PIN_D0,scl=PIN_D1,fast)

// notak definitzen dira bakoitzaren frekuentzia lortzeko timerrean kargatu 
// behar den balioa adieraziz

#define do1 239      // 261 Hz
#define reb 225      // 277 Hz
#define re 213       // 293 Hz
#define mib 200      // 311 Hz
#define mi 189       // 329 Hz
#define fa 179       // 349 Hz
#define solb 168     // 370 Hz
#define sol 160      // 391 Hz
#define lab 150      // 415 Hz
#define la 142       // 440 Hz
#define sib 134      // 466 Hz
#define si 126       // 494 Hz
#define do2 120      // 522 Hz

// 2 botoi daude aukera ezberdinak aukeratzeko eta kanasta sartu den 
// egiaztatzeko sensorea

#define boton_a input(PIN_A4) // Ezkerreko botoia
#define boton_b input(PIN_A3) // Eskubiko botoia
//#define kanasta input(PIN_B0) // Sensorea irakurtzeko pin-a

int1 sound=0; //sound=1 bada soinua egin daiteke
int8 valor_carga=0; // nota ezberdinak entzuteko timerrean kargatzeko balioa 
int8 eten_kop=0 ; //eten_kop kontatzeko T1-en etundurak
signed seg=0,min=0; // segunduak eta minutuak kontatzeko
int8 kanasta_kop=0;

/*******************************************************************************

               kanastak kontatzeko B= kanpoko etenduraren bidez

*******************************************************************************/

#int_ext
void canastas(void)
{
      kanasta_kop++;
}
/*******************************************************************************

               soinua egin funtzioa (timer 0)

sound=1 den bitartean, toggle eginez PIN_C0-tik uhin ezberdinak
ateratzea ahalbideratzen du, hau lortzeko timerrak gainezka egiten duen 
bakoitzean PIN_C0-tik balioaren aldaketa bat bidaltzen da, horrela timerrean
balio ezberdinak kargatuz frekuentzia ezberdinak lortzen dira eta era beran
nota ezberdinak

*******************************************************************************/

#int_rtcc
void sonido(void)
{
   if(sound)
      output_toggle(PIN_D7);
   else
      output_low(PIN_D7);
   set_rtcc(valor_carga);
}

/*******************************************************************************

               denbora kontadorea (timer 1)

Kontadore honek atzera kontua egiten du minutuak eta segunduak dekrementatzen 
joaten dira

*******************************************************************************/

#int_timer1
void kontadorea(void)
{
   if(eten_kop==0)
   {
      eten_kop++;
   }
   else
   {
      eten_kop=0;
      seg--;
      if(seg<0)
      {
         seg=59;
         min--;
      }
   }
   set_timer1(65536-62500);
}
/*******************************************************************************

                    NUNCHUK-a HASIERATZEKO

*******************************************************************************/
void inicio_nunchuk()      // konexioa ahalbideratzeko funtzioa
{
   i2c_start();            //
   i2c_write(0xA4);        // 
   i2c_write(0xF0);        //
   i2c_write(0x55);        //
   i2c_stop();             //
   delay_ms(1);            //
   i2c_start();            //
   i2c_write(0xA4);        //
   i2c_write(0xFB);        //
   i2c_write(0x00);        //
   i2c_stop();             //
}

/*******************************************************************************

Funtzio honek nunchuk-aren posizioak jakitea ahalbideratzen du, horrela jakin 
dezakegu dagoen posizioaren arabera zein motor eta zein zentzutan biratu behar 
den,datos[6]aldagaian gordeko dira posizioaren informazioa adierazten duten 
6 byte-ak

            joy_x_axis = datos[0];
            joy_y_axis = datos[1];
            accel_x_axis = datos[2] 
            accel_y_axis = datos[3]
            accel_z_axis = datos[4] ez da erabiltzen ardatz hau
            
datos[5] aldagaiak gordetzen den byte-ak informazio ezberdina adierazten du 
lehenengo 2 bitak botoientzako:

            z_button = datos[5] >> 0
            c_button = datos[5] >> 1
            
azkeneko 6 bitak aurreko byte-ak konplementatzeko dira, horrela 8 bit-eko
informazioa jaso beharrean 10 bit-etakoa jasotzen da

            accel_x_axis = datos[5] >> 2
            accel_x_axis = datos[5] >> 3 
            accel_y_axis = datos[5] >> 4
            accel_y_axis = datos[5] >> 5
            
accel_z_axis ez da erabiltzen            
            
            accel_z_axis = datos[5] >> 6
            accel_z_axis = datos[5] >> 7 


*******************************************************************************/

void pedir_datos()
{  
   i2c_start();     // i2c protokoloaren hasieratzea
   i2c_write(0xA4); // nuntchuk-aren helbidea idazten du
   i2c_write(0x00); // 0 idaztean eskatzen diogu mandoaren posizioa adierazten
                    // duten 6 byte-ak bidaltzea
}


void motor_zero()
{
   OUTPUT_C(0x00); 
   output_bit(PIN_A0,0);
   output_bit(PIN_A1,0);
   output_bit(PIN_A2,0);
}

/*******************************************************************************

                     FUNTZIO NAGUSIA

*******************************************************************************/
void main(void)
{
   int8 record_actual=0,record_guardado,min_record;
   int8 kanasta_kop_za;
   
   int t;
   int datos[6] = {0};
   int joy_x_axis,joy_y_axis;
   int16 accel_x_axis,accel_y_axis,accel_z_axis;
   int z_button,c_button;
   
   SET_TRIS_B(0x00);
   SET_TRIS_D(0x00);
   
   setup_adc_ports(NO_ANALOGS);
   setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8 );
   set_timer1(65536-62500);
   
   setup_counters( RTCC_INTERNAL, RTCC_DIV_8);

   enable_interrupts(INT_RTCC);
   enable_interrupts(INT_EXT);
   ext_int_edge( H_TO_L );   
   enable_interrupts(GLOBAL);

   set_rtcc(0);
  
   lcd_init();
   //write_eeprom (0xff, record);
   
   LCD_GOTOXY(1,1);//Paso a inicio
   printf(lcd_putc,"wii-ROBOT       ");
   ////////////////    jokoa hastean entzungo den melodia     /////////////////////                     
           
            sound=1;
            valor_carga=256-do1;
            delay_ms(100);
            sound=0;
            delay_ms(30);
            sound=1;
            valor_carga=256-mi;
            delay_ms(100);
            sound=0;
            delay_ms(30);
            sound=1;
            valor_carga=256-sol;
            delay_ms(100);
            sound=0;
            delay_ms(30);
            sound=1;
            valor_carga=256-do1;
            delay_ms(100);
            sound=0;
            delay_ms(30);
            sound=1;
            valor_carga=256-mi;
            delay_ms(100);
            sound=0;
            delay_ms(30);
            sound=1;
            valor_carga=256-sol;
            delay_ms(100);
            sound=0;
            delay_ms(30);            
            sound=1;
            valor_carga=256-do1;
            delay_ms(300);
            sound=0;
                                                  
////////////////////////////////////////////////////////////////////////////////
   delay_ms(1000);
   LCD_GOTOXY(1,1);//Paso a inicio
   printf(lcd_putc,"EGILEAK:      ");
   LCD_GOTOXY(1,2);
   printf(lcd_putc,"Belai eta Lander");
   delay_ms(2500);

   inicio_nunchuk();

   while(1)
   {
      LCD_GOTOXY(1,1);
      printf(lcd_putc,"    wii-Robot   ");
      LCD_GOTOXY(1,2);
      printf(lcd_putc,"JOKATU     MARKA");
      
      if(boton_a==0)// JOKATU AUKERA
      {
         sound=1;             //botoiaren soinua
         valor_carga=256-do1;
         delay_ms(50);
         sound=0;
         
         while(boton_a==0);
         delay_ms(20); 
         kanasta_kop=0;
         disable_interrupts(INT_TIMER1);
         min=seg=kanasta_kop=kanasta_kop_za=0;
         LCD_GOTOXY(1,1);
         printf(lcd_putc,"DENBORA:   %02d:%02d",min,seg);
         LCD_GOTOXY(1,2);
         printf(lcd_putc,"OK           MIN");
         do{
            if(boton_b==0)
            {
               sound=1;             //botoiaren soinua
               valor_carga=256-do1;
               delay_ms(50);
               sound=0;
               
               delay_ms(20); //antirrebotes
               min++;
               if(min>59)
               {
                  min=0;
               }
               LCD_GOTOXY(1,1);
               printf(lcd_putc,"DENBORA:   %02d:%02d",min,seg);
               while(boton_b==0);  //Espero hasta soltar boton
            }
         }while(boton_a==1);
         sound=1;             //botoiaren soinua
         valor_carga=256-do1;
         delay_ms(50);
         sound=0;
         
         min_record=min;
         
         do{
            LCD_GOTOXY(1,1);
            printf(lcd_putc,"DENBORA:   %02d:%02d",min,seg); 
            LCD_GOTOXY(1,2);
            printf(lcd_putc,"KANASTAK:     %02d",kanasta_kop);
            enable_interrupts(INT_TIMER1);

            delay_ms(100);
            pedir_datos();
            delay_ms(1);
            i2c_start();
            i2c_write(0xA5); 
            
            for (t=0;t<5;t++)
               datos[t] = i2c_read();
            datos[5] = i2c_read(0);  //último read no devuelve bit ack

            i2c_stop();

            // Ahora preparo los datos 
            // la lectura del acelerómetro ocupa 10 bits
            // así que leo 8 bits y le añado los 2 restantes.
            // Por eso voy a multiplicarlos *2*2 (10 bits = 2^10)

            joy_x_axis = datos[0];
            joy_y_axis = datos[1];
            accel_x_axis = datos[2] * 2 * 2; 
            accel_y_axis = datos[3] * 2 * 2;
            accel_z_axis = datos[4] * 2 * 2;

            z_button = 0;
            c_button = 0;

            // El byte datos[5] contiene bits para los botones z y c
            // también contine los bits menos significativos del acelerómetro
            // así que comprobamos cada bit de datos[5]
            
            if ((datos[5] >> 0) & 1) z_button = 1;
            if ((datos[5] >> 1) & 1) c_button = 1;
            if ((datos[5] >> 2) & 1) accel_x_axis += 2;
            if ((datos[5] >> 3) & 1) accel_x_axis += 1;
            if ((datos[5] >> 4) & 1) accel_y_axis += 2;
            if ((datos[5] >> 5) & 1) accel_y_axis += 1;
            if ((datos[5] >> 6) & 1) accel_z_axis += 2;
            if ((datos[5] >> 7) & 1) accel_z_axis += 1;
            
            //MOTOR 1
            
            if((accel_x_axis>300)&&(accel_x_axis<400))
            {
               output_bit(PIN_C0,1);
               output_bit(PIN_C1,0);
               //ezkerrera mugitu behar du
            }
            else if((accel_x_axis>150)&&(accel_x_axis<250))
            {
               output_bit(PIN_C0,0);
               output_bit(PIN_C1,1);
               //eskubira mugitu behar du
            }
            else
            {
               output_bit(PIN_C0,0);
               output_bit(PIN_C1,0);
               //gelditu
            }
            
            //MOTOR 2
            
            if((joy_y_axis<65)&&(joy_y_axis>=0)&&(c_button==1))// SIN C BOTON
            {
               output_bit(PIN_C2,0);
               output_bit(PIN_C3,1);
               //beheraka mugitu behar du
            }
            else if((joy_y_axis<=255)&&(joy_y_axis>200)&&(c_button==1))// SIN C BOTON
            {
               output_bit(PIN_C2,1);
               output_bit(PIN_C3,0);
               //goraka mugitu behar du
            }
            else
            {
               output_bit(PIN_C2,0);
               output_bit(PIN_C3,0);
               //gelditu
            }
            
            //MOTOR 3
            
            if((accel_y_axis>340)&&(accel_y_axis<400))
            {
               output_bit(PIN_C4,0);
               output_bit(PIN_C5,1);
               //goraka mugitu behar du
            }
            else if((accel_y_axis>70)&&(accel_y_axis<180))
            {
               output_bit(PIN_C4,1);
               output_bit(PIN_C5,0);
               //beheraka mugitu behar du
            }
            else
            {
               output_bit(PIN_C4,0);
               output_bit(PIN_C5,0);
               //gelditu
            }
            
            //MOTOR 4
            
            if((joy_y_axis<65)&&(joy_y_axis>=0)&&(c_button==0))//CON C BOTON
            
            {
               output_bit(PIN_C6,1);
               output_bit(PIN_C7,0);
               //beheraka
            }
            else if((joy_y_axis<=255)&&(joy_y_axis>200)&&(c_button==0))// CON C BOTON
            {
               output_bit(PIN_C6,0);
               output_bit(PIN_C7,1);
               //goraka
            }
            else
            {
               output_bit(PIN_C6,0);
               output_bit(PIN_C7,0);   
            }
            
            //MOTOR 5  PINTZAK
            
            if((joy_X_axis<65)&&(joy_x_axis>=0)&&(c_button==1))//SIN C BOTON
            {
               output_bit(PIN_A0,1);
               output_bit(PIN_A1,0);
               //ezkerrera mugitu behar du
            }
            else if((joy_x_axis<=255)&&(joy_x_axis>=200)&&(c_button==1))//SIN C BOTON
            {
               output_bit(PIN_A0,0);
               output_bit(PIN_A1,1);
               //eskubira mugitu behar du
            }
            else
            {
               output_bit(PIN_A0,0);
               output_bit(PIN_A1,0);
               //gelditu
            }
            
            //ARGIA
            
            if(z_button==0)
            {
               output_bit(PIN_A2,1);
               //argia piztu
            }
            if(z_button==1)
            {
               output_bit(PIN_A2,0);
               //argia itzali
            }            
            
            //Bisualizatu kanastak
            LCD_GOTOXY(1,2);
            printf(lcd_putc,"KANASTAK:     %02d",kanasta_kop);
                    
            if((min==0)&&(seg<=5))
            {
               sound=1;
               valor_carga=256-do1;
            }
            else
               sound=0;
            if(kanasta_kop_za < kanasta_kop)
            {
               sound=1;
               valor_carga=256-do1;
               delay_ms(50);
               valor_carga=256-do2;
               delay_ms(50);
               sound=0;
               kanasta_kop_za = kanasta_kop;   
            }
         }while(min>=0);
         sound=1;
         valor_carga=256-do2;
         delay_ms(50);
         sound=0;

         motor_zero();//   todos los motores a cero
    
         record_guardado=read_eeprom(0xff);
         record_actual=(kanasta_kop*10)/min_record;

         if(record_actual>record_guardado)
         {
////////////    rekorra gainditzean entzungo den melodia     /////////////////                     
           
            sound=1;
            valor_carga=256-do1;
            delay_ms(100);
            sound=0;
            delay_ms(30);
            sound=1;
            valor_carga=256-mi;
            delay_ms(100);
            sound=0;
            delay_ms(30);
            sound=1;
            valor_carga=256-sol;
            delay_ms(100);
            sound=0;
            delay_ms(30);
            sound=1;
            valor_carga=256-do1;
            delay_ms(100);
            sound=0;
            delay_ms(30);
            sound=1;
            valor_carga=256-mi;
            delay_ms(100);
            sound=0;
            delay_ms(30);
            sound=1;
            valor_carga=256-sol;
            delay_ms(100);
            sound=0;
            delay_ms(30);            
            sound=1;
            valor_carga=256-do2;
            delay_ms(300);
            sound=0;
                                                  
////////////////////////////////////////////////////////////////////////////////
            
            write_eeprom(0xff, record_actual);
            LCD_GOTOXY(1,1);
            printf(lcd_putc,"ZORIONAK!!!     ");
            LCD_GOTOXY(1,2);
            printf(lcd_putc,"Marka gainditua!");
            delay_ms(2000);
            LCD_GOTOXY(1,1);
            printf(lcd_putc,"PUNTUAZIOA: %02d  ",record_actual);
            LCD_GOTOXY(1,2);
            printf(lcd_putc,"HASIERA         ");
            while(boton_a==1);
            delay_ms(200);
         }
         else
         {
            LCD_GOTOXY(1,1);
            printf(lcd_putc,"Ez duzu marka   ");
            LCD_GOTOXY(1,2);
            printf(lcd_putc,"gainditu!       ");   
            delay_ms(2000);
            LCD_GOTOXY(1,1);
            printf(lcd_putc,"Saiatu berriro! ");
            LCD_GOTOXY(1,2);
            printf(lcd_putc,"                "); 
            delay_ms(2000);
         }
      }
      if(boton_b==0)
      {
         sound=1;             //botoiaren soinua
         valor_carga=256-do1;
         delay_ms(50);
         sound=0;
         
         while(boton_b==0);
         do
         {
            delay_ms(20);
            record_guardado=read_eeprom(0xff);
            LCD_GOTOXY(1,1);
            printf(lcd_putc,"PUNTUAZIOA: %02d       ",record_guardado);
            LCD_GOTOXY(1,2);
            printf(lcd_putc,"EZABATU   ATZERA");
         
            if(boton_a==0)
            {
               sound=1;             //botoiaren soinua
               valor_carga=256-do1;
               delay_ms(50);
               sound=0;
               
               record_guardado=0;
               write_eeprom(0xff,record_guardado);
               LCD_GOTOXY(1,2);
               printf(lcd_putc,"PUNTUAZIOA: %02d       ",record_guardado); 
               LCD_GOTOXY(1,2);
               printf(lcd_putc,"EZABATU   ATZERA");
               while(boton_a==0);
            }
         }while(boton_b==1); 
         sound=1;             //botoiaren soinua
         valor_carga=256-do1;
         delay_ms(50);
         sound=0;
         delay_ms(200);
      }
   }
}

No hay comentarios:

Publicar un comentario