Duda con variables en ccs

El tema trasladado tenia que ver mas con comunicaion-sincronizacion que variables, pero ya que estamos Si crei que era al revés solo hace falta señalar signed y poner %d en vez de %u.
Debido a este defecto esto tambien funciona.

k16=(int16)v8 * 10; //Si esto aminora los ciclos de ejecucion biembenido
 
Hola a todos, tengo el siguiente problema y la verdad es que no se donde esta el error. Declaro en CCS una variable del tipo "long long" (tambien la he declarado como int32) y al momento de hacer las cuentas las realiza como si fuera un número de 16 bits, pero lo raro es que si me reserva los 4 bytes de memoria para la variable de 32 bits. Tanto en la simulación como en la realidad (montado en placa) funciona mal. Adjunto el código del programa, el esquemático y la simulación en Proteus 7.9. Es un control de temperatura con un sensor RTD, con medición de temperatura en el rango de 0ºC a 320ºC. El problema en si esta en el valor de la temperatura que mide y que debe mostrar en el LCD. Para minimizar el ruido, realizo una promediación de los valores medidos y luego lo muestro en el display.
Lo que hice para intentar solucionar el problema fue, abrir un nuevo proyecto, pegar el codigo y compilar y siguió igual. Luego actualice el CCS de la versión 5.059 a la versión 5.076 por si justo era algún tipo de bug, pero siguió igual.
esquematico.jpg
Código
C:
#include <16F88.h>
#device ADC=10
#use delay(internal=4000000)
#fuses nowdt,intrc_io,nomclr,nocpd,nobrownout,nolvp,noput,nodebug,nowrt,noprotect
#use fast_io(A)
#use fast_io(B)

#define BAJAR PIN_B7
#define SUBIR PIN_B5
#define ENTER PIN_B6
#define RELE PIN_B1

#define LCD_DATA_PORT getenv("SFR:PORTA")

#define LCD_ENABLE_PIN PIN_A6
#define LCD_RS_PIN PIN_A7
#define LCD_RW_PIN PIN_B3
#define LCD_DATA4 PIN_A1
#define LCD_DATA5 PIN_A2
#define LCD_DATA6 PIN_A3
#define LCD_DATA7 PIN_A4

#include <lcd.c>

// Variables globales

long mem_temp_set;
long sierra = 0;
signed long error2_ant,error2;
long long SumaLectura;
long PromLectura;
long error;
long Temp_actual_ant,Temp_actual;
long Temp_set_ant,Temp_set=50;
int i = 0;
char sys_estado[2][4]={"OFF","ON "};

enum
{
   OFF = 0,
   ON,
};

typedef struct {
   unsigned int estado;
   unsigned int estado_ant;
} SYSInfo;
SYSInfo Sys;

#Int_timer1
void Calculos (void)
{
   set_timer1(45536);
   if (sierra < 400)
   {
      sierra = sierra + 1;
   }
   else
   {
      sierra = 0;
   }
   if (sierra < error2)
   {
      output_high(rele);
   }
   else
   {
      output_low(rele);
   }
}

signed long mapeo (long x, long ent_min, long ent_max, long sal_min, long sal_max)
{
   return (x - ent_min)*(sal_max - sal_min)/(ent_max - ent_min) + sal_min;
}

void sensado_temperatura (void)
{
   if (i < 200)
   {
      SumaLectura = (SumaLectura + read_adc());
      i++;
   }
   else
   {
      PromLectura = SumaLectura/i;
      Temp_actual = (320*PromLectura)/1023;
      i = 0;
      SumaLectura = 0;
   }
}

void main()
{
   set_tris_a (0b00100001) ; // Entradas:A0,A5 - Salidas:A1,A2,A3,A4,A6,A7
   output_a (0);
   set_tris_b (0b11110000); // Entradas:B4,B5,B6,B7 - Salidas:B0,B1,B2,B3
   output_b (0);
   setup_adc_ports(sAN0|VSS_VDD);
   setup_adc(ADC_CLOCK_INTERNAL);
   set_adc_channel(0);
   lcd_init();
   lcd_gotoxy (1,1);
   printf(lcd_putc,"Control de");
   lcd_gotoxy (1,0);
   printf(lcd_putc,"temperatura");
   setup_timer_1 (T1_INTERNAL|T1_DIV_BY_1);
   mem_temp_set = make16(read_eeprom (0),read_eeprom (1));
   if (mem_temp_set < 50)
      mem_temp_set = 50;
   if (mem_temp_set > 350)
      mem_temp_set = 50;
   Temp_set = (float)mem_temp_set;
   enable_interrupts (global);
   Sys.estado_ant = ON;
   Sys.estado = OFF;
   Temp_actual = (320*read_adc())/1023;
   error = Temp_set - Temp_actual;
   error2 = mapeo(error,0,10,0,400);
   delay_ms (1000);
   for(;;)
   {
      sensado_temperatura ();
      if (Temp_set_ant != Temp_set)
      {
         Temp_set_ant = Temp_set;
         lcd_gotoxy (1,1);
         printf(lcd_putc,"TS:%3.0LuC  ",Temp_set);
      }
      if (Temp_actual_ant != Temp_actual)
      {
         Temp_actual_ant = Temp_actual;
         lcd_gotoxy (10,1);
         printf(lcd_putc,"TM:%3.0LuC",Temp_actual);
      }
      if (error2_ant != error2)
      {
         error2_ant = error2;
         lcd_gotoxy (1,0);
         printf(lcd_putc,"ERR:%4.0Ld",error2);
      }
      if (Sys.estado_ant != Sys.estado)
      {
         Sys.estado_ant = Sys.estado;
         lcd_gotoxy (9,0);
         printf(lcd_putc," SIS:%s",sys_estado[Sys.estado]);
      }
      error = Temp_set - Temp_actual;
      error2 = mapeo(error,0,10,0,400);
      if (Sys.estado == ON)
      {
         if (error < 10)
         {
            enable_interrupts (Int_timer1);
         }
         else
         {
            disable_interrupts (Int_timer1);
         }
      }
      if (input(bajar) == 0)
      {
         while(input(bajar) == 0);
         if (Temp_set > 50)
         {
            Temp_set = Temp_set - 1;
            mem_temp_set = (long)Temp_set;
            write_eeprom (0,make8(mem_temp_set,1));
            write_eeprom (1,make8(mem_temp_set,0));
         }
      }
      if (input(subir) == 0)
      {
         while(input(subir) == 0);
         if (Temp_set < 320)
         {
            Temp_set = Temp_set + 1;
            mem_temp_set = (long)Temp_set;
            write_eeprom (0,make8(mem_temp_set,1));
            write_eeprom (1,make8(mem_temp_set,0));
         }
      }
      if (input(enter) == 0)
      {
         while(input(enter) == 0);
         if (Sys.estado == ON)
         {
            disable_interrupts (Int_timer1);
            output_low (rele);
            Sys.estado = OFF;       
         }
         else
         {
            Sys.estado = ON;
            output_high (rele);
         }
      }
   }
}
 

Adjuntos

  • Control de temperatura digital y simulación.rar
    67.9 KB · Visitas: 7
El problema en si esta en el valor de la temperatura que mide y que debe mostrar en el LCD. Para minimizar el ruido, realizo una promediación de los valores medidos y luego lo muestro en el display.
Y cual es específicamente el problema???
Hay una cosa rara:
C:
      PromLectura = SumaLectura/i;
Por que SumaLectura es long long y PromLectura es long, con lo cual podés estar perdiendo una parte de la variable.

PD: Si fueras alumno mío, te reprobaba el diseño de la función sensado_temperatura
 
Y cual es específicamente el problema???
Hay una cosa rara:
C:
      PromLectura = SumaLectura/i;
