Autor Tema: Duda de función ((seno 0°)*127)+127 = 127  (Leído 7808 veces)

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

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Duda de función ((seno 0°)*127)+127 = 127
« en: 24 de Diciembre de 2018, 11:39:51 »
Hace tiempo alguien publicó de manera general la forma de generar una onda seno con un pic. Del cual me surge una duda y recurro a ustedes.

Esto es lo que escribió esa persona:

Citar

Utilizo una resolución en el PWM de 8 bits (256 niveles de tensión). Lo que intento hacer es que estos niveles (salida PWM) varíen en el tiempo para describir una señal seno.
Primero elijo que resolución en frecuencia deseo darle a la "salida seno", es decir cuantos niveles de tensión deseas tener en un ciclo de la senoide, esto lo hago cada 5,625 grados eléctricos (el ciclo completo es 2pi=360 grados) por lo cual tendre 64 niveles distintos.
Para realizar lo anterior debo tener una salida PWM (obvio) y un timer que es el que te actualizará el valor del duty cycle de la salida.

Entonces calculo el tiempo en el que el timer debe recalcular el duty cycle de la salida.
Lla frecuencia de la seno es 60Hz por lo tanto:
el período es  ------>60 Hz = (1/60)seg = 16,67 ms

esto es lo que dura un período de la seno, como lo actualizamos cada 5,625 grados tendremos 64 niveles y cada uno durará:
Tiempo del timer ----> Tt = período / 64 = 16,67 / 64 = 260,468 Useg
Estos 260 Useg es cada cuanto debes recalcular el duty cycle del PWM.

Ahora bien, para calcular este duty cycle habría que calcular el seno de 5,625 grados, el de 11,25... hasta el de 360 grados y nuevamente el seno de 5,625.....y asi eternamente, esto es muy complejo de realizar con un microcontrolador de 8 bits. Lo que se hace es colocar los 64 resultados en una tabla, e irlos leyendo con la frecuencia que te da el timer que acabamos de calcular.

Luego los valores de la tabla serán:

para 0o = ((seno 0o)*127)+127 = 127
para 5,625o = ((seno 5,625o)*127)+127 = 139,44
para 11,25o = ((seno 11,25o)*127)+127 = 151,77
.
.
para 90o = ((seno 90o)*127)+127 = 254
.
.
para 180o = ((seno 270o)*127)+127 = 127
.
.
para 270o = ((seno 270o)*127)+127 = 0
.
.
para 360o = ((seno 360o)*127)+127 = 127




Bien, pues mi duda es de donde sale la fórmula:

0° = ((seno 0°)*127)+127 = 127

Me explicó mejor; ¿por que al sen0° lo multiplica por 127 y le suma 127?. Y esto es en todos los cálculos. 

Alguien que me oriente por favor, desde ya le agradezco.


« Última modificación: 29 de Diciembre de 2018, 12:03:27 por Abner_emanuel »
El señor es mi pastor,  nada me faltará.

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:Duda de función ((seno 0°)*127)+127 = 127
« Respuesta #1 en: 24 de Diciembre de 2018, 12:11:19 »
...
Bien, pues mi duda es de donde sale la fórmula:

0° = ((seno 0°)*127)+127 = 127

Me explicó mejor; ¿por que al sen0° lo multiplica por 127 y le suma 127?. Y esto es en todos los cálculos. 
...

La función seno varía entre [-1,1]  y se está necesitando una tabla donde los valores varíen entre [0, 255] -->  pues hago una transformación  y = a*seno+b   con a,b tales que encaje lo mejor posible en [0, 255]

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Re:Duda de función ((seno 0°)*127)+127 = 127
« Respuesta #2 en: 24 de Diciembre de 2018, 15:21:44 »
Eduardo2 gracias por responder pero no entendí muy bien. Quiere decir que de los 254 valores parte distribuyendo los valores a la mitad para 127. Pero por que la multiplicación y la suma?. Es una especie de regla de 3?.
El señor es mi pastor,  nada me faltará.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Duda de función ((seno 0°)*127)+127 = 127
« Respuesta #3 en: 24 de Diciembre de 2018, 16:16:19 »
Como te dijo... lo voy a tratar de explicar mejor...

La funcion seno devuelve un valor que va desde -1 a 1. Pero vos necesitas un valor de 0 a 255, es por eso que intenta aproximarlo como una ecuacion lineal, pensandolo en un grafico como los puntos [-1,0] y [1,254] obtendrias la linea que atravieza esos 2 puntos, en arduino le llaman map a la utilidad que te calcula ya de por si esto... Podes hacerlo con wolfram alpha si no te acordas las formulas de una funcion lineal:

Aca link al wolframalpha

Es decir intenta hacer corresponder (observando los valores limites) que el -1 termine devolviendo 0, y el +1 le devuelva lo mas proximo a 255 ( 254 en este caso, ya que 255 seria trabajar con numeros flotantes).

Para eso el termina multiplicando lo que le devuelve la funcion seno por 127 y luego le suma 127,
Analizalo en ciertos puntos, pensa que

Si el seno es -1 tendrias -127 luego de la multiplicacion, y luego al sumarle 127 queda en 0
Si el seno es 0 tendrias 0 luego de la multiplicacion, y luego al sumarle 127 queda en 127 ( la mitad aproximadamente)
Si el seno es 1 tendrias 127 luego de la multiplicacion, y luego al sumarle 127 queda en 254 ( el maximo)
« Última modificación: 24 de Diciembre de 2018, 16:18:50 por KILLERJC »

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Re:Duda de función ((seno 0°)*127)+127 = 127
« Respuesta #4 en: 24 de Diciembre de 2018, 16:29:10 »
:o  ((:-)) ahora si!!.  Me queda claro. Gracias  siempre encuentro respuestas en el foro. Nuevamente gracias.
El señor es mi pastor,  nada me faltará.

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Re:Duda de función ((seno 0°)*127)+127 = 127
« Respuesta #5 en: 27 de Diciembre de 2018, 16:06:34 »
Eduardo2 ó KILLERJC, pues de acuerdo con la teoría, esto es lo que me esta resultando como código...

Estoy poniendo el timer0 a desbordar cada 260 useg.
Código: C++
  1. #include <16f877A.h>                                           // PIC utilizado
  2.          #fuses XT,NOWDT,NOPROTECT,NOLVP                                // Configuramos los fuses
  3.          #use delay (clock=4000000)                                     // Oscilador a 4Mhz
  4.          #use fast_io(b)                                                // Optimizamos E/S del PORTB
  5.  
  6.          float const data[65]={127,139.44,151.77,163.86,175.6,186.86,197.55,207.56,216.8,225.17,232.59,239,244.33,248.53,
  7.                                251.55,253.38,254,253.38,251.55,248.53,244.33,239,232.59,225.17,216.8,207.56,197.55,186.86,
  8.                                175.6,163.86,151.77,139.44,127,114.55,102.22,90.13,78.399,67.13,56.44,46.43,37.19,28.82,21.4,
  9.                                14.99,9.66,5.46,2.44,0.61,0,0.61,2.44,5.46,9.66,14.99,21.4,28.82,37.19,46.43,56.44,67.13,78.399,
  10.                                90.13,102.22,114.55,127};
  11.          int i=0;
  12.          
  13.          #int_TIMER0
  14.          void  TIMER0_isr(void)
  15.          {        
  16.          set_timer0(126);                                               // desbordando el timer cada 260 Useg  
  17.          output_bit(PIN_B0,data[i]);
  18.          if(i>64){i=0;};i++;
  19.          }
  20.          
  21.          void main(void)
  22.          {
  23.          setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2|RTCC_8_bit);            
  24.          set_timer0(126);                                               // desbordando el timer cada 260 Useg
  25.          enable_interrupts(INT_TIMER0);                                 // Habilita la interrupcion  
  26.          enable_interrupts(GLOBAL);                                    
  27.          set_tris_b (0x00);                                             // Puerto b como salidas
  28.          output_b(0x00);                                                // Limpiamos el puerto b
  29.        
  30.          while(true);
  31.          {
  32.          
  33.          }
  34.          }

Estaré por buen camino para realizar el inversor senoidal a 60hz?

Anexo la tabla de valores resultantes de excel de valores para cargar en el array del código del pic.

esto es lo que utilizo para generar los valores del array de acuerdo a la teoría al inicio de este post.

Código: C++
  1. para 0o = ((seno 0o)*127)+127 = 127
  2. para 5,625o = ((seno 5,625o)*127)+127 = 139,44
  3. para 11,25o = ((seno 11,25o)*127)+127 = 151,77
  4. .
  5. .
  6. para 90o = ((seno 90o)*127)+127 = 254
  7. .
  8. .
  9. para 180o = ((seno 270o)*127)+127 = 127
  10. .
  11. .
  12. para 270o = ((seno 270o)*127)+127 = 0
  13. .
  14. .
  15. para 360o = ((seno 360o)*127)+127 = 127
« Última modificación: 27 de Diciembre de 2018, 16:35:05 por Abner_emanuel »
El señor es mi pastor,  nada me faltará.

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Duda de función ((seno 0°)*127)+127 = 127
« Respuesta #6 en: 27 de Diciembre de 2018, 16:44:38 »
Hola Abner_emanuel, te puedo echar una mano si explicas lo que necesitas (precisión, velocidad, tamaño de código, etc.)

