Go Down

Topic: SOLVED How to generate SINE PWM SOLVED (Read 66236 times) previous topic - next topic

so3ody

Mar 13, 2014, 02:31 pm Last Edit: Mar 24, 2014, 09:32 pm by so3ody Reason: 1
Hi there

I can generate PWM and I can genrate a Sin wave "mathematically throught a look up table"


But how can I generate a sign PWM signal with the Arduino Due

Can anyone help me

MarkT

Search for the existing thread here on that topic...  I think its here.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

so3ody

Hi

NO I cpuldnt find any PWM SINE help topics for Arduino Due

MarkT

[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

so3ody

....Well I found this  link...and I even commented it....

I need a SINE PWM not only a SINE wave throught DAC...this is my problem and this is what I cant find

StanO8

Periodically, update theta and change the PWM duty cycle to sin(theta)*127+127.

so3ody

Thanks for your reply


I cant imagine  what you actually mean

can you please post a code if you have  any?

MarkT


....Well I found this  link...and I even commented it....

I need a SINE PWM not only a SINE wave throught DAC...this is my problem and this is what I cant find


They both use analogWrite()
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

so3ody

@MarktT

What is the aim of your reply actually !!

I already mentioned that I can produce a PWM signal and that I can produce a sine wave throught a look up table. my question is how to produce a sine wave throught a pwm signal !!! its called SINE PWM

StanO8

I think you would be well served if you play with one of the first sample sketches: Fade

http://arduino.cc/en/Tutorial/Fade#.UyNCABebkfA

Once you fully understand the "Fade" sketch everything that you have been told will make more sense.
Good Luck!

so3ody

Well  I applied the Fade example last week to my arduino


I just dont understand how to "connect" the sine wave to my pwm signal

MarkT


@MarktT

What is the aim of your reply actually !!

I already mentioned that I can produce a PWM signal and that I can produce a sine wave throught a look up table. my question is how to produce a sine wave throught a pwm signal !!! its called SINE PWM


The aim of my reply is to point out that generating a sine wave via PWM is done exactly
the same as generating sine wave via DAC in software.

The hardware is different, but the software interface in both cases is analogWrite().

Once you can produce a PWM signal you just have to modulate it with whatever waveform
you like.  Via analogWrite.  The value passed to analogWrite is used to set the duty-cycle
of the PWM.  That duty cycle is the analog of the signal value for PWM, just as voltage
is the analog of the signal value with a DAC pin.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

so3ody

@ MarkT

I still cant get it.

This is my vode. it produces 3 PWM signals with variable Duty Cycle and Variable Frequency
Code: [Select]

#include "pwm01.h"
void setup()
{
    uint32_t  pwm_duty = 32767;
    uint32_t  pwm_freq1 = 300000; 
    uint32_t  pwm_freq2 = 300000;

    // Set PWM Resolution
    pwm_set_resolution(16); 

    // Setup PWM Once (Up to two unique frequencies allowed
    //-----------------------------------------------------   
    pwm_setup( 6, pwm_freq1, 1);  // Pin 6 freq set to "pwm_freq1" on clock A
    pwm_setup( 7, pwm_freq2, 2);  // Pin 7 freq set to "pwm_freq2" on clock B
    pwm_setup( 8, pwm_freq2, 2);  // Pin 8 freq set to "pwm_freq2" on clock B
    pwm_setup( 9, pwm_freq2, 2);  // Pin 9 freq set to "pwm_freq2" on clock B
     
    // Write PWM Duty Cycle Anytime After PWM Setup
    //-----------------------------------------------------   
    pwm_write_duty( 6, pwm_duty );  // 50% duty cycle on Pin 6
    pwm_write_duty( 7, pwm_duty );  // 50% duty cycle on Pin 7
    pwm_write_duty( 8, pwm_duty );  // 50% duty cycle on Pin 8
    pwm_write_duty( 9, pwm_duty );  // 50% duty cycle on Pin 9
   // analogWrite(PWM 6  , sinTable[k]) I tried with analogwirte alot of things...

    delay(30000);  // 30sec Delay; PWM signal will still stream
       
    // Force PWM Stop On All Pins
    //-----------------------------   
    //pwm_stop( 6 );
    //pwm_stop( 7 );
    //pwm_stop( 8 );
    //pwm_stop( 9 );
}

void loop()

}



This is the header file 
Code: [Select]
/* 

Library:     pwm01.h (version 01)
Date:        2/11/2013
Written By:  randomvibe 

Purpose:     
   Setup one or two unique PWM frequenices directly in sketch program,
   set PWM duty cycle, and stop PWM function.

User Functions:     
   pwm_set_resolution(int res) ~  setup PWM resolution; up to 16 bit
   pwm_setup( uint32_t pwm_pin, uint32_t pwm_freq, int iclock) ~ Setup PWM on clock-A (iclock=1) or clock-B (iclock-2)
   pwm_write_duty( uint32_t pwm_pin, uint32_t pwm_duty) ~ Write PWM duty cycle
   pwm_stop( uint32_t pwm_pin) ~ Force PWM stop

Notes:
   - Applies to Arduino-Due board, PWM pins 6, 7, 8 & 9.
   - Libary Does not operate on the TIO pins.
   - Unique frequencies set via PWM Clock-A ("CLKA") and Clock-B ("CLKB")
     Therefore, up to two unique frequencies allowed.
   - Set max duty cycle counts (pwm_max_duty_Ncount) equal to 255
     per Arduino approach.  This value is best SUITED for low frequency
     applications (2hz to 40,000hz) such as PWM motor drivers,
     38khz infrared transmitters, etc.
   - Future library versions will address high frequency applications.
   - Arduino's "wiring_analog.c" function was very helpful in this effort.
     
*/

#include "Arduino.h"


static int       pwm_resolution_nbit = 8;
static uint32_t  pwm_clockA_freq = 0;
static uint32_t  pwm_clockB_freq = 0;
static uint32_t  pwm_max_duty_Ncount = 255;


void pwm_set_resolution(int res)
{
pwm_resolution_nbit = res;
}


void pwm_set_clockA_freq(uint32_t  val)
{
pwm_clockA_freq = val;
}


void pwm_set_clockB_freq(uint32_t  val)
{
pwm_clockB_freq = val;
}


static inline uint32_t mapResolution(uint32_t value, uint32_t from, uint32_t to)
{
    if (from == to)
        return value;
    if (from > to)
        return value >> (from-to);
    else
        return value << (to-from);
}



// MAIN PWM INITIALIZATION
//--------------------------------
void  pwm_setup( uint32_t  pwm_pin,  uint32_t  pwm_freq,  int iclock  )
{
    uint32_t  pwm_duty = 0;   
    uint32_t  chan = g_APinDescription[pwm_pin].ulPWMChannel;
     
    // SET CLOCK FREQUENCY
    //------------------------
    if (iclock==1)  pwm_set_clockA_freq( pwm_max_duty_Ncount*pwm_freq );
    if (iclock==2)  pwm_set_clockB_freq( pwm_max_duty_Ncount*pwm_freq );


    if (pwm_pin>=6 && pwm_pin<=9)
    {   
        // SET PWM RESOLUTION
        //------------------------
        pwm_duty = mapResolution( pwm_duty, pwm_resolution_nbit, PWM_RESOLUTION);
   
        // PWM STARTUP AND SETUP CLOCK
        //-------------------------------
        pmc_enable_periph_clk( PWM_INTERFACE_ID );
        PWMC_ConfigureClocks( pwm_clockA_freq, pwm_clockB_freq, VARIANT_MCK );   
     
        // SETUP PWM FOR pwm_pin
        //------------------------
        PIO_Configure( g_APinDescription[pwm_pin].pPort,  g_APinDescription[pwm_pin].ulPinType,  g_APinDescription[pwm_pin].ulPin,  g_APinDescription[pwm_pin].ulPinConfiguration);
        if (iclock==1)  PWMC_ConfigureChannel(PWM_INTERFACE, chan, PWM_CMR_CPRE_CLKA, 0, 0);
        if (iclock==2)  PWMC_ConfigureChannel(PWM_INTERFACE, chan, PWM_CMR_CPRE_CLKB, 0, 0);
        PWMC_SetPeriod(PWM_INTERFACE, chan, pwm_max_duty_Ncount);
        PWMC_SetDutyCycle(PWM_INTERFACE, chan, pwm_duty);
        PWMC_EnableChannel(PWM_INTERFACE, chan);
    }

}



// WRITE DUTY CYCLE
//--------------------------------
void  pwm_write_duty( uint32_t  pwm_pin,  uint32_t  pwm_duty )
{
    if (pwm_pin>=6 && pwm_pin<=9)
    {   
        pwm_duty = mapResolution( pwm_duty, pwm_resolution_nbit, PWM_RESOLUTION);
       
        uint32_t  chan = g_APinDescription[pwm_pin].ulPWMChannel;
       
        PWMC_SetDutyCycle(PWM_INTERFACE, chan, pwm_duty);
    }
};



// FORCE PWM STOP
//--------------------------------
void  pwm_stop( uint32_t  pwm_pin )
{
    pinMode(pwm_pin, OUTPUT);      // sets the digital pin as output
    digitalWrite(pwm_pin, LOW);    // sets the LED off
};





Is it possible to modify the programm with  the  Analogwrite function so that I cant  have the sine wave with the pwm wave ?

I really dont get it

Grumpy_Mike

The analog write function is a function that generated PWM if not directed to the internal DAC.
So if you know how to do something with the internal DAC the code for PWM is exactly the same only you write to the PWM pins and it only has an 8 bit range ( 0 to 255 ).

so3ody

@
Grumpy_Mike

I think that you dont understand me ... what about the sine wave... what does it have to do with the analogwrite function...

Go Up