Por que SumaLectura es long long y PromLectura es long, con lo cual podés estar perdiendo una parte de la variable.

PD: Si fueras alumno mío, te reprobaba el diseño de la función sensado_temperatura
La señal de la temperatura la estoy adquiriendo con el adc en 10 bits, por lo que el máximo valor que puedo obtener es 1023. Ahora en total tomó 200 muestras, que si supongo el peor caso la variable SumaLectura debe valer 1023*200 = 204600 que es mayor a un número de 16 bits, de ahí que tomo 32. Luego que tome las 200 muestras, simplemente las promedio dividiendo por la cantidad de veces que muestrie. Y cuál sería el error entonces en la funcion del sensado de temperatura?
A caso la variable PromLectura debe ser de 32 bits también?
PD: Si fueras mi profesor, tendrías que justificarme el porque estaría mal la función con fundamentación.
 
Última edición:
A caso la variable PromLectura debe ser de 32 bits también?
En teoría, el long long tiene 64 bits y el long solo tiene 32 (-->verificar con el manual del CSS, pero parece que son 32 y 16 para los micros chicos). El compilador está haciendo una conversión implícita de tipo (no te tira un warning??) de algo GRANDE a algo CHICO y en el camino puede perderse el signo...en el mejor de los casos.

PD: Si fueras mi profesor, tendrías que justificarme el porque estaría mal la función con fundamentación.
Por que usás variables globales para gestionar variables locales, con el peligro que eso conlleva. Lo entendería si se usaran en una ISR, pero claramente no es el caso, así que podrías usar variables locales estáticas - que se almacenan en el mismo lugar que las globales - sin correr el riesgo de andar publicando variables que deberían ser privadas.
 
Yo no entiendo para que usar 10 bits si con 8 funciona bastante bien una muestra de temperatura.

Yo usaría 8 bits y trabajaría a 16 bits y me quitaría muchos problemas a la mitad
 
En teoría, el long long tiene 64 bits y el long solo tiene 32 (-->verificar con el manual del CSS, pero parece que son 32 y 16 para los micros chicos). El compilador está haciendo una conversión implícita de tipo (no te tira un warning??) de algo GRANDE a algo CHICO y en el camino puede perderse el signo...en el mejor de los casos.
Pues.... viendo el manual del CCS, en ningun lado dice que para micros chicos o grandes se usen diferentes tamaños para las declaraciones de las variables, es general.
Variables.jpg
No será a caso que te confundes con Arduino?, allí si las variables int son de 16 bits y las long son de 32bits.
Por que usás variables globales para gestionar variables locales, con el peligro que eso conlleva. Lo entendería si se usaran en una ISR, pero claramente no es el caso, así que podrías usar variables locales estáticas - que se almacenan en el mismo lugar que las globales - sin correr el riesgo de andar publicando variables que deberían ser privadas.
Entiendo, pero eso creo que queda a criterio del programador, siempre y cuando tenga en claro que las variables tienen relevancia en todo el programa, con lo que eso puede ser un problema en algunos casos. Pero lo de usar variables locales es sólo un enfoque, y no es el único para resolver el mismo problema, y si lo que implemento resuelve mi problema, y no genera uno nuevo, entonces mi método también es válido, y por lo tanto no estaría mal. Ahora si hablamos de buenas prácticas de programación, eso ya es otro tema, del cual en este caso no estamos abordando en principio.
Yo no entiendo para que usar 10 bits si con 8 funciona bastante bien una muestra de temperatura.

Yo usaría 8 bits y trabajaría a 16 bits y me quitaría muchos problemas a la mitad
Si en un momento me lo plantié, pero resulta que perdía mucha resolución, ya que con 255 valores para un rango de 0 a 320 grados, tenía que usar más de 1 bit para representar 1 grado. A diferencia de que con los 10 bits con casi 4 bits obtengo 1 grado. Era un desperdicio de bits que no me quería perder.