Un saludo.
« Última modificación: 27 de Diciembre de 2018, 16:49:37 por Picuino »

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Re:Duda de función ((seno 0°)*127)+127 = 127
« Respuesta #7 en: 27 de Diciembre de 2018, 16:47:38 »
Un saludo. Pues trato de hacer una onda senoidal a 60 hz como si fuera un inversor. Al inicio del post puse una teoría que me encontré y trato de hacerlo en código para ver si me resulta pero no se si voy por buen camino o si faltan cosas que no e considerado en el código.
El señor es mi pastor,  nada me faltará.

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Duda de función ((seno 0°)*127)+127 = 127
« Respuesta #8 en: 27 de Diciembre de 2018, 16:49:23 »
Perdona, que he editado el post anterior mientras escribías.
Lo repito por si acaso:

Por lo que he leído hasta ahora, necesitas 16 valores de la función seno.
La secuencia sería 16 valores desde 0 hasta 1. Otros 16 valores desde 1 hasta 0. Y todo eso repetido con valores negativos.

Para eso no hace falta más que una simple tabla con los 16 valores ya ajustados al rango de PWM necesario.

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Re:Duda de función ((seno 0°)*127)+127 = 127
« Respuesta #9 en: 27 de Diciembre de 2018, 16:55:36 »
En el array tengo 64 valores con una separación de 5.625 esto es:  360/5.625=64. El autor de esta teoría del inicio del post como comentario dice que habría que poner el timer0 con un retardo de 260 microsegundos para que ahí se vallan los datos del array. Así es como lo intento...
El señor es mi pastor,  nada me faltará.

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Duda de función ((seno 0°)*127)+127 = 127
« Respuesta #10 en: 27 de Diciembre de 2018, 17:08:43 »
Si necesitas un número mayor de valores, puedes hacer una tabla más grande o interpolar linealmente.

Si necesitas más valores y con mayor precisión, puedes implementar la función con splines por intervalos o con polinomios.

La función seno con un polinomio de tercer grado te puede dar 8 bits de precisión absoluta y es muy rápida:

Y = X * (A1 + X * X * A3)
A1 = 0,0172
A3 = -0,0000007572

Aquí tienes más info:
http://www.todopic.com.ar/foros/index.php?topic=43336

Saludos.

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Duda de función ((seno 0°)*127)+127 = 127
« Respuesta #11 en: 27 de Diciembre de 2018, 17:10:20 »
En el array tengo 64 valores con una separación de 5.625 esto es:  360/5.625=64. El autor de esta teoría del inicio del post como comentario dice que habría que poner el timer0 con un retardo de 260 microsegundos para que ahí se vallan los datos del array. Así es como lo intento...

No tiene sentido hacer una tabla tan grande porque la función seno es simétrica. Puedes quitar tres cuartos de esa tabla porque son valores que se repiten, como he comentado antes.

Saludos.

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Duda de función ((seno 0°)*127)+127 = 127
« Respuesta #12 en: 27 de Diciembre de 2018, 17:12:06 »
Si además son valores que tienes que ajustar para activar un PWM, lo lógico es guardar en la tabla el valor que vas a cargar en el registro del PWM, ya escalado a tus necesidades.
Así evitas cálculos en tiempo de ejecución.

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Duda de función ((seno 0°)*127)+127 = 127
« Respuesta #13 en: 27 de Diciembre de 2018, 17:27:55 »
No tiene sentido hacer una tabla tan grande porque la función seno es simétrica. Puedes quitar tres cuartos de esa tabla porque son valores que se repiten, como he comentado antes.

Yo pondría en la tabla estos valores:

[ 0, 25, 50, 74, 98, 120, 142, 162, 180, 197, 212, 225, 236, 244, 250, 254, 255 ]


El 255 corresponde a 90º.
El valor del siguiente ángulo 95.6º, es el mismo que el del ángulo anterior 84.4º, por lo que ahora tienes que seguir leyendo la tabla hacia atrás hasta llegar al cero.

Una vez que llegues a cero, comienzas otra vez a subir por la tabla, pero con valores negativos (esta vez vas a aplicar los valores a otra rama del puente en H)

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Re:Duda de función ((seno 0°)*127)+127 = 127
« Respuesta #14 en: 27 de Diciembre de 2018, 17:33:07 »
Entonces sólo aplico para 90° y los 270 los voy formando a partir de los 90°. Es verdad, los valores se repiten. Me podrías orientar con algo de código así como tu lo piensas?.
El señor es mi pastor,  nada me faltará.