TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Abner_emanuel en 25 de Marzo de 2023, 23:07:18

Título: Reducir funciones
Publicado por: Abner_emanuel en 25 de Marzo de 2023, 23:07:18
Saludos..

Quiero consultar y a la vez pedir de su ayuda para las siguientes funciones de mi código ccs c.

Tengo las siguiente funciones repetitivas y pretendo hacerla en una sola, ya que como bien dije se repiten.

Código: C++
  1. void pesando_1(void)
  2.          {
  3.          peso = get_units(10,1);                                                       // Lee el peso y hace un promedio de 10 muestras          
  4.          switch (unidad){
  5.          case 1:        
  6.                   factor = 1.0;
  7.                   lcd_gotoxy(1,2); printf(lcd_putc, "P1:%4.1f g ",peso/factor);
  8.                   break;
  9.          case 2:
  10.                   factor = 1000.0;
  11.                   lcd_gotoxy(1,2); printf(lcd_putc, "P1:%4.2f Kg",peso/factor);
  12.                   break;
  13.          case 3:
  14.                   factor = 28.35;
  15.                   lcd_gotoxy(1,2); printf(lcd_putc, "P1:%4.2f oz",peso/factor);
  16.                   break;
  17.                         }
  18.          }
  19.  
  20.          void pesando_2(void)
  21.          {
  22.          peso = get_units(10,2);                                                       // Lee el peso y hace un promedio de 10 muestras          
  23.          switch (unidad){
  24.          case 1:        
  25.                   factor = 1.0;
  26.                   lcd_gotoxy(1,3); printf(lcd_putc, "P2:%4.1f g ",peso/factor);
  27.                   break;
  28.          case 2:
  29.                   factor = 1000.0;
  30.                   lcd_gotoxy(1,3); printf(lcd_putc, "P2:%4.2f Kg",peso/factor);
  31.                   break;
  32.          case 3:
  33.                   factor = 28.35;
  34.                   lcd_gotoxy(1,3); printf(lcd_putc, "P2:%4.2f oz",peso/factor);
  35.                   break;
  36.                         }
  37.          }
  38.  
  39.          void pesando_3(void)
  40.          {
  41.          peso = get_units(10,3);                                                       // Lee el peso y hace un promedio de 10 muestras          
  42.          switch (unidad){
  43.          case 1:        
  44.                   factor = 1.0;
  45.                   lcd_gotoxy(1,4); printf(lcd_putc, "P3:%4.1f g ",peso/factor);
  46.                   break;
  47.          case 2:
  48.                   factor = 1000.0;
  49.                   lcd_gotoxy(1,4); printf(lcd_putc, "P3:%4.2f Kg",peso/factor);
  50.                   break;
  51.          case 3:
  52.                   factor = 28.35;
  53.                   lcd_gotoxy(1,4); printf(lcd_putc, "P3:%4.2f oz",peso/factor);
  54.                   break;
  55.                         }
  56.          }  
  57.  
  58.  
  59.          void pesando_4(void)
  60.          {
  61.          peso = get_units(10,4);                                                       // Lee el peso y hace un promedio de 10 muestras          
  62.          switch (unidad){
  63.          case 1:        
  64.                   factor = 1.0;
  65.                   lcd_gotoxy(13,3); printf(lcd_putc, "P4:%4.1f g ",peso/factor);
  66.                   break;
  67.          case 2:
  68.                   factor = 1000.0;
  69.                   lcd_gotoxy(13,3); printf(lcd_putc, "P4:%4.2f Kg",peso/factor);
  70.                   break;
  71.          case 3:
  72.                   factor = 28.35;
  73.                   lcd_gotoxy(13,3); printf(lcd_putc, "P4:%4.2f oz",peso/factor);
  74.                   break;
  75.                         }
  76.          }
  77.  
  78.          void pesando_5(void)
  79.          {
  80.          peso = get_units(10,5);                                                       // Lee el peso y hace un promedio de 10 muestras          
  81.          switch (unidad){
  82.          case 1:        
  83.                   factor = 1.0;
  84.                   lcd_gotoxy(13,4); printf(lcd_putc, "P5:%4.1f g ",peso/factor);
  85.                   break;
  86.          case 2:
  87.                   factor = 1000.0;
  88.                   lcd_gotoxy(13,4); printf(lcd_putc, "P5:%4.2f Kg",peso/factor);
  89.                   break;
  90.          case 3:
  91.                   factor = 28.35;
  92.                   lcd_gotoxy(13,4); printf(lcd_putc, "P5:%4.2f oz",peso/factor);
  93.                   break;
  94.                         }
  95.          }

