Autor Tema: ayuda para un encoder con pic18f4550  (Leído 5752 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado isa12345

  • PIC10
  • *
  • Mensajes: 19
ayuda para un encoder con pic18f4550
« en: 12 de Mayo de 2011, 15:16:05 »
mi codigo lo hice en ccs me trabaja bien en simulacion  pero ya en fisico me presenta bastante ruido incrementa mi valor de la cuenta de pulsos solos. alguien podria ayudarme con alguna idea para eliminar mi problema con el ruido o aportando alguna modificacion a mi codigo


el codigo es el siguiente


#include <18F4550.h>
#fuses INTHS,NOPBADEN 
#use delay(internal=8Mhz)

#BYTE TRISA=0xF92
#BYTE PORTA=0xF80
#BYTE TRISB=0xF93
#BYTE PORTB=0xF81
#BYTE TRISC=0xF94
#BYTE PORTC=0xF82
#BYTE TRISD=0xF95
#BYTE PORTD=0xF83

#include <lcdd.c>
int16 x=0;

#Int_Ext                        // Interrupción Externa por RB0: Decodificación de Encoder.
Void IntRB0()                       
{                                   
   // CCS se encarga de desactiva automáticamente cualquier interrupción.
   // No hace falta guardar contextos de registros.
                                         
   If (Bit_Test(PortB, 0))      // Si RB0 se ha puesto a 1 (flanco de subida),
           x++;                 // entonces incrementar una unidad el valor de X.
       
   }
 

void main(){
   lcd_init();
 
  Port_B_Pullups(FALSE);

   Ext_Int_Edge(0,L_TO_H);        // Inicialmente detectar interrupción por flanco de subida.
   Enable_Interrupts(Int_Ext);  // Activar Interrupción Externa por RB0/INT.
   Enable_Interrupts(GLOBAL);   // Interrupciones Generales Activadas.

   Set_Tris_B(0b11111111);      // Puerto B todo entradas (sólo usamos las entradas RB0 y RB1).
   
   // ---------- Programa Principial ----------

 While (True)
   {
           printf(lcd_putc," \f %Lu",x);
            delay_ms(100);
            }
   }


 
 

Desconectado Diego E.

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1086
Re: ayuda para un encoder con pic18f4550
« Respuesta #1 en: 12 de Mayo de 2011, 15:34:59 »
Hola, prueba sin el sensor para ver si te sigue incrementando solo, monta resistencia pull-ap, utiliza retardos entre lecturas del sensor...

Saludos.

Desconectado isa12345

  • PIC10
  • *
  • Mensajes: 19
Re: ayuda para un encoder con pic18f4550
« Respuesta #2 en: 12 de Mayo de 2011, 16:44:54 »
ya lo probe con un push-boton y la cuenta me la hace muy rara de repente cuenta uno por uno y luego aumenta hasta en 5.

Desconectado isa12345

  • PIC10
  • *
  • Mensajes: 19
Re: ayuda para un encoder con pic18f4550
« Respuesta #3 en: 12 de Mayo de 2011, 16:51:51 »
ya le meti un retardo de 100 ms

Void IntRB0()                       
{                                   
   // CCS se encarga de desactiva automáticamente cualquier interrupción.
   // No hace falta guardar contextos de registros.
                                         
   If (Bit_Test(PortB, 0))      // Si RB0 se ha puesto a 1 (flanco de subida),
       {    x++;                 // entonces incrementar una unidad el valor de X.
        }
       delay_ms(100);
}

Desconectado isa12345

  • PIC10
  • *
  • Mensajes: 19
Re: ayuda para un encoder con pic18f4550
« Respuesta #4 en: 12 de Mayo de 2011, 17:02:30 »
con el delay ya me hace bien la cuenta con el push-boton pero con el sensor no hace la cuenta.sabes q podria estar afectandome?

Desconectado wannaky

  • PIC12
  • **
  • Mensajes: 92
Re: ayuda para un encoder con pic18f4550
« Respuesta #5 en: 14 de Mayo de 2011, 07:14:52 »
con el delay ya me hace bien la cuenta con el push-boton pero con el sensor no hace la cuenta.sabes q podria estar afectandome?


hola isa12345, no pongas delays dentro de la interrupción, supongo que el compilador te da unos warnings, prueba a usar un flag dentro de la interrupción, y luego en tu main mira el estado de ese flag por ejemplo...


Código: [Seleccionar]

#Int_Ext                        // Interrupción Externa por RB0: Decodificación de Encoder.
Void IntRB0()                       
{                                   
   // CCS se encarga de desactiva automáticamente cualquier interrupción.
   // No hace falta guardar contextos de registros.
                                         
   If (Bit_Test(PortB, 0))
       aux=1;       //flag
       
   }
 


void main(){
   lcd_init();
 
  Port_B_Pullups(FALSE);

   Ext_Int_Edge(0,L_TO_H);        // Inicialmente detectar interrupción por flanco de subida.
   Enable_Interrupts(Int_Ext);  // Activar Interrupción Externa por RB0/INT.
   Enable_Interrupts(GLOBAL);   // Interrupciones Generales Activadas.

   Set_Tris_B(0b11111111);      // Puerto B todo entradas (sólo usamos las entradas RB0 y RB1).
   
   // ---------- Programa Principial ----------

 While (True)
   {
           
           if(aux==1)
            { 
             x++;
             printf(lcd_putc," \f %Lu",x);
             aux=0;
            }
   }


saludos...

Desconectado isa12345

  • PIC10
  • *
  • Mensajes: 19
Re: ayuda para un encoder con pic18f4550
« Respuesta #6 en: 17 de Mayo de 2011, 13:19:12 »
ya logre solucionar mi problema el código esta bien el problema se encontraba en mi sensor (llave óptica, un emisor y un receptor)
un amigo me recomendó acoplar un transistor a la salida de mi sensor para aumentar la corriente y problema solucionado. modifique el código para que me pueda aumentar y decrementar el valor de la x. gracias por su apoyo en verdad gracias


#include <18F4550.h>
#fuses INTHS,NOPBADEN 
#use delay(internal=8Mhz)

#BYTE TRISA=0xF92
#BYTE PORTA=0xF80
#BYTE TRISB=0xF93
#BYTE PORTB=0xF81
#BYTE TRISC=0xF94
#BYTE PORTC=0xF82
#BYTE TRISD=0xF95
#BYTE PORTD=0xF83

#include <lcdd.c>
int16 x=0;

#Int_Ext                        // Interrupción Externa por RB0: Decodificación de Encoder.
Void IntRB0()                       
{                                   
   // CCS se encarga de desactiva automáticamente cualquier interrupción.
   // No hace falta guardar contextos de registros.
                                         
   If (Bit_Test(PortB, 0))      // Si RB0 se ha puesto a 1 (flanco de subida),
       { if(input(pin_B4)==1)
       {
       x++;
     
       }// entonces incrementar una unidad el valor de X.
       if(input(pin_B5)==1)
       {
       x--;
       }
       
        }
}


void main()
{
   lcd_init();
 
  Port_B_Pullups(FALSE);

   Ext_Int_Edge(0,L_TO_H);        // Inicialmente detectar interrupción por flanco de subida.
   Enable_Interrupts(Int_Ext);  // Activar Interrupción Externa por RB0/INT.
   Enable_Interrupts(GLOBAL);   // Interrupciones Generales Activadas.

   Set_Tris_B(0b11111111);      // Puerto B todo entradas (sólo usamos las entradas RB0 y RB1).
   
   // ---------- Programa Principial ----------

 While (True)
   {
           printf(lcd_putc," \f %Lu",x);
            delay_ms(100);
            }
   }


 
 

Desconectado isa12345

  • PIC10
  • *
  • Mensajes: 19
Re: ayuda para un encoder con pic18f4550
« Respuesta #7 en: 17 de Mayo de 2011, 15:28:40 »
el encoder por si solo ya me jala en fisico pero resulta que es solo una parte de un proyecto mas grande y ya dentro del codigo no me funciona la interrupcion espero puedan aportarme ideas para poder hacer que funcione por completo mi proyecto gracias

codigo completo///



#include <18F4550.h>
#fuses INTHS,NOPBADEN 
#use delay(internal=16Mhz)
#include <lcdd.c>

#BYTE TRISA=0xF92
#BYTE PORTA=0xF80
#BYTE TRISB=0xF93
#BYTE PORTB=0xF81
#BYTE TRISC=0xF94
#BYTE PORTC=0xF82
#BYTE TRISD=0xF95
#BYTE PORTD=0xF83

int16 x=0;
int   i;
int16 amper;
float amper3;
float amper4;
float amper1;
float amper2;
int16 q;
int   flag2=0;
int   flag1=0;
     
#Int_Ext                        // Interrupción Externa por RB0: Decodificación de Encoder.
Void IntRB0()                       
{                                   
   // CCS se encarga de desactiva automáticamente cualquier interrupción.
   // No hace falta guardar contextos de registros.
                                         
   If (Bit_Test(PortB, 0))      // Si RB0 se ha puesto a 1 (flanco de subida),
       {
      x++;
      output_high(pin_c7);
}
}
Void  nada ();
void enrollar();
void desenrollar();
void cero();
void veinticinco();
void mitad();
void setentaycinco();
void cien();
void corriente();


void main(){
         
   Port_B_Pullups(FALSE);       
   Ext_Int_Edge(0,L_TO_H);        // Inicialmente detectar interrupción por flanco de subida.
   Enable_Interrupts(Int_Ext);  // Activar Interrupción Externa por RB0/INT.
   Enable_Interrupts(GLOBAL);
   setup_adc_ports(all_analog);
   setup_adc(ADC_CLOCK_INTERNAL);
   //setup_ccp1(CCP_PWM);
   //setup_timer_2(T2_DIV_BY_1, 127, 1); //Frecuencia de 15.62KHz
   //set_pwm1_duty(500);
   
   amper1=0.0;
   amper2=0.0;
   amper3=0.0;
   amper4=0.0;
         
   
   lcd_init();
      while(true)
      {
         
      set_adc_channel(0);
      delay_us(20);
      q = read_adc();
      lcd_gotoxy(1,1);
      printf(lcd_putc,"\ %Lu",q);
   
         lcd_gotoxy(10,2);
      printf(lcd_putc,"%Lu",x );
     
   
      if(q>200)
      cero();
       if((q>150)&&(q<200))
            veinticinco();
       if((q>151)&&(q<100))
                    mitad();
       if((q>50)&&(q<99))
             setentaycinco();
       if  ((q>49)&&(q<98))
             cien();
      }
         
      }
     
void cero(){
   lcd_gotoxy(10,1);
   printf(lcd_putc,"  ");

   lcd_gotoxy(10,1);
   printf(lcd_putc,"0");

   if (x>0)
      enrollar();
   }
void veinticinco(){
   lcd_gotoxy(10,1);
   printf(lcd_putc,"25");

   if (x>25)
   {   enrollar();
   }
   if(x==25)
   {
   nada ();
   }
   if(x<25)
   {   
   desenrollar();
   }
      }
   
void mitad(){
   lcd_gotoxy(10,1);
   printf(lcd_putc,"50");

  IF (x>50)
  {enrollar();
  }
  if(x==50)
   {
   nada ();
   }
   if (x<50)
  {
  desenrollar();
  }
   }
void setentaycinco()
   {
   lcd_gotoxy(10,1);
   printf(lcd_putc,"75");

   IF (x>75)
   {enrollar();
  }
   IF (x>50)
  {enrollar();
  }
  if(x==75)
   {   nada ();
   }
   if (x<75)
  {desenrollar();  }
   }

void cien ()
   {
   lcd_gotoxy(10,1);
   printf(lcd_putc,"100");
      IF (x>100)
      {  enrollar();
      }
            if(x==100)
            {   nada ();
              }
         if (x<100)
      {desenrollar(); 
      }
}

Void enrollar ()
   {
  //corriente();
   lcd_gotoxy(12,1);
   printf(lcd_putc,"EN");

     
        delay_ms(500);
        output_low(PIN_C4);
        delay_ms(500);
        output_high(PIN_C5);
        IntRB0();                       
         x--;
     
}

Void desenrollar ()

     // corriente();
      lcd_gotoxy(12,1);
         printf(lcd_putc,"DE");

        delay_ms(500);
        output_low(PIN_C5);
        delay_ms(500);
        output_high(PIN_C4);
         x++;
     
}

Void  nada ()
{        lcd_gotoxy(12,1);
         printf(lcd_putc,"na");
         output_low(PIN_C5);
        output_low(PIN_C4);
         flag1=0;
         flag2=0;
         
}

void corriente()
{

set_adc_channel(1);
      delay_us(20);
     
               amper3=0;
               amper4=0;

      for(i=0;i<=50;i++)
      {
     
      amper = read_adc();
      amper3=amper3+amper;
      amper4=amper3/51;
     
      }
      set_adc_channel(0);
      delay_us(20);
      //amper = read_adc();
      amper1 = (1.0*amper4)/200;
      amper2=(amper1*1.0)+(amper1*0.130);
     
    //lcd_gotoxy(10,1);
  // printf(lcd_putc,"\ %Lu ", amper);
   lcd_gotoxy(1,2);
   printf(lcd_putc,"\%04.4fjj", amper2);
   
}

Desconectado wannaky

  • PIC12
  • **
  • Mensajes: 92
Re: ayuda para un encoder con pic18f4550
« Respuesta #8 en: 17 de Mayo de 2011, 15:56:19 »

Void enrollar ()
   {
  //corriente();
   lcd_gotoxy(12,1);
   printf(lcd_putc,"EN");

     
        delay_ms(500);
        output_low(PIN_C4);
        delay_ms(500);
        output_high(PIN_C5);
        IntRB0();                        <---- AQUÍ                    
         x--;
     
}


en esta parte del código, donde pones IntRB0(); , lo que quieres es llamar a la interrupción?!?!?!   :? :? :?  la interrupción se ha de ejecutar sola...

pero de todos modos, podrías explicar que ha de hacer tu circuito, porque intentar deducir la idea viendo el código... al menos para mi es algo abstracto...  ;-)  ;-) ;-) pon algo mas de información de lo que pretendes hacer...   y de paso también comenta un poco lo que pretendes hacer en el código, porque veo que tomas unas 50 muestras con el ADC (supongo que de un sensor de corriente) y haces una media, no?!?!?!

un saludo...

Desconectado isa12345

  • PIC10
  • *
  • Mensajes: 19
Re: ayuda para un encoder con pic18f4550
« Respuesta #9 en: 18 de Mayo de 2011, 14:50:16 »
se que la interrupcion se va activar sola, jajaja pero estoy desesperado que no me jala mi codigo completo.
lo que quiero es manejar un motor dependiendo el valor de una fotoresistencia. de pendiendo en q valor se encuentre la fotoresistencia va a girar hacia la derecha el motor o a la izquierda. mi encoder lo utilizo solo como un contador de pulsos ya se aumentando o restando


 

anything