# Generador de onda senoidal de frecuencia variable con pic



## gago09 (Oct 31, 2009)

Hola , quisiera saber si alguien sabe o tiene como generar una onda seno con un pic , y que sea de frecuencia variable (de 50hz a 200khz).
Cualquier ayuda seria bien recibida...
Gracias .


----------



## Fogonazo (Oct 31, 2009)

Aquí tienes un par de esquemas para simular, son de salida cuasi-senoidal y un poco rústicos, pero te pueden dar una idea de funcionamiento.
Además los componentes están en cualquier librería de simuladores.


https://www.forosdeelectronica.com/f21/fuente-trifasica-11063/


----------



## ortega (Dic 1, 2009)

saludos colegas... me quiero embarcarme en un proyecto ... para que con un pic general un onda sinusoidal... para la aplicación que las personas que entren al foro les quieran dar...... así que soporto sugerencias por que... es un buen proyecto discutir


----------



## Fogonazo (Dic 1, 2009)

Divides el período de la señal en (Por ejemplo) 200 pasos
Calculas el seno para el punto 0 [X = Sen(P) siendo "P" = Nº Punto * (360º /200)]
Calculas el seno para el punto 1
Calculas el seno para el punto 2
Etc.
Etc.
Hasta llegar al valor 200, alli vuelves a comenzar desde 0

Los valores [X] que calculaste los conviertes a dato y los mandas a un conversor DA, a la salida del conversor tiene la señal senoidal.


----------



## ortega (Dic 6, 2009)

muchas gracias ........ entonces manos a la obra.... cuando haya algo lo posteo


----------



## microsistel (Dic 7, 2009)

ortega dijo:
			
		

> muchas gracias ........ entonces manos a la obra.... cuando haya algo lo posteo


Ahora bien, no se podrar hacer por tecnica PWM la generacion de la senoidal? entiendo que si....


----------



## elosciloscopio (Dic 7, 2009)

mediante una rutina puedes hacer que el siguiente punto de la onda no se genere hasta que llegue una señal de reloj externa, con lo que puedes rgular la frecuencia 

Creo que voy a intentarlo 

saludos


----------



## tecnogirl (Dic 7, 2009)

Ortega: Solo adiciono que, en general, en programacion se usa mucho crear inicialmente una tabla con los valores del seno de distintos angulos. La tabla se carga en memoria y se la emplea posteriormente para lo que necesites (mas calculos, graficas o enviarlos al conversor DA, etc). Esto reduce la gran cantidad de tiempo que emplea el micro haciendo calculos... pero el costo a pagar es que necesitas algo mas de memoria para cargar la tabla. Salu2.


----------



## ortega (Dic 7, 2009)

>>> conseguí algo bueno, que opinan <<< 


antes de pasar a los diagramas y codigos, es necesario conocer como funciona...  lo que se pretende con esta tecnica es tratar de generar una señal se salida que tenga una similitud a una señal senoidal alterna con determinada magnitud (Amplitud) y frecuencia. Yo parti del analisis de la onda senoidal pura; la cual tiene una area determinada en cualquiera de sus semiciclos, si, se mantiene a una amplitud y frecuencias constantes. La idea es dividir ese semiciclo en intervalor de tiempo iguales y en un numero par ( Mas adelante veremos porque ) para que en cada intervalo de tiempo se genere un pulso PWM con una Area equivalente a el area de la señal senoidal en ese mismo periodo de tiempo.

Como se observa en la figura lo que se tiene que calcular son los Anchos de Pulso o Duty Cicle para cada pulso de PWM a fin de que el area en ese pulso sea la misma area en el mismo instante en la señal senoidal. 


La velocidad del cristal a usar se elige en base a el tiempo que duren los pulsos PWM ya que si el tiempo es muy grande no nos alcanzara el TMR2 y PR2 para temporizar ese pulso sin complicarnos mucho. En este caso estoy dividiendo una señal senoidal a 60 Hz y con  proximadamente 180 Volts pico lo que me da un periodo de señal aproximado de 16 ms. y estoy dividiendo el ciclo senoidal en 20 pulsos de PWM con lo que el periodo del PWM viene siendo 16ms/20 = 0.8 ms.
Utilizo un cristal a 20 Mhz considerando la formula para el periodo PWM y tengo que:

*
PWM Period = [(PR2) + 1] • 4 • T**OSC • (TMR2 Prescale Value)
*[/size]​
Como se que PR2 es un registro de 8 bits puede valer como maximo 255 y calculo el valor de PR2 para el PWM period deseado y con el Tosc definido y con un Preescale value para TMR2 de 1:16:

*
PR2 = PWM Period / [ 4 • TOSC • (TMR2 Prescale Value)  ] - 1*
*PR2 = 0.8ms / [ 4 • (1/20Mhz) • ( 16 )   ] - 1*
*PR2 = 249
*

Con lo que los valores elegidos quedan bien.
Finalmente se obtienen unas ecuaciones para poder obtener el valor de cada Duty Cicle dependiendo del pulso que se trate. Se menciono que era preferible elegir una cantidad par para el numero de pulsos en los que dividiriamos a la señal, es porque analizando la primer grafica nos damos cuenta de que las areas A1 - A5 son diferentes pero despues se vuelven a repetir, por lo tanto solo hay que tener los primeros 5 Duty Cicles y los demas son repeticiones de ellos.
Para actualizar el valor de los Duty Cucle utilizamos la interrupcion  de coincidencia de PR2 con TMR2, con lo que en cada interrupcion se carga el nuevo valor de Duty Cicle, los 5 valorez necesarios para el Duty Cicle se calculan dependiendo de la lectura del Pote obteniendo resutados como estos:

El Diagrama del circuito queda asi:
http://micros.mforos.com/visit/?http://img338.imageshack.us/my.php?image=diagrampwmrp2.jpg


Se utilizan en total 3 fuentes de bajo voltaje y una bipolar de potencia, son necesarias porque debido a la conexion en medio puente es necesario aislar el circuito de conmutacion de cada transistor (MOSFET) puesto qeu si utilizamos una sola fuente estaria existiendo un corto entre los "Source" de cada transistor. La fuente bipolar de 180 V. se arma en un rectificador de media onda, tal y como se muestra en el siguiente diagrama.



Despues podria hacerse una modificacion para poder controlar tambien la frecuencia en vez de solo controlar la amplitud equivalente, y obtener resultados como estos; que son mas utiles en los motores sincronos.
​


----------



## elosciloscopio (Dic 8, 2009)

"Senosoidal" es una mezcla entre senoidal y sinusoidal?


----------



## deivy_nata (Dic 8, 2009)

por la web encontre algo de lo que creo que estan buscando, lo he probado y funciona. el unico problema es que no se puede crear musica solo son tonos de la frecuencia que elijamos 

http://blog.bricogeek.com/noticias/arduino/como-generar-sonido-de-alta-calidad-con-arduino/#more

mucha suerte


----------



## Rimach (Dic 8, 2009)

Hola, eso es relativamente facil. Es correcto lo q se ha dicho, yo mismo lo he hecho. Debes calcular el valor (por medio de un muestreo) de la señal en ciertos intervalos de tiempo como lo comenta ortega. Una vez realizado esto la opcion mas recomendable es almacenarlos permanettemente en la memoria del PIC (EEPROM). XQ en la EEPROM??

Bueno, de esta manera te evitas que el PIC este calculando a cada instante los valores, despues de todo es una señal senoidal y es un ciclo, los valores simplemente se repiten. Posteriormente dependiendo como configures tu programa, podras llamar una subrutina que lea y envie al puerto de salida los valores almacenadoe en la EEPROM y de esta manera tu seras capaz de conectar la salida del PIC a un OSC y observar tu señal senoidal. Obviamete deberas contemplar q la resolucion de tu señal varia directamente proporcional muestreo realizado (los valores en los cuales dividiste tu onda y guardaste en EEPROM) Spero haberme explicado


----------



## DJ DRACO (Dic 8, 2009)

La mejor forma, y la mas facil es la del PWm como explicaron anteriormente...y porqué lo digo...simplemente porque hay un muchacho que ha diseñado varios videojuegos con un PIC16F84A y saca el sonido por 1 solo puerto (obviamente es analogico) y en el programa utilizo PWM.


----------



## controlccs (Dic 8, 2009)

La mejor solución ya se ha propuesto, pero otra forma que se me ocurre es simplemente generar una onda cuadrada y pasarla por un filtro pasabanda  claro, si lo que se quiere es simplemente obtener "una onda sinusoidal"


----------



## DJ DRACO (Dic 9, 2009)

claro...sería una bobina en serie, y un capacitor a masa....verdad


----------



## jimmyneutron (Jun 7, 2010)

este es un generador de la onda seno con el pic16f877. espero les sirva.
ah incluye simulacion en proteus


----------



## niciba (Feb 9, 2012)

jimmyneutron dijo:


> este es un generador de la onda seno con el pic16f877. espero les sirva.
> ah incluye simulacion en proteus





jimmyneutron dijo:


> este es un generador de la onda seno con el pic16f877. espero les sirva.
> ah incluye simulacion en proteus




