Show Posts
Pages: [1]
1  Using Arduino / Project Guidance / Re: DDS Acceleration / Deceleration techniques? on: June 04, 2012, 10:47:02 pm
Just a quick note to say that I got the acceleration code up and running.  Thanks for the tips and info that helped me sort this out in my brain so that I could push out the necessary code !! 

2  Using Arduino / Project Guidance / Re: DDS Acceleration / Deceleration techniques? on: June 04, 2012, 06:31:32 pm
I had never heard of a DDS motor controller before. What is it?

AC synchronous motors are used in many vinyl turntables.  The speed regulation of the motor is controlled by the frequency of the sine wave of it's AC supply (usually 60Hz from the line voltage).  I have built a variable frequency dual sine wave generator to drive such motors so I can accurately set the RPMs of a turntable by varying the sine frequency.  A DDS generates a very precise sine wave via digital synthesis.  I use the Arduino to generate the two out of phase sine waves that are then amplified to drive the motor.

You can see detailed information about my project and my progress here at my audio blog, if it interests you:

3  Using Arduino / Project Guidance / Re: DDS Acceleration / Deceleration techniques? on: June 04, 2012, 05:12:57 pm
In any case looking to see if their is a formula/method/technique for properly doing an accel decel.  Thanks

It's just like any control algorithm.

In this case you need to start with a current actual speed and a target speed as inputs, and have an output that controls the motor in some way. For example it might be that you have a PWM regulator that effectively gives you torque control - or you might have a stepper motor where you control the speed explicitly.

Your algorithm needs to control the motor control output in order to drive the motor speed towards your target. You could use a PID algorithm for this (there's a library that implements this on Arduino) or just hand-code your own - code in knowledge of what acceleration profile you want the motor to follow and vary the motor control to follow that profile.


To me, functions that return constant values unrelated to what happened in the function smack of poor design - particularly when the return value is not actually used. To design robust code, your called code needs to indicate the normal and abnormal events that have occurred, and the calling code needs to deal with them. Returning garbage hides the places where the return value matters. Ignoring a return value that doesn't matter hides the places where you're ignoring return values that do matter.

Thank you Peter H. for the PID information, just what I was looking for, a proper technique to code.  I will see if I will use the library or just write my own code for it.

As for the return values, you are correct.  The code is in a rough alpha state and contains code that is in place as my thoughts and options were developing.  Some of these ideas never took form and I still have to go through the code to clean out the superfluous stuff such as those never developed return data.

Thanks for your assistance.
4  Using Arduino / Project Guidance / Re: DDS Acceleration / Deceleration techniques? on: June 04, 2012, 05:06:53 pm
Please, edit your post with a code, select it and hit  # hash button at the bar above.
Frequency, IMHO, defined by this line:
  phaccu = phaccu + tword_m;              // soft DDS, phase accumulator with 32 bits
changing tword_m up and down you could vary freq., and motor speed consequently.

Good stuff, done!

As for speed change, yes, as I was writing this post, my ideas started to clear up and I could see how to implement the speed change within the 'sineON'  'sineOFF' routine.  Just sorting out my options now but it should work fine.
Thanks for the help.
5  Using Arduino / Project Guidance / Re: DDS Acceleration / Deceleration techniques? on: June 04, 2012, 03:13:01 pm
It's a lot of code, lots of features so maybe I will just show some key parts of code that have to do with running the motor:

Code that turns motor on or off (user action first case only shown):

  switch (Action) {

        case 1:
        // Start/Stop Pressed
            Action = 0;                             // clear action code

            if (runState1 == 0) {                   // Check if motor is OFF
                sineON();                           // turn on PWMs - RUN ON !!!!
                speedChg = 0;                       // reset speed change flag - new run
            if (runState1 == 1) {                   // Check if motor is ON
                sineOFF();                          // turn off PWMs - RUN OFF !!!!
                if (speedChg == 1) {                // speed was changed during last run - can decide to store in EEPROM or not here.
                    // enter code here for storing speed change values if desired. Future Option?
            updateLCD();                            // update the display

Motor Turn On and Off Functions:

// sineON function;
// Function turns Sine generators ON and sets status bit.
// Returns 1 for on
boolean sineON() {
    sbi(TIMSK2,TOIE2);           // enable Timer2 Interrupt - TURN SINE WAVES ON !!!!
    runStatus |= (1 << 1);       // Set RUN flag bit 1 in run status register - sine ON
    return true;

// sineOFF function;
// Function turns Sine generators OFF and clears status bit.
// Returns 0 for off
boolean sineOFF() {
    cbi(TIMSK2,TOIE2);            // disable Timer2 Interrupt - TURN SINE WAVES OFF !!!!
    runStatus &= ~(1 << 1);       // reset RUN flag bit 1 in run status register - sine OFF
    return false;

Interrupt service routine for DDS operation:

// 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(PORTB,5);                           // Test / set PORTB,5 (pin13) LED - test pin high to observe timing with a oscope

    phaccu = phaccu + tword_m;              // soft DDS, phase accumulator with 32 bits
    icntA = phaccu >> 24;                   // use upper 8 bits for phase accumulator as frequency information
    icntB = icntA - phaseShift;             // calculate offset for lookup table value by -phaseShift setting for PWM B sine
                                            // where value of 64 = 90 degrees, each digit =~ 1.406 degrees

    // read value from ROM sine table and send to PWM DAC A
    OCR2A=pgm_read_byte_near(sine256 + icntA);
    // read value of sine table xx degrees out of phase to output 2nd sine on PWM DAC B
    OCR2B=pgm_read_byte_near(sine256 + icntB);

    if (icnt1++ == 125) {                   // increment variable c4ms every 4 milliseconds - used to compute 1 sec. delay for analogRead
        icnt1 = 0;

    cbi(PORTB,5);                           // reset PORTB,5 test pin (pin13) LED

Hope that is enough code to give you an idea of what is happening.  In any case looking to see if their is a formula/method/technique for properly doing an accel decel.  Thanks

6  Using Arduino / Project Guidance / DDS Acceleration / Deceleration techniques? on: June 04, 2012, 02:25:48 pm

I have a DDS based motor controller with an Arduino.  Working great to control AC synchronous motors.  Now I notice that I will likely have to implement an acceleration/deceleration routine for the motor to control spin up and spin down.  Does anyone know the best techniques / code ideas for how to best implement this?  The general idea is to start at a specified low RPM, accelerate in steps to the target RPM and do the reverse for deceleration. (note, cannot use Delay function as this has been disabled in the project to prevent problems with the DDS timing)

7  Using Arduino / Audio / Re: Arduino DDS Sinewave Generator on: June 02, 2012, 08:19:56 am
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.

8  Using Arduino / Programming Questions / Need help with serial comm and float input on: February 13, 2012, 11:08:31 am
Is there a decent library or other programming solution to simplify the following:

My project involves me interacting with the Arduino via serial console.  I need at some point to let the user enter a float number in the form ###.## via the keyboard and the serial comm.  The arduino needs to get this input and put it into a float variable for latter calculations.

It seems a pretty straight forward requirement, but I don't see any decent program examples or libraries that handle this.
Does anyone have knowledge of how to deal with this?

Any help is appreciated.
9  Using Arduino / Audio / Re: Arduino DDS Sinewave Generator on: February 02, 2012, 08:17:49 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.
10  Using Arduino / Audio / Re: Arduino DDS Sinewave Generator on: January 19, 2012, 08:52:48 am

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.
Pages: [1]