Pages: [1]   Go Down
Author Topic: SINE GENERATOR  (Read 643 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 6
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola!
Tengo este codigo que genera una señal sinusoidal en el pin 11 PWM
Lo que me interesa es si alguien puede modificar el codigo para que en en otro pin me salga otros pulsos sincronisados con el 11.
Con otras palavras .... tenemos el arry sine256[]  = {127,130,133,136,139,143,146,149.... y nesesito por ejemplo en el pin 4
como un reloj sincronizado con el sinus. Por ejemplo valor 127 .... pin 4 (0, 1)   valor 130 (0, 1)  por cada valor del sinus un pulso de 1 y 0

aqui le dejo el codigo!

#include "avr/pgmspace.h"
// table of 256 sine values / one sine period / stored in flash memory
PROGMEM  prog_uchar sine256[]  = {127,130,133,136,139,143,146,149,152,155,158,161,164,167,170,173,176,178,181,184,187,190,192,195,198,
200,203,205,208,210,212,215,217,219,221,223,225,227,229,231,233,234,236,238,239,240,242,243,244,245,247,248,249,249,250,251,252,252,
253,253,253,254,254,254,254,254,254,254,253,253,253,252,252,251,250,249,249,248,247,245,244,243,242,240,239,238,236,234,233,231,229,
227,225,223,221,219,217,215,212,210,208,205,203,200,198,195,192,190,187,184,181,178,176,173,170,167,164,161,158,155,152,149,146,143,
139,136,133,130,127,124,121,118,115,111,108,105,102,99,96,93,90,87,84,81,78,76,73,70,67,64,62,59,56,54,51,49,46,44,42,39,37,35,33,31,
29,27,25,23,21,20,18,16,15,14,12,11,10,9,7,6,5,5,4,3,2,2,1,1,1,0,0,0,0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,16,18,20,21,23,25,
27,29,31,33,35,37,39,42,44,46,49,51,54,56,59,62,64,67,70,73,76,78,81,84,87,90,93,96,99,102,105,108,111,115,118,121,124};

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

double dfreq;
// const double refclk=31372.549;  // =16MHz / 510
const double refclk=31376.6;      // measured

// variables used inside interrupt service declared as voilatile
volatile byte icnt;              // var inside interrupt
volatile byte icnt1;             // var inside interrupt
volatile byte c4ms;              // counter incremented all 4ms
volatile unsigned long phaccu;   // pahse accumulator
volatile unsigned long tword_m;  // dds tuning word m

void setup()
{
pinMode(11, OUTPUT);     // pin11= PWM  output / frequency output
Setup_timer2();
// disable interrupts to avoid timing distortion
  cbi (TIMSK0,TOIE0);              // disable Timer0 !!! delay() is now not available
  sbi (TIMSK2,TOIE2);              // enable Timer2 Interrupt

  dfreq=181.2;                    // initial output frequency = 1000.o Hz
  tword_m=pow(2,32)*dfreq/refclk;  // calulate DDS new tuning word

}
void loop()
{
}
//******************************************************************
// timer2 setup
// set prscaler to 1, PWM mode to phase correct PWM,  16000000/510 = 31372.55 Hz clock
void Setup_timer2() {

// Timer2 Clock Prescaler to : 1
  sbi (TCCR2B, CS20);
  cbi (TCCR2B, CS21);
  cbi (TCCR2B, CS22);

  // Timer2 PWM Mode set to Phase Correct PWM
  cbi (TCCR2A, COM2A0);  // clear Compare Match
  sbi (TCCR2A, COM2A1);

  sbi (TCCR2A, WGM20);  // Mode 1  / Phase Correct PWM
  cbi (TCCR2A, WGM21);
  cbi (TCCR2B, WGM22);
}

//******************************************************************
// Timer2 Interrupt Service at 31372,550 KHz = 32uSec
// this is the timebase REFCLOCK for the DDS generator
// FOUT = (M (REFCLK)) / (2 exp 32)
// runtime : 8 microseconds ( inclusive push and pop)
 ISR(TIMER2_OVF_vect) {
 phaccu=phaccu+tword_m; // soft DDS, phase accu with 32 bits
 icnt=phaccu >> 24;     // use upper 8 bits for phase accu as frequency information
                         // read value fron ROM sine table and send to PWM DAC
 OCR2A=pgm_read_byte_near(sine256 + icnt);
 if(icnt1++ == 125) {  // increment variable c4ms all 4 milliseconds
 c4ms++;
 icnt1=0;
 }   
 }

Logged

0
Offline Offline
Edison Member
*
Karma: 16
Posts: 1579
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola,

¿Qué es lo que no entiendes del código para no poder hacerlo tu mismo?
Mira este tutorial que está muy bien (en inglés):
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=50106


Saludos


smiley-wink
Logged


0
Offline Offline
Newbie
*
Karma: 0
Posts: 6
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola Igor!
Me vuelvo loquito entre los timers... si me puedes ayudar modificame el codigo y segurisimo te voy agradeser mucho!
lo unico que necesito es un clock a uno de los pines que quieres tu y un pino por el start. Es decir ... empiesa el sinus .. un pulso 1 al pin 6 por ejemplo y luego 0 asta que se termina el sinus y otro pin que cambia a 0 y 1 por cada valor del sinus.
te dejo tambien mi mess proy2002@yahoo.com para una larga colaboratcion y no lo haces por nada. Igual como se va leyendo una memoria eprom donde tenemos el clock el counter y los datos paralelos que salga de la memoria. Entonses me interesa el START , El CLOCK , y los valores del sinus existe en el pin 11. Mucha Gracia!
Logged

Donostia
Offline Offline
God Member
*****
Karma: 0
Posts: 740
elektronikadonbosco
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola,

¿Qué es lo que no entiendes del código para no poder hacerlo tu mismo?
Mira este tutorial que está muy bien (en inglés):
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=50106


Saludos


smiley-wink


Que buen tutorial Igor, (lastima lo del ingles, aunque con el google traductor y un poco de concentración es fácil) haber si hago un hueco y me pongo definitivamente con el tema de los timers. Muchas gracias

Hola Igor!
Me vuelvo loquito entre los timers... si me puedes ayudar modificame el codigo y segurisimo te voy agradeser mucho!

Profy deja de echarle jeta y trabajalo tu, ¿que te está costando? no pasa nada así se aprende. ¿Que tienes dudas puntuales tras consultar la página que ha puesto Igor? Pregúntalas seguro que Igor o algún otro te responde. Pero no creo que alguien te haga el código.
Logged

*
Offline Offline
Sr. Member
****
Karma: 0
Posts: 470
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ya ni preguntar dudas para intentar hacerlo uno mismo, directamente pedir que alguien te haga el código  smiley-mad

Logged

0
Offline Offline
Edison Member
*
Karma: 17
Posts: 1407
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola Igor!
Me vuelvo loquito entre los timers... si me puedes ayudar modificame el codigo y segurisimo te voy agradeser mucho!
lo unico que necesito es un clock a uno de los pines que quieres tu y un pino por el start. Es decir ... empiesa el sinus .. un pulso 1 al pin 6 por ejemplo y luego 0 asta que se termina el sinus y otro pin que cambia a 0 y 1 por cada valor del sinus.
te dejo tambien mi mess proy2002@yahoo.com para una larga colaboratcion y no lo haces por nada. Igual como se va leyendo una memoria eprom donde tenemos el clock el counter y los datos paralelos que salga de la memoria. Entonses me interesa el START , El CLOCK , y los valores del sinus existe en el pin 11. Mucha Gracia!

para que te hagan tu trabajo te recomiendo esta web
http://www.freelancer.com/  o esta  http://www.guru.com/

Logged

* Si preguntas, pon el código de tu programa, hace mucho mas fácil ayudarte. Y me ahorro un mensaje pidiendo que lo hagas.
* Si consigues solucionar tu problema, dedica unos minutos a explicar en tu post como lo conseguiste para beneficio de todos.
* Cambia el 'Subject' de tu hilo y añade 'SOLUCIONADO' cuando hayas llegado a una solución al problema que planteaste.
* Utiliza un 'Subject' para tu hilo que explique de que va el hilo.
Si estas empezando:
* Comienza a usar Arduino
* Guías de iniciación a Arduino
* Ejemplos
* Referencia del Lenguaje
* Conceptos básicos
Guia de usuario de arduino
Tutoriales en Ingles
Si necesitas que alguien te escriba el código: http://www.freelancer.com/  o esta  http://www.guru.com/

Málaga, Spain
Offline Offline
Edison Member
*
Karma: 38
Posts: 2173
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Pero mira que sois...

Hay que publicar directamente la cuenta de paypal, hombre.
Logged

   

0
Offline Offline
Edison Member
*
Karma: 16
Posts: 1579
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Si quereis en castellano un mini manual de introducción, escribí esto sobre el timer 2 => http://real2electronics.blogspot.com/2011/01/timer-2.html

smiley-wink
Logged


Euskadi
Offline Offline
God Member
*****
Karma: 16
Posts: 712
Arduinotarrak
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola,
gracias, Igor, me ha gustado el tutorial de avrfreaks, tan claro y didáctico. Ya sé lo que voy a empollarme este invierno: los timer, los puertos, las operaciones a nivel de bits... todo eso que suelo ver en el código de algunos programas, pero que nunca lo entendí detalladamente.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 6
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola a todos!
Primero tengo que agradecerle muchisimo a Igor porque de verdad me ayudo mucho.
No puedo decir que controlo los timers, despues de una noche de estudio pero he entendido leyendo su publicacion de que se trata y he echo los primeros pasos en cambiar mi codigo.
AQUI http://www.carpinteriaaluminioypvc.com/SINE_PULSE.jpg tienes una foto del osciloscopio y mas abajo le dejo el codigo, mas limpio y mas simple.

#include "avr/pgmspace.h"

// table of 256 sine values / one sine period / stored in flash memory
PROGMEM  prog_uchar sine256[]  = {
  127,130,133,136,139,143,146,149,152,155,158,161,164,167,170,173,176,178,181,184,187,190,192,195,198,200,203,205,208,210,212,215,217,219,221,223,225,227,229,231,233,234,236,238,239,240,
  242,243,244,245,247,248,249,249,250,251,252,252,253,253,253,254,254,254,254,254,254,254,253,253,253,252,252,251,250,249,249,248,247,245,244,243,242,240,239,238,236,234,233,231,229,227,225,223,
  221,219,217,215,212,210,208,205,203,200,198,195,192,190,187,184,181,178,176,173,170,167,164,161,158,155,152,149,146,143,139,136,133,130,127,124,121,118,115,111,108,105,102,99,96,93,90,87,84,81,78,
  76,73,70,67,64,62,59,56,54,51,49,46,44,42,39,37,35,33,31,29,27,25,23,21,20,18,16,15,14,12,11,10,9,7,6,5,5,4,3,2,2,1,1,1,0,0,0,0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,16,18,20,21,23,25,27,29,31,
  33,35,37,39,42,44,46,49,51,54,56,59,62,64,67,70,73,76,78,81,84,87,90,93,96,99,102,105,108,111,115,118,121,124

};
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
double dfreq;
// const double refclk=31372.549;  // =16MHz / 510
const double refclk=31376.6;      // measured

// variables used inside interrupt service declared as voilatile
volatile byte puls; 
volatile byte icnt;              // var inside interrupt

volatile byte c4ms;              // counter incremented all 4ms
volatile unsigned long phaccu;   // pahse accumulator
volatile unsigned long tword_m;  // dds tuning word m

void setup()
{
 pinMode (4, OUTPUT);
 pinMode (7, OUTPUT);
 pinMode(11, OUTPUT);     // pin11= PWM  output / frequency output
 Setup_timer2();

  // disable interrupts to avoid timing distortion
  cbi (TIMSK0,TOIE0);              // disable Timer0 !!! delay() is now not available
  sbi (TIMSK2,TOIE2);              // enable Timer2 Interrupt
 
  dfreq=40;                    // initial output frequency = 1000.o Hz
  tword_m=pow(2,32)*dfreq/refclk;  // calulate DDS new tuning word

}
void loop()
{
 
 
 }
//******************************************************************
// timer2 setup
// set prscaler to 1, PWM mode to phase correct PWM,  16000000/510 = 31372.55 Hz clock
void Setup_timer2() {

// Timer2 Clock Prescaler to : 1
  sbi (TCCR2B, CS20);
  cbi (TCCR2B, CS21);
  cbi (TCCR2B, CS22);

  // Timer2 PWM Mode set to Phase Correct PWM
  cbi (TCCR2A, COM2A0);  // clear Compare Match
  sbi (TCCR2A, COM2A1);

  sbi (TCCR2A, WGM20);  // Mode 1  / Phase Correct PWM
  cbi (TCCR2A, WGM21);
  cbi (TCCR2B, WGM22);
}

//******************************************************************
// Timer2 Interrupt Service at 31372,550 KHz = 32uSec
// this is the timebase REFCLOCK for the DDS generator
// FOUT = (M (REFCLK)) / (2 exp 32)
// runtime : 8 microseconds ( inclusive push and pop)
ISR(TIMER2_OVF_vect) {

  sbi(PORTD,7);          // Test / set PORTD,7 high to observe timing with a oscope
  cbi(PORTD,4);
  phaccu=phaccu+tword_m; // soft DDS, phase accu with 32 bits
  icnt=phaccu >> 24;     // use upper 8 bits for phase accu as frequency information
                         // read value fron ROM sine table and send to PWM DAC
  OCR2A=pgm_read_byte_near(sine256 + icnt);
  //if (bitRead(icnt++,7) == 0){sbi(PORTD,7);}
  if(icnt >= 192) {cbi(PORTD,7);}
  if (icnt % 2 == 0) // verificando paridad
  {
    sbi (PORTD,4);
  }
   
             // reset PORTD,7
}
Logged

0
Offline Offline
Edison Member
*
Karma: 16
Posts: 1579
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola profy,

Me alegro que vayas progresando en tu proyecto.

Ánimo!


smiley-wink
Logged


Pages: [1]   Go Up
Jump to: