Arduino Forum

Products => Arduino Due => Topic started by: so3ody on May 27, 2014, 03:29 pm

Title: Change the Sine wave frequency
Post by: so3ody on May 27, 2014, 03:29 pm
      Modified   thread " now its posted in thr right way I guess "

I try to generate a sine wave through vaaring the PWM duty cycle. IT works so far

I have a fixed PWM frequency of 10 KHz and I tried to cary the sine wave frequency in the ISR  throught  counting each second item from the sine  array--> this will result a doppel frequency

counting each 4th item of the sine aeeay will result a ground frequency*4

This method is not so good cause I cant really have  a fractions

The only part I need to change now to vary the frequency is this one



Code: [Select]

/* Standard frequency range e.g LENZE VFD 0-300 HZ */
/* Ground sine wave frequency = (PWM_Freq/ Size of sine wave array)
 = 10 000 HZ/ 120 = 83.3 Hz*/
 ul_count++;
/* to vary the sine wave frequency the  u_count must be re defined due to the desired frequency*/
//ul_count= ul_count+2 ;


Can anyone tell me how to make it in another way to change thefrequency not only in 2,4,6,8 way ?

Thanks in advance this is my code
Code:
Code: [Select]

// **INCLUDE FILES & HEADER DATA****INCLUDE FILES & HEADER DATA****INCLUDE FILES & HEADER DATA**
//################################################################################################################

#include "asf.h" // ATMEL SOFTWARE  FRAMEWORK
#include "conf_board.h"
#include "conf_clock.h"
#include "SineArray.h"

//##############################################################################################
// **Global variables and macros****Global variables and macros****Global variables and macros**
//##############################################################################################
/** PWM frequency in Hz */
#define PWM_FREQUENCY     10000
/** Period value of PWM output waveform */
#define PERIOD_VALUE       4096
/** Initial duty cycle value */
#define INIT_DUTY_VALUE   50

//----------------------------------------------------------------------------------------------------------------

//################################################################################################################
// **GPIO pin definitions for 3 PWM signals****GPIO pin definitions for 3 PWM signals**
//##############################################################################################
/* PIN Definition for the third PWM Channel @ Arduino Due Board = PWM  PIN 07 */
#define PIN_PWM_3DPWM_GPIO     PIO_PC23_IDX
#define PIN_PWM_3DPWM_FLAGS   (PIO_PERIPH_B | PIO_DEFAULT)
#define PIN_PWM_3DPWM_CHANNEL PWM_CHANNEL_6


/* PIN Definition for the second PWM Channel @ Arduino Due Board = PWM  PIN 08 */
#define PIN_PWM_2NDPWM_GPIO     PIO_PC22_IDX
#define PIN_PWM_2NDPWM_FLAGS   (PIO_PERIPH_B | PIO_DEFAULT)
#define PIN_PWM_2NDPWM_CHANNEL PWM_CHANNEL_5


/* PIN Definition for the first PWM Channel @ Arduino Due Board = PWM  PIN 09 */
#define PIN_PWM_1STPWM_GPIO     PIO_PC21_IDX
#define PIN_PWM_1STPWM_FLAGS   (PIO_PERIPH_B | PIO_DEFAULT)
#define PIN_PWM_1STPWM_CHANNEL PWM_CHANNEL_4

//----------------------------------------------------------------------------------------------------------------

/** PWM channel instance  */
pwm_channel_t g_pwm_channel_instance;

//##############################################################################################
// **Interrupt handler for the PWM controller****Interrupt handler for the PWM controller**
//##############################################################################################

void PWM_Handler(void)
{
static uint32_t size; /* Size of the sine array*/
static uint32_t ul_count = 0; /* PWM counter value */
static uint32_t ul_duty1 = INIT_DUTY_VALUE;  /* PWM duty cycle rate */
static uint32_t ul_duty2 = INIT_DUTY_VALUE;  /* PWM duty cycle rate */
static uint32_t ul_duty3 = INIT_DUTY_VALUE;  /* PWM duty cycle rate */

uint32_t events = pwm_channel_get_interrupt_status(PWM);

/* Standard frequency range e.g LENZE VFD 0-300 HZ */
/* Ground sine wave frequency = (PWM_Freq/ Size of sine wave array)
 = 10 000 HZ/ 120 = 83.3 Hz*/
 ul_count++;
/* to vary the sine wave frequency the  u_count must be re defined due to the desired frequency*/
//ul_count= ul_count+2 ;
/* to determine the size of the sine array*/
size = sizeof(sine)/2;
if (ul_count >= size) {
ul_count = 0;
}
/* Overlay a sine wave array to a  PWM signal */
/* each output signal is 120 degree phase shifted to the other one */
ul_duty1 = sine[ul_count%size];//  // 1st sine wave output 0 degree phase shift
ul_duty2 = sine[(ul_count+(size/3)) %size]; // 2nd sine wave output 120 degree phase shift
ul_duty3 = sine[(ul_count+(2*size/3))%size];// 3rd sine wave output 240  degree phase shift
/* Set new duty cycle */
g_pwm_channel_instance.channel = PIN_PWM_1STPWM_CHANNEL;
pwm_channel_update_duty(PWM, &g_pwm_channel_instance, ul_duty1);
g_pwm_channel_instance.channel = PIN_PWM_2NDPWM_CHANNEL;
pwm_channel_update_duty(PWM, &g_pwm_channel_instance, ul_duty2);
g_pwm_channel_instance.channel = PIN_PWM_3DPWM_CHANNEL;
pwm_channel_update_duty(PWM, &g_pwm_channel_instance, ul_duty3);

}
//########################################################################################################
// ******MAIN MENU*************************MAIN MENU*******************************MAIN MENU***************
//##############################################################################################
int main(void)
{
/* Initialize the SAM system */
sysclk_init();
board_init();

/* GPIO Pin configuration */
gpio_configure_pin(PIN_PWM_3DPWM_GPIO, PIN_PWM_3DPWM_FLAGS);  // for PWM PIN 3
gpio_configure_pin(PIN_PWM_2NDPWM_GPIO, PIN_PWM_2NDPWM_FLAGS);  // for PWM PIN 2
gpio_configure_pin(PIN_PWM_1STPWM_GPIO, PIN_PWM_1STPWM_FLAGS);  // for PWM PIN 1
/* Enable PWM peripheral clock */
pmc_enable_periph_clk(ID_PWM);

/* Disable PWM channels */
pwm_channel_disable(PWM, PIN_PWM_1STPWM_CHANNEL); // @ PWM PIN 9
pwm_channel_disable(PWM, PIN_PWM_2NDPWM_CHANNEL);  // @ PWM PIN 8
pwm_channel_disable(PWM, PIN_PWM_3DPWM_CHANNEL);  // @ PWM PIN 7
/* Set PWM clock A as PWM_FREQUENCY*PERIOD_VALUE (clock B is not used) */
pwm_clock_t clock_setting = {
.ul_clka = PWM_FREQUENCY * PERIOD_VALUE,
.ul_clkb = 0, // clock B is disabled
.ul_mck = sysclk_get_cpu_hz()
};
pwm_init(PWM, &clock_setting);
/* Initialize PWM channel for PWM PIN 7 */
/* Period is left-aligned */
g_pwm_channel_instance.alignment = PWM_ALIGN_LEFT;
/* Output waveform starts at a low level */
g_pwm_channel_instance.polarity = PWM_LOW;
/* Use PWM clock A as source clock */
g_pwm_channel_instance.ul_prescaler = PWM_CMR_CPRE_CLKA;
/* Period value of output waveform */
g_pwm_channel_instance.ul_period = PERIOD_VALUE;
/* Duty cycle value of output waveform */
g_pwm_channel_instance.ul_duty = INIT_DUTY_VALUE;
g_pwm_channel_instance.channel = PIN_PWM_3DPWM_CHANNEL;
pwm_channel_init(PWM, &g_pwm_channel_instance);
/* Initialize PWM channel for PWM PIN 8  */
/* Period is left-aligned */
g_pwm_channel_instance.alignment = PWM_ALIGN_LEFT;
/* Output waveform starts at a low level */
g_pwm_channel_instance.polarity = PWM_LOW;
/* Use PWM clock A as source clock */
g_pwm_channel_instance.ul_prescaler = PWM_CMR_CPRE_CLKA;
/* Period value of output waveform */
g_pwm_channel_instance.ul_period = PERIOD_VALUE;
/* Duty cycle value of output waveform */
g_pwm_channel_instance.ul_duty = INIT_DUTY_VALUE;
g_pwm_channel_instance.channel = PIN_PWM_2NDPWM_CHANNEL;
pwm_channel_init(PWM, &g_pwm_channel_instance);
/* Enable channel counter event interrupt */
pwm_channel_enable_interrupt(PWM, PIN_PWM_2NDPWM_CHANNEL, 0);
/* Initialize PWM channel for PWM PIN 9 */
/* Period is left-aligned */
g_pwm_channel_instance.alignment = PWM_ALIGN_LEFT;
/* Output waveform starts at a low level */
g_pwm_channel_instance.polarity = PWM_LOW;
/* Use PWM clock A as source clock */
g_pwm_channel_instance.ul_prescaler = PWM_CMR_CPRE_CLKA;
/* Period value of output waveform */
g_pwm_channel_instance.ul_period = PERIOD_VALUE;
/* Duty cycle value of output waveform */
g_pwm_channel_instance.ul_duty = INIT_DUTY_VALUE;
g_pwm_channel_instance.channel = PIN_PWM_1STPWM_CHANNEL;
pwm_channel_init(PWM, &g_pwm_channel_instance);
/* Disable channel counter event interrupt */
pwm_channel_disable_interrupt(PWM, PIN_PWM_1STPWM_CHANNEL, 0);

/* Configure interrupt and enable PWM interrupt */
NVIC_DisableIRQ(PWM_IRQn);
NVIC_ClearPendingIRQ(PWM_IRQn);
NVIC_SetPriority(PWM_IRQn, 0);
NVIC_EnableIRQ(PWM_IRQn);
/* Enable PWM channels  */
pwm_channel_enable(PWM, PIN_PWM_1STPWM_CHANNEL);  // @ PWM PIN 9
pwm_channel_enable(PWM, PIN_PWM_2NDPWM_CHANNEL); // @ PWM PIN 8
pwm_channel_enable(PWM, PIN_PWM_3DPWM_CHANNEL); //@ PWM PIN 7
//###########################################################################################
// ******MAIN LOOP*************************MAIN LOOP*******************************MAIN LOOP***************
//###########################################################################################
while (1) {
}
}
Title: Re: Change the Sine wave frequency
Post by: earx on May 27, 2014, 08:46 pm
i see you ditched the arduino analogWrite() and so on.. congrats. i'm also using less and less of that.

if you want something else as 2,4,6,8, etc (integers) try looking up "fixed point arithmetic". just reserve a couple of bits behind the comma. https://inst.eecs.berkeley.edu/~cs61c/sp06/handout/fixedpt.html this may be a nice place to start..
Title: Re: Change the Sine wave frequency
Post by: Grumpy_Mike on May 28, 2014, 09:39 am
You have 98 posts and still do not know how to post code.
Post it correctly by modifying your post and I will tell you how to do it.
Title: Re: Change the Sine wave frequency
Post by: so3ody on May 28, 2014, 10:15 am
@ Grumpy Mike so I changed it now
Title: Re: Change the Sine wave frequency
Post by: so3ody on May 28, 2014, 10:21 am

i see you ditched the arduino analogWrite() and so on.. congrats. i'm also using less and less of that.

if you want something else as 2,4,6,8, etc (integers) try looking up "fixed point arithmetic". just reserve a couple of bits behind the comma. https://inst.eecs.berkeley.edu/~cs61c/sp06/handout/fixedpt.html this may be a nice place to start..


Hi yes In try to get rid of Arduino commands at least for this apllication.

Thanks for your hint about the fixed point.

SO shallI make my sine array with a fixed point or ?

Can you please tell me what do i have to change in my code ? its commented in a good way I guess
Title: Re: Change the Sine wave frequency
Post by: Grumpy_Mike on May 28, 2014, 11:43 am
You have ul_count++ incrementing the count through the look up table.
Instead of this you have something like :-
Code: [Select]

ul_count += countIncrement;

Where count increment can be 100 times the amount you need. So for 2 times the frequency countIncrement is 200 for 4 times the frequency countIncrement is 400 and for 2.5 times the frequency countIncrement is 250, and so on.

When you come to use ul_count as an index to your lookup table you actually use ul_count divided by 100.
Also when you wrap round, that is ul_count becomes greater than your maximum index you subtract the range of your indexes from ul_count rather than just setting them to zero. This way you keep the fractional part of the count.

-----------------------------------

I have described this in terms of base 10. For an increase in speed have this in terms of a byte. In other words the ul_count will be divided by 256, which is simply a shift to the right 8 times, and the countIncrement is 256 times the frequency you want. It is exactly the same idea but the division and wrap round is easier.
Title: Re: Change the Sine wave frequency
Post by: so3ody on May 28, 2014, 01:06 pm
@ Mike thanks for your reply but it dosent work

I recive no signal anymore .. see screenshot

Would you please modifiy the stuff you described before ? I think I didnt understand it in a right way this is why it dosent work
Thanks in advance

I plan after everything works to post the project in this forum Hardware and software.. it will be then easier for everyone to use arduino due to drive a H bridge driver
Title: Re: Change the Sine wave frequency
Post by: Grumpy_Mike on May 28, 2014, 02:25 pm
Quote
but it dosent work

Then you haven't done it right.
please post what you have done.
Title: Re: Change the Sine wave frequency
Post by: so3ody on May 28, 2014, 02:45 pm
Hi Mike
I just replaced


Code: [Select]
ul_count ++;
with
Code: [Select]
ul_count += countIncrement;
and gave counterIncrement a value
I think that I didnt understand your explenation
Title: Re: Change the Sine wave frequency
Post by: Grumpy_Mike on May 28, 2014, 03:07 pm
Quote
I think that I didnt understand your explenation

Well at least you understood that much.

So let's take it one step at a time then:-
1) What value have you set countIncrement to be?

2) When you come to use ul_count as an index to your lookup table you actually use ul_count divided by 100. Have you done that? if not ask what you don't understand about it.

3) when you wrap round, that is ul_count becomes greater than your maximum index you subtract the range of your indexes from ul_count rather than just setting them to zero.
Have you done that? Again if not ask about what you do not understand.
Title: Re: Change the Sine wave frequency
Post by: so3ody on Jun 02, 2014, 10:26 am
Hello

Quote


1) What value have you set countIncrement to be?



I set 400,250 and 300 as test values to counterIncrement

Quote
2) When you come to use ul_count as an index to your lookup table you actually use ul_count divided by 100. Have you done that? if not ask what you don't understand about it.

Yes I divided my variable ul_count/100

Quote


3) when you wrap round, that is ul_count becomes greater than your maximum index you subtract the range of your indexes from ul_count rather than just setting them to zero.
Have you done that? Again if not ask about what you do not understand.


No Ididnt cause I dont understand it and dont know how to reialize it in a c code

Thanks in advance
Title: Re: Change the Sine wave frequency
Post by: AWOL on Jun 02, 2014, 02:02 pm
Quote
Can anyone tell me how to make it in another way to change thefrequency not only in 2,4,6,8 way

Google "phase accumulator"
Title: Re: Change the Sine wave frequency
Post by: Grumpy_Mike on Jun 02, 2014, 03:18 pm

Google "phase accumulator"

Yes that is what I am trying to implement with him.

Quote
3) when you wrap round, that is ul_count becomes greater than your maximum index you subtract the range of your indexes from ul_count rather than just setting them to zero.

Currently you have:-
Code: [Select]
if (ul_count >= size) {
ul_count = 0;
}

In your new code you should have:-


Code: [Select]
if ((ul_count /10) >= size) {
ul_count -= size * 10;
}


Next as you do not seem to know very much about what you are doing you must post ALL your code so far. That includes attaching any files you have included like the look up table.
That is real Arduino code not the rubbish you posted at the start of this thread.

Title: Re: Change the Sine wave frequency
Post by: so3ody on Jun 02, 2014, 03:24 pm
Hi Mike
thanks for your reply this the sine array which I didint post the the beginning

Code: [Select]
/*
* SineArray1.h
*
* Created: 26.05.2014 13:25:56
*  Author: Administrator
*/


#ifndef SINEARRAY_H_
#define SINEARRAY_H_



/** Sine wave array which will be overlayed to the pwm signals */
// The size of the sine array is 120
uint16_t sine[] = { 0x7ff, 0x86a, 0x8d5, 0x93f, 0x9a9, 0xa11, 0xa78, 0xadd, 0xb40, 0xba1,
0xbff, 0xc5a, 0xcb2, 0xd08, 0xd59, 0xda7, 0xdf1, 0xe36, 0xe77, 0xeb4,
0xeec, 0xf1f, 0xf4d, 0xf77, 0xf9a, 0xfb9, 0xfd2, 0xfe5, 0xff3, 0xffc,
0xfff, 0xffc, 0xff3, 0xfe5, 0xfd2, 0xfb9, 0xf9a, 0xf77, 0xf4d, 0xf1f,
0xeec, 0xeb4, 0xe77, 0xe36, 0xdf1, 0xda7, 0xd59, 0xd08, 0xcb2, 0xc5a,
0xbff, 0xba1, 0xb40, 0xadd, 0xa78, 0xa11, 0x9a9, 0x93f, 0x8d5, 0x86a,
0x7ff, 0x794, 0x729, 0x6bf, 0x655, 0x5ed, 0x586, 0x521, 0x4be, 0x45d,
0x3ff, 0x3a4, 0x34c, 0x2f6, 0x2a5, 0x257, 0x20d, 0x1c8, 0x187, 0x14a,
0x112, 0xdf, 0xb1, 0x87, 0x64, 0x45, 0x2c, 0x19, 0xb, 0x2,
0x0, 0x2, 0xb, 0x19, 0x2c, 0x45, 0x64, 0x87, 0xb1, 0xdf,
0x112, 0x14a, 0x187, 0x1c8, 0x20d, 0x257, 0x2a5, 0x2f6, 0x34c, 0x3a4,
0x3ff, 0x45d, 0x4be, 0x521, 0x586, 0x5ed, 0x655, 0x6bf, 0x729, 0x794};


#endif /* SINEARRAY1_H_ */
Title: Re: Change the Sine wave frequency
Post by: Grumpy_Mike on Jun 02, 2014, 03:46 pm
And the rest of the arduino code?
That you posted at the start had no setup or loop functions defined?
Title: Re: Change the Sine wave frequency
Post by: so3ody on Jun 02, 2014, 03:48 pm
Mike thats all what I have

Title: Re: Change the Sine wave frequency
Post by: Grumpy_Mike on Jun 02, 2014, 03:57 pm

Mike thats all what I have

No you have been making changes to the code so I would like at least to see the changes.

If I put that code into the arduino IDE it will not compile.
I have not got the files:-
"asf.h"
"conf_board.h"
"conf_clock.h"
There is also no setup or loop functions. Arduino IDE code will not compile without those.

Have you actually been trying to write any code or are you just trawling round the internet at random grabbing code with absolutely no idea of what is going on and getting mugs to try and modify it to what you want?
Title: Re: Change the Sine wave frequency
Post by: so3ody on Jun 02, 2014, 04:01 pm
Ah now I know what you mean  :)

yes im trying to write the code.. as you can see
but I have problems cause im new in programming microcontroller
Title: Re: Change the Sine wave frequency
Post by: so3ody on Jun 02, 2014, 04:01 pm
Mike It dindt work

So this is what I modified

I added a new variable
Code: [Select]
static uint_32t counterIncrement ;

then I replaced

Code: [Select]
ul_count++;
with
Code: [Select]
ul_count+=counterIncrement

and then

Code: [Select]
if (ul_count >= size) {
ul_count = 0;
}


with
Code: [Select]
if ((ul_count /10) >= size) {
ul_count -= size * 10;
}


I just recive nonsence

can you tell me whats wrong ? Thankls in advance
Title: Re: Change the Sine wave frequency
Post by: AWOL on Jun 02, 2014, 04:04 pm
Code: [Select]
// The size of the sine array is 120Phase accumulators are much easier to implement if the table size is an integer power of two in length.
log2 (120) is not an integer.
Title: Re: Change the Sine wave frequency
Post by: Grumpy_Mike on Jun 02, 2014, 04:21 pm
Quote
can you tell me whats wrong ?

How can I when you will not give me the code that YOU have changed?
How do I know you have done the changes correctly.
I told you three things to do. You have told me about two of them.
What about the third?
Title: Re: Change the Sine wave frequency
Post by: so3ody on Jun 02, 2014, 04:23 pm
Mike I already posted the changes and I posted my whole project folder as well


those are the changes and I changed them due to the 3 things you told me


please check my last two posts
Title: Re: Change the Sine wave frequency
Post by: Grumpy_Mike on Jun 02, 2014, 04:29 pm
Quote
Mike I already posted the changes and

Where?
I can see no evidence of any changes to the main.c file
Title: Re: Change the Sine wave frequency
Post by: so3ody on Jun 02, 2014, 06:25 pm
Hi I changed  following


line 107

Code: [Select]
static uint32_t counterIncrement ;

line 116

I replaced
Code: [Select]
ul_count ++

with
Code: [Select]
ul_count+=counterIncrement ;   

Line  130,131

Code: [Select]
if (ul_count >= size) {
//ul_count = 0; }


replaced with

Code: [Select]
if ((ul_count /10) >= size) {
ul_count -= size * 10;
}
Title: Re: Change the Sine wave frequency
Post by: Grumpy_Mike on Jun 02, 2014, 07:35 pm
Quote
Hi I changed  following....

You did on that new code you posted but not on the last code you posted. Are you jerking me about?

You have not changed lines 140, 141, 142 like I told you to:-
Quote
When you come to use ul_count as an index to your lookup table you actually use ul_count divided by 100.
Title: Re: Change the Sine wave frequency
Post by: so3ody on Jun 02, 2014, 09:10 pm
Hi Mike thanks for your reply and help I really appreciate it :)
No im not  jerking about you. I just had to modifiy the code again from my home pc. cause im not at the college any more !

I modified the last issue  line 140-142 which I forgot

I cant test it now cause I dont have my arduino board at home and no osciloscope  but I will let you tomorrow know it if works or not thanks alot  again
Title: Re: Change the Sine wave frequency
Post by: Grumpy_Mike on Jun 02, 2014, 09:51 pm
Quote
...... which I forgot

Which is why I asked to see your code.

Also you have:-
Code: [Select]
static uint32_t counterIncrement ;
But you have not defined it to be any value!

OK,
Just realised that in one piece I assumed the value in the counter was 10 times more that the increment, but I think we are working on 100 times so that code should be:-
Code: [Select]

if ((ul_count /100) >= size) {
ul_count -= size * 100;
}
Title: Re: Change the Sine wave frequency
Post by: so3ody on Jun 02, 2014, 10:57 pm
Thanks mike I insert the counterIncrement  with many vlaues like 100,200 aand 250

I will tell you tomorrow if it will work

Thanks alot :)
Title: Re: Change the Sine wave frequency
Post by: so3ody on Jun 03, 2014, 09:17 am
Morning Mike

It dosent work correctly I always get a wrong frequency when I give
counterIncrement a value of 250 I recive 213 Hz, 100->85 Hz,300->250 Hz

I modified everything as you said

Please check line
Code: [Select]

107
116
130,131
140,141,142

I attached the modified code
PS Do I have to change or modifiy the sine array ?
thanks in advance
Title: Re: Change the Sine wave frequency
Post by: AWOL on Jun 03, 2014, 09:29 am
4MB of attached code?
Get real.
Title: Re: Change the Sine wave frequency
Post by: so3ody on Jun 03, 2014, 09:32 am
OK mike you aready downloaded my code yesterday I guess

Just copy and pase this in the main.c

Code: [Select]


//################################################################################################################
// **INCLUDE FILES & HEADER DATA****INCLUDE FILES & HEADER DATA****INCLUDE FILES & HEADER DATA**
//################################################################################################################

#include "asf.h"   // ATMEL SOFTWARE  FRAMEWORK
#include "conf_board.h"  // standard Librarey from ASF
#include "conf_clock.h" // Standard Library from ASF
#include "SineArray.h" // Array which contains the sine wave elements

//----------------------------------------------------------------------------------------------------------------




//################################################################################################################
// **Global variables and macros****Global variables and macros****Global variables and macros**
//################################################################################################################




/** PWM frequency in Hz */
#define PWM_FREQUENCY     10000
/** Period value of PWM output waveform */
#define PERIOD_VALUE       4096
/** Initial duty cycle value 0-100 % */
#define INIT_DUTY_VALUE   50

//----------------------------------------------------------------------------------------------------------------

//################################################################################################################
// **GPIO pin definitions for 3 PWM signals****GPIO pin definitions for 3 PWM signals**
//################################################################################################################


/* PIN Definition for the third PWM Channel @ Arduino Due Board = PWM  PIN 07 */
#define PIN_PWM_3DPWM_GPIO     PIO_PC23_IDX
#define PIN_PWM_3DPWM_FLAGS   (PIO_PERIPH_B | PIO_DEFAULT)
#define PIN_PWM_3DPWM_CHANNEL PWM_CHANNEL_6


/* PIN Definition for the second PWM Channel @ Arduino Due Board = PWM  PIN 08 */
#define PIN_PWM_2NDPWM_GPIO     PIO_PC22_IDX
#define PIN_PWM_2NDPWM_FLAGS   (PIO_PERIPH_B | PIO_DEFAULT)
#define PIN_PWM_2NDPWM_CHANNEL PWM_CHANNEL_5


/* PIN Definition for the first PWM Channel @ Arduino Due Board = PWM  PIN 09 */
#define PIN_PWM_1STPWM_GPIO     PIO_PC21_IDX
#define PIN_PWM_1STPWM_FLAGS   (PIO_PERIPH_B | PIO_DEFAULT)
#define PIN_PWM_1STPWM_CHANNEL PWM_CHANNEL_4

//----------------------------------------------------------------------------------------------------------------

/** PWM channel instance  */
pwm_channel_t g_pwm_channel_instance;



//################################################################################################################
// **Interrupt handler for the PWM controller****Interrupt handler for the PWM controller**
//################################################################################################################


void PWM_Handler(void)
{
static uint32_t size; /* Size of the sine array*/
static uint32_t ul_count = 0; /* PWM counter value */
static uint32_t ul_duty1 = INIT_DUTY_VALUE;  /* PWM duty cycle rate */
static uint32_t ul_duty2 = INIT_DUTY_VALUE;  /* PWM duty cycle rate */
static uint32_t ul_duty3 = INIT_DUTY_VALUE;  /* PWM duty cycle rate */
static uint32_t counterIncrement ;

uint32_t events = pwm_channel_get_interrupt_status(PWM);

/* Standard frequency range e.g LENZE VFD 0-300 HZ */
/* Ground sine wave frequency = (PWM_Freq/ Size of sine wave array)
  = 10 000 HZ/ 120 = 83.3 Hz*/


ul_count+=counterIncrement ;
  //ul_count++;



/* to vary the sine wave frequency the  u_count must be re defined due to the desired frequency*/
    //ul_count= ul_count+2 ;


/* to determine the size of the sine array*/
size = sizeof(sine)/2;



if ((ul_count /100) >= size) {
ul_count -= size * 100;

//if (ul_count >= size) {
//ul_count = 0; }
}


/* Overlay a sine wave array to a  PWM signal */
/* each output signal is 120 degree phase shifted to the other one */
ul_duty1 = sine[ul_count/100%size];              // 1st sine wave output 0 degree phase shift
ul_duty2 = sine[(ul_count/100+(size/3)) %size]; // 2nd sine wave output 120 degree phase shift
ul_duty3 = sine[(ul_count/100+(2*size/3))%size];// 3rd sine wave output 240  degree phase shift


/* Set new duty cycle for the 3 pwm signals */

g_pwm_channel_instance.channel = PIN_PWM_1STPWM_CHANNEL;
pwm_channel_update_duty(PWM, &g_pwm_channel_instance, ul_duty1);
g_pwm_channel_instance.channel = PIN_PWM_2NDPWM_CHANNEL;
pwm_channel_update_duty(PWM, &g_pwm_channel_instance, ul_duty2);
g_pwm_channel_instance.channel = PIN_PWM_3DPWM_CHANNEL;
pwm_channel_update_duty(PWM, &g_pwm_channel_instance, ul_duty3);

}



//########################################################################################################
// ******MAIN MENU*************************MAIN MENU*******************************MAIN MENU***************
//########################################################################################################


int main(void)
{
/* Initialize the SAM system */
sysclk_init();
board_init();

/* GPIO Pin configuration */
gpio_configure_pin(PIN_PWM_3DPWM_GPIO, PIN_PWM_3DPWM_FLAGS);  // for PWM PIN 3
gpio_configure_pin(PIN_PWM_2NDPWM_GPIO, PIN_PWM_2NDPWM_FLAGS);  // for PWM PIN 2
gpio_configure_pin(PIN_PWM_1STPWM_GPIO, PIN_PWM_1STPWM_FLAGS);  // for PWM PIN 1

/* Enable PWM peripheral clock */
pmc_enable_periph_clk(ID_PWM);

/* Disable PWM channels */
pwm_channel_disable(PWM, PIN_PWM_1STPWM_CHANNEL); // @ PWM PIN 9
pwm_channel_disable(PWM, PIN_PWM_2NDPWM_CHANNEL);  // @ PWM PIN 8
pwm_channel_disable(PWM, PIN_PWM_3DPWM_CHANNEL);  // @ PWM PIN 7

/* Set PWM clock A as PWM_FREQUENCY*PERIOD_VALUE (clock B is not used) */
pwm_clock_t clock_setting = {
.ul_clka = PWM_FREQUENCY * PERIOD_VALUE,
.ul_clkb = 0, // clock B is disabled
.ul_mck = sysclk_get_cpu_hz()
};
pwm_init(PWM, &clock_setting);


/* Initialize PWM channel for PWM PIN 7 */
/* Period is left-aligned */
g_pwm_channel_instance.alignment = PWM_ALIGN_LEFT;
/* Output waveform starts at a low level */
g_pwm_channel_instance.polarity = PWM_LOW;
/* Use PWM clock A as source clock */
g_pwm_channel_instance.ul_prescaler = PWM_CMR_CPRE_CLKA;
/* Period value of output waveform */
g_pwm_channel_instance.ul_period = PERIOD_VALUE;
/* Duty cycle value of output waveform */
g_pwm_channel_instance.ul_duty = INIT_DUTY_VALUE;
g_pwm_channel_instance.channel = PIN_PWM_3DPWM_CHANNEL;
pwm_channel_init(PWM, &g_pwm_channel_instance);




/* Initialize PWM channel for PWM PIN 8  */
/* Period is left-aligned */
g_pwm_channel_instance.alignment = PWM_ALIGN_LEFT;
/* Output waveform starts at a low level */
g_pwm_channel_instance.polarity = PWM_LOW;
/* Use PWM clock A as source clock */
g_pwm_channel_instance.ul_prescaler = PWM_CMR_CPRE_CLKA;
/* Period value of output waveform */
g_pwm_channel_instance.ul_period = PERIOD_VALUE;
/* Duty cycle value of output waveform */
g_pwm_channel_instance.ul_duty = INIT_DUTY_VALUE;
g_pwm_channel_instance.channel = PIN_PWM_2NDPWM_CHANNEL;
pwm_channel_init(PWM, &g_pwm_channel_instance);

/* Enable channel counter event interrupt */
pwm_channel_enable_interrupt(PWM, PIN_PWM_2NDPWM_CHANNEL, 0);

/* Initialize PWM channel for PWM PIN 9 */
/* Period is left-aligned */
g_pwm_channel_instance.alignment = PWM_ALIGN_LEFT;
/* Output waveform starts at a low level */
g_pwm_channel_instance.polarity = PWM_LOW;
/* Use PWM clock A as source clock */
g_pwm_channel_instance.ul_prescaler = PWM_CMR_CPRE_CLKA;
/* Period value of output waveform */
g_pwm_channel_instance.ul_period = PERIOD_VALUE;
/* Duty cycle value of output waveform */
g_pwm_channel_instance.ul_duty = INIT_DUTY_VALUE;
g_pwm_channel_instance.channel = PIN_PWM_1STPWM_CHANNEL;
pwm_channel_init(PWM, &g_pwm_channel_instance);



/* Disable channel counter event interrupt */
pwm_channel_disable_interrupt(PWM, PIN_PWM_1STPWM_CHANNEL, 0);

/* Configure interrupt and enable PWM interrupt */
NVIC_DisableIRQ(PWM_IRQn);
NVIC_ClearPendingIRQ(PWM_IRQn);
NVIC_SetPriority(PWM_IRQn, 0);
NVIC_EnableIRQ(PWM_IRQn);

/* Enable PWM channels  */
pwm_channel_enable(PWM, PIN_PWM_1STPWM_CHANNEL);  // @ PWM PIN 9
pwm_channel_enable(PWM, PIN_PWM_2NDPWM_CHANNEL); // @ PWM PIN 8
pwm_channel_enable(PWM, PIN_PWM_3DPWM_CHANNEL); //@ PWM PIN 7


//###########################################################################################################
// ******MAIN LOOP*************************MAIN LOOP*******************************MAIN LOOP***************
//###########################################################################################################
while (1) {
}
}
Title: Re: Change the Sine wave frequency
Post by: Grumpy_Mike on Jun 03, 2014, 11:44 am
Quote
It dosent work correctly I always get a wrong frequency when I give
counterIncrement a value of 250 I recive 213 Hz, 100->85 Hz,300->250 Hz

What is wrong with the frequency?
The smaller the increment amount the lower the frequency will be. That seems to be holding.

What are you expecting?
Title: Re: Change the Sine wave frequency
Post by: so3ody on Jun 03, 2014, 12:01 pm
yeah it holds but how can I contorl it i mean when I enter 300 I recive 250 Hz actually it should be 300 hz as well or ?
Title: Re: Change the Sine wave frequency
Post by: so3ody on Jun 03, 2014, 01:12 pm
WTF

Mike I think that my whole project is wrong..

I thought that  my next step it to generate the SVPWM
http://en.wikipedia.org/wiki/Space_vector_modulation
to be able to vary the output voltage of the pwm signal ( the amplitude) to be able to drive a 3phase ac motor with a vatiable voltage and a variable frequency

This will not work with my code I guess or figured it out today
Title: Re: Change the Sine wave frequency
Post by: Grumpy_Mike on Jun 03, 2014, 02:12 pm
Quote
to be able to vary the output voltage of the pwm signal

Yes you have been told on other threads that you can not / do not want to / do not need to do this.

Quote
but how can I contorl it i mean when I enter 300 I recive 250 Hz actually it should be 300 hz as well

No there is no direct collation like that. What is wrong with a look up table to map the two.

There are things you can do to speed up the code like having a multiply factor not of 100 but of a power of two like 256. This means that instead of dividing by 100 you can use the shift operation >> to shift the number 8 places to the right which is much quicker than divide by 256. Also you should pre calculate values that you end up recalculating.
So in this code:-
Code: [Select]
ul_duty1 = sine[ul_count/100%size];              // 1st sine wave output 0 degree phase shift
ul_duty2 = sine[(ul_count/100+(size/3)) %size]; // 2nd sine wave output 120 degree phase shift
ul_duty3 = sine[(ul_count/100+(2*size/3))%size];// 3rd sine wave output 240  degree phase shift

You have a calculation size / 3 calculated twice. Does it change from sample to sample - no so only calculate 'size / 3' and '2* size / 3' once when you calculate size.
Title: Re: Change the Sine wave frequency
Post by: so3ody on Jun 03, 2014, 02:24 pm
Quote
Yes you have been told on other threads that you can not / do not want to / do not need to do this.


well I have ben told that but it is wrong

You need a variable voltage in order to control a motor due to the FOC method

You need this SVPWM as i already posted in my last thread

Title: Re: Change the Sine wave frequency
Post by: so3ody on Jun 04, 2014, 04:12 pm
Hello Mike thanlks for your tipp with the size/3. I already modified it

So I figured out that I can change the amplitude of my sine wave if i devide one of those 3 lines through a factor
Code: [Select]
/* Overlay a sine wave array to a  PWM signal */
/* each output signal is 120 degree phase shifted to the other one */
ul_duty1 = sine[ul_count/100%size];              // 1st sine wave output 0 degree phase shift
ul_duty2 = sine[(ul_count/100+(size_3)) %size]; // 2nd sine wave output 120 degree phase shift
ul_duty3 = sine[(ul_count/100+(2*size_3/3))%size];// 3rd sine wave output 240  degree phase shift

e.g if i divide
Code: [Select]
ul_duty1 = sine[ul_count/100%size];              // 1st sine wave output 0 degree phase shift through 2
I will get the half of the max amplitude. So I think  I still on the right way devolping my H brdige 3 phase driver
but I still need the phase which is called (omega). Omega is the angle  which tells you in which rotating sector your motor  lies.
Actually I need to tell my software now..e.g sine wave Nr 1 should have e.g. 30 degree omega
http://www.china-power.net/psta/dzkw/212/tu/Cjg2.gif

can I link the two somehow together ? I think with this code it couldnt work or ?

The last modifiucations on my code are attached to this thread
thanks in advance


Title: Re: Change the Sine wave frequency
Post by: Grumpy_Mike on Jun 04, 2014, 06:38 pm
You are still dividing by 100 and not doing the shifting type division. This will reduce your overheads a lot.

If it were me I would not use a file for the look up table array but populate it with values you calculate once at the start of run time.
Then you could have two (or more) look up tables for different amplitudes of sin wave and just switch to what ever one you need at the time.
Title: Re: Change the Sine wave frequency
Post by: so3ody on Jun 05, 2014, 09:36 am
Hi Mike and what about omega
Title: Re: Change the Sine wave frequency
Post by: Grumpy_Mike on Jun 05, 2014, 05:37 pm
What about it?
I think you are on your own for this.
Title: Re: Change the Sine wave frequency
Post by: pjrc on Jun 08, 2014, 03:24 pm
FWIW, ARM Cortex-M3 has a 2-cycle hardware divide instruction for unsigned 32 bit integers.  The compiler is pretty crafty about using divide then subtract to quickly compute integer modulus.  There's little speed benefit to redesigning for a power-of-2 division or modulus.

On 8 bit AVR, integer division is a terribly slow operation, involving a function call to code which loops 32 times, shifting and subtracting (a.k.a. "long division").  When Arduino Zero becomes available, the same will be true, because the Cortex-M0+ lacks hardware divide.

Only the M3 & M4 versions have the fast integer divide instruction.  Arduino Due is based on the Cortex-M3.