Autor Tema: Varios problemitas con la programación en C  (Leído 7088 veces)

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

Desconectado arielmdq

  • PIC16
  • ***
  • Mensajes: 166
Re: Varios problemitas con la programación en C
« Respuesta #30 en: 20 de Junio de 2015, 18:24:17 »
Bueno les muestro todo lo que pude hacer por hoy , como veran me cuesta bastante  ja ja pero va saliendo .Hasta ahora funciona bien pero sin grabar en la eeprom ,asignando valores fijos a los parametros .Con lo que me trabe bastante fue con los limites, que cuando llegara a los limites me accionara , lo que ahora son led en la simulacion, pero en realidad son relays , y que por mas que se pasara de los limites , el ciclo util quedara tanto en el max como en el min ,por que si no me liaba las cuentas .Ahora quedo bien, asi que mañana veré de hacerlo grabar en la EEPROM y leer los valores desde alli Con esto llego a la conclusion que el ultimo programa que me paso killerjc funcionaba siempre y cuando modificara lo que mencione en el anterior post. Asi que muchas gracias Killerjc sos un genio .Bueno mañana si puedo seguiré intentando y si se me complica espero poder recurrir a ustedes nuevamente. Obiamente que cuando tenga algo definido los voy a consultar para que le den el visto bueno .
                                                                                    Saludos !!!!
Código: C
  1. #include <16f876a.h>
  2. #device adc =10
  3. #use delay (clock=8M)
  4. #fuses XT,NOWDT,NOPROTECT,NOLVP
  5. #include <internal_eeprom.c>
  6. #use fast_io(B)
  7. #use fast_io(c)
  8. #use fast_io(a)
  9.  
  10. //******declaracion de variables******************************
  11.  
  12. unsigned int16 cursor=0,toper,topbr,cero,ciclo_util=0,a,b;
  13.  
  14. float Ai,Ad,Bi,Bd;
  15.  
  16. //***********************************************************
  17. void main()
  18. {
  19.  
  20.    //int i;
  21.  
  22.    set_tris_c(0b00000000);
  23.    output_c(0b00000000);
  24.    set_tris_b(0b11111111);
  25.    output_b(0b00000000);
  26. //****************ADC**************************
  27.    setup_adc_ports(AN0);//* entrada analogica*//
  28.    setup_adc (ADC_CLOCK_INTERNAL);
  29.    setup_COUNTERS(RTCC_internal.rtcc_div_8);
  30.  
  31. // *************PWM**************************************
  32.  
  33.    setup_ccp1(CCP_PWM);
  34.    setup_timer_2(T2_DIV_BY_16,255, 1);
  35.    set_pwm1_duty(ciclo_util);
  36.    
  37. //**************Recupero Valores************************  
  38. //Aqui sis se reinicio tomo los valores , los calculo para lo que esta guardado en el EEPROM
  39.  
  40.  
  41.       topbr=205;
  42.       toper=818;
  43.       cero=511;
  44.  
  45.    Ai = (float)511 / (cero-topbr);            // Valores recta izquierda y derecha:
  46.    Bi = ((float)-511*topbr)/(cero-topbr);         // Yi = Ai*X +Bi
  47.    Ad = (float)512 / (toper-cero);            // Yd = Ad*x +Bd
  48.    Bd = 511 - (((float)512*cero)/(toper-cero));
  49.  
  50.    
  51.  
  52.    
  53.    WHILE (1)
  54.    {
  55.       set_pwm1_duty(ciclo_util);
  56.       set_adc_channel (0);
  57.       delay_us (20);
  58.       cursor = read_adc ();
  59.    
  60.  
  61.   //********************************************
  62.   // Funcionamiento normal
  63.   //********************************************
  64.  
  65.          
  66.         IF ( cursor < topbr && cursor > 0)
  67.       {
  68.         output_low(PIN_c6);
  69.         output_high (PIN_c5);
  70.         ciclo_util=0;
  71.       }
  72.    
  73.            
  74.         if (cursor>toper &&cursor<1023)
  75.    {
  76.       output_high(PIN_c6);//led************************
  77.       output_low (PIN_c5);
  78.       ciclo_util=1023;
  79.  
  80. }
  81.      
  82.  
  83.          if(cursor>cero && cursor< toper)                     // Caso que Cursor sea mayor a cero
  84.          {                        // Es decir lado derecho
  85.             a = Ad*cursor + Bd;
  86.             ciclo_util = a ;
  87.            output_low (PIN_c5);
  88.            output_low(PIN_c6);
  89.          }
  90.           if (cursor<cero &&cursor >topbr)                  
  91.          {                        // Es decir lado izquierdo
  92.             b = Ai*cursor + Bi;
  93.             ciclo_util = b ;
  94.              output_low (PIN_c5);
  95.              output_low(PIN_c6);
  96.          }
  97.          if (cursor == cero)                        // Caso que cursor este al medio
  98.          {
  99.            ciclo_util=511;
  100.             output_low (PIN_c5);
  101.             output_low(PIN_c6);
  102.          }
  103.          
  104.    }  
  105. }

PD:por favor cualquier correccion o sugerencia con respecto a este programa que subi ahora ,haganmela saber .Gracias
« Última modificación: 20 de Junio de 2015, 18:33:55 por arielmdq »
El tiempo es una ilusión ,solo existe el presente................

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Varios problemitas con la programación en C
« Respuesta #31 en: 20 de Junio de 2015, 19:19:39 »
Me parece que las condiciones estan mal o hay condiciones en los if por denas, no se necesita tantos para eso.

Solamente que lo limites entre topbr - toper
Por eso mismo los if que habia puesto.
Esos if hacian que si cursor era menor que topbr, directamente cursor tomara el valor minimo es decir topbr.
Lo mismo ocurria para toper


Realmente no tuve tiempo de ver los codigos asi que no te puedo dar ninguna apreciacion sobre el mismo.
Cuando posea mas tiempo te digo si hay algo que se puede mejorar/quitar/agregar.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Varios problemitas con la programación en C
« Respuesta #32 en: 22 de Junio de 2015, 14:18:04 »
Ahi vi el programa. Sinceramente no se por que no funciona esas 2 lineas que puse.

Con respecto a las condiciones de mas


        IF ( cursor < topbr && cursor > 0)
        if (cursor>toper &&cursor<1023)

Eso esta por demas, cursor es un unsigned int, es decir va de 0 a 2^16 , por lo tanto nunca va a ser menor que cero, por otro lado le asignas lo del ADC, lo cual jamas va a ser mayor que 1023, ademas estas excluyendo los valores '0' y '1023' de esa condicion.
lo que claramente puede ser reemplazado por

        IF ( cursor < topbr)
        if (cursor>toper)


PD: Con tu codigo el programa se ejecuta mas rapido, ya que directamente no calcula nada al ser un valor no valido, asi que eso es genial. Mientras mas rapido mas cosas para hacer tenes.

Con respecto a lo demas yo lo hice con un if...else if .. else
Mientras que vos lo hiciste con un if...if....if

No va a haber problema, por un lado tu programa va a preguntar en todos los if si se cumplen las condiciones, es decir todas las condiciones se van a probar.
Con el if.. else if.. else se prueba la primera condicion si se cumple se hace el codigo y luego se termina ahi nomas, no pregunta por las demas condiciones. el peor caso seria que pregunte por 2 condicones el del if...else if ,, y termine en el ultimo else sin necesidad de poner una condicion ahi.

Pero bueno lo importante es que funcione  hasta ahora vas bien , solo falta agregar las otras cosas.

Desconectado arielmdq

  • PIC16
  • ***
  • Mensajes: 166
Re: Varios problemitas con la programación en C
« Respuesta #33 en: 22 de Junio de 2015, 18:48:13 »
Hola les cuento los avances y las frustraciones .
Entiendo  lo que me decis killerjc ,pero lo que yo pense es que con estas instrucciones :
                        if(cursor<topbr){cursor=topbr;}               
         if(cursor>toper){cursor=toper;}
No es que le asignamos el valor de los topes a cursor en vez de asignarselos a ciclo util y por eso no funciona
O es que se los asignamos  a cursor ,de ahi a hacer cuentas y de ahi a asignarle el valor a ciclo util
O estoy diciendo una burrada ja ja !!!pero tenes razon solo con esto
                     IF ( cursor < topbr)
                      if (cursor>toper)
ya deberia andar ,pero como ya andaba de la otra manera lo deje asi y segui con el resto .Bueno y aca viene el avance, termine el programa le agregué unas cosas como me dijiste, de proteccion por si graban mal los parametros ,pero por supuesto a mi bruta manera ja ja .Le puse un led en Rc0 que cuando este en configuracion encienda , si la config esta bien cuando entra en modo funcionamiento se apague y si los parametros estan mal, quede el led en toggle y no entre en modo funcionamiento.Fuaaa para mi era mucho hacer esto ja ja y ni hablar que funcione ja ja .Bueno lo cierto es que funciono  :) ,probe en proteus 10mil posibilidades y funciono siempre asique re contento ,pero la alegria duro hasta que lo grabe en el pic y lo probe.........no hace nada  :5] por alla quedaba el led titilando por alla se encendia no funcionaba el pwm ,un desastre .De las pocas cosas que hice con pics ,siempre que las probaba en proteus si andaba ahi en la realidad tambien pero esta vez no fue asi y ahora si se me estan quemando los papeles y la cabeza  :5] .Volvi a grabar con el  codigo viejo y funciona asi que el pic no es.Sera un tema de fuses ? o alguna configuracion del pic que me falto ? .Bueno por ahora les subo en codigo que en proteus me funciona pero fisicamente no ,a ver si lo pueden chequeear por favor  por si falta algo ,la verdad que no se que puede ser .Muchas gracias !!!
                                                                                                                Saludos!!!!
PD: Como la placa ya la tenia armada con un dipswitch de 4 y un boton para grabar en eeprom modifique el programa para que funcione asi ,para la proxima lo hare como dice killerjc con pulsadores y un solo switch. Tambien acomode los topes:
                                            toper => derecha
                                            topbr => izquierda
Como lo tengo tan grabado en la cabeza que es asi y estaban alrevez me hacia mucho lio  ja ja


