Autor Tema: Reducción de Memoria ROM  (Leído 5471 veces)

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

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Reducción de Memoria ROM
« en: 08 de Septiembre de 2018, 03:31:00 »
Buen día amigos, aquí desvelándome un poco en busca de la solución a este Proyecto.

Bien, pues me encuentro en un gran dilema desarrollando una aplicación con un PIC18F4550, y es que tengo una rutina, la cual me esta consumiendo mucha memoria ROM, me gustaría saber la manera de hacerlo de una manera que consuma menos ROM.

Aquí lo que me consume mucha memoria:


Código: C#
  1. if ((AD>ADx[1])&&(AD<=ADx[2]))  Tm = (AD*(Tx[1]-Tx[2])   - Tx[1]*ADx[2]   + ADx[1]*Tx[2])/(ADx[1]-ADx[2]);          
  2.       if ((AD>ADx[2])&&(AD<=ADx[3]))   Tm = (AD*(Tx[2]-Tx[3])   - Tx[2]*ADx[3]   + ADx[2]*Tx[3])/(ADx[2]-ADx[3]);          
  3.       if ((AD>ADx[3])&&(AD<=ADx[4]))   Tm = (AD*(Tx[3]-Tx[4])   - Tx[3]*ADx[4]   + ADx[3]*Tx[4])/(ADx[3]-ADx[4]);            
  4.       if ((AD>ADx[4])&&(AD<=ADx[5]))   Tm = (AD*(Tx[4]-Tx[5])   - Tx[4]*ADx[5]   + ADx[4]*Tx[5])/(ADx[4]-ADx[5]);            
  5.       if ((AD>ADx[5])&&(AD<=ADx[6]))   Tm = (AD*(Tx[5]-Tx[6])   - Tx[5]*ADx[6]   + ADx[5]*Tx[6])/(ADx[5]-ADx[6]);            
  6.       if ((AD>ADx[6])&&(AD<=ADx[7]))   Tm = (AD*(Tx[6]-Tx[7])   - Tx[6]*ADx[7]   + ADx[6]*Tx[7])/(ADx[6]-ADx[7]);            
  7.       if ((AD>ADx[7])&&(AD<=ADx[8]))   Tm = (AD*(Tx[7]-Tx[8])   - Tx[7]*ADx[8]   + ADx[7]*Tx[8])/(ADx[7]-ADx[8]);            
  8.       if ((AD>ADx[8])&&(AD<=ADx[9]))   Tm = (AD*(Tx[8]-Tx[9])   - Tx[8]*ADx[9]   + ADx[8]*Tx[9])/(ADx[8]-ADx[9]);          
  9.       if ((AD>ADx[9])&&(AD<=ADx[10]))  Tm = (AD*(Tx[9]-Tx[10])  - Tx[9]*ADx[10]  + ADx[9]*Tx[10])/(ADx[9]-ADx[10]);        
  10.       if ((AD>ADx[10])&&(AD<=ADx[11])) Tm = (AD*(Tx[10]-Tx[11]) - Tx[10]*ADx[11] + ADx[10]*Tx[11])/(ADx[10]-ADx[11]);      
  11.       if ((AD>ADx[11])&&(AD<=ADx[12])) Tm = (AD*(Tx[11]-Tx[12]) - Tx[11]*ADx[12] + ADx[11]*Tx[12])/(ADx[11]-ADx[12]);      
  12.       if ((AD>ADx[12])&&(AD<=ADx[13])) Tm = (AD*(Tx[12]-Tx[13]) - Tx[12]*ADx[13] + ADx[12]*Tx[13])/(ADx[12]-ADx[13]);        
  13.       if ((AD>ADx[13])&&(AD<=ADx[14])) Tm = (AD*(Tx[13]-Tx[14]) - Tx[13]*ADx[14] + ADx[13]*Tx[14])/(ADx[13]-ADx[14]);          
  14.       if ((AD>ADx[14])&&(AD<=ADx[15])) Tm = (AD*(Tx[14]-Tx[15]) - Tx[14]*ADx[15] + ADx[14]*Tx[15])/(ADx[14]-ADx[15]);          
  15.       if ((AD>ADx[15])&&(AD<=ADx[16])) Tm = (AD*(Tx[15]-Tx[16]) - Tx[15]*ADx[16] + ADx[15]*Tx[16])/(ADx[15]-ADx[16]);          
  16.       if ((AD>ADx[16])&&(AD<=ADx[17])) Tm = (AD*(Tx[16]-Tx[17]) - Tx[16]*ADx[17] + ADx[16]*Tx[17])/(ADx[16]-ADx[17]);          
  17.       if ((AD>ADx[17])&&(AD<=ADx[18])) Tm = (AD*(Tx[17]-Tx[18]) - Tx[17]*ADx[18] + ADx[17]*Tx[18])/(ADx[17]-ADx[18]);          
  18.       if ((AD>ADx[18])&&(AD<=ADx[19])) Tm = (AD*(Tx[18]-Tx[19]) - Tx[18]*ADx[19] + ADx[18]*Tx[19])/(ADx[18]-ADx[19]);          
  19.       if ((AD>ADx[19])&&(AD<=ADx[20])) Tm = (AD*(Tx[19]-Tx[20]) - Tx[19]*ADx[20] + ADx[19]*Tx[20])/(ADx[19]-ADx[20]);          
  20.       if ((AD>ADx[20])&&(AD<=ADx[21])) Tm = (AD*(Tx[20]-Tx[21]) - Tx[20]*ADx[21] + ADx[20]*Tx[21])/(ADx[20]-ADx[21]);          
  21.       if ((AD>ADx[21])&&(AD<=ADx[22])) Tm = (AD*(Tx[21]-Tx[22]) - Tx[21]*ADx[22] + ADx[21]*Tx[22])/(ADx[21]-ADx[22]);          
  22.       if ((AD>ADx[22])&&(AD<=ADx[23])) Tm = (AD*(Tx[22]-Tx[23]) - Tx[22]*ADx[23] + ADx[22]*Tx[23])/(ADx[22]-ADx[23]);          
  23.       if ((AD>ADx[23])&&(AD<=ADx[24])) Tm = (AD*(Tx[23]-Tx[24]) - Tx[23]*ADx[24] + ADx[23]*Tx[24])/(ADx[23]-ADx[24]);          
  24.       if ((AD>ADx[24])&&(AD<=ADx[25])) Tm = (AD*(Tx[24]-Tx[25]) - Tx[24]*ADx[25] + ADx[24]*Tx[25])/(ADx[24]-ADx[25]);          
  25.       if ((AD>ADx[25])&&(AD<=ADx[26])) Tm = (AD*(Tx[25]-Tx[26]) - Tx[25]*ADx[26] + ADx[25]*Tx[26])/(ADx[25]-ADx[26]);          
  26.       if ((AD>ADx[26])&&(AD<=ADx[27])) Tm = (AD*(Tx[26]-Tx[27]) - Tx[26]*ADx[27] + ADx[26]*Tx[27])/(ADx[26]-ADx[27]);          
  27.       if ((AD>ADx[27])&&(AD<=ADx[28])) Tm = (AD*(Tx[27]-Tx[28]) - Tx[27]*ADx[28] + ADx[27]*Tx[28])/(ADx[27]-ADx[28]);          
  28.       if ((AD>ADx[28])&&(AD<=ADx[29])) Tm = (AD*(Tx[28]-Tx[29]) - Tx[28]*ADx[29] + ADx[28]*Tx[29])/(ADx[28]-ADx[28]);          
  29.       if ((AD>ADx[29])&&(AD<=ADx[30])) Tm = (AD*(Tx[29]-Tx[30]) - Tx[29]*ADx[30] + ADx[29]*Tx[30])/(ADx[29]-ADx[30]);          
  30.       if ((AD>ADx[30])&&(AD<=ADx[31])) Tm = (AD*(Tx[30]-Tx[31]) - Tx[30]*ADx[31] + ADx[30]*Tx[31])/(ADx[30]-ADx[31]);          
  31.       if ((AD>ADx[31])&&(AD<=ADx[32])) Tm = (AD*(Tx[31]-Tx[32]) - Tx[31]*ADx[32] + ADx[31]*Tx[32])/(ADx[31]-ADx[32]);          
  32.       if ((AD>ADx[32])&&(AD<=ADx[33])) Tm = (AD*(Tx[32]-Tx[33]) - Tx[32]*ADx[33] + ADx[32]*Tx[33])/(ADx[32]-ADx[33]);          
  33.       if ((AD>ADx[33])&&(AD<=ADx[34])) Tm = (AD*(Tx[33]-Tx[34]) - Tx[33]*ADx[34] + ADx[33]*Tx[34])/(ADx[33]-ADx[34]);          
  34.       if ((AD>ADx[34])&&(AD<=ADx[35])) Tm = (AD*(Tx[34]-Tx[35]) - Tx[34]*ADx[35] + ADx[34]*Tx[35])/(ADx[34]-ADx[35]);

     Estaba pensando de la siguiente manera para acortar tantos if y hacerlo con un Ciclo For de la siguiente forma:

   
