Ayuda con diente de sierra

Estimados,

necesito generar una señal diente de sierra en el arduino uno y ser mostrada en el osciloscopio, la verdad es que no se por donde partir. si alguien me puede ayudar se los agradecería.

Con pwm y un operacional en modo integrador

es posible generar la señal diente de sierra de forma interna dentro del arduino? que es lo que tengo que hacer

no puedes, no posees un conversor digital a analogico interno, lo qeu puedes hacer es que con PWM varias la frecuencia de la onda cuadrada, esta ingresa a un Operacional configurado como integrador y vas a obtener una señal bastante parecida a eso.

Muchas gracias MAxid

Hola, una pregunta sobre el tema:

maxid: no puedes, no posees un conversor digital a analogico interno,

Con el arduino mega se podría? Tengo entendido que tiene un DAC interno, o es otra cosa?. No estoy muy puesto en estos temas...

Es un DAC, pero ni el Mega1280 ni el 2560 traen DAC interno. Pero en el ejemplo que te pase se hace muy simple, sino busca en google hay cientos de circuitos similares. si quieres aprender usa lo que te expliqué

Hola, quisiera saber como generar la señal diente sierra con el arduino Due, teniendo en cuanta que dicho arduino si cuenta con dos DAC’s internos, la señal la genero con codigo pero la frecuencia no es la necesaria, necesito la señal a una frecuencia minima de 1Khz, con una resolucion de 12Bits, si alguien sabe como lo puedo hacer le agradecerian me ilustraran respecto al caso

Hola,

Aqui hay un ejemplo para generar ondas entre 1Hz y 170Hz con el DUE http://arduino.cc/en/Tutorial/DueSimpleWaveformGenerator. Al parecer la limitación allí es el tiempo de espera del analogRead().

Pero como tu quieres es un 1Khz, saquemos cuentas:

Si tienes 12 bits, significa valores entre 0 y 4095.

Si quieres 1Khz significa que cada 1ms tienes que mandar una rampa completa de 0 a 4095. Es decir, a máxima resolución tienes que mandar 4096 valores cada 1ms, por lo tanto necesitas mandar 1 nuevo valor cada 1/4096 ms = 244ns.

El Arduino DUE trabaja a 84Mhz, algo asi como 11ns cada ciclo. Asi que si el DAC responde rápido parece posible.

Yo siendo tu mando a escribir valores al DAC de 0 a 4095 de manera sucesiva y veo como se comporta la salida y cual es esa máxima frecuencia que obtengo, y a partir de alli le agrego algunos nop o codigo de retraso que no haga nada para ajustar la frecuencia. Lo otro es que veas cada cuanto puedes generar una interrupcion y trabajes con eso. Y si no alcanzas la resolucion en lugar de aumentar en pasos de 1 lo haces en pasos de 4 por ejemplo, una cuenta rapida serian interrupciones cada 1ms y pasas valores entre 0 y 3996 aumentados de 4 en 4.

Son ideas, montalas para comprobarlas.

Saludos.

Hola Luis_AM3C, estoy haciendo lo mismo que marcos y me parece buena la idea de: "...y a partir de alli le agrego algunos nop o codigo de retraso que no haga nada para ajustar la frecuencia." pero donde encuentro información acerca de esto o, si no es mucha molestia, ¿me podrías decir como se hace eso en el DUE?

"Lo otro es que veas cada cuanto puedes generar una interrupcion y trabajes con eso." o esta, por favor. y Gracias!

Creo que partiendo del código que propone Luis_AM3C, es posible obtener ese diente de sierra (lo que yo no sabía es que el due sí tiene puerto analógico). Creo que más importante que crear un código rápido es crear un código "regular", es decir que en cada iteracción realice el mismo número de operaciones, para evitar irregularidades al cambiar condiciones (que se alcance el pico máximo o mínimo de la señal). A partir de ahí, si aparte de la frecuencia de la señal no estamos excesivamente condicionados por la amplitud máxima, no deberíamos tener demasiadas pegas para obtener la frecuencia (más o menos aproximada) deseada. Propongo el siguiente código:

void setup() {
  analogWriteResolution(12);  // set the analog output resolution to 12 bit (4096 levels)
}
void loop() {
int numincrementos=10;
int fine_tune=0;

int valor=0;
int incremento=4000/numincrementos;
int maxval=incremento*numincrementos
      while(1){  
            analogWrite(DAC0, valor);  // write the selected waveform on DAC0
            valor+=incremento;
            valor=(valor>maxval?0:valor);
            delayMicroseconds(fine_tune);
      }
}

A partir de ahí, podremos jugar primero con la variable numincrementos, hasta obtener el resultado superior al Khz más cercano, y después con la variable fine_tune, terminar de aproximar. Hablo totalmente de forma teórica, pues no dispongo de un Due. Si alguien lo prueba, por favor, que comparta el resultado.

Acabo de probar el codigo, en el Due y sale error en la siguiente linea

valor=(valor>maxval?0;valor);

el error que sale es: expected ':'before';' token

El interrogante en la linea de programacion ¿Que significa?

Perdón por la errata. Me pillaste fuera y sólo pude corregirla desde el teléfono móvil. La instrucción (expresión?valor si verdadero:valor si falso) devuelve uno de los dos valores, dependiendo de la evaluación de la expresión. Es el equivalente a iif de visual basic.

Amigo que verguenza pero no entendi bn lo que me trato de decir, es que no conozco visual basic, si he utilizado el comando "if" pero en otros lenguajes de programacion ccomo "ISE o el de C", pero mas o menos como debe ir la linea donde sale el error.?

Está ya editada y corregida en mi post inicial. Cambia el punto y coma por dos puntos. Espero que no haya más erratas, pero es que lo escribí "al vuelo". Saludos.

Hola señores Gracias a noter por su aporte, lo he probado y sale a una menor frecuencia que la que he hecho normalmente. normalmente me salía a 280 y con la de noter sale a 157Hz

Efectivamente, en el código busqué más la regularidad (que cada loop dure lo mismo) que la velocidad.

¿Podrías exponer el código que te da la velocidad más alta? Podríamos intentar depurarlo un poco a ver si nos acercamos al Khz.

Hola,

Por lo que comentas el DAC del DUE puede escribir aproximadamente 280 x 4096 = 1146880 valores por segundo (~1MHz), y no es posible generar una diente de sierra con resolucion de 12 bits, 4096 pasos y frecuencia de 1Khz, aquí es que dependiendo para que lo vayas a usar puedas sacrificar la cantidad de pasos a 1024 por ejemplo, que te daria una frecuencia teórica de 280 x 4 = 1.12 KHz, puedes dejar la resolucion del DAC en 12 bits pero como yo lo veo seria igual que cambiarla a 10bits.

Saludos.

El programa del ejemplo de la página anterior (supongo que es el que da los 280 hz), aunque usa la resolución de 12 bits no utiliza los 4096 valores, sino una muestra de 120 valores. Para aproximar al Khz debería reducir la muestra a aproximadamente 34 valores. Para ello debería modificar el #define maxSamplesNum (con eso ya debería aparecer un diente de sierra más aproximado al Khz, aunque de pequeña amplitud) y reajustar esos 34 valores para darle la forma y amplitud deseadas.