I'm playing around with Martin Nawrath's DDS Sinewave Generator (http://interface.khm.de/index.php/lab/experiments/arduino-dds-sinewave-generator/) and I'm trying to understand the code. At it's most basic, I get what most of it is doing. I've been able to create arrays with values for square waves, triangle waves, ramps, and what-not and have them play back but I'm having trouble understanding how it actually reads through the arrays.
The part of the code in question is this:
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
}
I get that when the timer2 interrupt occurs this function is called and I get what the sbi and cbi calls are doing (though I don't need that functionality since I don't have an oscope yet), but I don't understand how this interrupt outputs the values in the sine256 array at the correct intervals/frequency. I know it's just a lack of knowledge on my part (this is one of my first ventures into microcontrollers and programming in general) but I'm wondering if anyone can help me. An initial search turned up nothing.
sbi() and cbi() are assembly instruction to set or clear a bit directly on a port. Those functions are just wrappers around the instruction to make the code as efficiently as possible.
I think it's a about time that someone should make a complete tutorial for a complete noob how to create a sinewave using the arduino, to explain how timers and their specific registers work,
how interrupts are implemented in such project, how a sine table is calculated and defined. I know there's plenty information on the internet (avrfreaks and such) but that info is for profesional programmers and electronics designers that have plenty of expirience and understanding, and mosto of us are just mere mortals that just have entered the world of microcontrollers so please help. :-/
Don't take this the wrong way I am still a noob and in my current project I need to generate a PWM that in a kind of way mimics sinewave (SPWM), the PWM will switch powerful transistors in a H-bridge (in diagonal pairs) to create this PWM sinewave for a 1PHASE Induction Motor.
I don't think noobs who don't understand basic arithmetic (for that is all a phase accumulator is) should be writing software to control 'powerful' hardware that moves and could therefore potentially cause injury.
Well, after researching what a phase accumulator was (fancy name for a counter/address offset) and understanding what pgm_read_byte_near() was doing, I still don't understand how that controls the PWM at pin 11. I see that OCR2A is an output compare register but I can't find any information on how that affects or controls the PWM.
Regardless, I understand how this works at the functional level and I'm curious if there's a way to do the same thing with a parallel 8-bit DAC on PORTD. In my mind, it should work. Just write the value from pgm_read_byte_near(sine256+icnt) to PORTD but I want to know if I'm missing anything.
I don't think noobs who don't understand basic arithmetic (for that is all a phase accumulator is) should be writing software to control 'powerful' hardware that moves and could therefore potentially cause injury.
THIS IS MY PERSONAL OPINION
Well it's not just about the phase accumulator, it's about how the whole proccess of creating that sine is done.
Everyone started from scratch eventually and tries to understand what is before him, nobody was born with the knowledge of those before him( though I don't know to what point the experiments with DNA memory have progressed ).So this is why I am asking for help.
For starters how the sine look up table is calculated?
And don't worry everything is tested before entering real service and as always there's 'hardware' failsafe solution in parrallel
To create a array of values for a sinusoid, first decide how many values are going to be in that array. For example, say you're going to use 32 values. Then decide what level of resolution you want on that sine wave. Let's say 8 bits (max value of 255). In a tool like Excel, do something like this: (sin(2[ch8719]/(32x))*127)+127 where x is the index in the array plus 1. That's how I did it, at least. It seemed to work for me but now I'm just having trouble understanding how the OCR2A register controls the PWM.
(I know you were being rhetorical about the sine wave table but hey... ::))
GtrBMart I'll contact you someday about that DDS Sine Gen for tutoring and clarification so be prepared, I am serious, I hope you're fine with that? :-?
GtrBMart I'll contact you someday about that DDS Sine Gen for tutoring and clarification so be prepared, I am serious, I hope you're fine with that?
If you'd like! I think I understand most of it now. I think my misunderstanding mostly stemmed from not knowing how the ATMega worked. I sure wouldn't mind some clarification though!