Código: C
  1. int n=1;

Código: C#
  1. for(ADx[n]; ADx[n]<ADx[36-n]; ADx[n++])
  2.       {
  3.       if ((AD>=ADx[n])&&(AD<=ADx[n+1])) Tm = (AD*(Tx[n]-Tx[n+1]) - Tx[n]*ADx[n+1] + ADx[n]*Tx[n+1])/(ADx[n]-ADx[n+1]);
  4.       }

Tratando de hacerlo con un Ciclo For para recorrer cada numero de 1 al 34 o del 2 al 35 no resulto,  pero me aparece un warning en CCS al compilar, donde me dice que el código no es efectuado.

>>> Warning 207 "SENSOR4.c" Line 34(1,1): Code has no effect

Y ese Warning apunta presisamente al ciclo for

Agradezco su tiempo en leer el tema y espero me puedan ayudar

.
« Última modificación: 08 de Septiembre de 2018, 03:40:11 por Abner_emanuel »
El señor es mi pastor,  nada me faltará.

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3520
    • Pinballsp
Re:Reducción de Memoria ROM
« Respuesta #1 en: 08 de Septiembre de 2018, 04:27:01 »

Te ha quedado un for raro,  prueba así. Lo unico que tienes que variar en el bucle es el contador n como índice  de la matriz, no el contenido de la matriz.

Código: C++
  1. for(int n=1; n<35; n++)
  2. {
  3.      if ((AD>=ADx[n])&&(AD<=ADx[n+1])) Tm = (AD*(Tx[n]-Tx[n+1]) - Tx[n]*ADx[n+1] + ADx[n]*Tx[n+1])/(ADx[n] - ADx[n+1]);
  4. }
« Última modificación: 08 de Septiembre de 2018, 04:43:04 por planeta9999 »

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Re:Reducción de Memoria ROM
« Respuesta #2 en: 08 de Septiembre de 2018, 09:56:43 »
Muchas gracias Planeta9999 se a eliminado el Warning :-/  tal como propones el ciclo for

Solo me queda una duda...

Código: C++
  1. for(int n=1; n<35; n++)
  2. {
  3.      if ((AD>=ADx[n])&&(AD<=ADx[n+1])) Tm = (AD*(Tx[n]-Tx[n+1]) - Tx[n]*ADx[n+1] + ADx[n]*Tx[n+1])/(ADx[n] - ADx[n+1]);
  4. }

La duda es si esta terminando de la siguiente manera el ford

Código: C++
  1. for(int n=1; n<35; n++)
  2. {
  3.      if ((AD>=ADx[1])&&(AD<=ADx[2])) Tm = (AD*(Tx[1]-Tx[2]) - Tx[1]*ADx[2] + ADx[1]*Tx[2])/(ADx[1] - ADx[2]);
  4.                                                                              
  5.                                                             .
  6.                                                             .
  7.                                                             .
  8.                                                             .
  9.                                                             .
  10.  
  11.      if ((AD>=ADx[34])&&(AD<=ADx[35])) Tm = (AD*(Tx[34]-Tx[35]) - Tx[34]*ADx[35] + ADx[34]*Tx[35])/(ADx[34] - ADx[35]);
  12. }

Ya que el FOR esta limitado a <35 que es 34. Es decir al final del for estará haciendo:

if ((AD>=ADx[n])&&(AD<=ADx[n+1])) igual a  if ((AD>=ADx[34])&&(AD<=ADx[35])) aunque el for este limitado a 34?.

Espero haberme dado a entender..


« Última modificación: 08 de Septiembre de 2018, 10:00:58 por Abner_emanuel »
El señor es mi pastor,  nada me faltará.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Reducción de Memoria ROM
« Respuesta #3 en: 08 de Septiembre de 2018, 09:58:53 »
Voy a reformular un poco el for de planeta

Código: C
  1. for(int n=35; n>1; n--)
  2. {
  3.      if ((AD>=ADx[n-1])&&(AD<=ADx[n])) Tm = (Tx[n-1]*( AD - ADx[n]) + Tx[n]*(ADx[n-1] - AD)) / (ADx[n-1] - ADx[n]); break;
  4. }