Código: C
  1. #include <16f876a.h>
  2. #device adc =10
  3. #use delay (clock=8M)
  4. #fuses XT,NOWDT,NOPROTECT,NOLVP
  5. #include <internal_eeprom.c>
  6. #use fast_io(B)
  7. #use fast_io(c)
  8. #use fast_io(a)
  9.  
  10. //******declaracion de variables******************************
  11.  unsigned int16 cursor=0,toper=0,topbr=0,cero=0,ciclo_util=0,a=0,b=0;
  12.  
  13. float Ai,Ad,Bi,Bd;
  14.  
  15. //***********************************************************
  16. void main()
  17. {
  18.    set_tris_c(0b00000000);
  19.    output_c(0b00000000);
  20.    set_tris_b(0b11111111);
  21.    output_b(0b00000000);
  22.    
  23. //****************ADC**************************
  24.    setup_adc_ports(AN0);//* entrada analogica*//
  25.    setup_adc (ADC_CLOCK_INTERNAL);
  26.    setup_COUNTERS(RTCC_internal.rtcc_div_8);
  27.  
  28. // *************PWM**************************************
  29.  
  30.    setup_ccp1(CCP_PWM);
  31.    setup_timer_2(T2_DIV_BY_16,255, 1);
  32.    set_pwm1_duty(ciclo_util);
  33.    
  34.  //**************Lectura de Valores**********************
  35.       toper=read_int16_eeprom(0x120);
  36.       delay_ms(15);                  
  37.        
  38.       topbr=read_int16_eeprom(0x122);
  39.       delay_ms(15);
  40.  
  41.       cero=read_int16_eeprom(0x126);
  42.       delay_ms(15);
  43.      
  44. //**************Cuentas************************************
  45.  
  46.    Ai = (float)511 / (cero-topbr);            
  47.    Bi = ((float)-511*topbr)/(cero-topbr);        
  48.    Ad = (float)512 / (toper-cero);            
  49.    Bd = 511 - (((float)512*cero)/(toper-cero));    
  50.          
  51.  
  52.      
  53.      
  54.    WHILE (1)
  55.    {
  56.       set_pwm1_duty(ciclo_util);
  57.       set_adc_channel (0);
  58.       delay_us (20);
  59.       cursor = read_adc ();
  60.      
  61.      
  62.      
  63.  //*********************************************
  64.  // Programacion
  65.  //*********************************************
  66.  
  67.        if (input(pin_b4)==0)//configuracion
  68.       {
  69.         output_high (PIN_c0);//enciendo led aviso de configuracion
  70.         output_low (PIN_c5);// Desactivo ambos limites
  71.         output_low(PIN_c6);//  de carrera para configuracion
  72.      
  73.      
  74.        if (input(pin_b1)==1)//  configuro limite derecho toper
  75.       {
  76.  
  77.        if (input(pin_b0)==1)//boton que graba en la eeprom
  78.       {
  79.          delay_ms(20);
  80.          write_int16_eeprom(0x120,(int16) cursor);// escribe en la memoria toper        
  81.          toper=read_int16_eeprom(0x120);          // lee para hacer las cuentas
  82.          delay_ms(15);
  83.          Ad = (float)512 / (toper-cero);            
  84.          Bd = 511 - (((float)512*cero)/(toper-cero));
  85.       }
  86.  
  87.    }  
  88.       if (input(pin_b2)==1)// configuro limite izquierdo topbr
  89.      {    
  90.                        
  91.        if (input(pin_b0)==1)//boton que graba en la eeprom
  92.       {      
  93.         delay_ms(20);
  94.         write_int16_eeprom(0x122,(int16) cursor);// escribe en la memoria topbr
  95.         topbr=read_int16_eeprom(0x122);         // lee para hacer las cuentas
  96.         delay_ms(15);
  97.         Ai = (float)511 / (cero-topbr);            
  98.         Bi = ((float)-511*topbr)/(cero-topbr);
  99.       }
  100.    }
  101.  //****************CERO************************
  102.       if (input(pin_b3)==1)
  103.      {
  104.       if (input(pin_b0)==1)//boton que graba en la eeprom
  105.      {  
  106.         delay_ms(20);  
  107.         write_int16_eeprom(0x126,(int16) cursor);// escribe en la memoria
  108.         cero=read_int16_eeprom(0x126);           // lee para hacer las cuentas
  109.         delay_ms(15);
  110.         Ai = (float)511 / (cero-topbr);            
  111.         Bi = ((float)-511*topbr)/(cero-topbr);        
  112.         Ad = (float)512 / (toper-cero);            
  113.         Bd = 511 - (((float)512*cero)/(toper-cero));    
  114.          
  115.      }
  116.  
  117.    }
  118.   }
  119.   //********************************************
  120.   // Funcionamiento normal
  121.   //********************************************
  122.  
  123.        if (input(pin_b4)==1)//switch que habilita el funcionamiemto
  124.       {
  125.        if (topbr<cero && cero<toper)// si se cumple entra en funcionamiento
  126.       {
  127.         output_low (PIN_c0);//apago led de configuracion
  128.        
  129.  
  130.        if ( cursor < topbr && cursor > 0)
  131.       {
  132.         output_low(PIN_c6);
  133.         output_high (PIN_c5);
  134.         ciclo_util=0;
  135.       }
  136.              
  137.        if (cursor>toper &&cursor<1023)
  138.       {
  139.         output_high(PIN_c6);//led************************
  140.         output_low (PIN_c5);
  141.         ciclo_util=1023;
  142.  
  143.        }
  144.        if(cursor>cero && cursor< toper)                    
  145.        {                        
  146.          a = Ad*cursor + Bd;
  147.          ciclo_util = a ;
  148.          output_low (PIN_c5);
  149.          output_low(PIN_c6);
  150.        }
  151.         if (cursor<cero &&cursor >topbr)                  
  152.        {                        
  153.           b = Ai*cursor + Bi;
  154.           ciclo_util = b ;
  155.           output_low (PIN_c5);
  156.           output_low(PIN_c6);
  157.        }
  158.         if (cursor == cero)                        
  159.        {
  160.           ciclo_util=511;
  161.           output_low (PIN_c5);
  162.           output_low(PIN_c6);
  163.        }              
  164.      }
  165.         else
  166.        {
  167.           output_toggle (PIN_c0);// si esta mal configurado
  168.        }
  169.     }        
  170.   }  
  171. }
  PD: ya probe sacarle el if y el ultimo  else ,que era la proteccion por la mala programacion
El tiempo es una ilusión ,solo existe el presente................

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Varios problemitas con la programación en C
« Respuesta #34 en: 22 de Junio de 2015, 20:18:17 »
El proteus no tiene en cuenta FUSES , cristal y no se si algo mas. Asi que espero que ahi este el problema.

Ya que si funciona en el Proteus, a no ser que este inventando algo el mismo no veo por que no deberia funcionar.

En fin, falta ese ULTIMO paso y ya estarias, revisa todas las conexciones, que el cristal este bien puesto, que todos los fuses esten configurados.



PD: Si tenes 1 solo pulsador y los demas llaves. Podrias hacer asi:

1 llave para funcionamiento-configuracion
3 llaves para elegir izq,centro,derecha
y cuando presionas el pulsador se guarden los valores.

Es decir, pones la llave en configuracion, activas la llave de la izquierda. moves cursor y presionas el boton(aca se guarda), desactivas el de izquierda, activas centro... y lo mismo que antes. asi hasta todos y luego pasas a funcionamiento.
Pero es mucho mas facil con los 3 botones.. o directamente podes usar 1 llave y 1 boton.

Con una llave y 1 boton podria ser asi:

Configuracion:
Encender Led (indicando que esta en modo programacion)
Mover izquierda, presionar boton
Mover centro , presionar boton
Mover derecha, presionar boton
Apagar Led indicando que termino la programacion

O de ultima y mas reducido 1 solo boton. Esto implica mas cosas. Como detectar el boton un tiempo asi no se entra "accidentalmente" a la forma de programacion, y vas a tener que crear una maquinita de estados como en el caso anterior.
Pero en fin esto reduce y la cantidad de componentes y posibles problemas de soldadura.

Te deje mas ideas para que las mastiques :)

Desconectado arielmdq

  • PIC16
  • ***
  • Mensajes: 166
Re: Varios problemitas con la programación en C
« Respuesta #35 en: 22 de Junio de 2015, 20:36:03 »
Gracias killerjc ,si  es asi como funcionan las 4 llaves y el boton .LO que voy a hacer ahora es chequear la placa y hacer un programa que solo me siga el pwm al adc,  osea que moviendo el potenciometro me incremente o me decremente el pwm para comprobar que funcione gradualmente y bueno seguire viendo.
Te queria preguntar tambien como es eso de en vez de poner un pote, poner un sensor  optico . Por que en realidad la idea es usar lo que ya tienen los barcos que es un reostato de 250 ohms,te parece que puede traer problemas el reostato ?.Igual me intereso cuando me propusiste lo del optico , Gracias . Saludos !!!
El tiempo es una ilusión ,solo existe el presente................

Desconectado arielmdq

  • PIC16
  • ***
  • Mensajes: 166
Re: Varios problemitas con la programación en C
« Respuesta #36 en: 22 de Junio de 2015, 20:59:59 »
Creo que lo encontre tenia como fuse del cristal  : XT y tengo un cristal de 8mhz
Para 8 mhz va como fuse HS    no?
El tiempo es una ilusión ,solo existe el presente................

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Varios problemitas con la programación en C
« Respuesta #37 en: 22 de Junio de 2015, 22:15:26 »
Si 4Mhz o mas va HS.

Yo pense que vos ibas a poner un potencimetro comun, pero si ya posee un reostato usa ese.
Lo que me referia a optico es lo que se puede encontrar como un Encoder rotativo optico y tal ves para esa aplicacion sirva un encoder absoluto. Pero el costo de estos no es nada barato :)

Desconectado arielmdq

  • PIC16
  • ***
  • Mensajes: 166
Re: Varios problemitas con la programación en C
« Respuesta #38 en: 23 de Junio de 2015, 13:34:45 »
Hola gente !!! les cuento que el problema era ese ,cambie el fuse de XT a HS y salio funcionando  :-/ , ahora deje la placa conectada  con el instrumento y los reles,la estoy probando con todas las posibilidades de configuracion a ver que hace .Tambien le conecte un reostato de 250ohm 25w, que es lo que ya esta instalado en el barco, con 20 metros de cable para ver si lee correctamente el adc del pic.
El centro del reostato conecta a la entrada del adc, atraves de una resistencia de 10k en serie para limitar la corriente ,lo cual no se si sea necesario ?.
La quiero dejar un par de dias conectada  funcionando, a ver si surge algun problemita de calentamiento de componentes o algo por el estilo, ya que esto una ves instalado quien sabe si alguna vez alguien lo apague ja ja .
La hice para que se pueda alimentar con 12v y 24v ,que en relidad son 14,2v y 28v por que va conectado con grupos de baterias que poseen cargadores automaticos .
Y aca es donde tengo otra duda ,con un switch selecciono si el (+) de entrada de alimentacion va a pasar 1º por un 7815 y despues por un 7805 o si pasa directamente por el 7805 ( en caso que se alimente con 12v).Asi que si tienen alguna manera mejor de hacer esto les agradeceria el comentario.
La otra duda que tengo es: si colocarle unos diodos de proteccion a la entrada por si alguien lo conecta alrevez,para evitar que quemen algo, o ya el 78xx no deja pasar si esta conectado alreves ?
Bueno queria agradecer enormemente a los que me ayudaron en especial a Killerjc y a chaly29  ((:-)) ,que no solo me ayudaron a solucionar problemas, sino que me enseñaron como hacerlo con explicaciones super claras y cordiales a ellos muchas gracias  ((:-)) !!!!!!!!!!!!!
Cualquier sugerencia por favor diganme .
                                                                                   Saludos !!!!!
                                                                                             
El tiempo es una ilusión ,solo existe el presente................