Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:
Hola, necesito alguien que pueda decirme donde puedo conseguir información bien detallada de cómo hacer una función para calcular el seno y el coseno en un microcontrolador PIC 16f84.
Muchas Gracias
CEVR
En ccs la funcion seno es:
val = sin (rad)
por ejemplo:
x=sin(3.14/2)
La funcion coseno es:
val = cos (rad)
Ademas tienes todas estas:
SIN ()
COS()
TAN()
ASIN()
ACOS()
ATAN()
SINH()
COSH()
TANH()
ATAN2()
Yo ya abordé ese problema hace tiempo, intentándolo por la vía matemática directa sin mucho resultado. Al final opté por emplear una tabla en memoria a fin de agilizar los cálculos. Te recomiendo que uses un PIC con más memoria... al menos un 16F876. El método consiste en introducir en la eeprom la tabla del seno o la del coseno. Como tenemos poca memoria, introduciremos sólo un cuadrante... por ejemplo entre 0 y 90º... A partir de ahí, dependiendo de la resolución que quieras, deberás usar más o menos bytes para representar cada ángulo.
Por ejemplo, si tienes 256 bytes de EEPROM, supongamos que usamos 16 bits para tener senos con 4 decimales... Esto quiere decir que al usar 16 bits disponemos de la mitad de palabras... 128... para almacenar senos en la tabla. Como son 128 posiciones, podemos calcular senos que se diferencien de otros en incrementos de: 90/128 = 0.70º... o sea ... 0º ... 0,70º ... 1,40º... etc, hasta 90. Si tenemos que calcular el SEN(2)... el más cercano en nuestra tabla será el SEN(2.1)... por supuesto... hay un pequeño error... pero es el precio que hay que pagar por hacer cálculos trigonométricos con rapidez en un PIC.
Cómo organizar la tabla?... Como tenemos número de 16 bits y la memoria está dividida por bytes... una forma de organizarla podría ser colocando en la primera posición la parte alta del byte y en la siguiente la parte baja. Podemos suponer que, dado que vamos a usar 4 decimales, almacenaremos números de 5 dígitos... un número entero que como mucho será 1, y la parte decimal. Por ejemplo... el SEN(0) = 0, que en binario es 00000000 00000000. El SEN(0.70)=0.0122, que en binario es 00000000 01111010. El SEN(1.4)=0.0244, que en binario es 00000000 11110100.... Todo esto almacenado en la EEPROM podría ir:
DIRECCIÓN GRADOS DEL SENO VALOR BINARIO
00 HEX_____________0º______________00000000 (parte alta)
01 HEX_____________0º______________00000000 (parte baja)
02 HEX_____________0.7º____________00000000 (parte alta)
03 HEX_____________0.7º____________01111010 (parte baja)
04 HEX_____________1.4º____________00000000 (parte alta)
05 HEX_____________1.4º____________11110100 (parte baja)
Para encontrar el seno de un ángulo mayor de 90 debes aprovecharte de la simetría de los cuadrantes. Por ejemplo, para calcular el seno de un ángulo entre 90 y 128, observa en la gráfica del seno, que dos ángulos que disten lo mismo en el eje X de 90º (por delante y por detrás) tienen el mismo seno... Por ejemplo, el seno de 20º (que está en el primer cuadrante) da lo mismo que el seno de [(90º-20º)+90º]= 160º que está en el segundo cuadrante. Igualmente, debes aprovechar el hecho del desfase existente entre seno y coseno para hallar este último con la tabla del seno...
SALUDOS
Si no dispones de las librerías de las que abla Mif, porque trabajas en ensamblador u otra razón, puedes usar una tabla. Haces una tabla de 360 valores float (o de la precisión que quieras) en la que cada valor crresponda al seno o coseno de un grado. El problema es la precisión, que está limitada a 1 grado (para 1/2 grado se hace una tabla del doble de valores) y la cantidad de memoria que consume. Haces la tabla del seno, por ejemplo, y el coseno lo obtienes por trigonometría: cos (90 - α) = sen α.
Seria algo así:
float TablaSeno[360] = {0, 0.0174, 0.034...... ....-0.1745, 0);
float Sin (int grados)
{
return TablaSeno[grados];
}
También se puede calentar uno la cabeza y hacer solo la tabla de 90 grados (1 cuadrante) y obtener a partir de esta tabla los senos y cosenos del resto de cuadrantes. (Hay que ponerse al día en trigonometría).
O, lo más sofisticado, si son datos que no tienen relación con senos y cosenos del mundo real, inventar una nueva trigonometría binaria basada en circunferencias de 256 grados etc. Es parecisdo a lo que hacen las tarjetas aceleradoras gráficas para el cálculo de perspectivas, como los datos solo existen en la pantalla no tienen por que usar la trigonometría convencional.
Hay muchas formas de hacerlo. Las librerías que incluye el C son de mucha precisión pero muy lentas de procesar, mal rollo para tiempo real.
En el foro del compilador CCS hay muchos recursos interesantes, por ejemplo:
http://www.ccsinfo.com/forum/viewtopic . ... hlight=cos
Yo también lo utilicé en una ocasión y recurrí a la tabla, aunque en mi caso fui más bruto y sólo cargué resultados de 45º.
Si tienes esa información puedes reconstruir cualquier dato en los 360º porque se repiten 8 veces.
Los senos de 0º a 45º equivalen a los cosenos de 46º a 90º y viceversa. En los otros tres cuadrantes sólo tienes que cambiar de signo.