Unstable sine PWM output


Closed Thread
Results 1 to 30 of 30

Hybrid View

  1. #1
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default Re: Unstable sine PWM output

    Hi,
    Aaargh, sorry about that, temporary brain-fart on my behalf.

    At the moment I'm afraid I can't come up with an alternative solution. I'm sure there is one though and hopefully someone else will jump in.

    I've never used the floating point routines and I don't really see any reason to do it here. N-Bit math might be an option but I currently don't have the time to do the experiments for you so you're going to have to try it yourself. Darrels examples in the thread is pretty self explainatory.

  2. #2


    Did you find this post helpful? Yes | No

    Default Re: Unstable sine PWM output

    To avoid an useless calculation, I would store the 1120*1000 result (1120000) into a 24-bit variable with the N-bit math function (but how?). And then divide this by the frequency, and so on.

    Thanks anyway. Now I know where is my problem. I think I will open a new thread, because the DIV32 problem is different than PWM and sines.

  3. #3
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default Re: Unstable sine PWM output

    Hi,
    I gave it a shot anyway:
    Code:
    PRECISION CON 3 SYSTEM          ' 24bits is sufficent for this
    INCLUDE "N-bit_Math.pbp"        ' Include the math routines.
     
    Dummy1 VAR BYTE[PRECISION]      ' Used by N-Bit math
    Dummy2 VAR BYTE[PRECISION]      ' Used by N-Bit math
    Result VAR BYTE[PRECISION]      ' Used by N-Bit math
     
    Frequency VAR WORD              ' Desired output frequency times 10 (123=12.3Hz)
    Reload VAR Word                 ' Caluclated timer reload value to get desired interrupt rate.
    i VAR BYTE                      ' General purpose counter
     
    HSEROUT ["Start",13]
     
    Main:
      For i = 0 to 20
        Lookup2 i, [18, 20, 22, 25, 30, 40, 50, 60, 80, 100, 150, 200, 300, 400, 500, 700, 800, 900, 1000, 1100, 1200], Frequency
        Gosub CalculateIt
        Gosub PrintIt
        Pause 100
      Next
    END
     
    CalculateIt:
      ' There's 90 "steps" for a complete sine-cycle. If we want 1Hz output frequency
      ' we need an interrupt frequency of 90Hz, 1/90=0.01111111111111s.
      ' At 40MHz each instruction cycle (and timertick when prescaler is 1:1) is 100nS
      ' so 0.0111111111111/100E-9 = 111111 but because we want one decimal place on the
      ' frequency variable (123 = 12.3Hz) we multiply that by 10 so 1111111.
     
      ' Load 1111111 into first 24bit math variable.
      Dummy1[2] = $10
      Dummy1[1] = $F4
      Dummy1[0] = $47
     
      'Load frequency variable into second math variable
      Dummy2[2] = 0
      Dummy2[1] = Frequency.HighByte
      Dummy2[0] = Frequency.LowByte
     
      'Perform the division.
    @ MATH_DIV _Dummy1, _Dummy2, _Result
     
      'Move the result to the Reload variable
    @ MOVE?PW  _Result, _Reload          ; Truncate Result into a WORD var
     
      'Negate the value to get the actual reload value.
    Reload = -Reload
     
    RETURN
    End
     
    PrintIt:
      HSEROUT ["Frequency: ", #Frequency/10, ".", #Frequency // 10, "Hz", "   Reload: ", #Reload, 13]
    Return
    1111111 is closer to the real deal than 1120000, upto around Freq=1100 the error is less than 0.01% while at Freq=1200 it "jumps" to 0.1% - pretty good.

    Remember that you can not allow the Frequency variable to be less than 17 or you'll end up with a negative reload value which means the frequency will be WAY off. Ie you can't allow Frequency to be 10 for 1Hz output.

  4. #4


    Did you find this post helpful? Yes | No

    Default Re: Unstable sine PWM output

    Henrik, you had right about the DIV32 command. It doesn't disturbs DT Instant Interrupts at all.

    Look at this routine :

    Code:
    dum=dum1*dum2
    reload=DIV32 freq
    reload=(65535-reload)+8
    The result of the division is stored into the "reload" variable.
    But if the TMR1 interrupt occurs BEFORE the end of the calculation (before reload=(65535-test)+8)), the timer management routine located in TMR1 interrupt will take the "unfinished" reload variable. So is how the sine "jumps".

    But now, with this :

    Code:
    dum=dum1*dum2
    store=DIV32 freq
    reload=(65535-store)+8
    The result of the division is stored into the "store" variable, so when "reload" is calculated, the routine calculation is really finished.

    I've tried this, and now, absolutely no glitch appears on the sine. So this fixed my problem.

    3 days for find that.

  5. #5


    Did you find this post helpful? Yes | No

    Default Re: Unstable sine PWM output

    Quote Originally Posted by HenrikOlsson View Post
    Hi,
    I gave it a shot anyway:
    Code:
    PRECISION CON 3 SYSTEM          ' 24bits is sufficent for this
    INCLUDE "N-bit_Math.pbp"        ' Include the math routines.
     
    Dummy1 VAR BYTE[PRECISION]      ' Used by N-Bit math
    Dummy2 VAR BYTE[PRECISION]      ' Used by N-Bit math
    Result VAR BYTE[PRECISION]      ' Used by N-Bit math
     
    Frequency VAR WORD              ' Desired output frequency times 10 (123=12.3Hz)
    Reload VAR Word                 ' Caluclated timer reload value to get desired interrupt rate.
    i VAR BYTE                      ' General purpose counter
     
    HSEROUT ["Start",13]
     
    Main:
      For i = 0 to 20
        Lookup2 i, [18, 20, 22, 25, 30, 40, 50, 60, 80, 100, 150, 200, 300, 400, 500, 700, 800, 900, 1000, 1100, 1200], Frequency
        Gosub CalculateIt
        Gosub PrintIt
        Pause 100
      Next
    END
     
    CalculateIt:
      ' There's 90 "steps" for a complete sine-cycle. If we want 1Hz output frequency
      ' we need an interrupt frequency of 90Hz, 1/90=0.01111111111111s.
      ' At 40MHz each instruction cycle (and timertick when prescaler is 1:1) is 100nS
      ' so 0.0111111111111/100E-9 = 111111 but because we want one decimal place on the
      ' frequency variable (123 = 12.3Hz) we multiply that by 10 so 1111111.
     
      ' Load 1111111 into first 24bit math variable.
      Dummy1[2] = $10
      Dummy1[1] = $F4
      Dummy1[0] = $47
     
      'Load frequency variable into second math variable
      Dummy2[2] = 0
      Dummy2[1] = Frequency.HighByte
      Dummy2[0] = Frequency.LowByte
     
      'Perform the division.
    @ MATH_DIV _Dummy1, _Dummy2, _Result
     
      'Move the result to the Reload variable
    @ MOVE?PW  _Result, _Reload          ; Truncate Result into a WORD var
     
      'Negate the value to get the actual reload value.
    Reload = -Reload
     
    RETURN
    End
     
    PrintIt:
      HSEROUT ["Frequency: ", #Frequency/10, ".", #Frequency // 10, "Hz", "   Reload: ", #Reload, 13]
    Return
    1111111 is closer to the real deal than 1120000, upto around Freq=1100 the error is less than 0.01% while at Freq=1200 it "jumps" to 0.1% - pretty good.

    Remember that you can not allow the Frequency variable to be less than 17 or you'll end up with a negative reload value which means the frequency will be WAY off. Ie you can't allow Frequency to be 10 for 1Hz output.
    Thanks, maybe I will later modify my program with this.

  6. #6
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default Re: Unstable sine PWM output

    Sometimes it's just there, staring you in the face all along and you still don't see it.... I guess this is one of those of times. It's pretty obvious now that you found it, which I'm glad you did!

    Now that it works properly with DIV32 I see no reason to change to N-Bit math.

  7. #7


    Did you find this post helpful? Yes | No

    Default Re: Unstable sine PWM output

    Quote Originally Posted by HenrikOlsson View Post
    Sometimes it's just there, staring you in the face all along and you still don't see it.... I guess this is one of those of times. It's pretty obvious now that you found it, which I'm glad you did!

    Now that it works properly with DIV32 I see no reason to change to N-Bit math.
    Maybe your new routine with n-bit maths is more accurate?

    Anyway, I think that I will open an another thread soon for this 3-phase VFD, with a YouTube video, the source code, schematics, etc. Because it works fine on my 250W 3-phase motor (in theory my IGBT module is capable of 2,2kW of output power). It will be cool.
    Last edited by pxidr84; - 15th May 2011 at 14:21.

  8. #8
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default Re: Unstable sine PWM output

    Hi,
    I tried both methods for both accuarcy and speed, here are the results:
    Code:
    N-BIT:  Frequency: 1.8Hz   Reload: 3808    Cycles: 4497
    DIV32:  Frequency: 1.8Hz   Reload: 3809    Cycles: 333
    N-BIT:  Frequency: 2.0Hz   Reload: 9981    Cycles: 4593
    DIV32:  Frequency: 2.0Hz   Reload: 9981    Cycles: 345
    N-BIT:  Frequency: 2.2Hz   Reload: 15031    Cycles: 4579
    DIV32:  Frequency: 2.2Hz   Reload: 15032    Cycles: 349
    N-BIT:  Frequency: 2.5Hz   Reload: 21092    Cycles: 4743
    DIV32:  Frequency: 2.5Hz   Reload: 21092    Cycles: 337
    N-BIT:  Frequency: 3.0Hz   Reload: 28499    Cycles: 4583
    DIV32:  Frequency: 3.0Hz   Reload: 28500    Cycles: 349
    N-BIT:  Frequency: 4.0Hz   Reload: 37759    Cycles: 4282
    DIV32:  Frequency: 4.0Hz   Reload: 37759    Cycles: 349
    N-BIT:  Frequency: 5.0Hz   Reload: 43314    Cycles: 4528
    DIV32:  Frequency: 5.0Hz   Reload: 43314    Cycles: 337
    N-BIT:  Frequency: 6.0Hz   Reload: 47018    Cycles: 4272
    DIV32:  Frequency: 6.0Hz   Reload: 47018    Cycles: 349
    N-BIT:  Frequency: 8.0Hz   Reload: 51648    Cycles: 3971
    DIV32:  Frequency: 8.0Hz   Reload: 51648    Cycles: 353
    N-BIT:  Frequency: 10.0Hz   Reload: 54425    Cycles: 4313
    DIV32:  Frequency: 10.0Hz   Reload: 54425    Cycles: 337
    N-BIT:  Frequency: 15.0Hz   Reload: 58129    Cycles: 4270
    DIV32:  Frequency: 15.0Hz   Reload: 58129    Cycles: 333
    N-BIT:  Frequency: 20.0Hz   Reload: 59981    Cycles: 4002
    DIV32:  Frequency: 20.0Hz   Reload: 59981    Cycles: 341
    N-BIT:  Frequency: 30.0Hz   Reload: 61833    Cycles: 3959
    DIV32:  Frequency: 30.0Hz   Reload: 61833    Cycles: 337
    N-BIT:  Frequency: 40.0Hz   Reload: 62759    Cycles: 3705
    DIV32:  Frequency: 40.0Hz   Reload: 62759    Cycles: 345
    N-BIT:  Frequency: 50.0Hz   Reload: 63314    Cycles: 3617
    DIV32:  Frequency: 50.0Hz   Reload: 63314    Cycles: 349
    N-BIT:  Frequency: 70.0Hz   Reload: 63949    Cycles: 3420
    DIV32:  Frequency: 70.0Hz   Reload: 63949    Cycles: 349
    N-BIT:  Frequency: 80.0Hz   Reload: 64148    Cycles: 3412
    DIV32:  Frequency: 80.0Hz   Reload: 64148    Cycles: 349
    N-BIT:  Frequency: 90.0Hz   Reload: 64302    Cycles: 3298
    DIV32:  Frequency: 90.0Hz   Reload: 64302    Cycles: 353
    N-BIT:  Frequency: 100.0Hz   Reload: 64425    Cycles: 3420
    DIV32:  Frequency: 100.0Hz   Reload: 64425    Cycles: 349
    N-BIT:  Frequency: 110.0Hz   Reload: 64526    Cycles: 3333
    DIV32:  Frequency: 110.0Hz   Reload: 64526    Cycles: 345
    N-BIT:  Frequency: 120.0Hz   Reload: 64611    Cycles: 3351
    DIV32:  Frequency: 120.0Hz   Reload: 64611    Cycles: 345
    For N-Bit I used 1111111/frequency and for DIV32 I used 11111*100 DIV32 Frequency. As you can see the results are pretty much spot on, the small difference there is likely due to 11111*100=1111100. What is surprising is that DIV32 is about 10 times faster than N-Bit in this particular case so I wouldn't change if I were you - it's just way more power than you need for this, and it comes a cost.

    Yes, please do post the project.

    /Henrik.

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts