Arduino Forum

Using Arduino => Audio => Topic started by: marnaw on Jun 17, 2011, 08:27 am

Title: Arduino DDS Sinewave Generator
Post by: marnaw on Jun 17, 2011, 08:27 am

has anyone tryed to run this code on a Mega 1280

http://interface.khm.de/index.php/lab/experiments/arduino-dds-sinewave-generator/ (http://interface.khm.de/index.php/lab/experiments/arduino-dds-sinewave-generator/)

since i have not such a board i cant check where the problem is.
my suspicion is the timer2 unit, please compare in both datasheets the register description of timer2.

martin
Title: Re: Arduino DDS Sinewave Generator
Post by: johnwasser on Jun 17, 2011, 01:07 pm
On an Arduino Mega the pin mappings are somewhat different.  The compare output for Timer 2A is on pin 10 instead of 11.

Pin mappings:
https://spreadsheets.google.com/pub?key=rtHw_R6eVL140KS9_G8GPkA&gid=0
Title: Re: Arduino DDS Sinewave Generator
Post by: timb0 on Jun 19, 2011, 09:18 am
Yes, thanks guys, I can confirm that it works a charm using pin10 instead of 11 :) Good reference, that spreadsheet!
Title: Re: Arduino DDS Sinewave Generator
Post by: fjgarcid on Jul 08, 2011, 08:39 am
Good work.
Can i generate a 40kHz senoidal signal?.
Title: Re: Arduino DDS Sinewave Generator
Post by: AWOL on Jul 08, 2011, 11:09 am
Quote
Can i generate a 40kHz senoidal signal?.

Do you mean "sinusoidal"?
With that software, no - you'd need to boost the clock to at least 80kHz, and I'm not sure the ISR would run at that frequency.

Do you really need a 40kHz sine wave?
Title: Re: Arduino DDS Sinewave Generator
Post by: D4p0up on Jul 13, 2011, 06:19 pm

Quote
Can i generate a 40kHz senoidal signal?.

Do you mean "sinusoidal"?
With that software, no - you'd need to boost the clock to at least 80kHz, and I'm not sure the ISR would run at that frequency.

Do you really need a 40kHz sine wave?


I managed to do it. My current 8bit look up table dds has a 4us interrupt, I have been able to reach 80khz sampling rate but this reaches the limit of the Arduino.
44k is Ok, but without much CPU overhead for somerhing else. Im working on midi synth with 22k rate atm.

EDIT : With this code, I have been able to operate my DIY 8 BIT SPI DAC (http://fullmaj.rd-h.fr/wordpress/?page_id=269) at a frequency of 330kHz. The output of the DAC was a saw signal (image of the counter...) at 1.35kHz / 256 samples per cycle.
So a 44kHz DDS using a Look up Table is highly feasible indeed.

Quote

//Pin connected to ST_CP of 74HC595
int latchPin = 10;
//Pin connected to SH_CP of 74HC595
int clockPin = 13;
////Pin connected to DS of 74HC595
int dataPin = 11;
////
unsigned char test_char=0;

//--- Used to setup SPI based on current pin setup
//    this is called in the setup routine;
void setupSPI(){
 byte clr;
 SPCR |= ( (1<<SPE) | (1<<MSTR) ); // enable SPI as master
 SPCR &= ~( (1<<SPR1) | (1<<SPR0) ); // clear prescaler bits
 clr=SPSR; // clear SPI status reg
 clr=SPDR; // clear SPI data reg
 SPSR |= (1<<SPI2X); // set prescaler bits
 delay(10);
}


//--- The really fast SPI version of shiftOut
byte spi_transfer(byte data)
{
 SPDR = data;           // Start the transmission
 loop_until_bit_is_set(SPSR, SPIF);
 return SPDR;           // return the received byte, we don't need that
}

void setup() {
 // put your setup code here, to run once:
 pinMode(latchPin, OUTPUT);
 pinMode(clockPin, OUTPUT);
 pinMode(dataPin, OUTPUT);
 digitalWrite(latchPin, HIGH);
 digitalWrite(clockPin, LOW);
 digitalWrite(dataPin, LOW);
 byte clr;
 SPCR |= ( (1<<SPE) | (1<<MSTR) ); // enable SPI as master
 SPCR &= ~( (1<<SPR1) | (1<<SPR0) ); // clear prescaler bits
 clr=SPSR; // clear SPI status reg
 clr=SPDR; // clear SPI data reg
 SPSR |= (1<<SPI2X); // set prescaler bits
 delay(10);
 Serial.begin(9600);
 Serial.println("Init Ok");
}

void loop() {
 // put your main code here, to run repeatedly:
 //shiftOut(dataPin, clockPin, MSBFIRST, test_char);  
 spi_transfer(test_char);
 PORTB &= ~(4); //digitalWrite(latchPin, LOW);
 //Serial.println(test_char,DEC);
 PORTB |= 4; //digitalWrite(latchPin, HIGH);
 //delay(1000);
 test_char += 1;
 //delay(1000);
}

Title: Re: Arduino DDS Sinewave Generator
Post by: robtillaart on Jul 13, 2011, 10:48 pm
@D4p0up

why not call  setupSPI();  in  setup()  ??

The same code....

and try Serial.begin(115200)  then you have more time for other things....

Title: Re: Arduino DDS Sinewave Generator
Post by: Utopia on Jul 14, 2011, 06:37 am

With this code, I have been able to operate my DIY 8 BIT SPI DAC at a frequency of 330kHz.


Very nice - I was wondering, from the page you referenced, 1% resistors are needed for 6 bit, and more precise for higher bits - has anyone had success using potentiometers to get more accurate resistances?
Title: Re: Arduino DDS Sinewave Generator
Post by: D4p0up on Jul 14, 2011, 12:19 pm
Just thinking about it, you reach a point where even the soldering flux has an impact on the total resistor of the resulting design...

integrated chip designers do nanometric adjusments of the R2R ladders to reach the expected accuracy. So with pots... you might end up spending your life seeking for a percentage of digit on your multimeter... in vain.
Title: Re: Arduino DDS Sinewave Generator
Post by: D4p0up on Jul 22, 2011, 09:00 am
COntinuing the discussion and answering the question...

About the SPI, I feel like digging into the Datasheet of the AVR and configuring every single bit on my own instead of using the Arduino dedicated functions. Of course they are much more user friendly, but I want to learn more about the HW and be closer as possible to it, so i might do the same, I prefer ton configure it on my own.

About the ADC, I have today very good audio results with my 8 bits DAC presented in the links above. Resistors are basic 5% tolerance, so there is non linearities spread among the way, it can be heared, but for a "lowfi but still accurate" project, it's worth it.

I will eventually use MCP4921's for my final Synth Shield, but only for "cleaning" purpose, I feel perfectly at ease with the current resistor based 8 bit DAC. I have not tried higher resolutions though, because of this table you mention.
Title: Re: Arduino DDS Sinewave Generator
Post by: MarkT on Jul 27, 2011, 01:23 am
I don't understand why you don't just lose the shift register and have the R-2R ladder on 8 Arduino pins (say port D then writing is a single instruction).  You'll get to MHz with the sinewave table perhaps?
Title: Re: Arduino DDS Sinewave Generator
Post by: D4p0up on Jul 27, 2011, 02:23 pm
Good question, simple answer: The lower the pin count, the better it is.

In the audio synth application I'm currently working on, I need the pins 0 & 1 for Midi In/Out purpose, and also need four analog inputs for control Knobs and so on. Add to this three Leds for Synth operation purpose (gate + lfo rate + general purpose), four buttons for operation like preset managment and edition, and make the breakout:

2 + 4 + 3 + 4 = 13 pins, with 9 being discretes.

With this basic setup, I have no room for Port dedicated 8 Bit DAC on a Uno board.

Then, in the future I plan to use a MCP4921 as a DAC. This will lead to better results, so using a homemade SPI DAC in this case is the best way to anticipate design evolutions.

However, as I mentionned on my blog, I started using a rough 6bits DAC on PortC with great success... except for dynamic range of course :)

Title: Re: Arduino DDS Sinewave Generator
Post by: marnaw on Sep 07, 2011, 08:35 am
        Is it possible to have a three phase sine wave with this generator ?
        I would like to generate a 10 kHz to idealy 18 kHz three phase wave.
        Does miro-Hertz precision will pertain with this change ?

ten Khz is anyway a problem, the atmega is to slw for that. using a dedicated DDS chip would be a solution
maybe some manufactor has a 3 phase version.

martin
Title: Re: Arduino DDS Sinewave Generator
Post by: D4p0up on Sep 08, 2011, 11:07 am
You definitely could with the R2R SPI DAC trick presented above:

Just chain 3 x 74HC595 with their associated DAC, and use the same method as described above, except that the 3 respective phase accumulators should be initialised with 0, (1/3)x2^16, (2/3)x2^16.

This will make 3 outputs !
Title: Re: Arduino DDS Sinewave Generator
Post by: sriliam on Sep 21, 2011, 06:31 pm
Thanks for those two replies, the original post about frequency production limit came from an email that I addressed to marnaw about 10 Khz to 18 Khz 3-phase sine wave.
I found this (http://digitalcommons.calpoly.edu/cgi/viewcontent.cgi?article=1129&context=eesp) and marnaw is in the pdf file.(I)

I did not be able to contact the author and he claimed of 13 Khz, I think it's about switching pwm, don't you ?
So, first, my question still pertain : does I really need a dedicated dds to perform my signals ?

Second, does marnaw work deal with this (http://www.sxlist.com/techref/io/pwm/harmonic.htm), sometimes also called magic sine waves ?(II)
Best regards.
Sril

Edit (09/23/11) :
(I) is a non finish student work about control motor, does not need to be read, sorry.
(II) deal with a method to suppress harmony under a certain level from base frequency and is not the same as described heare, sorry.
I insist to present my apologizes for stupid lost time to read me.

Go-on my work with a 3-phased generating circuit.
Title: Re: Arduino DDS Sinewave Generator
Post by: BitChanger on Jan 19, 2012, 02:52 pm
Hi

Came across this utility/routine for the Arduino, looks great.  I am still digesting the program as I have very basic knowledge of C language and specifically some of the commands used in this routine.

My question is this;
I would like to modify this to be able to generate 2 sine wave outputs, same frequency, but one of the sine wave needs to be shifted 90 degrees from the other.  Can it be modified for this?  Some help in finding where explanations of all these particular commands could be found would be useful.  I imagine that the commands to drive the second sine wave would need to be contained in the interrupt service routine.

I think I should be able to use the same sine value table but shifted by 64 values for an out of phase wave of 90 degrees.
Thanks for any help.
Title: Re: Arduino DDS Sinewave Generator
Post by: AWOL on Jan 19, 2012, 03:54 pm
Can't you just maintain two table pointers 90 degrees out of phase, and do the summing in the ISR?
(watch out for unsigned arithmetic summing the samples)
It would limit the highest frequency you could generate.
Or, if the two signals are always the same amount out of phase, simply generate a single lookup at compile-time.
Title: Re: Arduino DDS Sinewave Generator
Post by: D4p0up on Feb 01, 2012, 11:44 pm
AWOL nailed it.

As mentioned above, just initialise the two phase accumulators with 0 and 16384 (pi/2).

The rest of the DDS is the same...
Title: Re: Arduino DDS Sinewave Generator
Post by: BitChanger on Feb 02, 2012, 02:17 pm
Thanks for the suggestions.
I got it working just as hoped.  I simply initialized the second PWM output then created a second sine table lookup pointer that is shifted by -64 bytes, which generates the same wave but phase shifted by 90 degrees.  Awesome.  My project can now move ahead.
Title: Re: Arduino DDS Sinewave Generator
Post by: iyahdub on Jun 02, 2012, 11:11 am
A question for those who used this code ( And apologies if some of the question might sound silly, but my issue will be more to do with the hardware).
Would i be feasible to transform this code to  also modulate the signal, using an input ( from a pot, lets say) to influence the speed of modulation ( a LFO, lets say) ?!?
I notice there is a pot...Is that pot influencing the frequency ?!?
Always found this code interesting, but only more recently im getting to grips with the hardware features and limitations.
My aims are low frequencies, audio based anyway. By the way, what would be the limitations of this, as is ?!( I noticed the ook-up table issues for higher frequencies etc)
*PS-GOT IT
Quote
The frequency range reaches form zero to 16 KHz with a resolution of a millionth part of one Hertz!



Thanks in advance and many thanks to the original programmer above all !!
Title: Re: Arduino DDS Sinewave Generator
Post by: BitChanger on Jun 02, 2012, 03:19 pm
Yes, it would be easy to use a potentiometer.  Since the program requires that you specify a frequency value, you can read the pot and use that value to specify the frequency to generate.  The original program used a pot for this very purpose.  I took this out of the code as I needed specific digital frequency values entered by the user.

Title: Re: Arduino DDS Sinewave Generator
Post by: D4p0up on Aug 17, 2012, 06:45 pm
Late reply but hey...

The answer to the question is : probably yes, but not sure at all. Let me explain : LFO, modulation and so on, those require multiplication at which Arduino does not excel at. Multiplication take several clocks depending on what you are doing, and this definitely makes the point.

44.1kHz clock means... one sample every 22 micro second.

You roughly have 18us to do the job, so the math of your modulation shall not be too big, indeed.

Hope this helps.
Title: Re: Arduino DDS Sinewave Generator
Post by: moxy on Nov 29, 2012, 01:00 am
I added a TI 5515 DSP which sped things up a bit ..
Title: Re: Arduino DDS Sinewave Generator
Post by: vanashree on Aug 11, 2013, 07:34 pm
hi,
in my project i want to use dds with arduino for generation of desired frequency upon command in the range of 125 hz to 8khz and then also vary there amplitude (increase or decrease) upon command using a variable gain amplifier.I want this selection of frequency and amplitude to be done using computer i.e. generation of desired frequency and amplitude upon a click on computer.
Kindly suggest me a proper board and its cost in India.
Kindly reply as soon as possible.
Title: Re: Arduino DDS Sinewave Generator
Post by: Nishant_Sood on Aug 15, 2013, 01:01 pm
Quote
Kindly suggest me a proper board and its cost in India.
Kindly reply as soon as possible.


Well you just need a standard Arduino Deumilanove or uno etc clones out there remember that the code used is working with registers of an ATmega328 (ATmega168 and 88 will suffice too!) so lookon to have the arduino clone or original arduino which these chips, also you would needsomepassives to create the low-pass filter.

How to make it: The linkis here:

http://interface.khm.de/index.php/lab/experiments/arduino-dds-sinewave-generator/
Title: Re: Arduino DDS Sinewave Generator
Post by: tjk3052 on Nov 16, 2013, 03:10 am
Hi. I have a question about this DDS sinewave generator. Why is Timer0 is disabled in the setup? I need to use the millis() function and it doesn't work without Timer0.

Code: [Select]

  // disable interrupts to avoid timing distortion
  cbi (TIMSK0,TOIE0);              // disable Timer0 !!! delay() is now not available
  sbi (TIMSK2,TOIE2);              // enable Timer2 Interrupt
Title: Re: Arduino DDS Sinewave Generator
Post by: dc42 on Nov 16, 2013, 05:59 pm

Hi. I have a question about this DDS sinewave generator. Why is Timer0 is disabled in the setup?


Probably because if you don't disable it, the interrupt service routine for timer 0 that gets executed nearly every millisecond causes the DDS interrupt service routine to be delayed a little, and that spoils the purity of the signal.
Title: Re: Arduino DDS Sinewave Generator
Post by: iyahdub on Nov 16, 2013, 06:24 pm
If you dont need much accuracy, you can count time using many other methods... Interrupts being one of them ?! If not, there is always the option of a real time clock chip  ?! Or the proverbial 32.768 kHz crystal, to keep the time? I think it depends how accurate you need it to be !

PS: Actually, the interrupt on the code is quite close... Every 31250  Clock Interrupts, will be  a second, 15625 half a second, and each interrup 0.000032  of a second... A millisecond will be 31.250(31+1/4) and 125 will, make exactly 4 millis...
Title: Re: Arduino DDS Sinewave Generator
Post by: hessaacd on Dec 18, 2013, 12:54 am

Thanks for the suggestions.
I got it working just as hoped.  I simply initialized the second PWM output then created a second sine table lookup pointer that is shifted by -64 bytes, which generates the same wave but phase shifted by 90 degrees.  Awesome.  My project can now move ahead.



I want to do the exact same thing, which is to shift a second sine wave by 90 degrees. Can anyone provide the updated code to perform this? I'm having trouble figuring out what needs to be added.
Alan
Title: Re: Arduino DDS Sinewave Generator reply quick
Post by: vanashree on Jan 06, 2014, 03:45 pm
i have bought arduino uno borad. i found the attached file from arduino forum. but shows compling errors:
AD9835 doesnot have a name type.
and in the other file:
ad9835_forum_arduino.ino:4:22: error: WProgram.h: No such file or directory.
i want to program my dds kindly help this is urgent.
reply soon.
regards
vanashree.
Title: Re: Arduino DDS Sinewave Generator
Post by: dc42 on Jan 06, 2014, 04:13 pm
You need to rename file ad9835_forum_arduino.ino to AD9835.h, and inside that file change #include "WProgram.h" to #include "Arduino.h".
Title: Re: Arduino DDS Sinewave Generator
Post by: haydensmart on Jan 24, 2014, 02:34 am
Hi all,
Long time reader, first time seeker.

I am trying to create a Pure Sine Wave, Fixed Frequency Inverter utilizing a H-Bridge output circuit feeding a Transformer. This way I can use half the DC Voltage to produce the same Final Output. The issue I have is that whilst utilizing one output, the the Transformer is always live as I swap the polarity of the winding when I turn off. This creates Noise and reduces efficiency.

My Aim is to utilize two PWM outputs and achieve the following.

Positive Wave Cycle Output A Utilises PWM Signal from Sin of the Angle Output B Remains Low.
    This Pulses DC+ on the 48V Terminal of Transformer Input and Maintains DC- on The 0V Terminal
    This will eliminate the Reversing of the Input Winding when the Output is low.
Negative Wave Cycle Output B Remains Low and Output B Utilizes PWM signal from Sin of the Angle.
    This Maintains DC- on the 48V Terminal of the Transformer Input and Pulsed DC+ on the 0V Terminal

Could anyone please help me with code or any further suggestions?
Title: Re: Arduino DDS Sinewave Generator
Post by: haydensmart on Jan 24, 2014, 03:39 am
Just a Quick update that people may be interested in.

What I have done to work my previous post is to create a second wave 180 deg out, then use the sin of the angle to set the pwm rate.

To do this I use an actual sin table as opposed to the amplitude sin map, then to create an inverse wave i simply use inv of sin = (1-(Sin of angle))-1

if sin of the angle =< 0 set the pwm to 0
if sin of the angle > 0 set the pwm to (sin of angle * 100%)

100% is 254 on 8bit PWM

I will post code soon.
Title: Re: Arduino DDS Sinewave Generator
Post by: _eric_ on Mar 19, 2014, 02:22 pm
Hi,

dfreq and refclk are double and pow return a double.

the result of this calcul should be a double:
Code: [Select]
tword_m=pow(2,32)*dfreq/refclk;  // calulate DDS new tuning word


But tword_m is declared as volatile unsigned long.

Can you explain ?
Title: Re: Arduino DDS Sinewave Generator
Post by: _eric_ on Mar 19, 2014, 07:20 pm
I don't understand the use of tword_m and phaccu.
Why multiply by 2^32 and then divide by 2^24  with icnt=phaccu >> 24?

directly in main  :

Code: [Select]
icnt = 256 * defreq / refclk; // 256 = sizeof (sine256)

with defreq, refclk and icnt unsigned int long.
Title: Re: Arduino DDS Sinewave Generator
Post by: _eric_ on Mar 19, 2014, 09:17 pm
I have tested with in the Interrupt :
 
Code: [Select]
offset += icnt;
  if (offset > 255) offset = 0; 
  OCR2A=pgm_read_byte_near(sine256 + offset);


It's OK but poor resolution...

I have now understand the effect Of 2^32 multiplication for the high resolution.
Very interesting concept !
Title: Re: Arduino DDS Sinewave Generator
Post by: pito on Mar 19, 2014, 09:43 pm
When working with AD98xx dds chips you have to work with 64bit (long long) as otherwise the calculated tuning word will be not precise..
For example:
Code: [Select]
volatile long long unsigned int tword_m = (4294967296LL * dfreq) / refclk;  // calulate DDS new tuning word
Title: Re: Arduino DDS Sinewave Generator
Post by: AdaZus on Jul 02, 2014, 01:06 pm
Hello,
firstly many thanks at Martin for your useful and interesting work about sine wave generation on Arduino!
I build it in the same way and amplified the sinevawe with the TDA7052. It works fine.
But now I need also to regulate the volume with a digital potentiometer.
I found this example:
http://www.instructables.com/id/Digital-Potentiometer-MCP41100-and-Arduino/all/?lang=de
Unfortunately the ISP communication needs PIN 11 for MOSI.
http://arduino.cc/de/Reference/SPI
To solve this problem, I tried to change the frequency output pin11 to pin3,
pinMode(11, OUTPUT);     // pin11= PWM  output / frequency output now
pinMode(3, OUTPUT);     // pin3= PWM  output / frequency output

Timer 2 is assigned to pin11 and pin3
http://www.micha.st/?Arduino-Notizbuch:Erfahrungen:Never_touch_timer0, but it didn't work.  

Are there also other changes to make? Maybe anyone knows what to do?

Title: Re: Arduino DDS Sinewave Generator
Post by: rbarr80 on Oct 31, 2014, 05:34 pm
Is there a wiring diagram for this function generator?
Title: Re: Arduino DDS Sinewave Generator
Post by: badoumba on Mar 16, 2015, 05:21 pm
Hello experts.

I tried this code which is obviously working very well, but must be adapted for a specific need I have: on the full range of audio frequencies (20Hz - 20KHz), I would need some waveform with the lesser possible distortion rate and an almost constant volume.

- I will add a class 2 Butterworth low-pass filter instead so to have a flat output from my active band.

- I was wondering if upgrading for a 512 resolution and 2ms instead of 4 would be possible with my Arduino Uno board? I don't have any scope, so I can't figure out what the code would produce. This will reject the distorsion frequencies much higher I imagine and reduce their volume at the same time (20log512 > 20log256). What would be the best possible output with this Arduino board (and should I upgrade it as well)?

Thanks for any thought!


PS: I am not visiting so often in this forum. I apologize if I omit to thank some of you for their replies on previous posts, this might have happened!

Title: Re: Arduino DDS Sinewave Generator
Post by: germancorrea on Mar 30, 2015, 05:59 am
has anyone tryed to run this code on a Arduino Due using same PWM

Can you supply code modifications
Title: Re: Arduino DDS Sinewave Generator
Post by: alexandr_st on Apr 27, 2015, 02:13 pm
Hello guys,
Please can you help me to run code of sinewave generator on Arduino Nano   atMega328 IC?  I'm new user of Arduino and haven't any knowleges of programming. Compiller write next message "Arduino: 1.6.3 (Windows XP), board Arduino Nano, ATmega328"

DDS_generator.ino:16:10: error: 'prog_uchar' does not name a type

In file included from DDS_generator.ino:13:0:

DDS_generator.ino: In function 'void __vector_9()':

DDS_generator.ino:118:28: error: 'sine256' was not declared in this scope

I need to generate sinewave signal for servomotor resolver for output signal reading. My big thanks for any answers!


Title: Re: Arduino DDS Sinewave Generator
Post by: alexandr_st on Apr 29, 2015, 05:00 pm
Problem solved. My best wishes to guys from russian cyberforum!

PROGMEM  prog_uchar sine256[]

replaced to

const PROGMEM  unsigned char sine256[]

board generate signal  excellent
Title: Re: Arduino DDS Sinewave Generator
Post by: Virtualan on May 05, 2015, 11:13 pm
Hello,
firstly many thanks at Martin for your useful and interesting work about sine wave generation on Arduino!
I build it in the same way and amplified the sinevawe with the TDA7052. It works fine.
But now I need also to regulate the volume with a digital potentiometer.
I found this example:
http://www.instructables.com/id/Digital-Potentiometer-MCP41100-and-Arduino/all/?lang=de
Unfortunately the ISP communication needs PIN 11 for MOSI.
http://arduino.cc/de/Reference/SPI
To solve this problem, I tried to change the frequency output pin11 to pin3,
pinMode(11, OUTPUT);     // pin11= PWM  output / frequency output now
pinMode(3, OUTPUT);     // pin3= PWM  output / frequency output

Timer 2 is assigned to pin11 and pin3
http://www.micha.st/?Arduino-Notizbuch:Erfahrungen:Never_touch_timer0, but it didn't work. 

Are there also other changes to make? Maybe anyone knows what to do?


I had similar issue using a UNO. I had to make the following changes to get it on pin 3.

pinMode(6, OUTPUT);      // sets the digital pin as output
pinMode(7, OUTPUT);      // sets the digital pin as output
pinMode(3, OUTPUT);     // pin11= PWM  output / frequency output

then change the PWM timer...

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

  // Timer2 PWM Mode set to Phase Correct PWM
  cbi (TCCR2A, COM2B0);//  <<<<<<<    Change these // clear Compare Match
  sbi (TCCR2A, COM2B1);//  <<<<<<<

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

then change the read line to..

OCR2B=pgm_read_byte_near(sine256 + icnt);

Hope it works for you.
Title: Re: Arduino DDS Sinewave Generator
Post by: Schotterpaule on Jul 13, 2015, 08:50 pm
I implemented this DDS for a turntable motor control.  I could use a second 90° phase shifted second output. I understand the theory, send a value 64 steps further from the lookup table to pin 10 but i am totally lost. My arduino knowledge is pretty basic, the last micro i programmed was an AT8051 compatible, i already read the Secrets of Arduino PWM but thats pretty advanced, can anybody give me a hint how to start?
Title: Re: Arduino DDS Sinewave Generator
Post by: Schotterpaule on Jul 13, 2015, 09:20 pm
Problem Solved:

http://digitalcommons.calpoly.edu/cgi/viewcontent.cgi?article=1129&context=eesp
Title: Re: Arduino DDS Sinewave Generator
Post by: crlMidi on Dec 21, 2015, 09:11 pm
Still relevant to this thread:

With the latest versions of Arduino you need to change a line in the code given in
http://interface.khm.de/index.php/lab/interfaces-advanced/arduino-dds-sinewave-generator/

The reason is given in http://forum.arduino.cc/index.php?topic=272313.0

Change
PROGMEM  prog_uchar sine256[]  = {
to
PROGMEM  byte sine256[]  = {       ...or
PROGMEM  char sine256[]  = {

Both work for me but I don't which is the more correct; byte seems the more logical.
Title: Re: Arduino DDS Sinewave Generator
Post by: Suzzannee144 on Jan 20, 2016, 04:48 am
@D4p0up

why not call  setupSPI();  in  setup()  ??

The same code....

and try Serial.begin(115200)  then you have more time for other things....


I would like to set up a loop whereby six different frequencies will run , one after the other. Is this the proper board
http://interface.khm.de/index.php/lab/interfaces-advanced/arduino-dds-sinewave-generator/

for this undertaking? I am familiar with arduino but writing code makes my head hurt. I want to use it in conjunction with some experiments that may be very useful in combating nuclear radiation, so far my tests have been somewhat successful, but I think using the varied frequencies would be much better and cannot see myself getting up every 4 hours to change the frequency...Can you help?
Title: Re: Arduino DDS Sinewave Generator
Post by: pjrc on Jan 20, 2016, 12:46 pm
Can you help?
Maybe, but details like the 6 specific frequencies would make your question clearer...
Title: Re: Arduino DDS Sinewave Generator
Post by: Picotest on Feb 16, 2016, 07:24 pm
I just published an article on improving the AD9851 output filter and thought this forum might find it helpful

http://www.edn.com/design/test-and-measurement/4441389/2/Optimizing-Arduino-and-the-AD9851-DDS-signal-generator

Title: Re: Arduino DDS Sinewave Generator
Post by: Bob808 on Mar 05, 2016, 04:47 am
The output sine wave is 0-5V or -2.5V to 2.5V ?
If it's 0V to 5V then that might be a problem as some hardware might consider the sinewave riding a DC of half it's vpp value.
Title: Re: Arduino DDS Sinewave Generator
Post by: Mimay on Mar 12, 2016, 11:11 pm
hey when verify this DDS sine wave generator code give me this error
any body can help me please

error: 'prog_uchar' does not name a type

 PROGMEM  prog_uchar sine256[]  = {

          ^

In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:28:0,

                 from sketch\zezo.ino.cpp:1:

C:\Users\ENG MOHAMED\Desktop\zezo\zezo.ino: In function 'void __vector_9()':

zezo:113: error: 'sine256' was not declared in this scope

   OCR2A=pgm_read_byte_near(sine256 + icnt);   

                            ^

exit status 1
'prog_uchar' does not name a type





* 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
}
Title: Re: Arduino DDS Sinewave Generator
Post by: AWOL on Mar 12, 2016, 11:15 pm
https://www.arduino.cc/en/Reference/PROGMEM
Title: Re: Arduino DDS Sinewave Generator
Post by: sandyufp91 on Mar 16, 2016, 01:49 pm
PROGMEM  prog_uchar sine256[] ------->>>>>>  PROGMEM  const unsigned char sine256[]
That solved my problem. But i want to ask a question:

Why the array of sine256 is only 256 values. Because from 127->255->127 are 256 and for the other halfwave is 127->0->127 are too 256. I think 512 will double the precision but not sure ??!?
Title: Re: Arduino DDS Sinewave Generator
Post by: AWOL on Mar 16, 2016, 02:09 pm
Quote
I think 512 will double the precision
. . . and halve the frequency.
Title: Re: Arduino DDS Sinewave Generator
Post by: sandyufp91 on Mar 16, 2016, 02:36 pm
. . . and halve the frequency.
Yes, but can we double the frequency? I think no for timer2. But what to change in code to use timer0 on 62500Hz and use it with pins 5 or 6 to generate the sinewave? So that i can generate sinewave with 32000hz and 512values right?
And thank you for fast response
Title: Re: Arduino DDS Sinewave Generator
Post by: wb8nbs on Mar 21, 2016, 02:21 am
Yes, but can we double the frequency? I think no for timer2. But what to change in code to use timer0 on 62500Hz and use it with pins 5 or 6 to generate the sinewave? So that i can generate sinewave with 32000hz and 512values right?
And thank you for fast response
I think you will find that at higher frequencys, the phase accumulator is skipping over values in the table anyway. I posted some waveforms on my wordpress page (https://wb8nbs.wordpress.com/2015/12/08/more-fun-with-direct-digital-synthesis-32u4-and-fast-pwm/). Look at the shape difference between 1000Hz, 5000Hz and 10000Hz.
Title: Re: Arduino DDS Sinewave Generator
Post by: giammamob on Apr 05, 2016, 05:27 pm
Hello,
I tried to use your Arduino sketch for generate a sinusoydal wave.

I load it on my Genuino mega 2560 but it returns me this error at line 16 'prog_uchar' does not name a type
Can you help me about fix it please? i'm getting crazy
Title: Re: Arduino DDS Sinewave Generator
Post by: AWOL on Apr 05, 2016, 06:13 pm
See reply #53
Title: Re: Arduino DDS Sinewave Generator
Post by: allanhurst on Apr 07, 2016, 01:28 am
I'd do this in fast hardware  - FPGA's - brilliant widgets.
program in verilog or VHDL

not trivial.

not really an arduino job at high speed.

regards

Allan.

ps done it up to 100MHz for RF
Title: Re: Arduino DDS Sinewave Generator
Post by: nernoe on Jul 14, 2016, 07:56 am
Hi ,

I have a similar problem as you do the 90degree phase shifted second output.
I want a second output , with continously variable phase shifting (with an second poti).

I'm a beginner, can you help code ?

Thank You
nernoe


nernoe@gmail.com

Title: Re: Arduino DDS Sinewave Generator
Post by: eightbitguy on Sep 20, 2016, 05:17 am
Someone else was looking at a 3 phase AC motor controller. I am on the learning curve and there are MANY details in 3 phase AC motor control that I am just starting to understand. I think you get the best efficiency if you measure currents in the windings and do field oriented control. Second choice seems to be using a rotational position sensor and put the motor on a dynamometer to map out the phase needed to drive the motor at peak efficiency at different frequencies. Third choice is a constant V/f (Voltage over frequency) drive. There are tons of details to get those working so I won't go into that here.

So.... I was wondering if option Three (V/F) mode could be coded up and if an Arduino could be fast enough. I have NOT developed the high voltage drivers but I think the following code, distilled from various sources may be a starting point. It does not control V/F=Constant and only puts out a AC voltage that is centered around V/2 or 5V/2=2.5V with an amplitude of 2.5VAC. I think eventually, I will need SIX PWM circuits with two required for each phase: one to generate a POSITIVE drive and a separate PWM to drive the NEGATIVE side of a MOSFET/IGBT pair. Some hardware to prevent "Shoot-through" will be required and some of the dedicated three phase driver chips may be an option. It's probably best the keep everything digital all the way to the MOSFET drivers.

So, back to the Aurduino side. The following code seems to work. I set the frequency to a very 0.5Hz, triggered my scope on the TEST_BIT (pin 7) and watched the PWM period grow and shrink absolutely symmetrically around a point a few microseconds before the TEST_BIT went high. The three phases so this sequentially. For now, I am just using THREE PWM channel with TWO Timers. Importantly, the two timers are synchronized (See this page about synchronizing the timers: http://www.openmusiclabs.com/learning/digital/synchronizing-timers/ ). Please see the comments in the code for credit where credit is due. I did little to the code but a few tweaks were needed to sync the timers and make sure the interrupt routine completed before being interrupted again. Floating point math was a big NO-NO!

I ran it on an Duemilenove. Some thoughts: The interrupt rate is about 31.372kHz. and the maximum update rate is two samples of the sinusoid so the maximum frequency will be something like 16kHz. How close you get to 16kHz will depend on filtering you do on the PWM. However, Nyquist is a limit and it would be easier to run much lower in frequency. Consider that a 12000RPM motor is running at 12000RPM/60seconds or 200Hz. So I think we have more than enough sampling on the high end. We have 24 bits below the actual value passed to the lookup table. Any changes below the bits passed to the sin look-up table will result in the same values being output by the PWM. The lowest frequency without repeating points in the sine table will be 31.372kHz/256 (for a 256 point lookup table) or 122Hz. You will get quantization noise below 122Hz but that's probably okay. How clean a spectrum do you need to drive an AC inductive motor? It's a huge inductor so getting high frequencies into it will be hard. It's a natural low pass filter.

I added 4 oscilloscope plots. The interrupt service routine uses 5.691 us but there is some overhead (pushing stuff on the stack before and popping it back after the interrupt) adds another 3-4 usec. The green trace is high while the interrupt vector is executing the code. The yellow, blue and magenta traces show nice synced PWM pulses and vary around the center of the display as the Phase-correct PWM should.

Next Steps:
0) I want to drive some LEDs to visualize the output and add a potentiometer as a throttle.
1) Add V/F amplitude control. This will depend on the motor specs so perhaps getting the high voltage/current section will higher on this list.
2) Driving the High and Low Side with PWM: Two options. Maybe I add sign bit and use some AND gates to control either the high or low side but not both. Or I double the number of PWM channels to SIX and drive each phase with a separate but SYNCED PWM. However, this relies on software to prevent shoot-through by making sure both the high and low sides are NOT simultaneously, on!
3) Interface to a MOSFET driver.
4) Correct me if I'm wrong: The PWM generates a desired voltage when we really want to control current. Some feedback from current sensors is going to be needed to make sure we get a current proportional to this voltage. Then, is the Arduino going to be fast enough to do all the desired/ required signal processing?

Title: Re: Arduino DDS Sinewave Generator
Post by: eightbitguy on Sep 21, 2016, 04:22 am
V/f control added.

You need to find the voltage and the frequency cutoff to use. The voltage will vary linearly from ZERO at zero frequency to full amplitude (100% city cycle PWM) at the cutoff frequency and above.

Title: Re: Arduino DDS Sinewave Generator
Post by: AWOL on Sep 21, 2016, 10:15 am
Code: [Select]
const uint64_t twoTo32 = pow(2, 32); // compute value at startup and use as constant
Isn't the following more intuitive ?
Code: [Select]
const uint64_t twoTo32 = 0x100000000ULL;
Title: Re: Arduino DDS Sinewave Generator
Post by: eightbitguy on Sep 21, 2016, 08:53 pm
Yup! Thanks.

Just ordered an IR2130 and some opto couplers from DigiKey!

I have a motor I want to see spin! Gotta work up to the appropriate voltages but with no load, I may be able to do this with 20-30 Volts.
Title: Re: Arduino DDS Sinewave Generator
Post by: eightbitguy on Sep 22, 2016, 11:45 pm
I think I understand the code in loop() that disables interrupts. I believe the correct thing to do is the following:

I think resetting the TIMSK2 bit, TOIE2 will prevent an interrupt from occurring. What I actually want is for the interrupt to occur but let it be queued until the ISR() has completed. Therefore, I want to use noInterrupts() and interrupts() rather than the cbi() and sbi() to turn off the interrupts. It's a subtle but important issue:

If an interrupt is missed, the phase of the sinusoid will be delayed and the error is cumulative. The spectral purity of the sinusoid will be affected. If an interrupt occurs during the writes to the variables, the ISR may see invalid or incomplete values which will affect a single but whole PWM period of 32usec.

I still need to check if this is a problem...

I may not have measured this correctly but I measured on the scope that the Amplitude calculation took 12.62us and the tword_m calculation took 41.52us. this means that the interrupt could be delayed by as much as 54.14usec PLUS the overhead of the noInterrupt() and interrupt() calls.

Maybe Arduino is just not fast enough to run at 32us. Perhaps I need to switch to a pre-scale of 8...


void loop()
{
//       cbi (TIMSK2, TOIE2); // disble Timer2 Interrupt
         noInterrupts();      // Does this cause interrupts to be queued?
// These two variable ARE used by the ISR AND must be matched to each other
// therefore I am protecting them from interrupts during this phase of the code. 
         Amplitude = 256 * dAmplitude;        // This takes 12.62usec
         tword_m = twoTo32 * dfreq / refclk; // calculate new DDS tuning word  --> Takes 41.52usec
         interrupts();
//       sbi (TIMSK2, TOIE2); // enable Timer2 Interrupt
Title: Re: Arduino DDS Sinewave Generator
Post by: eightbitguy on Sep 27, 2016, 11:36 pm
Hi All,

Okay, I now have it working as THREE phase sinusoidal DDS. I have a high and a low output for each sinusoidal channel. Let's call the three phases U, V, and W.

Pin # Channel
6         U-high
5         U-low

9         V-high
10       V-low

11       W-high
3         W-low

Trigger your scope on Pin 7
If you are debugging the interrupt routines pin 7 is high while you are in the interrupt routine (after all the stack pushes).

Use pin 13 (LED pin) to see what's happening in the loop() but you will need to uncomment the digitalWrite() statements surrounding the noInterrupts() and interrupts() calls.

The Interrupt service routine runs in just under the period of the interrupt of 32us. Any longer and we will be in trouble. The loop() section of the sketch disables interrupts and it too runs in under 32usec. However, this only happens once per second. If either of these two sections gets longer than 32us interrupt period, we will miss interrupts. I'm watching the output on a scope and haven't seen any glitches but your mileage may vary. Glitches may destroy your MOSFET or drivers so be careful. I haven't built that part of the circuit yet.

Hopefully I have commented the code sufficiently that you can figure out what I'm trying to do...


Title: Re: Arduino DDS Sinewave Generator
Post by: Rabobsel on Nov 22, 2018, 04:02 pm
Hi, I'm an interested hobby electronics just learning Arduino, but I'm not very well versed in C-programming.
I would be glad if you could answer a few questions about the project that can be found under the link in the first post Arduino DDS Sinewave Generator by Martin Nawrath (http://interface.khm.de/index.php/lab/interfaces-advanced/arduino-dds-sinewave-generator/).
The program runs flawlessly on my arduino uno, but despite reading some passages in the user manual of the Atmega8 and tormenting google, I do not understand some parts of the program code.

1.)
To save myself the manual entry of 255 sine values into an array, I tried to do this with the following code:
-----------------------------------------------------------------------------------------------
#include <math.h>
#include <avr/pgmspace.h>

int sinusArray[] = {};

for (int i = 0; i < 255; i++)
 {
   const int sinusArray PROGMEM = {sin((2*PI*i)/255)};
 }
-----------------------------------------------------------------------------------------------
As you expect, this does not work for several reasons:
- You can not change const variables, but variables in flash memory must be const type.
- You can not release or write to flash memory from a running program, but a for loop can only be used in a running program.

What are the advantages of saving the sine values in flash memory and not in the RAM or EEPROM ?
Do you know a way to realize what I wanted to do, or the manual entry is the only possible way ?

2.)
In the comments the author makes some calculations that I can not understand:

In line 33, the author names a "measured" PWM-clock of 31376.6 Hz, but how did he measure it?

In line 114, the author gives a calculated value of 31472.55 Hz for the same measure, I assume he calculated it with the formula f (PWM) = f (clk) / (N * 510) from the Atmega8 user manual.
I have read the whole section in the user manual about the phase correct PWM mode, but there is no reference to the value 510 or where it came from. How does this value of 510 come about?

In line 117 the author calls a runtime of 8 milliseconds. Where did he get this value from?
I did not find anything about runtime computation in the User Guide.

3.)
In line 73, the author uses an infinite loop (while (1) {}) in the "voidLoop () {}" method. I'm surprised, because I thought so far that the "voidLoop () {}" method itself is already an endless loop.

4.)
In lines 123 and 127 the author shifts the value of the variable "phacculow" and "phaccuhigh" by 24 digits to the right. I do not understand why he is doing this, because the variable gets a completely different value then.