Jimmy muy bueno el ejemplo tuyo. Hay algunas cosas que no entendi bien de la programacion.
Cuando  vos utilizas int seno[67]={...} pones los valores que va a tomar la  funcion. Pero no termino de entender como haces para determinar la  frecuencia.

puerto_b = seno[desbordes];
         set_rtcc(15);

Lo unico que pude notar es que si aumentas el valor dentro de set_rtcc() la frecuencia aumenta.

Lo otro que no pude entender fue lo que se encuentra dentro de void main, las siguientes instrucciones:

enable_interrupts(global);
     enable_interrupts(int_rtcc);        
     setup_counters(rtcc_internal, rtcc_div_64);      
     set_rtcc(240);

Muchas Gracias!!
Nico


----------



## caifan (Ago 14, 2012)

Hola una ves en la escuela nos pidieron generar una señal senoidal con un pic, y lo logramos, usamos un pic 18f2550 y un dac I2C (PCF8591), Aqui les comparto el programa (en PICC) y la simulacion (en isis de proteus v7).  el pic esta a 48 MHZ con el PLL con un cristal de 12 mhz. espero que a alguien le sea util


----------



## turkomac (Abr 11, 2013)

niciba dijo:


> Jimmy muy bueno el ejemplo tuyo. Hay algunas cosas que no entendi bien de la programacion.
> Cuando  vos utilizas int seno[67]={...} pones los valores que va a tomar la  funcion. Pero no termino de entender como haces para determinar la  frecuencia.
> 
> puerto_b = seno[desbordes];
> ...



Veo que no te contestaron , mi duda es : ese arreglo de Intseno[67]= ( ... ) , esos valores yo los meto manual o como es lo que no entiendo.


----------



## turkomac (Abr 16, 2013)

Hola , estoy haciendo un proyecto en el cual la primera fase es sacar dos ondas seno a traves de los puertos del microcontrolador PIC18 , estas ondas la genero con una tabla de valores de seno que hago en matlab y lo que hago sacarlas por los puertos y estos datos va hacia un DAC, este a su salida me estará generando la onda seno.

ADJUNTO el código de lo antes dicho. :


```
#include <18f4550.h>
#fuses hspll,mclr,nowdt,noprotect,nolvp,nodebug,usbdiv,pll3,cpudiv1,novregen,nopbaden
#use delay (clock=48000000)
#use standard_io(B)
#use standard_io(C)
#use standard_io(D)


int16 frecuencia=0;
int8 desbordes=0;
int seno[100]={77,82,86,91,96,101,105,109,114,118,122,126,129,133,136,
139,142,144,146,148,150,151,152,153,153,154,153,153,152,151,150,148,146,144,142,
139,136,133,129,126,122,118,114,109,105,101,96,91,86,82,77,72,67,62,58,53,49,44,
40,36,32,28,24,21,18,15,12,9,7,5,4,2,1,1,0,0,1,1,2,4,5,7,9,12,15,18,21,24,28,32,36,
40,44,49,53,58,62,67,72,77};

#int_rtcc
void rtcc_isr(){
        
        frecuencia=read_adc();        
        output_B(seno[desbordes]);
        output_d(seno[desbordes]);
        set_rtcc(frecuencia); 
        desbordes++;
        if(desbordes>=100)
        
        
                     {
                          desbordes = 0;
                        }   
  }

void main()
  {
     setup_adc_ports(all_analog);
     setup_adc(adc_clock_internal);
     set_adc_channel(0);  
     set_tris_b(0x00);
     set_tris_d(0x00);
     setup_counters(rtcc_internal, rtcc_div_4 | rtcc_8_bit);      
     enable_interrupts(int_rtcc);       
     enable_interrupts(global);
     set_rtcc(231);
     desbordes = 0;

   while(true)
   {
   
   }
   }
```
PREGUNTAS:

los valores de seno en lugar de generarlos por matlab , es posible generar una tabla o Lookup table dentro del mismo y de ahi separarlos en en valores impares y pares. para sacar posteriormente cada arreglo por cada DAC.

Con el esquema que pongo es posible modificar su frecuencia de cierto valor a cierto valor , como configuraria el pic para que este diera su maxima frecuencia posible de salida. tomando en cuenta que la frecuencia maxima de oscilacion del CPU segun microchip es de 48 mhz!


----------



## anthony123 (Abr 22, 2013)

jimmyneutron dijo:


> este es un generador de la onda seno con el pic16f877. espero les sirva.
> ah incluye simulacion en proteus




Este código puede aplicarse con los 16F84 o 628 (con las modificaciones pertinentes, claro está)? Por que quiero generar una frecuencia de 5 a 60Hz para un variador. 

Saludos!


----------



## yv5kg (Jun 19, 2013)

Saludos amigo estoy verificando el programa y se ve muy bueno mañana dios mediante cargo el file .HEX en el f4550, y verifico seria bueno disponer de cuales son las patillas del PIC  por donde sale la señal, o el esquema electronico ya que solo en los fil .rar no lo puede visualizar o esta en alguno de file, y se necesita de algun programa para verlos, agradesco su preciada ayuda.

Jhonny Aldana






turkomac dijo:


> Hola , estoy haciendo un proyecto en el cual la primera fase es sacar dos ondas seno a traves de los puertos del microcontrolador PIC18 , estas ondas la genero con una tabla de valores de seno que hago en matlab y lo que hago sacarlas por los puertos y estos datos va hacia un DAC, este a su salida me estará generando la onda seno.
> 
> ADJUNTO el código de lo antes dicho. :
> 
> ...


----------



## MrCarlos (Jun 20, 2013)

Hola yv5kg

En el archivo *Gnerador3.rar* que adjuntó turkomac, en su mensaje #7, trae una carpeta(Fólder) llamada Gnerador3 y dentro de ella hay varios archivos:
Generador1fase.DSN
Generador1fase.C
Estos son los importantes. 
El que tiene la extensión .DSN se abre con ISIS de Proteus.
El que tiene la extensión .C se abre con el compilador C.

Abriendo el .DSN con ISIS de Proteus puedes magnificarlo para ver los números de las terminales.

Ojala puedas verlos en la imagen que te adjunto.

saludos
a sus ordenes


----------



## anthony123 (Jun 30, 2013)

En lugar de usar un conversor analógico digital, tengo pensado usar un 4017 con divisores de tensión en la salida por lo que tengo que sacar una frecuencia 10 veces superior a la necesaria por un puerto del PIC (ejemplo 50Hz para una salida de 5Hz).

Para todo esto he creado un arreglo de periodos para cargárselos al "delay_ms (periodo)"

output_high (salida);
delay_ms (periodo);
output_low (salida);
delay_ms (periodo);

pero tengo problemas con el bucle dado a que la idea es que pueda modificar los valores de periodo para hacer la senoidal variable. ¿Cómo podría hacer en este punto?


Saludos


----------



## jcperezp (Jul 28, 2013)

caifan dijo:


> Hola una ves en la escuela nos pidieron generar una señal senoidal con un pic, y lo logramos, usamos un pic 18f2550 y un dac I2C (PCF8591), Aqui les comparto el programa (en PICC) y la simulacion (en isis de proteus v7).  el pic esta a 48 MHZ con el PLL con un cristal de 12 mhz. espero que a alguien le sea util




buenas amigo, me ha sido de gran ayuda tu programa pero tengo un problema, la señal que necesito generar debe sere de 400 Khz o por lo menos 200 Khz, pero no he podido hacerlo con tu programas, te agradecería tu colaboración


----------



## seaarg (Jul 28, 2013)

Sugiero una salida PWM de duty cycle variable conectada a un filtro pasabajos RC. Sencillo pero funcional.

Sino, una escalera r2r, donde usaran 8 pines del pic pero es tan simple de usar como escribir un valor en un puerto.

Todo dependera de la perfeccion que se requiera en la senoidal.


----------



## kiwhilario (Jul 29, 2013)

Un conversor digital análogo como el DAC0800 con un filtro pasabajas de orden 2 tipo bessel (revisa http://www.electro-tech-online.com/custompdfs/2010/11/sloa088.pdf) es una solucion un tanto elaborada pero da buenisimos resultados.


----------



## pablinza (Jul 30, 2013)

Yo en una ocasion genere la onda empleando el DAC del PIC12F1822 para generar tonos DTMF, la onda senoidal la represente en 32 puntos. Pero la frecuencia mas alta era 1.633Khz y el tiempo de muestra era  1/(32*F) = 19.15uS. el PIC trabajaba a 16MHZ y el Tcy = 0.25uS.
Viendo tu caso reconstruir una senal de 200KHz en 32 puntos requiere tiempos de muestra de 0.15uS, lo que veo algo complicado en un PIC comun.
El AN655 de microchip explica los dos metodos ya mencionados PWM y resitencias R2R pero las frecuencias no superan los 4KHz.
Pienso que la solucion pasaria por implementar algun circuito VFO o tal vez un PIC DSP.
Saludos,.


----------



## Fogonazo (Oct 10, 2014)

​


----------

