TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Chaly29 en 17 de Junio de 2015, 22:52:06

Título: Varios problemitas con la programación en C
Publicado por: Chaly29 en 17 de Junio de 2015, 22:52:06
Hola a todos, el colega arielmdq tiene unos problemitas con la programación en C.

Primeramente había problemas de hardware que ya los solucionamos y ahora esta complicado con el software, el programa en C y yo no estoy capacitado para darle una mano.

En este POST (http://www.todopic.com.ar/foros/index.php?topic=44651.msg370855#msg370855) yo le pasé unos cálculos matemáticos para implementar el programa que necesita, el ya lo a intentado y se le presentaron los problemas que indica en este POST (http://www.todopic.com.ar/foros/index.php?topic=44651.msg370988#msg370988), porlo tanto a quien pueda darle una ayudita, se le estará muy agradecido.

Un saludo.

Atte. CARLOS.

Título: Re: Varios problemitas con la programación en C
Publicado por: KILLERJC en 18 de Junio de 2015, 03:11:45
Bueno, mirando solo y unicamente la parte de programacion sin mirar exactamente que debe hacer el programa me encuentro con los siguientes problemas:

1- Demasiadas escrituras a la EEPROM, va a hacer que se destruya en un ratito.
2- El float en XC8 es de 24bits por default, se puede agrandar a 32bits pero veo que el nombre que dice tu funcion es de 16bits.
3- La implementacion de "menu" esta mal, por que eso se ejecuta MUY rapidamente, lo cual guardar valores en la EEPROM va a ser muy rapido y tal ves es una sola presionada se grabe 30 veces. Y tal ves tengas que presionar 2 botones juntos.

De todas formas si queres usar la EEPROM, primero hacelo funcionar desde la RAM.
Y Como primer programa tambien deberias de hacer unicamente la funcion que te interesa,  luego hacer el menu aparte y finalmente juntarlo todo.

Título: Re: Varios problemitas con la programación en C
Publicado por: juaperser1 en 18 de Junio de 2015, 05:53:50
Bueno, pues como dice killer hay demasiadas escrituras de memoria, a parte eso lleva a muchos delay, uno por cada escritura o lectura, y eso nunca es bueno para llevar una base de tiempo como un pwm, si eso lo juntamos con que es CCS podemos tener bastantes funcionamientos extraños,.

En cuanto al tamaño de las variables que dice killer, no lo he mirado pero killer creo que no se ha dado cuenta de que es CCS y no xc8.
 
Lo primero que yo haría seria simular que el menú funcione correctamente. En cuanto a que no ves las variables. A cuales te refieres? En el CCS ? Hace ya muchísimo que no uso CCS pero hay se podía simular o ver variables?

Desgraciadamente estoy de exámenes y no puedo, ponerme ha arreglarte personalmente el programa lo siento :(

Un saludo.
Título: Re: Varios problemitas con la programación en C
Publicado por: arielmdq en 18 de Junio de 2015, 08:11:17
Hola gente !!! muchas gracias por responder .Cuando leo sus respuestas me confunde un poco la parte en que dicen que se va a romper la eeprom.En la eeprom solo guardo 3 parametros que es a la hora de calibrar el instrumento y despues no se vuelve a tocar , o al menos esa es la idea y despues los uso para hacer los calculos .Pero tal vez este mal escrito el programa, tal como lo ven ustedes y sí ,este grabando continuamente pero eso no es lo que quiero.Me gustaria si alguno me puede sacar de esa duda por favor les estare agradecido.Saludos !!!!!
Título: Re: Varios problemitas con la programación en C
Publicado por: KILLERJC en 18 de Junio de 2015, 13:57:04
Citar
En cuanto al tamaño de las variables que dice killer, no lo he mirado pero killer creo que no se ha dado cuenta de que es CCS y no xc8.

Si me confundi, de todas formas son de 24 bits igual.

Hola gente !!! muchas gracias por responder .Cuando leo sus respuestas me confunde un poco la parte en que dicen que se va a romper la eeprom.En la eeprom solo guardo 3 parametros que es a la hora de calibrar el instrumento y despues no se vuelve a tocar , o al menos esa es la idea y despues los uso para hacer los calculos .Pero tal vez este mal escrito el programa, tal como lo ven ustedes y sí ,este grabando continuamente pero eso no es lo que quiero.Me gustaria si alguno me puede sacar de esa duda por favor les estare agradecido.Saludos !!!!!

Lo dije por que la EEPROM tiene un numero limitado de escrituras y todo depende de cuanto las ibas a estar actualizando, como estaba el programa iba a ser seguro que cada ves que presionaras se guardara varias veces.
Pero para "evitar" por ahora la complicacion de guardar y leer la EEPROM podrias haberlo hecho en RAM, luego si lo haces en como queres.
El manual de CCS aporta un codigo de como escribir y leer un float(24bytes):

Código: C
  1. WRITE_FLOAT_EXT_EEPROM( long int n, float data) {
  2. int i;
  3. for (i = 0; i < 4 ; i++)
  4. write_ ext_ eeprom(i + n, *(((int 8 *)&data + i) ) ;
  5. }
  6.  
  7. float READ_FLOAT_EXT_EEPROM( long int n) {
  8. int i;
  9. float data;
  10. for (i = 0; i < 4; i++)
  11. *(((int 8 *)&data) + i) = read_ ext_ eeprom(i + n);
  12. return(data);
  13. }
(n tiene que ser multiplo de 4 para los floats ( 4bytes ) )

Lo raro que le ADC da un valor de 10bits como maximo y no tiene sentido que lo castees a float, como lo estas haciendo. si guardaras solo el valor del ADC entonces serian 16bits, pero bueno te dejo la funcion por igual

Con respecto al menu no soy de hacerlo de esa forma... Si es cosiderado un "menu" pero aca te dejo una parte del codigo:

Código: C
  1. if (input(pin_b4)==0)                                                   //switch que habilita la configuracion de parametros
  2.                 {                                                                        
  3.                         if (input(pin_b1)==1)                                           //switch que habilita para establecer
  4.                         {                                                               // el limite izquierdo ( toper)  
  5.                                 delay_ms(20);                                           // Antirebote
  6.                                 while(input(pin_b1));                                   // Espero hasta que suelte
  7.                                 write_int16_eeprom(0x120,(float) cursor);               // escribe en la memoria
  8.                                 delay_ms(15);                                           // el valor de toper
  9.                                 toper=read_int16_eeprom(0x120);          
  10.                         }
  11.  
  12.                         if (input(pin_b2)==1)                                           //switch que habilita para establecer
  13.                         {                                                               // el limite derecho ( topbr)
  14.                                 delay_ms(20);                                           // Antirebote
  15.                                 while(input(pin_b1));                                   // Espero hasta que suelte
  16.                                 write_int16_eeprom(0x122,(float) cursor);               // escribe en la memoria
  17.                                 delay_ms(15);                                           // el valor de topbr
  18.                                 topbr=read_int16_eeprom(0x122);
  19.                         }
  20.                         if (input(pin_b3)==1)                                           //switch que habilita para establecer
  21.                         {                                                               // el valor central  ( cero )
  22.                                 delay_ms(20);                                           // Antirebote
  23.                                 while(input(pin_b1));                                   // Espero hasta que suelte
  24.                                 write_int16_eeprom(0x126,(float) cursor);               // escribe en la memoria
  25.                                 delay_ms(15);                                           // el valor central (cero)
  26.                                 cero= read_int16_eeprom(0x126);
  27.                                 delay_ms(15);
  28.                         }
  29.                 }

La diferencia aca radica en que tenes que presionar y soltar el boton para que haga lo que debe el programa, esto para evitar que si lo tenes presionado siga entrando. Esta es una solucion simple, tambien esta la otra que es guardar el valor del puerto y hasta que no cambie no entrar de nuevo ahi.

Problemas que puede traer la solucion que dije arriba? Si tu PWM esta realizado por software va a dejar de funcionar mientras RB4 sea igual a 0, pero ese problema ya lo tenias antes.

Por otro lado te presento una nueva... alternativa solo para que lo penses si conviene o tal ves no.. en ves de guardar lo que da el ADC, si guardas directamente el valor de duty (16bits entero) ?, esto evitaria que tengas que volver a hacer TODAS las operaciones cuando arranque, y con una lectura de la EEPROM apenas arranca el programa, este arrancaria con el duty que dejo cuando se apago a diferencia como esta ahora el programa.
Título: Re: Varios problemitas con la programación en C
Publicado por: arielmdq en 18 de Junio de 2015, 17:21:26
Wow cuantas cosas por aprender!!! .Muchas gracias killerjc !!! muy bueno todo lo que me explicas.Pero claaaaro ahora te entiendo lo del rebote al grabar en la eeprom  ,si con cada pulsacion se grabarian un monton de veces ja ja .Leí los 2 mensajes que pusiste y bueno creo entender ,pero a la vez se me siembran algunas dudas:
La idea de escribir en la eeprom ,es para que cuando se apague el instrumento no se pierdan esos parametros que guardo,segun tenia entendido en la RAM se me borrarian no es asi ?.

De todos modos para evitar confuciones me gustaria explicar como funciona esto : un vez que  instalo el instrumento necesito  calibrarlo ,como hago:pongo el switch en modo configuracion, muevo el timon todo para una banda por ejemplo a la derecha ( estribor ) grabo ese parametro ,lo muevo a la otra banda izquierda (babor)grabo el otro limite , lo llevo al centro  y grabo el cero o centro, muevo el switch a modo de uso y listo el programa se encargaria de hacer el resto (por lo visto no como estaba  el mio ja ja ).
Se supone que una vez que grabo estos 3 parametros, no los vuelvo a tocar nunca mas ,o hasta que para una reparacion, se desarme el sistema y se tenga que volver a calibrar .
Otra cosa que hace el programa y que no lo subi aca para simplificarlo un poco, es que cuando llega a los limites babor y estribor accionan unos reles que hacen que si el timon esta en modo electrico, cortan unas solenoides que lo frenan para no forzarlo. Bien sigo con las dudas:
                    El tema de las variables, en el programa original yo estaba usando int16 en todas ya que mi adc es de 10 bits y manejaba numeros de 0 a 1023 pero el programa era demasiado rustico ,(aclaro soy muy principiante y autodidacta programando) entonces  chaly me planteo lo de las cuentas y como vi que tenian coma ,pase todo a float pero aca empece con el problema ,que ahora veo que me mostras la forma correcta  de guardar un float en la eeprom,asi que al parecer ahi tenia un problema.
                   Ahora, se puede hacer con int16 ?
                  Como haria las cuentas con coma ?
                  Se pueden mezclar tipos distintas de variables en una cuenta ?
                  Si se me llenara la eeprom como la vacío ?
Aclaracion :No es problema que deje de funcionar el pwm cuando estoy configurando ya que en ese momento no necesito ver el instrumento, pero si leer el adc.
                Lo del menu ,supongo que intenta serlo ja ja ja :D .Aunque solo visualizo mediante 2 leds uno me muestra cuando esta en modo configuracion y otro cuando pulso el boton que graba en la eeprom , pero si me podes enseñar otra forma de hacerlo bienvenido sea .
Killerjc ,te agradezco un monton que te hallas interesado en el tema ,la verdad que cada vez que pregunto algo en el foro aprendo muchas cosas ,esta buenisimo!!!.Asi que voy a empezar a probar todo lo que me decis ,aunque me frena un poco el tema de las variables ,saber cual me conviene usar ? Bueno manos a la obra !!!! Mil gracias !!! Saudos !!!!

Hago otra aclaracion : en el while seria pin_bo  no  b1
                           
Código: C
  1. if (input(pin_b3)==1)                                            
  2.                         {                                                              
  3.                                 delay_ms(20);
  4.                                 while(input(pin_b1));           //Aca seria while(input(pin_b0));                                                                                                                                                                                              
  5.                                 write_int16_eeprom(0x126,(float) cursor);      
  6.                                 delay_ms(15);                                          
  7.                                 cero= read_int16_eeprom(0x126);
  8.                                 delay_ms(15);
Título: Re: Varios problemitas con la programación en C
Publicado por: KILLERJC en 18 de Junio de 2015, 18:00:47
Bueno ahora que lo explicaste veo mejor que queres hacer.

Si el ADC es de 16 bits, y deberias guardarlo con 16 bits, y no llevarlo a float, cuando haces las operaciones recien ahi lo pones en float.

Otra cosa.. Yo pense que los limites eran fijos  y querias guardar por ejemplo el valor del duty. Ahora viendo tu explicacion. Observo un error.

Chaly dio las formulas como si fuera lineal desde el extremo izquierdo al extremo derecho, dejando el centro que se acomode solo con la formula.
Ahora si vos me decis que queres grabar los valores: "MAXIMO", "MINIMO" y "CENTRO".

Eso quiere decir que Entre centro y maximo vas a tener que multiplicarlo por un valor y minimo y centro por otro. Ya que centro muy rara ves te va a quedar JUSTO en la mitad de Minimo y maximo. Ahora si solo tomas esos 2 extremos ya no hay tantos problemas.
Ya que el centro se calcularia como (Maximo - Minimo)/2

Respondo las dudas ahora

Citar
Ahora, se puede hacer con int16 ?

Si se puede hacer. Hay cosas nomas que interesan que sean "float" es decir con decimales, por ejemplo lo que pasas como parametro en set_pwm_duty() es un entero, lo cual no interesa que tengan comas. C normalmente agranda el tamaño de las vriables para trabajar con las mismas. Poer hay veces que tenes que "castearlas" ( de cast en ingles ).

Suponete esto:

int ADCResultado = 1000, valor;

valor = ADCResultado * 1.6486 - 450.68

Asi como esta C va a convertir el resultado de la operacion ( ADCResultado*1.6486 ) en float , por que uno de los operandos tiene coma, luego sumas y vas a encontrarte que tiene coma tambien y lo va a seguir tratando como un float.
Luego cuando intenta guardar ese resultado en valor se encuentra que valor es un int, entonces transforma ese float a un int y lo guarda., Ahora si haces pasos intermedio si vas a tener que guardarlo como float

Con lo cual tu resultado del ADC, tu resultado de la operacion es decir el duty pueden ser enteros. Que es necesario que sea float? El resultado de hacer 1023 / (max-min) , pero eso no es necesario guardarlo.

Citar
Si se me llenara la eeprom como la vacío ?
No se te va a llenar ya que estas escribiendo siempre sobre la misma posicion, pero la idea es tocar lo menos posible la EEPROM


Citar
Hago otra aclaracion : en el while seria pin_bo  no  b1

Si ... se me fue en el copy paste de todos xD... en realidad lo que esta dentro del while es lo mismo que el if, asi:

Código: C
  1. if (input(pin_b3)==1)                                            
  2.                         {                                                              
  3.                                 delay_ms(20);
  4.                                 while(input(pin_b3));                          //Espero que suelte

Título: Re: Varios problemitas con la programación en C
Publicado por: pablomanieri en 18 de Junio de 2015, 18:20:30
...Ahora si solo tomas esos 2 extremos ya no hay tantos problemas.
Ya que el centro se calcularia como (Maximo - Minimo)/2
...

El centro en realidad sería (Maximo+Minimo)/2

Saludos
Título: Re: Varios problemitas con la programación en C
Publicado por: KILLERJC en 18 de Junio de 2015, 18:27:55
Perdon por el doble post,, pero espero que este codig te funcione:

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. int16 cursor,toper,topbr,cero,ciclo_util;
  13. float c;
  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. //****************ADC**************************
  23.         setup_adc_ports(AN0);//* entrada analogica*//
  24.         setup_adc (ADC_CLOCK_INTERNAL);
  25.         setup_COUNTERS(RTCC_internal.rtcc_div_8);
  26.  
  27. // *************PWM**************************************
  28.  
  29.         setup_ccp1(CCP_PWM);
  30.         setup_timer_2(T2_DIV_BY_16,255, 1);
  31.         set_pwm1_duty(ciclo_util);
  32.    
  33. //**************Recupero Valores************************  
  34. //Aqui sis se reinicio tomo los valores , los calculo para lo que esta guardado en el EEPROM
  35.  
  36.  
  37.         toper=read_int16_eeprom(0x120);
  38.         delay_ms(15);                  
  39.    
  40.         topbr=read_int16_eeprom(0x122);
  41.         delay_ms(15);
  42.  
  43.         cero=(toper+topbr)/2;
  44.         c = (float)1023/(topbr - toper);
  45.    
  46.         WHILE (1)
  47.         {
  48.    
  49.                 set_adc_channel (0);
  50.                 delay_us (20);
  51.                 cursor = read_adc ();
  52.      
  53.  //*********************************************
  54.  // Programacion
  55.  //*********************************************
  56.  
  57.                 if (input(pin_b4)==0)                                                   //switch que habilita la configuracion de parametros
  58.                 {                                                                        
  59.                         if (input(pin_b1)==1)                                           //switch que habilita para establecer
  60.                         {                                                               // el limite izquierdo ( toper)  
  61.                                 delay_ms(20);                                           // Antirebote
  62.                                 while(input(pin_b1));                                   // Espero hasta que suelte
  63.                                 if(cursor!=toper)
  64.                                 {
  65.                                         write_int16_eeprom(0x120, cursor);              // escribe en la memoria
  66.                                         toper = cursor;
  67.                                         cero = (toper+topbr)/2;                         // Calculo nuevamente centro con el nuevo valor
  68.                                         c = (float)1023/(topbr - toper);                        // 1023 /(limite izq - limite derecho)
  69.                                 }
  70.                         }
  71.  
  72.                         if (input(pin_b2)==1)                                           //switch que habilita para establecer
  73.                         {                                                               // el limite derecho ( topbr)
  74.                                 delay_ms(20);                                           // Antirebote
  75.                                 while(input(pin_b2));                                   // Espero hasta que suelte
  76.                                 if(cursor!=topbr)
  77.                                 {
  78.                                         write_int16_eeprom(0x122, cursor);              // escribe en la memoria
  79.                                         topbr = cursor;
  80.                                         cero = (toper+topbr)/2;                         // Calculo nuevamente centro con el nuevo valor
  81.                                         c = (float)1023/(topbr - toper);                        // 1023 /(limite izq - limite derecho)
  82.                                 }
  83.                         }
  84.                 }
  85.    
  86.  
  87.   //********************************************
  88.   // Funcionamiento normal
  89.   //********************************************
  90.  
  91.                 if (input(pin_b4)==1)//switch que habilita el funcionamiemto
  92.                 {
  93.  
  94.                         if(cursor<topbr){cursor=topbr;}                                 // Fijo los limites de la entrada
  95.                         if(cursor>toper){cursor=toper;}
  96.  
  97.                         if(cursor>cero)                                                 // Caso que Cursor sea mayor a cero
  98.                         {
  99.                                 a = ((cursor-cero)*c)+cero;
  100.                         }
  101.                         else
  102.                         {
  103.                                 a = ((cero-cursor)*c)-cero;
  104.                         }
  105.                         if(a!=ciclo_util)                                               // Luego de los calculos, es necesario volver a cargar el duty ?
  106.                         {
  107.                                 set_pwm1_duty(a);
  108.                                 ciclo_util=a;
  109.                         }
  110.                 }
  111.         }  
  112. }

Cambios realizados:

- Cuando arranca el micro en la parte de configuracion ahi recupero los valores de la EEPROM y calculo los valroes necesarios, ya que estos tengo que calcularlos una sola ves.
- Elimine muchas funciones que hacian mas voluptuoso el programa, asi ademas condense las formulas para ocupar la menor cantidad e variables.
- Quite la programacion del "centro" por las razones que explique anteriormente, si aun asi deseas hacerlo con el centro, hay que cambiar el programa para que calcule las 2 distintas pendientes.
- Solamente se vuelven a calcular y guardar los valores SI es que cambiaron de los valores ay predefinidos, sino no vale la pena volverlos a calcular, esto es capricho mio, una para guardar lo menos posible en la EEPROM y la otra para ahorrar tiempo.
- Agregue los limites a cursor, si es menor o mayor de los valores esperados se fijan esos valores, ahi puede activarse algo si deseas.
- Por ultimo si no cambia el ciclo_util entonces que no actualize el PWM, esto en si no es preocupantes, en ciclo_util mantengo el valor viejo, y "a" es el valor nuevo.

Una cosa que no agregue es cuando "cursor" es igual a "cero", que lo podria haber realizado con unos else if. Y hubiera quedado de esta forma:

Código: C++
  1. if(cursor>cero)                                                 // Caso que Cursor sea mayor a cero
  2.                         {
  3.                                 a = ((cursor-cero)*c)+cero;
  4.                         }
  5.                         else if (cursor<cero)
  6.                         {
  7.                                 a = ((cero-cursor)*c)-cero;
  8.                         }
  9.                         else
  10.                         {
  11.                                 a=512;
  12.                         }

PD: Gracias por la correccion pablomanieri
Título: Re: Varios problemitas con la programación en C
Publicado por: arielmdq en 18 de Junio de 2015, 18:33:56
Pero Si necesito grabar el centro .El centro en los timones nunca esta a la mitad exacta de los dos extremos puede diferir un poquito  
lo que no me quedo claro es como primero tengo el adc en un int16 y despues lo paso a float para hacer las cuentas .Lo declaro global como int16 y despues local como float ? como seria ?
Ahora te entendi lo que me explicas del while para grabar en la eepron ,de esta manera no nesecito boton solo con colocar el switch y cuando lo cambio de posicion se grabaria .Antes yo lo hacia colocando un switch de bajo a alto para entrar en la configuracion de ese parametro y luego con un boton lo gravaba. Gracias !!!!


A disculpa recien veo que subiste un codigo , lo leo y despues te cuento muchas gracias !!!!
Título: Re: Varios problemitas con la programación en C
Publicado por: KILLERJC en 18 de Junio de 2015, 18:53:09
Tenes que entender esto de C:

Entero * Entero => resultado en entero => asigno resultado al lugar destino.

float c;
int16 a=5,b=2;

c = a / b;

entero / entero => entero => luego asigno ese entero al float
5/2 => 2 => 2.0

eso por que son variables, ahora si yo le digo al compilador que los trate como float

c = (float)a/b

entero(casteado a float) / entero => resultado en float => asigno a c
5(como float)/2 => 2.5 => c=2.5

Si fueran constantes podrias hacer:

c = 5.0/2

al tener una coma se lo toma como flotante.
Ahora un ejemplo un poco mas concreto a lo tuyo

a = ((cursor-cero)*c)+cero;

entero - entero = entero  (cursor-cero)

entero * flotante = flotante (resultado anterior por c )

flotante + entero = flotante ( toda la ecuacion)

flotante asignado al entero, le quita lo de la coma.


-------------------------------


Cambiando de tema, si me decis que el centro no se encuentra en el medio, entonces para un lado o para el otro va a tener disitnta "pendiente" la funcion, lo que hizo Chaly matematicamente hablando es encontrar una pendiente a una recta en el que entra valores (topbr a centro) y sale con valor 0 a mitad del duty. (y= cx +z <= funcion de una recta)

Ahora si vos cambias el valor centro por uno mas chico por ejemplo, esa funcion, va a tener que crecer mas rapido la señal, por lo cual "c" tiene que se mas grande del lado izquierdo, pero en el lado derecho va a tener que tomar otro valor, un valor mas chico. Asi que ahora tenes que tener un "c" para cada lado. Una funcion distinta para cada lado. Espero hacerme entender.
Título: Re: Varios problemitas con la programación en C
Publicado por: arielmdq en 18 de Junio de 2015, 19:49:30
Disculpa la demora para responder,justo cuando esto se esta poniendo bueno ..... ,pero tengo un bebe de 4 meses y me toco bañarlo  :) ,Ahora y leyendo rapido para tratar de responder ,sos un capo como me explicaste todo , muchas gracias!!! creo que voy  entendiendo esto de las variables  . Estaba revisando el programa mio y tenes razon estaba usando la misma constante (c) para ambos lados y tendria que ser una para cada lado, por que es asi , depende como este armada la parte mecanica del timon puede que una banda sea mas amplia para un lado que para el otro. De todos modos probe el codigo que me pasaste pero no funciona , lo simule en proteus pero cuando tengo el pote en el centro no me marca 2,5 volt y cuando esta en los extremos no llega ni a 0v  ni a 5v  .Pero bueno voy a revisar todo de nuevo mas tranquilo a ver que me surge
Título: Re: Varios problemitas con la programación en C
Publicado por: KILLERJC en 18 de Junio de 2015, 20:22:27
Puede que le erre en algo, estoy haciendolo en el bloc de notas, no lo estoy simulando ni nada por el estilo. Luego sigo agregando mas cosas. Para que tengas en cuenta, y tal ves le ponga un poco de matematica.. Asi que espero que logres entenderme.
Título: Re: Varios problemitas con la programación en C
Publicado por: arielmdq en 18 de Junio de 2015, 20:47:43
Si si muchas gracias , creo que te voy entendiendo bien ,pero tranqui cuando puedas .
                                                                                                                      Saludos !!!!
Título: Re: Varios problemitas con la programación en C
Publicado por: KILLERJC en 18 de Junio de 2015, 23:02:45
Bueno no se en que esta fallando mi codigo, ya lo voy a tener que simular y ver realmente que es.


Por ahora continuo..

Calculando los valores correctos
Como dije estamos tratando de crear una recta que pasa por 2 puntos bien definidos. Una recta para la izquierda y otra para la derecha del centro. Esta ecuacion de la recta va a transformar nuestra entrada ( x  o cursor ) en un valor de salida (y o duty)
Entonces primero debemos encontrarla, para esto tu programa debe de calcular esa recta.

Entonces buscamos un poco de informacion https://es.wikipedia.org/wiki/Recta
Y encontramos que la ecuacion de nuestra recta que pasa por los puntos (x1,y1) y (x2,y2) esta dado por la ecuacion:

(https://upload.wikimedia.org/math/d/9/0/d90fec206450345209516043ddde6261.png)

Para dar un ejemplo voy a usar los valores que dio Chaly en el post que te explico,
Sabemos que cuando sea minimo ( es decir cursor=x=205 , nos tiene que dar como resultado 0 ) , o es lo mismo que decir (205,0) x1=205 e y1=0
Por otra parte sabemos que cuando llegue a su maximo 818, tiene que llegar a 1023 es decir (818,1023) o x2=818 e y2=1023.

Si reemplazamos esos valores nos va a dar una formula asi:

1.6688 * X - 342.11  

( yo me ayude con una pagina )
https://www.wolframalpha.com/input/?i=line+through+%28205%2C0%29+and+%28818%2C1023%29

Es decir si yo tengo una X con un valor de 205 a 818 de ahi sale 0 a 1023 , la mitad en caso que sea igual para ambos lados (205+818)/2 = 516
Con ese valor y la perdida de algunos valores luego de la coma me da como salida 519 casi casi cerca de la mitad. Si tomara exactamente todos los digitos daria 511.5 exacto ( es decir 1023/2 )

Ahora como dije si movemos el centro y queremos que en todo el recorrido ya sea izquierda o derecha vaya variando de forma lineal, necesitamos de 2 rectas.
Una del minimo al centro, y la otra del centro al maximo. Yo agregue que solo cuando pasa por el centro ya me de el valor 511

Es decir los puntos serian:

una de (min,0) a (centro,511)
Y otra de (centro,511) a (max,1023)
si es igual a centro(511) se obtiene 511 directamente de las rectas, pero para evitar que posible falta de precision no llegue al valor de 511 como salida, hago que cuando cursor sea igual a centro, salga un 511. (511.5 seria lo exacto pero no admite coma el duty)

reemplazando los valores en la ecuacion de la recta tenemos:

Yizq = 511 / (centro-min) X -  ((511*min) / (centro-min))

Yder = 512 / (max-centro) X + 511 -  ((512*min) / (max-centro))

Finalmente tenemos las 2 formulas, el calculo es complejo asi que mientras menos se haga mejor, por que lleva mucho tiempo.

Segun el valor de cursor, si esta por debajo de centro se va a usar Yizq (salida de 0-510), si esta por encima se va a usar Yder(salida de 512 a 1023), si es igual a centro entonces es igual a 511

Vamos a hacer unos ejemplos.....

min = 100
max = 1000
centro = 400

2 lineas de
(100,0) a (399,510)           =>     y=510/299x - 51000/299     , https://www.wolframalpha.com/input/?i=line+through+%28100%2C0%29+and+%28399%2C510%29
(401,512) a (1000,1023)    =>     y=511/599x + 101777/599  , https://www.wolframalpha.com/input/?i=line+through+%28401%2C512%29+and+%281000%2C1023%29
1 punto:
(400,511)

Y una grafica de las 2 rectas
http://m.wolframalpha.com/input/?i=plot+%28510%2F299%29*x+-+51000%2F299%2C+%28511%2F599%29*x+%2B+101777%2F599%2C+x%3D0+to+1000&x=0&y=0

Se puede ver como una comienza en x=100 y equivale a Y=0 a medida que aumenta se cruzan en aproximadamente 400 que es el centro y de ahi en adelante se usa la otra linea, que cuando llega a 1000 es 1023.

Ecuacion de la recta:
Y = Ax + B

Fijate en las formulas que A y B son numeros. Esos numeros los vas a tener que calcular cada ves que modifiques los valores de derecha,izquierda y centro.

Toma de datos del ADC

Con una sola toma de datos del ADC es mas que suficiente, pero es muy comun que siempre esten variando los ultimos bits, entonces para eliminar esto recurrimos a un promedio, usamos un multiplo de 2^n para que sea mas simple para el micro

for(i=0;i<8;i++)
{
  cursor += read_adc ();
}

cursor/=8;

Es decir sumo 8 resultados y luego lo divido por 8, con 8 siendo el maximo de 1023 es de 8184 (8*1023) asi que no va a superar los 16bits de mi variable.

Por ultimo y mas importante EL USUARIO!!!

Si ese que mete la pata en los mejores momentos y hacen que el programa funcione mal, por su ineptitud o descuido. Entonces hay que tomar ciertos "cuidados", siempre desconfia del usuario, incluso aunque seas vos mismo.
Por ejemplo teniendo estos valores:

min = 200
max = 800

y alguien le cambia el centro a el valor 100.. No hay nada que lo evite.
Otra cosa, imaginate ahora que le ponga un valor de 201. Tambien otro comportamiento "no previsto".

Entonces te tenes que asegurar de algunas cosas.. Dejar un espacio minimo entre min y max, asi no se juntan demasiado, tambien definir un espacio minimo entre min-centro y centro-max. Y que se cumpla que min < centro < max
Esto evitaria todas esas clases de problemas, si alguno mete la manito, o un dia te levantaste mal y presionaste sin querer algo por lo menos no va a andar tan mal.

PD: tal ves me fui un poco en la matematica pero es para que entiendas de donde calcular los valores de la formula. Que luego queres implementar en tu programa.
Título: Re: Varios problemitas con la programación en C
Publicado por: arielmdq en 19 de Junio de 2015, 08:40:23
IMPECABLE lo suyo killerjc ((:-)) muchas gracias te pasaste con la explicacion, bueno ahora veo la presicion de los calculos, los cuales tendre que revisar nuevamente ,por que ayer estuve intentando modificar tu codigo pero obiamente no me funciono ja ja .Le agregue la grabacion del cero ,elimine la cuenta para calcularlo .Le puse dos costantes (b) y (c) ,(que son constantes despues que se calculan ) y a partir de ahi hice las cuentas ,con una constante para un lado y con otra  para el otro lado ,re confiado que iba a salir andando peroooo nop,ja ja .Bueno voy a revisar nuevamente todos los calculos de  tu explicacion y a seguir probando a ver que pasa .Te agradezco muchisimo tu voluntad ,sos muy claro para explicar .De todos modos te subo el codigo que modifique y me voy a trabajar que se me hace tarde ja ja . 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. int16 cursor,toper,topbr,cero,ciclo_util,a; // faltaba declarar (a)
  13. float c,b;                                             // agregue (b)
  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. //****************ADC**************************
  23.    setup_adc_ports(AN0);//* entrada analogica*//
  24.    setup_adc (ADC_CLOCK_INTERNAL);
  25.    setup_COUNTERS(RTCC_internal.rtcc_div_8);
  26.  
  27. // *************PWM**************************************
  28.  
  29.    setup_ccp1(CCP_PWM);
  30.    setup_timer_2(T2_DIV_BY_16,255, 1);
  31.    set_pwm1_duty(ciclo_util);
  32.    
  33. //**************Recupero Valores************************  
  34. //Aqui sis se reinicio tomo los valores , los calculo para lo que esta guardado en el EEPROM
  35.  
  36.  
  37.       toper=read_int16_eeprom(0x120);
  38.       delay_ms(15);                  
  39.    
  40.       topbr=read_int16_eeprom(0x122);
  41.       delay_ms(15);
  42.  
  43.       cero=read_int16_eeprom(0x126);      // agregue  lectura de la variable cero
  44.       delay_ms(15);
  45.      
  46.    WHILE (1)
  47.    {
  48.    
  49.       set_adc_channel (0);
  50.       delay_us (20);
  51.       cursor = read_adc ();
  52.      
  53.  //*********************************************
  54.  // Programacion
  55.  //*********************************************
  56.  
  57.       if (input(pin_b4)==0)                     //
  58.       {  
  59.         if (input(pin_b3)==1)                  //
  60.             {                                        //
  61.              delay_ms(20);                  //
  62.             while(input(pin_b3));               // Agregue esto para grabar el cero
  63.             if(cursor!=cero)
  64.             {
  65.                write_int16_eeprom(0x126, cursor);      //
  66.                cero = cursor;
  67.                        
  68.             }
  69.             }
  70.          if (input(pin_b1)==1)                  //switch que habilita para establecer
  71.          {                                        // el limite dercho ( toper)  
  72.              delay_ms(20);                  //
  73.             while(input(pin_b1));               //
  74.             if(cursor!=toper)
  75.             {
  76.                write_int16_eeprom(0x120, cursor);      //
  77.                toper = cursor;
  78.                
  79.                    c = (float)511/(toper - cero );         // toper es el mas grande mas cerca de 1023
  80.             }
  81.            }
  82.  
  83.            if (input(pin_b2)==1)                  //switch que habilita para establecer
  84.             {                                        // el limite derecho ( topbr)
  85.              delay_ms(20);                  //
  86.             while(input(pin_b2));               //
  87.             if(cursor!=topbr)
  88.             {
  89.                write_int16_eeprom(0x122, cursor);      //
  90.                topbr = cursor;
  91.              
  92.                    b = (float)511/(cero - topbr );         // topbr es el mas cerca de 0
  93.             }
  94.             }
  95.            
  96.           }
  97.    
  98.  
  99.   //********************************************
  100.   // Funcionamiento normal
  101.   //********************************************
  102.  
  103.       if (input(pin_b4)==1)//switch que habilita el funcionamiemto
  104.       {
  105.              
  106.          if(cursor<topbr){cursor=topbr;}               // Fijo los limites de la entrada
  107.          if(cursor>toper){cursor=toper;}
  108.  
  109.          if(cursor>cero)                     // Caso que Cursor sea mayor a cero
  110.          {
  111.             a = ((cursor-cero)*c)+cero;
  112.          }
  113.          else
  114.          {
  115.             a = ((cero-cursor)*b)-cero;
  116.          }
  117.          if(a!=ciclo_util)                  // Luego de los calculos, es necesario volver a cargar el duty ?
  118.          {
  119.             set_pwm1_duty(a);
  120.             ciclo_util=a;
  121.          }
  122.         }
  123.        
  124.    }  
  125. }

Modifique el programa nuevamente ,por que habia un error en el momento de grabar los parametros estaban alrevez los limites asi que aclaro :
toper es el mas cercano a 1023
topbr es el mas cercano a 0
Igual sigue sin funcionar adjunto el cuadro de variables en la simulacion
Título: Re: Varios problemitas con la programación en C
Publicado por: KILLERJC en 19 de Junio de 2015, 14:39:46
Bueno recien veo que mi explicacion esta un poco mal en la matematica, la voy a corregir, se me escapo una suma por ahi.

****************      EDIT:
Recien veo que modificaste toper y topbr, yo lo hice como estaba antes. asi que el codigo estan cambiados, pero es basicamente los nombres.
Si queres simularlo comenza primero con la simulacion cuando esta funcionando (RB4=1), y asignale los valores manualmente a topbr/toper/cero.
Esto implica que tengas que cambiar la parte del codigo al comienzo, en vez de leerlo de la EEPROM que directamente le cargues el numero. Una ves funcionando eso, avanzas a el tema de la EEPROM
**************************

En fin aca esta el codigo:

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;
  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.         toper=read_int16_eeprom(0x120);
  42.         delay_ms(15);                  
  43.    
  44.         topbr=read_int16_eeprom(0x122);
  45.         delay_ms(15);
  46.  
  47.         cero=read_int16_eeprom(0x124);
  48.  
  49.         Ai = (float)511 / (cero-toper);                         // Valores recta izquierda y derecha:
  50.         Bi = ((float)-511*toper)/(cero-toper);                  // Yi = Ai*X +Bi
  51.         Ad = (float)512 / (topbr-cero);                         // Yd = Ad*x +Bd
  52.         Bd = 511 - (((float)512*cero)/(topbr-cero));
  53.    
  54.         WHILE (1)
  55.         {
  56.    
  57.                 set_adc_channel (0);
  58.                 delay_us (20);
  59.  
  60.                 for(i=0;i<8;i++)                                //Promediado del ADC
  61.                 {
  62.                         cursor = read_adc ();
  63.                 }
  64.                 cursor /= 8;
  65.      
  66.  //*********************************************
  67.  // Programacion
  68.  //*********************************************
  69.  
  70.                 if (input(pin_b4)==0)                                                   // switch que habilita la configuracion de parametros
  71.                 {                                                                        
  72.                         if (input(pin_b1)==1)                                           // switch que habilita para establecer
  73.                         {                                                               // el limite izquierdo ( toper)  
  74.                                 delay_ms(20);                                           // Antirebote
  75.                                 while(input(pin_b1));                                   // Espero hasta que suelte
  76.                                 if(cursor!=toper && cero>toper)
  77.                                 {
  78.                                         // Introducir comprobacion de rangos
  79.                                         write_int16_eeprom(0x120, cursor);              // escribe en la memoria
  80.                                         Ai = (float)511 / (cero-toper);                 // Calcula los nuevos coeficientes de la izquierda
  81.                                         Bi = ((float)-511*toper)/(cero-toper);
  82.                                 }
  83.                         }
  84.  
  85.                         if (input(pin_b2)==1)                                           //switch que habilita para establecer
  86.                         {                                                               // el limite derecho ( topbr)
  87.                                 delay_ms(20);                                           // Antirebote
  88.                                 while(input(pin_b2));                                   // Espero hasta que suelte
  89.                                 if(cursor!=topbr && cero<topbr)
  90.                                 {
  91.                                         // Introducir comprobacion de rangos
  92.                                         write_int16_eeprom(0x122, cursor);              // escribe en la memoria
  93.                                         Ad = (float)512 / (topbr-cero);                 // Calcula los coeficientes de la derecha
  94.                                         Bd = 511 - (((float)512*cero)/(topbr-cero));
  95.                                 }
  96.  
  97.                         if (input(pin_b3)==1)                                           // switch que habilita para establecer
  98.                         {                                                               // el centro (cero)
  99.                                 delay_ms(20);                                           // Antirebote
  100.                                 while(input(pin_b3));                                   // Espero hasta que suelte
  101.                                 if(cursor!=cero)
  102.                                 {
  103.                                         // Introducir comprobacion de rangos
  104.                                         write_int16_eeprom(0x124, cursor);              // escribe en la memoria
  105.                                         Ai = (float)511 / (cero-toper);                 // Calcula ambos coeficientes ya que
  106.                                         Bi = ((float)-511*toper)/(cero-toper);          // cambia el centro y cambian ambas rectas
  107.                                         Ad = (float)512 / (topbr-cero);                  
  108.                                         Bd = 511 - (((float)512*cero)/(topbr-cero));
  109.                                 }
  110.                         }
  111.                 }
  112.    
  113.  
  114.   //********************************************
  115.   // Funcionamiento normal
  116.   //********************************************
  117.  
  118.                 if (input(pin_b4)==1)//switch que habilita el funcionamiemto
  119.                 {
  120.  
  121.                         if(cursor<topbr){cursor=topbr;}                                 // Fijo los limites de la entrada
  122.                         if(cursor>toper){cursor=toper;}
  123.  
  124.                         if(cursor>cero)                                                 // Caso que Cursor sea mayor a cero
  125.                         {                                                               // Es decir lado derecho
  126.                                 a = (Ad*cursor) + Bd;
  127.                         }
  128.                         else if (cursor<cero)                                           // Caso Cursor sea menor a 0
  129.                         {                                                               // Es decir lado izquierdo
  130.                                 a = (Ai*cursor) + Bi;
  131.                         }
  132.                         else                                                            // Caso que cursor este al medio
  133.                         {
  134.                                 a=511;
  135.                         }
  136.                         if(a!=ciclo_util)                                               // Luego de los calculos
  137.                         {                                                               // Si cambia lo actualizo al duty
  138.                                 set_pwm1_duty(a);
  139.                                 ciclo_util=a;
  140.                         }
  141.                 }
  142.         }  
  143. }

Funcionamiento?
RB4 tiene una llave.
RB1,RB2,RB3 son botones.

Para el lado que pone a 0 el pin RB4 activa el modo de configuracion, este modo te permite girar tu "cursor" y al presionar RB1 se fija el izquierdo, al presionar RB2 el derecho y RB3 el centro. Una ves posicionado "cursor" se presiona el boton y cuando se suelta comienza a grabarlo en la EEPROM.

No le puse el codigo que limita estas funciones para posibles errores. Eso ya lo comente antes. Igual estan los comments donde se deberian colocar.

Al comienzo del programa se toma los datos de la EEPROM y se calculan los 2 coeficientes de la recta A y B de cada una => Y = Ax + B, siendo el siguiente caracter el lado que corresponden Ai,Bi izquierda y el otro derecha.
Cuando calculo esto ? lo calculo al comienzo del programa y queda guardado en 4 float, el otro caso que tenga que calcularlo es cuando se cambie algun limite, si se cambia el izquierdo entonces debo modificar unicamente la recta izquierda, si es el derecho solo la recta de la derecha, ahora si es el centro, afecta a ambos, por lo tanto calculo las 2.

Finalmente cuando el programa esta marchando se cumple:

Limite izquierda = 0% duty PWM (0)
Centro = 50% duty PWM (511)
Limite derecha = 100% duty PWM ( 1023 )

Sea cual sea el limite de la izquierda, el centro y el limite de la derecha. Siempre y cuando se cumpla que toper < cero < topbr

Visto de otra forma

Lim Izq -------- Centro --------- Lim Der
   0%                 50%                100%

Los calculos del los factores Ai,Bi,Ad,Bd los hice con C en XC8 por que no poseo CCS pero imagino que seran correctos tambien en el otro compilador, los simule y verifique y me dan valores correctos con los que deben ser.
Espero que funcione ya que no posee nada raro el programa, y perdon por haber metido bastante teoria sobre rectas, es que si queres generarlas dinamicamente como vos queres y no con unos valores fijos entonces no le veo otra escapatoria.

Siguiendo un poco mas el tema, esto es para algo que no posea creo que demasiado movimiento.
El principal problema por ahi es el desgaste del potenciometro si es que vas a usar eso.
Si queres eliminar el problema de contacto y desgaste aun mas, ya vas a tener que pensar en un sensor optico.
Título: Re: Varios problemitas con la programación en C
Publicado por: arielmdq en 19 de Junio de 2015, 19:04:18
Hola killerjc , ahi estuve probando el programa que me pasaste pero no me funciona ,te cuento : Te falto definir la variable (a) por lo que no compilaba, asi que lo hice con un int16 . Probe eliminando todas las lecturas y escrituras a la eeprom y asignando los valores a toper=205 topbr=818 y cero =511,como para usar valores conocidos  ,pero tampoco funciono .Cuando hago la simulacion veo que me esta leyendo el adc ( cursor ) ,tambien figuran los 3 valores antes mencionados ( toper=205 topbr=818 y cero =511) pero es como que no esta haciendo las cuentas por que no me figuran ni Ai,Bi,Ad,Bd y por logica no sale ni (a) ni ciclo util ,
Comprobe todas las cuentas a mano con calculadora suponiendo ejemplos y estan bien, pero por algun motivo no las hace el programa.Que podra ser???? .
Título: Re: Varios problemitas con la programación en C
Publicado por: KILLERJC en 19 de Junio de 2015, 19:42:16
Si me comi la a xD.
Como decis las cuentas estan bien. probar yo probe hacer las cuentas con distintos valores de cursor aplicando las mismas formulas que te pase en el programa ( con XC8 y use valores como 100,400,1000 en toper,cero,topbr ) y siempre obtenia los valores que necesitaba tener. para 100 , a me daba 0, fui incrementando "cursor" de 100 en 100 y fue aumentando hasta llegar a 1023 cuando era 1000.

Por las dudas te dejo un codigo "simplificado" es decir le quite la parte de configuracion, promediado de datos, lectura de EEPROM, incluso ni pregunto por RB4, simplemente uso el PWM. Y ahi deberia andar si o si. Si no es algo con las cuentas, pero me parece raro, como ya dije logre hacer todo bien en mi PC (con XC8). Puede que el proteus este teniendo errores, o vaya muy lento, realmente no se.

Pero no veo el por que no lo hace.

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;
  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.         toper=205;
  42.         topbr=818;
  43.         cero=511;
  44.  
  45.         Ai = (float)511 / (cero-toper);                         // Valores recta izquierda y derecha:
  46.         Bi = ((float)-511*toper)/(cero-toper);                  // Yi = Ai*X +Bi
  47.         Ad = (float)512 / (topbr-cero);                         // Yd = Ad*x +Bd
  48.         Bd = 511 - (((float)512*cero)/(topbr-cero));
  49.  
  50.         set_adc_channel (0);
  51.         delay_us (20);
  52.  
  53.    
  54.         WHILE (1)
  55.         {
  56.    
  57.                 cursor = read_adc();
  58.    
  59.  
  60.   //********************************************
  61.   // Funcionamiento normal
  62.   //********************************************
  63.  
  64.                         if(cursor<topbr){cursor=topbr;}                                 // Fijo los limites de la entrada
  65.                         if(cursor>toper){cursor=toper;}
  66.  
  67.                         if(cursor>cero)                                                 // Caso que Cursor sea mayor a cero
  68.                         {                                                               // Es decir lado derecho
  69.                                 a = Ad*cursor + Bd;
  70.                         }
  71.                         else if (cursor<cero)                                           // Caso Cursor sea menor a 0
  72.                         {                                                               // Es decir lado izquierdo
  73.                                 a = Ai*cursor + Bi;
  74.                         }
  75.                         else                                                            // Caso que cursor este al medio
  76.                         {
  77.                                 a=511;
  78.                         }
  79.                         set_pwm1_duty(a);
  80.         }  
  81. }

Una pregunta mas... ademas del proteus, CCS no te permite "simularlo" paso a paso ? ahi podes ver si las variables estan mal o que pasa. Si podes simularlo instruccion por instruccion mucho mejor.
Título: Re: Varios problemitas con la programación en C
Publicado por: arielmdq en 19 de Junio de 2015, 21:07:57
 Ahora nisiquiera lee el adc ja ja ,que va a ser, hay algo mal que no anda bien  :D  ja ja , un poco de humor por que ya me va a explotar la cabeza.Ahora cursor adopta directamente el valor de  toper osea 205 y ahi queda clavado ,para mi por alguna razon no hace las cuentas con float ,que era lo que me pasaba desde el principio.
La verdad que no se si se puede simular con ccs pero lo voy a googlear a ver que onda
Título: Re: Varios problemitas con la programación en C
Publicado por: arielmdq en 19 de Junio de 2015, 21:31:49
Un avance  :-/  encontre la solucion a poder ver las variables float en proteus y estaba aca :
 http://www.todopic.com.ar/foros/index.php?topic=37183.0
ahora las veo pero sigue sin hacer las cuentas , asi que sigo investigando
Título: Re: Varios problemitas con la programación en C
Publicado por: KILLERJC en 19 de Junio de 2015, 21:58:52
Sinceramente no se que decirte.

Estoy acostumbrado al compilador de Microchip,en ese SI puedo simularlo paso a paso, lo hice para ver los resultados que daban y si me estaba equivocando en alguno, todo bien.
Lo unico que puede llegar a cambiar son los tamaños/definicion de los tipos de variables ( ejemplo que pueda poner uint16_t en ves de unsigned int16, aunque eso viene con stdint.h ) Pero ambos son lo mismo, las operaciones es C, es el mismo C, lo cual deberia realizarlas por igual.

Pero veo que NO quiere realizarlas, ahora aparecen Ai,Ad,Bi y Bd pero no tienen valor, es como si se quedara atrapado ahi..
Lo dejaste simulando un rato para ver si aparecian los valores? Es lo unico que se me puede ocurrir

Es mas aca es lo que tarda en hacer esas operaciones con valores de 100,400,1000 y cursor 300 usando flotante

Citar
Ai = Target halted. Stopwatch cycle count = 1033
Bi = Target halted. Stopwatch cycle count = 1723
Ad = Target halted. Stopwatch cycle count = 998
Bd = Target halted. Stopwatch cycle count = 1900
a = Target halted. Stopwatch cycle count = 1213

a 8 Mhz => 0.5us cada ciclo.
con 2000 ciclos es 1ms, asi que ni deberia notarse. Y no creo que corra tan lento la simulacion del proteus para que ocurra eso, o directamente el proteus esta fallando.
Pero lo raro que vi gente hacer cosas con flotante en el proteus y no tuvieron problemas, encima luego lo mandaban a un LCD.
Tampoco tengo el Proteus como para probarlo. Si alguno lo tiene y le subis los archivos .hex/.cof + la simulacion del Proteus pueda ayudarte.
Título: Re: Varios problemitas con la programación en C
Publicado por: arielmdq en 19 de Junio de 2015, 23:02:03

Pero veo que NO quiere realizarlas, ahora aparecen Ai,Ad,Bi y Bd pero no tienen valor, es como si se quedara atrapado ahi..

Si, aparecen Ai,Ad,Bi y Bd y con sus valores corespondientes eso ahora esta bien
 Lo que aparecen en 0 son (a ) y ciclo util, lo que me dice , supongo ,que no esta haciendo las cuentas
 
Lo dejaste simulando un rato para ver si aparecian los valores? Es lo unico que se me puede ocurrir

Tengo dos versiones de proteus esta ultima que probe es la 8 y tampoco lo hace (los valores de las cuentas ) .Despues subo todos los archivos

Lo que estoy pensando, si vos decis que deberia andar, es en grabar el pic y probarlo, tal vez funcione ,no?.Total tengo toda la plaqueta armada que ya esta funcionando con el programa rustico ese que hice lleno de if ja ja que puse en el otro post, Lo que no se ahora es cual programa probar ,ya me maree con tantas pruebas ja ja ja .
bueno sigo un poco mas y despues subo los archivos de proteus
Te agradezco un monton todo lo que has hecho eh !!!.Espero poder hacerlo andar, asi no te defraudo, y no es en vano todo tu esfuerzo.Muchas gracias !!!

Los ezfuerzos en vano no son por que aprendi muchas cosas :)



 
Título: Re: Varios problemitas con la programación en C
Publicado por: arielmdq en 19 de Junio de 2015, 23:20:43
Aca van  todos los archivos
Título: Re: Varios problemitas con la programación en C
Publicado por: juaperser1 en 20 de Junio de 2015, 07:59:34
Hola no estoy siguiendo el hilo por falta de tiempo, pero quería preguntarte si tus proteus son la versión de evaluación? Esque me ha parecido leer por algún sitio que la limitación que tienen es precisamente en el código que se ejecuta en los pic, y si killer dice que le funciona en el mplab, ed muy probable que te este limitando el uso de los flota o algo por el estilo.

Un saludo.
Título: Re: Varios problemitas con la programación en C
Publicado por: arielmdq en 20 de Junio de 2015, 13:27:15
Hola juaperser1.La verdad que no se si es la version de evaluacion pero tengo la version 7.6 y la 8 y en los dos hace lo mismo ahora aparecen las variables con sus datos pero por alguna razon el programa no hace las cuentas .Hoy grabe 2 micros y los probe una con el programa simple que no escribe en eeprom y ya tiene los valores asignados y el otro que escribe en eeprom  y ninguno de los dos funciona. Lo que voy a hacer ahora es empezar a probar haciendo un programa con  cuentas sencillas pero con float y probarlo en proteus a ver que hace .
La placa se que funciona por que la tenia andando con el programa primitivo, que ese si que funciona, el problema es que no tiene precision, ademas de que esta horrible  por que lo diseñe yo  :D .Bueno sabado de frio en mar del plata  :2] ideal para romperme la cabeza pensando como solucionar esto ja ja .Si a alguno se le ocurre algo les estaré muy  agradecido.
                                                                                      Saludos !!!!
Título: Re: Varios problemitas con la programación en C
Publicado por: KILLERJC en 20 de Junio de 2015, 14:27:54
Podrias tratar de hacer la formula en varios pasos, para ver si es algo del CCS.
Título: Re: Varios problemitas con la programación en C
Publicado por: arielmdq en 20 de Junio de 2015, 14:34:37
Tengo el mplab 8.8 tambien pero nunca lo use , si crees que puede ser el ccs el problema .Podria probar hacerlo en mplab me miro unos tutoriales y lo hago
Título: Re: Varios problemitas con la programación en C
Publicado por: juaperser1 en 20 de Junio de 2015, 14:51:24
Si tienes oportunidad de dejar CCS y pasar al MPLAB seria estupendo, ya no por este problema en particular, si no por todo en general. CCS esta bien para dar los primeros pasos pero luego se te quedará corto ya que te abstrae mucho del hardware.

pero te llevará tiempo, por ejemplo escribir en rom no es simplemente poner una linea. ni configurar los puertos. aunque cuando aprendes se hace bastante sencillo, pero lo mejor que ganaras es poder debugear tu programa ademas de simularlo, eso es una gozada.

un saludo.
Título: Re: Varios problemitas con la programación en C
Publicado por: arielmdq en 20 de Junio de 2015, 15:02:09
Listo empezo a funcionar  :-/ :-/ :-/ , este es el primer avance . Le faltaba  asignar el valor de (a) a ciclo util

                                     ciclo_util = a ;

Y salio andando hace las cuentas y todo ja ja ( podria haber avanzado mas para contarles pero me gano la emocion )

Otra cosa :
               
        // if(cursor<topbr){cursor=topbr;}               //si habilito estas dos instrucciones deja de funcionar
         //if(cursor>toper){cursor=toper;}  




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;
  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.       toper=205;
  42.       topbr=818;
  43.       cero=511;
  44.  
  45.    Ai = (float)511 / (cero-toper);            // Valores recta izquierda y derecha:
  46.    Bi = ((float)-511*toper)/(cero-toper);         // Yi = Ai*X +Bi
  47.    Ad = (float)512 / (topbr-cero);            // Yd = Ad*x +Bd
  48.    Bd = 511 - (((float)512*cero)/(topbr-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.         // if(cursor<topbr){cursor=topbr;}               //si habilito estas dos instrucciones deja de funcionar
  66.          //if(cursor>toper){cursor=toper;}
  67.  
  68.          if(cursor>cero)                     // Caso que Cursor sea mayor a cero
  69.          {                        // Es decir lado derecho
  70.             a = Ad*cursor + Bd;
  71.          }
  72.          else if (cursor<cero)                  // Caso Cursor sea menor a 0
  73.          {                        // Es decir lado izquierdo
  74.             a = Ai*cursor + Bi;
  75.          }
  76.          else                        // Caso que cursor este al medio
  77.          {
  78.             a=511;
  79.          }
  80.          ciclo_util = a ;
  81.    }  
  82. }
Título: Re: Varios problemitas con la programación en C
Publicado por: arielmdq 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
Título: Re: Varios problemitas con la programación en C
Publicado por: KILLERJC 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.
Título: Re: Varios problemitas con la programación en C
Publicado por: KILLERJC 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.
Título: Re: Varios problemitas con la programación en C
Publicado por: arielmdq 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
Título: Re: Varios problemitas con la programación en C
Publicado por: KILLERJC 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 :)
Título: Re: Varios problemitas con la programación en C
Publicado por: arielmdq 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 !!!
Título: Re: Varios problemitas con la programación en C
Publicado por: arielmdq 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?
Título: Re: Varios problemitas con la programación en C
Publicado por: KILLERJC 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 :)
Título: Re: Varios problemitas con la programación en C
Publicado por: arielmdq 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 !!!!!