5.)
From line 131 to 134, the author uses the following code:
-----------------------------------------------------------------------------------------------
if(icnt1++ == 125) { // increment variable c4ms all 4 milliseconds
c4ms++;
icnt1=0;
}
-----------------------------------------------------------------------------------------------
I think I understand why this code exists, but I do not understand how the author comes to the values used. (125 and 4 milliseconds).
Is the 4 milliseconds halfway through 8 milliseconds runtime from the prvious calculation and so rests half a period ?
Are the 125 almost half the cycle time for the array with the 254 sine values so it resets after an half-sine-wave?

I apologize for the long text and thank you, if you have read this far.

Sincerely,
Rabobsel
Title: Re: Arduino DDS Sinewave Generator
Post by: MarkT on Nov 22, 2018, 07:44 pm
Hi, I'm an interested hobby electronics just learning Arduino, but I'm not very well versed in C-programming.
I would be glad if you could answer a few questions about the project that can be found under the link in the first post  "Arduino DDS Sinewave Generator by Martin Nawrath".
Can you please quote the link here, rather than expect people to search for it...  I found a slightly
different copy with different line numbers in places...
Quote
The program runs flawlessly on my arduino uno, but despite reading some passages in the user manual of the Atmega8 and tormenting google, I do not understand some parts of the program code.

