Autor Tema: Problema al declarar variables  (Leído 3101 veces)

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

Desconectado D1to

  • PIC10
  • *
  • Mensajes: 39
Problema al declarar variables
« en: 18 de Enero de 2017, 01:07:15 »
Hola a todos, nuevamente estoy aquí, desde hace mucho  estaba lidiando con u pequeño pero molesta problema al momento de declarar variables en un pic 16f877a con MikroC Pro, soy estudiante, discúlpenme si me lío fácilmente, el problema surge cuando necesito declarar una variable que voy a utilizar en el void main y en el vector interrupt, estoy trabajando con dos libros pero, en situaciones como estas no son de mucha ayuda. Por cierto este pequeño proyecto de trata del sistema de control pid, en el cual yo tengo que manipular las variables PID y estudiar el comportamiento del sistema, en el codigo que estoy haciendo estoy usando el timer0 como interrupción para que tome lectura del sensor y calcule la salida y en el vector principal, el menu en el cual yo pueda cambiar set point y valores p,i,d. _Desde ya agradezco su su interés

* Error al declarar variables.jpg
(77.99 kB, 2538x649 - visto 623 veces)
.

* Duda.jpg
(53.57 kB, 2538x649 - visto 561 veces)
.
« Última modificación: 18 de Enero de 2017, 01:09:33 por D1to »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Problema al declarar variables
« Respuesta #1 en: 18 de Enero de 2017, 01:40:35 »
EDIT: Tal ves mis palabras puedan parecer "duras", pero creo que no hay demasiada forma de explicarlo, si tenes la pregunta concreta con gusto intento buscarte la respuesta.

Tus imagenes no sirven de nada, no explican nada, simplemente hay 2 partes de codigos que ni siquiera estan completos o relacionados con el problema (especialmente la segunda).
Tu explicacion de tu problema TAMPOCO sirve de mucho, porque no presentas ningun problema, simplemente contas lo que estas haciendo. No es lo mismo que dijeras:

Citar
yo declaro asi las variables, en el main lo uso asi (codigo donde usas las variables).... en la interrupcion las uso asi (codigo donde se usan las variables).... pero a veces falla y no responde como corresponde se que el codigo del PID es correcto, no se que puede estar sucediendo

Te sugiero que intentes buscar una pregunta que sea puntual o al menos dirija a la persona que lo lee a encontrar la causa de tu problema.
Lo mejor es copiar el codigo aca y no usar imagenes como las que subiste, ejemplo:

Código: C
  1. static void FnMostrarNum(void)
  2. {
  3.  
  4.         static enum Flag_Display DisplayActivo = UNIDAD;              // Bool indicando el display que debe encenderse
  5.  
  6.     // Asi cuando es 0 no muestra nada
  7.     if (Timers.Current != 0)
  8.     {
(Luego de copiado el codigo, seleccionalo y en el menu donde podes poner negrita,etc tenes una lista que dice Codigo, abrila y selecciona C)

Si no queres copiar todo el codigo por que no queres que la gente lo vea, podes tratar de crear un ejemplo simple en el cual ocurra tu problema y de alli tratar de ayudarte.

A pesar de todo esto, sucede en el foro de gente que pone parte de los codigos creyendo que estan ahi los problemas y terminan siendo otras partes del mismo, lo cual termina siendo un desperdicio de tiempo para las demas personas. Por eso mi idea fue de que trates de crear un "ejemplo sencillo" de forma aparte para reproducirlo alli.

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

Citar
estaba lidiando con u pequeño pero molesta problema al momento de declarar variables en un pic 16f877a con MikroC Pro,  el problema surge cuando necesito declarar una variable que voy a utilizar en el void main y en el vector interrupt

Lo unico que puedo distinguir es esto. Pero en tu primera imagen parece todo correcto.
Lo que te puedo llegar a decir (porque no se cual es tu problema), es que si vas a usar optimizaciones uses "volatile", es decir:

Código: C
  1. volatile int sp, P, I, D, pid, oldpid;

Aun asi hay que tener mucho cuidado con las mismas, ya que si son de 2 o mas bytes ( 16/24/32 bits, en arquitectura de PIC16/18 esta afirmacion) y lo estas cambiando desde un lado y leyendo del otro, podrias tener problemas. Recalco lo de las arquitecturas, porque PIC24/dsPIC y otros integrados (Atmel/ARM) pueden presentar el mismo problema incluso con variables de 1 byte o mas.

-----------

Respecto a tu segunda imagen, PUNTO_DE_CONTROL y SENSOR, no tienen sentido de ser float.. Al menos para guardar esos valores que son enteros. Complicarse usando floats ( de 24 o 32 bits) y su sobrecarga en funciones para manejar estos, cuando podes usar un entero de 8bits no tiene sentido.
« Última modificación: 18 de Enero de 2017, 01:51:25 por KILLERJC »

Desconectado D1to

  • PIC10
  • *
  • Mensajes: 39
Re:Problema al declarar variables
« Respuesta #2 en: 18 de Enero de 2017, 02:33:13 »
Agradezco tu pronta respuesta, es verdad me desvié del tema, no tengo ningún problema para compartir mi código, de hecho esta incompleto. ahora mismo estoy tratando de usar "volatile ".Verás estuve haciendo un ejemplo sencillo y pues resulta que no me dio problemas para compilarlo, pero en el codigo de mi proyecto si, por alguna razon ya no se produce el error, inicialmente Cuando yo declaraba una variable global (la necesito en void main y void interrupt), al momento de compilar me indicaba que esta no había sido declarada  y me señalaba el vector principal

declaración de variables globales
void interrupt
void main
de esta forma yo lo hacia, pero me daba errores obligándome a declararla dentro de void main y dentro de void interrupt, y cuando no me salia ese error me salia que la variable había sido redefinida, tal como lo indica una de las fotos que adjunte, este mensaje esta en la parte inferior  en inf de compilación. Bueno, el error no se me presento otra vez, pero igual, estoy muy agradecido por la ayuda, por cierto con respecto a la siguiente foto, la parte subrayada de color rojo, no comprendo, agradecería si pudieras explicarme, aunque creo que ese punto ya no corresponde al tema, gracias de antemano.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Problema al declarar variables
« Respuesta #3 en: 18 de Enero de 2017, 04:57:27 »
Como te digo en las fotos no aparece el error, ni nada por el estilo. Seguramente es un error en el codigo o en algun include (No creo que sea nada relacionado con el proyecto). Podes hacer lo siguiente.

- Compila el codigo que te da error, si no es muy grande pasa el codigo, tambien copia y pega el error que te da (por que en los errores aparecen los numeros de linea del error), todo esto en texto, no en imagenes.
- Cambiale el nombre a las variables, usa my_pid , my_oldpid, etc. es decir ponele el my_ adelante, si no te da error entonces es que en algun lado la estas redefiniendo sin querer.

Desconectado D1to

  • PIC10
  • *
  • Mensajes: 39
Re:Problema al declarar variables
« Respuesta #4 en: 18 de Enero de 2017, 09:20:41 »
Una vez mas agradezco tu ayuda, hice lo que me sugeriste, le agregue my_ a las variables que me daban error y pude compilarlo sin problemas, bueno en parte, ahora me da otro error "No enought RAM for call stack", muchas gracias por tu ayuda, por cierto te adjunto el código por si  puedes verlo. Supongo que este error debe ser por que le puse mucha informacion al vector interrupt, otra vez tendre que modificar todo (soy estudiante asi q ya te imaginaras). Y es verdad cuando corte la imagen para enfocar el problema, tambien corté la parte q me indicaba error. Gracias una vez mas  :o  :o
 
Código: [Seleccionar]
// Lcd pinout settings
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D4 at RB0_bit;

// Pin direction
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D7_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB0_bit;

char text [4] ;
char text1 [6] ;
char text2 [6] ;
char text3 [6] ;
char text4 [5] ;

int sp , my_P , I , my_D , pid, oldpid ;
float kp,ki,kd, E, E_1, E_2, sal, pv , Radc;
int T =10000;

void interrupt (){

               // Toma de datos
               Radc = Adc_Read (0) ;
               pv = 0.244 * Radc ;            //2.5 * Radc /10,23 ;
               E = sp - pv ;
               floattostr(pv,text4) ;

               //Operaciones
               kp = (100/my_P*sp) ;
               Ki = (E+(I/T*(E_1+E_2))) ;
               kd = (my_D*(E-E_1));
               sal = kp*ki+kd ;

               if (sal > 255){
                sal = 255 ;
               }
               if (sal < 0){
                sal = 0 ;
               }
               PWM1_set_duty(sal) ;
               delay_ms(10) ;
 
               INTCON.F2=0;
}

void main() {

sal = 0 ;
sp = 100 ;
my_P = 0 ;
I = 0 ;
my_D = 0 ;
pid = 0 ;
oldpid = 0 ;
Adcon1 = 0b00000001   ;

Lcd_Init();
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF);
Lcd_out(1,1,"Set Point:") ;
Lcd_out(2,1,"Temp:") ;
inttostr(sp,text3);

PWM1_Init(20000) ;
PWM1_set_duty(0) ;
PWM1_Start();

trisd = 0x07 ;
portc = 0 ;

OPTION_REG = 0b00000110;
INTCON = 0b10100000;


          while (1){
               while (pid > 0) {
                     if (Button(&PORTD, 0,50, 1)) {
                      pid = +1 ;
                          if (pid ==5) {
                           pid = 0 ;
                          }
                     }
                     if (Button(&PORTD, 1,50, 1)) {
                          if (pid == 1){
                           sp =+0.1 ;
                                 if (sp > 150){
                                  sp = 150 ;
                                 }
                          }
                          if (pid ==2){
                           my_P=+0.1 ;
                          }
                          if (pid ==3){
                           I=+1 ;
                          }
                          if (pid ==4){
                           my_D=+1 ;
                          }
                     }
                     if (Button(&PORTD, 2,50, 1)) {
                          if (pid == 1){
                           sp =-0.1 ;
                                 if (sp < 0){
                                  sp = 0 ;
                                 }
                          }
                          if (pid ==2){
                           my_p=-0.1 ;
                                if (P < 0){
                                 my_P= 0 ;
                                }
                          }
                          if (pid ==3){
                           I=-1 ;
                                if (I < 0){
                                 I= 0 ;
                                }
                          }
                          if(pid ==4){
                           my_D = -1 ;
                                if (D < 0){
                                 my_D= 0 ;
                                }
                          }
                     }
                    intTostr(P,text) ;
                    intToStr(I,text1) ;
                    intToStr(D,text2) ;
                    intTostr(sp,text3) ;
                    if (oldpid > 0){
                          if (pid ==1) {
                           Lcd_out(1,12,text3) ;
                           delay_ms(5) ;
                          }
                          if ((pid >1)&&(pid < 5)){
                           Lcd_out(2,1,text) ;
                           Lcd_out(2,5,text1 ) ;
                           Lcd_out(2,12,text2 ) ;
                           delay_ms (5) ;
                          }
                    }
                    else{
                          if (pid == 1){
                           Lcd_cmd(_Lcd_clear) ;
                           Lcd_out(1,1,"Set Point:") ;
                           Lcd_out(1,11,text3) ;
                           delay_ms(5) ;
                          }
                          if ((pid >1)&&(pid <5)){
                           Lcd_cmd(_Lcd_clear) ;
                           Lcd_out(1,1,"P:") ;
                           Lcd_out(1,6,"I:") ;
                           Lcd_out(1,12,"D:") ;
                           Lcd_out(2,1,text) ;
                           Lcd_out(2,5,text1 ) ;
                           Lcd_out(2,12,text2 ) ;
                           delay_ms (5) ;
                          }
                    }
                 }

               if (pid == 0) {
                       if (oldpid == 0){
                       Lcd_out(1,11,text3) ;            //Indicacion del error actual
                       Lcd_out(2,13,text4) ;
                       delay_ms(5) ;
                       }
                       else{
                       Lcd_Cmd(_LCD_CLEAR);
                       Lcd_out(1,1,"Set Point:") ;
                       Lcd_out(2,1,"Temp:") ;
                       Lcd_out(1,11,text3) ;            //Indicacion del error actual
                       Lcd_out(2,13,text4) ;
                       delay_ms(5) ;
                       }
               }
               oldpid = pid ;
              }
}
:o
« Última modificación: 18 de Enero de 2017, 09:55:40 por D1to »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Problema al declarar variables
« Respuesta #5 en: 18 de Enero de 2017, 10:13:45 »
Bueno tenes un gran problema o muchisimos problemas pequeños. tal ves es por tener muchas variables, o por no organizarte un poco mas. Dejo una recopilación de todo lo que encontre mirandolo, no esta en orden, simplemente lo primero que encontraba escribia aca.

No entiendo como puede compilar eso.
El tema de redefinir las variables parece que es cierto. Si te compila y ya no te da mas error, entonces en algun otro lado lo estas haciendo, tal ves en algun include, o en alguna libreria...

Ejemplo

Código: C
  1. my_D = -1 ;
  2.                                 if (D < 0){
  3.                                  my_D= 0 ;
  4.                                 }

Lo curioso es que no tenemos D, pero aun asi "compila" como si existiera realmente pero de otro lado, si fuera my_D ese codigo simplemente no tiene sentido.
Tambien my_D es tipo int, lo cual implicitamente es "unsigned" o sin signo asi que cargar un -1 es cargarle 2^16 - 1

Mas problemas

Código: C
  1. if (pid ==2){
  2.                            my_p=-0.1 ;
  3.                                 if (P < 0){
  4.                                  my_P= 0 ;
  5.                                 }

C es case-sensitive asi que my_P no es lo mismo que my_p, serian 2 variables totalmente distintas, pero vos unicamente definiste my_P, P y my_p no estan definidas, aca si o si deberia darte un error. Tambien my_p es un entero, y estas intentandole poner un -0.1.

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

No tiene sentido hacer esto:

Código: C
  1. char text [4] ;
  2. char text1 [6] ;
  3. char text2 [6] ;
  4. char text3 [6] ;
  5. char text4 [5] ;

Solo necesitas 1, convertis el que necesitas y mostras, asi de simple.

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

Radc no tiene sentido de ser float, si int.

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

NUNCA pongas un delay en una interrupcion, ni tampoco funciones que tarden demasiado o innecesarias, como el floattostr().

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

Código: C
  1. if (Button(&PORTD, 0,50, 1)) {
  2.                       pid = +1 ;
  3.                           if (pid ==5) {
  4.                            pid = 0 ;
  5.                           }

pid siempre va a ser igual a 1.

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

Este error

No enought RAM for call stack

Es por que el PIC tiene una memoria limitada de "llamadas" a funcion, cada vez que el PIC llama a una funcion guarda su direccion, otros micros usan la RAM para esto lo cual lo unico que lo limita es la cantidad de RAM, el PIC posee un espacio propio, lo cual no permite demasiadas llamadas, Te doy un ejemplo aunque los nombres de las funciones no son reales.

Estoy en el main, del main uso Lcd_out, Lcd_out llama a Lcd_putc que pone caracter a caracter, Lcd_putc llama a otra funcion que es el envio de datos Lcd_dataout.
En este momento en el stack ese tengo las direcciones de Lcd_putc, Lcd_out y main.
Ocurre una interrupcion, ocupo otro lugar del stack.
En la interrupcion llamo a floattostr, esta funcion llama a uno que divide por 10 supongamos f_div10 , y esa llama a una que hace un BCD_to_ASCII.
Genial ahora tenemos f_div10 y floattostr en el stack ademas de lo anterior.

En un ratito y sin complicarnos tenemos ya 7 llamadas que deben ser guardadas. Y hay micros con incluso 8 lugares nomas o menos. Entonces el compilador te avisa que "no hay mas lugar" O que tenes que tener demasiado en cuenta que podes excederte, si estas MUY seguro no deberia darte problemas.

Desconectado D1to

  • PIC10
  • *
  • Mensajes: 39
Re:Problema al declarar variables
« Respuesta #6 en: 18 de Enero de 2017, 11:08:30 »
Muchas gracias una vez mas. lo de los decrementos es por que no deseo q los valores sean negativos. Me gustaría que el valor de p se incremente de 0.0 hasta 100 en 0.1, debo usar float?. Alguna sugerencia para no tener el problema de del espacio en ram?  Gracias una vez mas, voy a trabajar en la observaciones.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Problema al declarar variables
« Respuesta #7 en: 18 de Enero de 2017, 14:05:03 »
Muchas gracias una vez mas. lo de los decrementos es por que no deseo q los valores sean negativos. Me gustaría que el valor de p se incremente de 0.0 hasta 100 en 0.1, debo usar float?. Alguna sugerencia para no tener el problema de del espacio en ram?  Gracias una vez mas, voy a trabajar en la observaciones.

Nuevamente no es tema de RAM, es que estas llamando a muchas funciones de forma anidadas, la sugerencia es directamente no llamar a nada desde la interrupcion.

Si queres con punto entonces si o si tiene que ser float. Pero podrias simplmente usar un entero de 0 a 1000 , y cuando lo necesites ahi lo pasas a float y dividis por 10.

Desconectado D1to

  • PIC10
  • *
  • Mensajes: 39
Re:Problema al declarar variables
« Respuesta #8 en: 19 de Enero de 2017, 03:22:16 »
Muchas gracias KILLERJC, ya modifique todo el codigo y ya no tengo ninguno de esos errores, mañana lo pruebo en protobord por q en el simulador ya van tan lento q practicamente no hace nada. Si surgen mas complicaciones con las que no pueda estare publicando nuevamente