Please help with a sinewave single tone generator

Greetings,

I just have recently discovered arduino. I have made one thing and use code from the net and changed a few parameters. I had to have help from an experienced arduino coder.

I am looking to create a sinewave single tone generator. The sinewave must go all the time when power is applied.

I have searched and searched the net and have not found anything simple enough for me to understand. I keep finding musical ones and ones with multiple buttons. I don;t need all that.

I have purchased a nano and a DAC. I am looking for code to create a 1950hz sinewave tone continuously.

Sounds simple right? Not for me.

Can anyone help me out?

Thank you in advance

Mike

You request help for a specific frequency to be created on an Arduino. I would have thought this one task would be easier using analogue methods.

Is there more to your project?

Weedpharma

There is nothing more to the project then creating the 1950 Hz tone. I just need an audible sine wave do you inject into a voting receiver comparator. It seems pretty simple enough but it has to be very stable because that tone is required to have it operate correctly.

I also have been looking at this: http://interface.khm.de/index.php/lab/interfaces-advanced/arduino-dds-sinewave-generator/

I have purchased all of the components for the filter.
Is there a way to create this on an arduino the analog way?

The arduino has no true analogue outputs.

Doing that with an Arduino is a little nuts.

SignalGenerator

Regards,
Ray L.

Which DAC?
Direct Digital Synthesis (DDS) of a sine wave has been done many times.
You can create a table of 1/4 of the sinewave, and send that to the DAC.
Send the date up from 2.5V to 5V, then reverse the table from 5V to 2.5V, then flip it again from 2.5V to 0, and change again from 0 to 2.5V.

Attached is a pic on the dac. If pic does not work. It is a mcp4725 board.

I dont know how to do all that you talking about.

I was looking at this but has too many things i do not need. I have ordered the filter parts and they are on the way.
http://interface.khm.de/index.php/lab/interfaces-advanced/arduino-dds-sinewave-generator/

Can anyone decypher that amd weed out what is not needed? I tried amd keep getting errors. I do not have enough experience being so new to this stuff.

Thank you

Mike

Threads merged.

Mike44:
At the advice of another member I made a topic with a different title.

Next time just modify your original post.

Well, here's some code, but I'm certain it won't do what you want. It's set for 50Hz. No way in heck will it do anything reasonable at the frequency you want.

Google "phase shift oscillator". A relative simple circuit that produces a nice, neat sine wave.

const double freqHz = 50;
double phase = 0;
unsigned long prevTus;

void setup() {
  // put your setup code here, to run once:

  prevTus = micros();
}

void loop() {
  unsigned long currTus = micros();

  if (currTus == prevTus) return;

  // The compiler will convert 1e-6 * freqHz * PI * 2 to a constant
  phase += ((double)(currTus - prevTus)) * 1e-6 * freqHz * PI * 2;
  while(phase > 2*PI) phase -= 2*PI;

  analogWrite(3, (byte) ((sin(phase) + 1) * 1023.99));

  prevTus = currTus;
}

Have tried the code at the Lab3 site? It compiled ok for me.

/*
 *
 * DDS Sine Generator mit ATMEGS 168
 * Timer2 generates the 31250 KHz Clock Interrupt
 *
 * KHM 2009 / Martin Nawrath
 * Kunsthochschule fuer Medien Koeln
 * Academy of Media Arts Cologne

 */

#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))

int ledPin = 13; // LED pin 7
int testPin = 7;
int t2Pin = 6;
byte bb;

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(ledPin, OUTPUT); // sets the digital pin as output
 Serial.begin(115200); // connect to the serial port
 Serial.println("DDS Test");

 pinMode(6, OUTPUT); // sets the digital pin as output
 pinMode(7, OUTPUT); // sets the digital pin as 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=1000.0; // initial output frequency = 1000.o Hz
 tword_m=pow(2,32)*dfreq/refclk; // calulate DDS new tuning word 

}
void loop()
{
 while(1) {
 if (c4ms > 250) { // timer / wait fou a full second
 c4ms=0;
 dfreq=analogRead(0); // read Poti on analog pin 0 to adjust output frequency from 0..1023 Hz

 cbi (TIMSK2,TOIE2); // disble Timer2 Interrupt
 tword_m=pow(2,32)*dfreq/refclk; // calulate DDS new tuning word
 sbi (TIMSK2,TOIE2); // enable Timer2 Interrupt 

 Serial.print(dfreq);
 Serial.print(" ");
 Serial.println(tword_m);
 }

 sbi(PORTD,6); // Test / set PORTD,7 high to observe timing with a scope
 cbi(PORTD,6); // Test /reset PORTD,7 high to observe timing with a scope
 }
 }
//******************************************************************
// 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

 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;
 } 

 cbi(PORTD,7); // reset PORTD,7
}

We don't need no stinkin' Arduino! apologies to Alfonso Bedoya/John Huston

Make a simple circuit using a readily available 555 timer. Here's a recipe.