1.)
To save myself the manual entry of 255 sine values into an array, I tried to do this with the following code:
-----------------------------------------------------------------------------------------------
#include <math.h>
#include <avr/pgmspace.h>

int sinusArray[] = {};

for (int i = 0; i < 255; i++)
  {
    const int sinusArray PROGMEM = {sin((2*PI*i)/255)};
  }
-----------------------------------------------------------------------------------------------
As you expect, this does not work for several reasons:
- You can not change const variables, but variables in flash memory must be const type.
- You can not release or write to flash memory from a running program, but a for loop can only be used in a running program.
Indeed - you need to use an array initializer with precomputed values to set up PROGMEM
Quote
What are the advantages of saving the sine values in flash memory and not in the RAM or EEPROM ?
Far more memory available in flash, Uno has 32k flash, 1k EEprom, 2k SRAM IIRC
Quote
Do you know a way to realize what I wanted to do, or the manual entry is the only possible way ?
What manual entry?  Just stick the data in a generated header file as is normally done
for big tables.
Quote
2.)
In the comments the author makes some calculations that I can not understand:

In line 33, the author names a "measured" PWM-clock of 31376.6 Hz, but how did he measure it?
With a frequency meter I guess, or something with one built in like a 'scope.
Quote
In line 114, the author gives a calculated value of 31472.55 Hz for the same measure, I assume he calculated it with the formula f (PWM) = f (clk) / (N * 510) from the Atmega8 user manual.
I have read the whole section in the user manual about the phase correct PWM mode, but there is no reference to the value 510 or where it came from. How does this value of 510 come about?
In phase correct mode the timer counts up then down 0, 1, 2, 3, ...., 0xFE, 0xFF, 0xFE, ..., 2, 1, 0, 1, ...
Quote
In line 117 the author calls a runtime of 8 milliseconds. Where did he get this value from?
I did not find anything about runtime computation in the User Guide.
Misprint, obviously meant to be 8µs
Quote
3.)
In line 73, the author uses an infinite loop (while (1) {}) in the "voidLoop () {}" method. I'm surprised, because I thought so far that the "voidLoop () {}" method itself is already an endless loop.
Can only speculate that's to avoid the time penalty of all the serial checking that happens in the loop that
calls loop(), but yes it seems pointless.
Quote
4.)
In lines 123 and 127 the author shifts the value of the variable "phacculow" and "phaccuhigh" by 24 digits to the right. I do not understand why he is doing this, because the variable gets a completely different value then.
You think a 2^32 entry sine table is practical?
Quote
5.)
From line 131 to 134, the author uses the following code:
-----------------------------------------------------------------------------------------------
if(icnt1++ == 125) { // increment variable c4ms all 4 milliseconds
c4ms++;
icnt1=0;
}
-----------------------------------------------------------------------------------------------
I think I understand why this code exists, but I do not understand how the author comes to the values used. (125 and 4 milliseconds).
Is the 4 milliseconds halfway through 8 milliseconds runtime from the prvious calculation and so rests half a period ?
Are the 125 almost half the cycle time for the array with the 254 sine values so it resets after an half-sine-wave?
4ms is 125 cycles of the PWM waveform (approximately).  This is so c4ms variable can be used for timing in loop().  The normal timer0 interrupt is disabled to prevent jitter in running the timer2 ISR.
Quote
I apologize for the long text and thank you, if you have read this far.

Sincerely,
Rabobsel
Title: Re: Arduino DDS Sinewave Generator
Post by: bulyshor on Apr 16, 2019, 07:34 pm
Can someone explian to me from it comes 4ms for c4ms, 250 in void loop and 125 in ISR?
Title: Re: Arduino DDS Sinewave Generator
Post by: MarkT on Apr 19, 2019, 11:14 pm
The timer is in phase-correct mode, so counts up and down, cycling every 510 system clocks.
At 16MHz system clock thats a cycle rate of 31.37kHz approx, divide that by 125 and you get
251Hz roughly, ie a period of 4ms.