De esas 5 funciones como puedo hacerla en una sola que realice lo mismo?. Su ayuda!!.
Título: Re:Reducir funciones
Publicado por: Eduardo2 en 26 de Marzo de 2023, 00:14:56
Si leí bien y no olvidé nada:
Código: [Seleccionar]
// n = 1,2,3
// unidad = 0,1,2

const float factor[]={1.0,1000.0,28.35};

void pesando(int8 n)   
{
    peso = get_units(10,n);         // Lee el peso y hace un promedio de 10 muestras           
    lcd_gotoxy(1,n+1); printf(lcd_putc, "P%u:%4.1f g ", n , peso/factor[unidad]);
}
Título: Re:Reducir funciones
Publicado por: Abner_emanuel en 26 de Marzo de 2023, 00:46:22
Eduardo2. Gracias por responder. Una pregunta.... Ahora cómo hace n para ir avanzando desde n=1 hasta n=5. Con algún ciclo for?.
Título: Re:Reducir funciones
Publicado por: Eduardo2 en 26 de Marzo de 2023, 02:12:03
Eduardo2. Gracias por responder. Una pregunta.... Ahora cómo hace n para ir avanzando desde n=1 hasta n=5. Con algún ciclo for?.

Vos mostraste solamente las funciones pesando_1..5 donde se supone que eran llamadas cuando correspondía.

Si antes las llamabas:
Código: [Seleccionar]
pesando_1() ;
pesando_2() ;
pesando_3() ;
pesando_4() ;
pesando_5() ;

ahora las llamas con argumento:
Código: [Seleccionar]
pesando(1) ;
pesando(2) ;
....

Podrías poner un for dentro de pesando()  para que lea y muestre los 5, pero no te alcanzan las líneas del display y no puedo adivinar cómo debería mostrarse.

Por otro lado, recién veo que en pesando_4..5  usás las líneas 3 y 4, en ese caso se puede agregar otra tabla:
Código: [Seleccionar]
// n = 1,2,3,4,5
// unidad = 0,1,2

const float factor[]={1.0,1000.0,28.35};
const int8 linea[]={2,3,4,3,4};

void pesando(int8 n)   
{
    peso = get_units(10,n);         // Lee el peso y hace un promedio de 10 muestras           
    lcd_gotoxy(1,linea[n-1]); printf(lcd_putc, "P%u:%4.1f g ",n,peso/factor[unidad]);
}


Título: Re:Reducir funciones
Publicado por: Abner_emanuel en 27 de Marzo de 2023, 20:39:07
Hola Eduardo2.

Pero para hacer que esta función pueda ser seleccionada (switch (unidad)) necesariamente entraran los case. De otra manera no se como se podría seleccionar alguna de estas.

Lo que me compartiste me dio un panorama extenso pero si es necesario seleccionar una opcion.

Título: Re:Reducir funciones
Publicado por: Eduardo2 en 27 de Marzo de 2023, 21:01:20
En tu código unidad es una variable global que vale 1,2 o 3.

Por simplicidad, y para no desperdiciar el trabajo de sabios indios, te modifiqué unidad a que valga 0,1 o 2  y sea el índice de un array ( const float factor[] ).
Título: Re:Reducir funciones
Publicado por: Abner_emanuel en 28 de Marzo de 2023, 00:28:36
Creo que mi nivel de programación está muy por debajo del suyo Eduardo2. Yo tardo para entender lo que usted coloca con tanta facilidad.

Tanto es así que aún no lo entiendo  :D
Título: Re:Reducir funciones
Publicado por: Abner_emanuel en 05 de Mayo de 2023, 13:59:20
Un saludo.

Creo que al final de todo no me viene la manera para mostrar las 5 variables en la LCD4x20 por que me ocupa toda la LCD.