Bueno, de todas formas ya resolví el problema, lo solucioné de la siguiente manera, antes tenía declaradas las variables de la siguiente forma:
C:
long long SumaLectura;
long PromLectura;
long Temp_actual_ant,Temp_actual;
Y ahora amplié las variables a que sean todas de 32 bits así, y se resolvió el problema:
C:
long long SumaLectura;
long long PromLectura;
long long Temp_actual_ant,Temp_actual;

Gracias a todos por interesarse en el tema, tomarse el tiempo de escribir e impartir su punto de vista o parecer al respecto del tema, así es como un foro se hace grande, con aporte que eriquescan y sirvan para otras personas.
 
Última edición:
Tienes razón el problema de ccs es que no es estándar.
No lo es por el simple hecho de hacer uso de long long 32 bits y eso de int1 o int16 no va en cualquier compilador C.

A mi me gusta por qué es fácil de usar pero si es de reciclar código para otro compilador hay que hacer uso de ANSI C.
 
Lo bueno es que eso se puede cambiar al estándar, declarando #type
Por ejemplo:
#type short=8, int=16, long=32
Con #type signed se asume que todas las variables sean con signo y habrá que cambiarlas con unsigned.
Y si se requiere distinción entre mayúsculas y minúsculas, se declara #case
 
Pero lo de usar variables locales es sólo un enfoque, y no es el único para resolver el mismo problema, y si lo que implemento resuelve mi problema, y no genera uno nuevo, entonces mi método también es válido, y por lo tanto no estaría mal.
El problema con ese tipo de opiniones es que valen para una charla personal, pero no tanto en un foro público consultado por miles de personas, ya que induce a pensar que es lo mismo resolver el problema de cualquier forma....y en verdad no lo es: Hay UNA (o muy pocas) forma de hacerlo bien y CIENTOS de formas de hacerlo regular o mal. Cualquiera de ellas puede resultar en un bloque de código que "funcione", pero eso no significa que se haya usado la solución correcta.

Hace unos pocos días un par de alumnos, formados en una escuela técnica, me plantearon algo muy parecido a esta charla...aún cuando varios meses antes les había advertido que debían olvidarse de la forma de "construcción" de software que habían aprendido en la escuela por que tenía muchas fallas conceptuales y estructurales. Pues bueno, llegó la evaluación y los tuve que reprobar por que aunque el código "funcionaba" lo que habían diseñado era un engendro que ocupaba un 50% más código que el necesario (lo que no importa tanto) a la vez que destruía la operación coherente de las estructuras de control de flujo que debían usar (y eso es muy serio). Cuando me consultaron el motivo de la nota se los expliqué muy facilmente: "Uds vienen a clase y yo les enseño que los clavos se clavan con un martillo y que los tornillos se ajustan con un destornillador. Luego, cuando vienen a rendir la evaluación me dicen: a nosotros nos gusta poner los clavos con la llave inglesa por que total, si queda puesto nos soluciona el problema y no tenemos que buscar en los libros. Ahora, yo les muestro que mellaron toda la llave inglesa, que el clavo quedó doblado y que no pudieron controlar la profundidad de la inserción, ergo... vuelvan cuando aprendan a usar correctamente las herramientas de las que disponen." ;)

Ahora si hablamos de buenas prácticas de programación, eso ya es otro tema, del cual en este caso no estamos abordando en principio.
Es que no es necesario abordar el tema de las buenas prácticas de programación por que siempre está subyacente en el diseño de software y es lo que soporta y dá solidez a la solución desarrollada. No tenerlas en cuenta es como construir una casa con cimientos de hielo: mientras hace frío se mantiene en pié... pero no sé que va a pasar cuando llegue el verano. ;)
 
Tienes razón Dr yo no soy maestro me hubiera gustado serlo pero en mi antiguo trabajo y en el actual veo como resuelven mal los problemas y si hay soluciones
La correcta, la buena ,la regular, la mala y la mejor ya no le metas mano.
 
Atrás
Arriba