El porque lo hice es porque tu codigo prioriza siemrpe el ultimo resultado, no tiene sentido que pase por los 30 primeros if calculando todo, si el 31 se calcula y guarda nuevamente Tm con ese resultado. Ya que no se acumula ni nada por el estilo. Asi que comenzar desde el ultimo, y cuando apenas ocurre opino que es lo mejor.
Por otro lado reacomode un poco los terminos de la ecuacion. Asi quedan 2 multiplicaciones y no 3 en el dividendo.

Citar
Ya que el FOR esta limitado a <35 que es 34. Supongo que silo hace, pregunto para estar seguro.

Llega hasta 34 n, pero con el n+1 lo hace 35.

Lo mismo con el for que presento, n si es mayor a 1, llega hasta n=2, pero con el n-1 queda en 1.
« Última modificación: 08 de Septiembre de 2018, 10:07:30 por KILLERJC »

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Re:Reducción de Memoria ROM
« Respuesta #4 en: 08 de Septiembre de 2018, 10:10:48 »

KILLERJC un saludo.

A quedad quitando sin el break;, aunque la forma en que recorrió el for Planeta9999 también funciono bien en el proteus.

Ahora solo tenia la duda de que si estaba terminando con 34 y 35 intercalados como lo dice la ecuación, pero creo que a quedado claro con lo tuyo.
El señor es mi pastor,  nada me faltará.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Reducción de Memoria ROM
« Respuesta #5 en: 08 de Septiembre de 2018, 11:34:01 »
Es que el break es lo importante de mi codigo. Sino NO es lo mismo que tu codigo.

Voy a explicarme nuevamente. Tu codigo resumido y simplificado para que sirva como ejemplo es algo asi:

Código: C
  1. if(condicion1) Tm = 1
  2. if(condicion2) Tm = 2
  3. if(condicion3) Tm = 3
  4. if(condicion4) Tm = 4
  5. if(condicion5) Tm = 5
  6. if(condicion6) Tm = 6

Si lo hacemos un for como el de planeta va a ser lo mismo, Lo que estas haciendo vos es cambiar el valor de Tm segun entra o no en el if. Supongamos que condicion1 , el 3 y 6 se cumplen.Primero entra al if de la condicion1 y queda Tm = 1, luego entra al de la condicion3 y termina con Tm = 3, y finalmente a la condicion6.
Cual es el resultado de Tm al final de eso? Tm = 6. ¿Importo que yo calcule el del 1 y el del 3? NO, solo el ultimo
Otro ejemplo. Que pasa si condicion2 y 5 se cumplen. ¿Cual es el resultado de Tm?, es Tm = 5.

Porque es el ULTIMO en asignarle el valor a Tm el que IMPORTA. Asi que al final, lo que importa no es pasar por todos, sino saber cual es el ultimo de todos los casos que cumplen la condicion. Y una ves encontrado no seguir mas.
Entonces ¿para que voy a gastar tiempo calculando lo de las condiciones anteriores si solo me interesa el ultimo? Por eso mismo mi for comienza desde el ultimo, y apenas asigna el valor de Tm sale del for con el break, sino daria un valor erroneo. El resultado de mi codigo deberia ser el mismo que el tuyo y que el de planeta, es decir Tm deberia tener el mismo valor al salir del for.

Si solo uno solo entraria, sigue siendo mejor ir de atras hacia el 1, debido a que termina siendo mas rapido.
« Última modificación: 08 de Septiembre de 2018, 11:40:49 por KILLERJC »

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Reducción de Memoria ROM
« Respuesta #6 en: 08 de Septiembre de 2018, 12:31:33 »
Si no me equivoco, se trata de una rutina de interpolación con varios tramos.
Si los tramos son equidistantes, se puede simplificar más.

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Re:Reducción de Memoria ROM
« Respuesta #7 en: 08 de Septiembre de 2018, 12:34:23 »
Ahora mas claro KillerJC. Solo que compile el código con el break; y no me mostró nada en la LCD, o mejor dicho me mostró el valor en cero (000) y no el valor deseado. Es por eso que quite el break.

Picuino así es, cual es tu idea respecto a esto.
« Última modificación: 08 de Septiembre de 2018, 12:36:43 por Abner_emanuel »
El señor es mi pastor,  nada me faltará.

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Re:Reducción de Memoria ROM
« Respuesta #8 en: 08 de Septiembre de 2018, 12:47:52 »
El código consumía 68 de ROM como inicialmente lo tenia, ahora con el ciclo for consume 16% de la ROM  del PIC18F. Genial por que así puedo escribir mas code. Jejeje  :mrgreen:
« Última modificación: 08 de Septiembre de 2018, 13:06:54 por Abner_emanuel »
El señor es mi pastor,  nada me faltará.

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3520
    • Pinballsp
Re:Reducción de Memoria ROM
« Respuesta #9 en: 08 de Septiembre de 2018, 12:53:39 »
Ahora mas claro KillerJC. Solo que compile el código con el break; y no me mostró nada en la LCD, o mejor dicho me mostró el valor en cero (000) y no el valor deseado. Es por eso que quite el break.


Para que ese break funcione, falta que el resultado del IF esté entre llaves, si no se sale de inmediato en la primera comprobación, se cumpla o no.

Así te debería de funcionar.

Código: C++
  1. for(int n=35; n>1; n--)
  2. {
  3.      if ((AD>=ADx[n-1])&&(AD<=ADx[n]))
  4.       {
  5.           Tm = (Tx[n-1]*( AD - ADx[n]) +
  6.                 Tx[n]*(ADx[n-1] - AD)) / (ADx[n-1] - ADx[n]);
  7.           break;
  8.       }
  9. }

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Re:Reducción de Memoria ROM
« Respuesta #10 en: 08 de Septiembre de 2018, 13:44:13 »
Genios locos!!!. Y yo que pensaba emigrarlo a otro PIC. Agradezco su ayuda KillerJC y Planeta9999.
El señor es mi pastor,  nada me faltará.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Reducción de Memoria ROM
« Respuesta #11 en: 08 de Septiembre de 2018, 13:45:33 »
Si.. me comi las llaves por estar haciendo otra cosa. Como dice planeta es lo correcto.

Si no me equivoco, se trata de una rutina de interpolación con varios tramos.
Si los tramos son equidistantes, se puede simplificar más.

El tema es que por lo que veo son unicamente "variables" por eso no puedo suponer que se cumpla.
Tambien otra forma de realizarlo es no usar 2 indices como lo estamos haciendo, sino que cada vuelta apunte a un unico indice e incremente de a 1, pienso que seria mas rapido de realizar. De todas formas si hay problemas de espacio, seguramente esto no sea lo unico ni lo indispensable.

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Reducción de Memoria ROM
« Respuesta #12 en: 08 de Septiembre de 2018, 14:36:25 »
1° Comprobar si AD se sale de la tabla. Fuera del bucle, con 2 if

2° recorrer la tabla con el for y hacer una sola comprobacion de «mayor que» en el if, no 2. Con esto se establece el índice i y se sale del bucle sin calcular nada.

3° Calcular Tm con el índice i. Sustituir las diferencias de ADx por un valor fijo o por una variable con la diferencia precalculada.

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Reducción de Memoria ROM
« Respuesta #13 en: 08 de Septiembre de 2018, 14:46:55 »
Ciertos compiladores trabajan muy mal con tablas y es mucho más eficiente trabajar con punteros. Prueba a cambiar a punteros el bucle. Si mejora, intenta cambiar todo lo que puedas a punteros.

Saludos.

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:Reducción de Memoria ROM
« Respuesta #14 en: 08 de Septiembre de 2018, 14:57:09 »
Si la tabla con los valores de ADx(i) está ordenada, es decir ADx(i) < ADx(i+1) , podés simplificar mas la comparación:

Código: [Seleccionar]
      for(i = 34 ; AD <= ADx(i) ; i--) ;
      Tm = (AD*(Tx[i]-Tx[i+1]) - Tx[i]*ADx[i+1] + ADx[i]*Tx[i+1])/(ADx[i]-ADx[i+1]) ;

Tal como estaba implícito en tu programa,  ADx(1)  es el mínimo valor posible pero que nunca se alcanza ==> siempre termina el for.

Si esta operación fuera de uso intensivo te va a convenir cargar unas tablas para ahorrar multiplicaciones entre constantes.
 
Fijate que  Tm = (AD*(Tx-Tx[i+1j]) - Tx*ADx[i+1] + ADx*Tx[i+1])/(ADx-ADx[i+1]); 

es equivalente a  Tm = Z(i) + M(i)*AD

con  M(i) = (Tx-Tx[j])/(ADx-ADx[j])
y    Z(i) = (ADx*Tx[j]) - Tx*ADx[j])/(ADx-ADx[j])

O sea, previamente te armás esas tablas y después hacés

Código: [Seleccionar]
     for(i = 34 ; AD <= ADx(i) ; i--) ; 
      Tm = Z(i) + M(i)*AD ;