Citar
void pesando_1(void)
         {
         peso = get_units(10,1);                                                       // Lee el peso y hace un promedio de 10 muestras           
         switch (unidad){
         case 1:       
                  factor = 1.0;
                  lcd_gotoxy(1,2); printf(lcd_putc, "P1:%4.1f g ",peso/factor);
                  break;
         case 2:
                  factor = 1000.0;
                  lcd_gotoxy(1,2); printf(lcd_putc, "P1:%4.2f Kg",peso/factor);
                  break;
         case 3:
                  factor = 28.35;
                  lcd_gotoxy(1,2); printf(lcd_putc, "P1:%4.2f oz",peso/factor);
                  break;
                        }
         }
 
         void pesando_2(void)
         {
         peso = get_units(10,2);                                                       // Lee el peso y hace un promedio de 10 muestras           
         switch (unidad){
         case 1:       
                  factor = 1.0;
                  lcd_gotoxy(1,3); printf(lcd_putc, "P2:%4.1f g ",peso/factor);
                  break;
         case 2:
                  factor = 1000.0;
                  lcd_gotoxy(1,3); printf(lcd_putc, "P2:%4.2f Kg",peso/factor);
                  break;
         case 3:
                  factor = 28.35;
                  lcd_gotoxy(1,3); printf(lcd_putc, "P2:%4.2f oz",peso/factor);
                  break;
                        }
         }
 
         void pesando_3(void)
         {
         peso = get_units(10,3);                                                       // Lee el peso y hace un promedio de 10 muestras           
         switch (unidad){
         case 1:       
                  factor = 1.0;
                  lcd_gotoxy(1,4); printf(lcd_putc, "P3:%4.1f g ",peso/factor);
                  break;
         case 2:
                  factor = 1000.0;
                  lcd_gotoxy(1,4); printf(lcd_putc, "P3:%4.2f Kg",peso/factor);
                  break;
         case 3:
                  factor = 28.35;
                  lcd_gotoxy(1,4); printf(lcd_putc, "P3:%4.2f oz",peso/factor);
                  break;
                        }
         } 
 
 
         void pesando_4(void)
         {
         peso = get_units(10,4);                                                       // Lee el peso y hace un promedio de 10 muestras           
         switch (unidad){
         case 1:       
                  factor = 1.0;
                  lcd_gotoxy(13,3); printf(lcd_putc, "P4:%4.1f g ",peso/factor);
                  break;
         case 2:
                  factor = 1000.0;
                  lcd_gotoxy(13,3); printf(lcd_putc, "P4:%4.2f Kg",peso/factor);
                  break;
         case 3:
                  factor = 28.35;
                  lcd_gotoxy(13,3); printf(lcd_putc, "P4:%4.2f oz",peso/factor);
                  break;
                        }
         }
 
         void pesando_5(void)
         {
         peso = get_units(10,5);                                                       // Lee el peso y hace un promedio de 10 muestras           
         switch (unidad){
         case 1:       
                  factor = 1.0;
                  lcd_gotoxy(13,4); printf(lcd_putc, "P5:%4.1f g ",peso/factor);
                  break;
         case 2:
                  factor = 1000.0;
                  lcd_gotoxy(13,4); printf(lcd_putc, "P5:%4.2f Kg",peso/factor);
                  break;
         case 3:
                  factor = 28.35;
                  lcd_gotoxy(13,4); printf(lcd_putc, "P5:%4.2f oz",peso/factor);
                  break;
                        }
         }

Lo e pensado y creo que seria una mejor solución mostrar las cinco variables en una sola línea a manera de scroll.

por ejemplo en la linea lcd_gotoxy(1,4) mostrar las cinco variables desplazándose de izquierda a derecha.

pesando_1();
         pesando_2();
         pesando_3();
         pesando_4();
         pesando_5();

Sin embargo creo que no se por donde empezar para hacer esto. Help pleaseeee!!
Título: Re:Reducir funciones
Publicado por: Eduardo2 en 05 de Mayo de 2023, 20:12:19
Mostrar las 5 variables deslizándose me parece la manera mas ilegible de presentar las lecturas.  Con un texto va bien, pero con esto no.

En mi opinión, si no hay lugar en el display primero hay que sacar todo lo redundante.
Por ejemplo, en lugar de en cada lectura poner la leyenda "Pn:xx.xKg" , volar la 'P' y las unidades, porque con escribirlas una sola vez basta.  De esa manera, no solo entra todo sino que te permite mas dígitos.

Algo así:
Código: [Seleccionar]
void pesando(void){

    for(int8 k=1 , fila=3 , columna=1 ; k<=5 ; k++ , fila++){
       
        lcd_gotoxy(4,2) ;       
        switch(unidad){                 // unidad: 1,2 o 3
            case 1:     printf(lcd_putc, "[g] ") ; break ;
            case 2:     printf(lcd_putc, "[Kg]") ; break ;
            case 3:     printf(lcd_putc, "[oz]") ;
        }     
       
        if(k==3){ fila=2 ; columna=12 ; }
        lcd_gotoxy(columna,fila) ;
        printf(lcd_putc, "%1u:" , k);
               
        float peso ;
        switch(unidad){
            case 1:
                peso = get_units(10,k);
                printf(lcd_putc,"%6.2f",peso) ;
                break ;
            case 2:
                peso = get_units(10,k)/1000.0 ;
                printf(lcd_putc,"%6.3f",peso) ;
                break ;
            case 3:
                peso = get_units(10,k)/28.35 ;
                printf(lcd_putc,"%6.3f",peso) ;
        }
    }
}

Mostrar las 5 variables es solamente una llamada:

Código: [Seleccionar]
    pesando() ;       // muestra los 5 pesos

Título: Re:Reducir funciones
Publicado por: Abner_emanuel en 05 de Mayo de 2023, 20:58:11
Usted lo pensó muy bien Eduardo2. Así funciona perfecto.

Aquí la evidencia adjunta en la imagen.
Título: Re:Reducir funciones
Publicado por: Eduardo2 en 05 de Mayo de 2023, 21:58:38
Usted lo pensó muy bien Eduardo2. Así funciona perfecto.

No tanto   :oops:  , acabo de ver que repito inútilmente la escritura de la unidad.

Versión corregida:
Código: [Seleccionar]
void pesando(void){

    lcd_gotoxy(1,2) ;       
    switch(unidad){
        case 1:     printf(lcd_putc, "P  [g] ") ; break ;
        case 2:     printf(lcd_putc, "P  [Kg]") ; break ;
        case 3:     printf(lcd_putc, "P  [oz]") ;
    }     

    for(int8 k=1 , fila=3 , columna=1 ; k<=5 ; k++ , fila++){       
       
        if(k==3){ fila=2 ; columna=12 ; }
        lcd_gotoxy(columna,fila) ;
        printf(lcd_putc, "%1u:" , k);               
        float peso = get_units(10,k);
        switch(unidad){
            case 1: printf(lcd_putc,"%6.2f",peso)        ; break ;
            case 2: printf(lcd_putc,"%6.3f",peso/1000.0) ; break ;
            case 3: printf(lcd_putc,"%6.3f",peso/28.35)  ;
        }
    }
}
Título: Re:Reducir funciones
Publicado por: Abner_emanuel en 06 de Mayo de 2023, 00:57:38

Si, ya lo probé en físico y todo perfecto.  :-/

Gracias no podrían estar mejor reducidas las funciones. :D
Título: Re:Reducir funciones
Publicado por: Abner_emanuel en 15 de Mayo de 2023, 22:38:27
Eduardo2

Del código...
Citar
void pesando(void){

    lcd_gotoxy(1,2) ;       
    switch(unidad){
        case 1:     printf(lcd_putc, "P  [g] ") ; break ;
        case 2:     printf(lcd_putc, "P  [Kg]") ; break ;
        case 3:     printf(lcd_putc, "P  [oz]") ;
    }     

    for(int8 k=1 , fila=3 , columna=1 ; k<=5 ; k++ , fila++){       
       
        if(k==3){ fila=2 ; columna=12 ; }
        lcd_gotoxy(columna,fila) ;
        printf(lcd_putc, "%1u:" , k);               
        float peso = get_units(10,k);
        switch(unidad){
            case 1: printf(lcd_putc,"%6.2f",peso)        ; break ;
            case 2: printf(lcd_putc,"%6.3f",peso/1000.0) ; break ;
            case 3: printf(lcd_putc,"%6.3f",peso/28.35)  ;
        }
    }
}

Ahora me surge la necesidad de si el peso 1 y el peso 3 son menores a 100 gramos activar un led del Pic. Podría ser output_high(pin_a0);

solo que ahora no se como hacer para separarlos pesos. Y hacer lo que pretendo por que ahora peso = get_units(10,k);.

Como hago para que el peso 1 y 3. enciendan ese led.
Título: Re:Reducir funciones
Publicado por: Eduardo2 en 15 de Mayo de 2023, 23:28:48
En ese caso a las 5 lecturas las vas guardando en un vector y después hacés las comparaciones.

Código: [Seleccionar]
void pesando(void){

    float peso[5] ;  // Está como variable local
                     // Cambialo de lugar si necesitas que sea global.
   
    lcd_gotoxy(1,2) ;       
    switch(unidad){
        case 1: printf(lcd_putc, "P  [g] ") ; break ;
        case 2: printf(lcd_putc, "P  [Kg]") ; break ;
        case 3: printf(lcd_putc, "P  [oz]") ;
    }     

    for(int8 k=1 , fila=3 , columna=1 ; k<=5 ; k++ , fila++){       
       
        if(k==3){ fila=2 ; columna=12 ; }
       
        lcd_gotoxy(columna,fila) ;
        printf(lcd_putc, "%1u:" , k);               
       
        float x = peso[k-1] = get_units(10,k);
        switch(unidad){
            case 1: printf(lcd_putc,"%6.2f",x)        ; break ;
            case 2: printf(lcd_putc,"%6.3f",x/1000.0) ; break ;
            case 3: printf(lcd_putc,"%6.3f",x/28.35)  ;
        }
    }
   
    //-----------------------------------
   
    if(peso[0]<100. && peso[2]<100.) output_high(PIN_A0) ;
    else                             output_low (PIN_A0) ;
   
    //-----------------------------------
}
Título: Re:Reducir funciones
Publicado por: Abner_emanuel en 16 de Mayo de 2023, 19:09:49
Aunque muestra correctamente los valores de peso en gramos, no esta obedeciendo a la condición...

if(peso[0]<100. && peso[2]<100.)

Algo falta..
Título: Re:Reducir funciones
Publicado por: Abner_emanuel en 16 de Mayo de 2023, 22:04:50

Fe de erratas. Yo lo implemente mal. El Código funciona perfecto.
Título: Re:Reducir funciones
Publicado por: Abner_emanuel en 18 de Mayo de 2023, 23:29:18
Aunque un poco fuera de tema, aunque para el mismo. Me atreví a preguntas esto...

Trato de configurar los fuses para el PIC18F4620 a 40Mhz. Por ahí leí que se debe poner #fuses H4 para un cristal externo de 10Mhz.

Y lo puse de la siguiente manera:

#fuses NOWDT, WDT128, H4, NOFCMEN, NOIESO, NOPUT, NOBROWNOUT, NOPBADEN, NOLPT1OSC, MCLR, STVREN, NOLVP, NOXINST, NODEBUG, NOPROTECT, NOCPB, NOCPD, NOWRT, NOWRTC, NOWRTB, NOWRTD, NOEBTR, NOEBTRB
         #use delay(clock=40000000, crystal=10000000)

Pero tal parece que el pic no responde a 40Mhz. Alguna recomendación...


Título: Re:Reducir funciones
Publicado por: DominusDRR en 19 de Mayo de 2023, 10:45:22
Aunque un poco fuera de tema, aunque para el mismo. Me atreví a preguntas esto...

Trato de configurar los fuses para el PIC18F4620 a 40Mhz. Por ahí leí que se debe poner #fuses H4 para un cristal externo de 10Mhz.

Y lo puse de la siguiente manera:

#fuses NOWDT, WDT128, H4, NOFCMEN, NOIESO, NOPUT, NOBROWNOUT, NOPBADEN, NOLPT1OSC, MCLR, STVREN, NOLVP, NOXINST, NODEBUG, NOPROTECT, NOCPB, NOCPD, NOWRT, NOWRTC, NOWRTB, NOWRTD, NOEBTR, NOEBTRB
         #use delay(clock=40000000, crystal=10000000)

Pero tal parece que el pic no responde a 40Mhz. Alguna recomendación...

Al googlear:

http://www.ccsinfo.com/forum/viewtopic.php?t=43085 (http://www.ccsinfo.com/forum/viewtopic.php?t=43085)

Creo que es HS en lugar de H2 y falta setup_oscillator(OSC_PLL_ON);



Título: Re:Reducir funciones
Publicado por: Eduardo2 en 19 de Mayo de 2023, 13:01:56
...Trato de configurar los fuses para el PIC18F4620 a 40Mhz. Por ahí leí que se debe poner #fuses H4 para un cristal externo de 10Mhz.

Y lo puse de la siguiente manera:

#fuses NOWDT, WDT128, H4, NOFCMEN, NOIESO, NOPUT, NOBROWNOUT, NOPBADEN, NOLPT1OSC, MCLR, STVREN, NOLVP, NOXINST, NODEBUG, NOPROTECT, NOCPB, NOCPD, NOWRT, NOWRTC, NOWRTB, NOWRTD, NOEBTR, NOEBTRB
         #use delay(clock=40000000, crystal=10000000)

Pero tal parece que el pic no responde a 40Mhz. Alguna recomendación...

En CCS, con solamente   #use delay(clock=40000000, crystal=10000000)   
por defecto te hace esta configuración de fuses
Código: [Seleccionar]
   Word  1: C600   H4  FCMEN  IESO
   Word  2: 1E1E   PUT BROWNOUT BORV21 NOWDT WDT32768
   Word  3: 8700   CCP2C1 PBADEN LPT1OSC MCLR
   Word  4: 0081   STVREN NOLVP NOXINST NODEBUG
   Word  5: C00F   NOPROTECT NOCPB NOCPD
   Word  6: E00F   NOWRT NOWRTC NOWRTB NOWRTD
   Word  7: 400F   NOEBTR NOEBTRB

Probá si te funciona.

Título: Re:Reducir funciones
Publicado por: Abner_emanuel en 19 de Mayo de 2023, 13:12:19
Entonces está de más el poner #fuses H4. Pruebo y comento, pero tendrá que ser físicamente por qué simulado en PROTEUS pareciera que no lo hace por qué simulado todo va más lento.   
Título: Re:Reducir funciones
Publicado por: Eduardo2 en 19 de Mayo de 2023, 13:55:42
Entonces está de más el poner #fuses H4. Pruebo y comento, pero tendrá que ser físicamente por qué simulado en PROTEUS pareciera que no lo hace por qué simulado todo va más lento.

Para sacarme dudas escribí algo muy simple:
Código: [Seleccionar]
#include<18F4620.h>
#use delay(clock=40MHz,crystal=10MHz)
void main(void){
    set_tris_b(0) ;
    int8 n=0;
    while(1){
        n++;
        if(n==0)  output_toggle(PIN_B0) ;
        delay_ms(10) ;
    }
}
Y Proteus me lo simula a la velocidad correcta.
Título: Re:Reducir funciones
Publicado por: Abner_emanuel en 19 de Mayo de 2023, 15:05:45
Si pones los demás sique corriendo igual?.

#fuses NOWDT, WDT128, NOFCMEN, NOIESO, NOPUT, NOBROWNOUT, NOPBADEN, NOLPT1OSC, MCLR, STVREN, NOLVP, NOXINST, NODEBUG, NOPROTECT, NOCPB, NOCPD, NOWRT, NOWRTC, NOWRTB, NOWRTD, NOEBTR, NOEBTRB
         
Tengo la versión 5.114 del ccs c. Pruebo así como dices...

Gracias por responder.
Título: Re:Reducir funciones
Publicado por: Eduardo2 en 19 de Mayo de 2023, 15:47:59
Con esa línea de fuses me corre bien, 100ns por instrucción y el delay_ms(10) demora efectivamente 10ms.