Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Sine PWM calculated with pic, instead of using table

Status
Not open for further replies.

ljille

Member level 2
Joined
Jul 21, 2016
Messages
43
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,288
Activity points
1,904
I have seen several posts about PWM in order to make a one phase inverter,

and most use a long values table calculated to get the sine wave,

Ciclo_PWM_628A.png

but what if it calculates the duty value each time?

I have a graph where can be seen some details, but I don't see the way to
attach it. There I see I will have to compensate about 1/7 of cicle time due to the
calculation time.


Code Basic4GL - [expand]
1
2
3
4
5
6
7
8
9
-----------------     picbasic pro:
counter=0  
loop:  
duty=sin[(counter/100)]    '  to compesate decimal handle in above lines  PWM 
pin,duty,1      ´  PWM pin,duty,cycle  at 11,718 Hz  
counter=counter+ n    ' 127 cicles n=1,  n= 127/195= 0.65  -> 65  
if counter= 19500 then counter=0  
goto loop 
-----------------



So, What do you think about it?
Thank you in advance for your answer
L.J.
 
Last edited by a moderator:

Question is, do you have enough CPU / MCU cycles per PWM
period to perform this calculation?

Calculating it once and storing a table is more CPU-efficient,
less memory-efficient. Which do you have more of, resource-
wise?
 

    V

    Points: 2
    Helpful Answer Positive Rating
The sine function produces negative values for a portion of each cycle. Does your switching scheme need positive numbers only? Or, does your loop calculate only the positive waveform?
 

    V

    Points: 2
    Helpful Answer Positive Rating
>
Question is, do you have enough CPU / MCU cycles per PWM
>period to perform this calculation?

I don't have the machine cycles reference for each picbasic instruction, so I'm supossing that simple ones take 10 cycles and complex as if of goto takes 20 cycles. That plus 30 extra cycles gives me 100 cycles, which I estimate about 7 uS. Thats why I say I have to compensate it, otherwise it would be added to the 'switch off' of the IGBTs I plot to use, so I have to sustain 3 uS a high value of duty at each side of the sinus maximum. But I'd like to know first if this idea you think can work in order to go implementing with a little more confidence.

>Calculating it once and storing a table is more CPU-efficient,
>less memory-efficient. Which do you have more of, resource-wise?
16F628A has 128 EEPROM bytes, so I'd have to handle 1/4 of sine cycle and decrement pointer to handle about 100 data table. So it is possible but some tricky, and maybe I liked how short is this program without memory and table handles.


What do you think?

- - - Updated - - -

For BradtheRad:
Good point. I plot to have two pins with PWM out (I have not complemented the program but I will), p1 (maybe port B0) for branch 1 of a IGBTs bridge (FWD direction) and p2 (maybe port B1) for branch 2 of the bridge (BAK direction), in a way that by program (with programmed histeresis) I set ON one branch showing a sinus half wave, and then it becomes OFF, takes histeresis time and then set ON the opposite branch on the other pin. Each branch will handle two IGBTs drivers simultaneously, so it becomes practically impossible to get a short circuit. I suppose that 100 pulses/half sinus cycle gives us a smooth curve after the final filter.
What do you think?
 

I don't think you can "compensate" a cycle-by-cycle slip,
you're going to roll through the beat cycle.

You could look at the amount of sine wave distortion you
can stand; overkill on the pulse width resolution helps
none. Maybe there are hybrid approaches such as stored
"delta" and simple add, per cycle. Figure the per-clock
delta of an 8-bit sine wave is what, a couple of bits?
Store them 4 to a byte?

Of course there are now many, many microcontroller dev
options out there and many with more better resources
than you describe using. I would not be surprised if there
was something out there in app notes that is like what
you're doing, and maybe eval kits that are set up like you
want. Don't get too committed to whatever specific one
you have in hand (unless somebody else has gone and
committed you to it).
 

    V

    Points: 2
    Helpful Answer Positive Rating
Hi,

Don't:
* wait for the timout (PWM interrupt, timer interrupt...)
* calculate value (resulting in unpredictable delay)
* output the calculated value

But do:
* wait for the timout (PWM interrupt, timer interrupt...)
* output the previously calculated value
* pre-calculate the next value and store it (causing no jitter and no delay)

With this you get low jitter, low delay (from timeout to output) output signal.

Klaus
 

    V

    Points: 2
    Helpful Answer Positive Rating
16F628A has 128 EEPROM bytes, so I'd have to handle 1/4 of sine cycle and decrement pointer to handle about 100 data table.
Easier to store the sine table in program memory than EEPROM. I don't know PicBasic but the equivalent in 'C' of making it a 'const' table.
I doubt the 16F628A can manage 'on the fly' calculations with sufficient timing accuracy, trig functions can be very slow and more importantly take different times for each value. Even using Klaus's pre-calculate method I doubt it would keep up and if it had to do anything else, for example react to feedback it wouldn't cope.

Brian.
 

The concept of using constant table in flash is to fully dedicate the processing to interrupts/perepherials. So, the main cycle will be free for other purpose.
In your case you don't need mcu at all. Just store the table in EPROM and switch the values by counter.
 
  • Like
Reactions: ljille

    ljille

    Points: 2
    Helpful Answer Positive Rating
The advantage I saw of using PWM function would be not to deal with measuring time and its interruptions.
* Is there a picbasic document who gives us the time of execution of each instruction in the loop as the program showed?.
* Would it be better to make the subrutine of clock, to make the loop and avoid PWM function?
What do you think?
 

Hi,

I recommend to use PWM ... and PWM hardware. It generates the perfect timing without processing power.

Is there a picbasic document who gives us the time of execution of each instruction in the loop as the program showed?.
I'm not experienced with PIC, but each instruction set (in the datasheet or in an extra document) should show the count of clock cycles per instruction.

Klaus
 

Hi,

I recommend to use PWM ... and PWM hardware. ...

Klaus

I was in a confusion: PWM is different than HPWM. PWM is a very slow software based picbasic instruction. HPWM is a pcbasic instruction that handles the hardware based PWM for PICs with this capability. So, table 9-3 of the PIC I have, works for HPWM instruction on CCP1 (RB3 port) and the times there stated are true under this instruction. Thank you for your comments. I will reconfigure the program and reply it.
 

Hi,

PWM = pulse width modulation
HPWM .... never heared about it.....you mentioned it for the first time now.

PWM can be made with software, but very most nowadays microcontrollers have built in PWM periferal.
I'd always prefer to use built in hardware.

What is "table 9-3 of the pic"?

Klaus
 
  • Like
Reactions: ljille

    ljille

    Points: 2
    Helpful Answer Positive Rating
HPWM .... never heared about it.....you mentioned it for the first time now.
I'd assume it is short for Hardware PWM

google also seems to indicate that PICs use that acronym for the Hardware PWM.
 
  • Like
Reactions: ljille

    ljille

    Points: 2
    Helpful Answer Positive Rating
Well, considering comments, What do you think of this version of program for inverter?:

'This is a version for Sinus wave inverter without PWM or HPWM instructions
'It alternates pins, each one responsible of a branch oa an H bridge of IGBTs
'half positive half cycle on 96 program cycles
'Table of 1/4 cycle, 48 pulses then it decrement pointer to get 1/2 cycle
'Then it repeats but for the other H branch
'Pendant: to shorten to compensate program time, taking some time to the off time of cycle Luis Jiménez

'It can be done a timers and interrupt version (not pulsout)


Code dot - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
ARRAYWRITE SineWave {0,2,5,8,10,13,16,19,21,24,27,29,32,34,37,39,42,44,46,49,51,53,55,57,59,61,63,65,67,68,70,71,73,74,75,77,78,79,80,81,82,82,83,84,84,84,85,85,85}   ' uS  (excel calculated originally for HPWM but anyway it most work
 
'INITIAL SETTINGS OF 16F628A, WILL BE HERE   CLOCK 12 MHz
 
b0 VAR BYTE   ' array's pointer
Dir VAR BIT       ' pointer direction 
MAXIT = [MAX SineWave Count]   '
dir =0   
b0=0  
´set off PINs 
 
MAIN:
  'BRANCH 1
  PIN = RB0       '   DEFINE PORT (ver circuito)
  DO HALF_CYCLE
  pauseus 40      'histeresys to set off IGBTs
 
  'BRANCH 2
  PIN = RB1        ' DEFINE PORT 
  Do HALF_CYCLE
  pauseus 40       'histéresis
 
GOTO MAIN
 
HALF_CYCLE:         ' each cycle = 1/195 pulses
  FIN=0
  DO WHILE FIN=0
    ON= SineWave[b0]
    OFF = 85 - ON         'this makes a fixed pulse width   (uS)
 
    PULSOUT PIN, ON    ' send pulse by PIN, width as table elem. 
                                            'pulse width 1/11,700 + calc
    Pauseus OFF  
 
    IF Dir = 0 THEN      ' increment or decrement pointer
      b0 = b0 + 1
    ELSE
      b0 = b0 - 1
    ENDIF
 
    IF (b0 = MAXIT)  THEN   'changes pointer direction or ends half second of one branch
      Dir = 1
    ENDIF
    IF (b0 = 0) AND (Dir = 1) THEN
      Dir = 0
      FIN = 1  
    ENDIF
 
  END WHILE
RETURN
 
END SUB
 
'----------------


Thank you for your comments
Luis J
 
Last edited by a moderator:

I think it will work but the waveform will be quite distorted. I do not use BASIC at all but I would guess the PULSOUT command uses a software loop to create the delay. It is unlikely the delay will be exact because your calculations and the software loop time uses 16-bit values and it is an 8-bit processor which means the path taken to get a result will depend on the internal algorithms used by the language.

Seriously, the 16F628A has a built in PWM module which does most of the work for you and is extremely accurate, why not use it?

All you have to do is set the timers so you get the frequency you need then for each point in the sine wave you load the value from the array into the PWM registers, there may already be a command for doing that in PicBasic.

Brian.
 
  • Like
Reactions: ljille

    ljille

    Points: 2
    Helpful Answer Positive Rating
I think it will work but the waveform will be quite distorted....
there may already be a command for doing that in PicBasic.
Brian.

Yes, the HPWM instruction of PicBasic uses the PWM hardware. I ommited this because I wanted to use two branches (so two pins), one for each branch, but this uController has only one PWM port RB3, so I have to use an external AND gate in order to get the two branches control.

OK. Considering what you tell, I'll make the HPWM version although I have to use the AND gate, so I get a high quality sinus function out, then I'll post it.

Thank you very much
Best regards
Luis Jiménez
 

Remember that you can't produce two different PWM signals simultaneously with only one PWM generator but if one of the signals is the inverse of the other you can use a logic inverter to produce it.

Brian.
 

This squema I think can clarify what I am trying to do. I was trying to avoid the logical gates after the PIC, but as I have only one PWM port... The other factor is that I have already a printed circuit board good for this PIC, so I only will put components on it, solder and will see it easier than doing it from scratch. Esquema_PWM_PIC.png
 
Last edited:


Code Basic4GL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
'This is a version for Sinus wave inverter with hardware PWM module
' in uController
'It alternates pins, each one responsible of a branch on a H bridge
'half positive cycle on 96 program cycles
'Table of 1/4 cycle, 48 pulses then it decrement pointer to get 1/2 cycle
'Then it repeats but for the other H branch 
'Pendant to shorten to compensate program time, taking some time 'to the off time of cycle       Luis Jiménez
 
'It can be done a timers and interrupt version  (not pulsout)
 
ARRAYWRITE SineWave {0,8,16,24,32,40,48,56,64,72,80,88,96,103,111,118,125,132,139,146,152,159,165,171,177,183,189,194,199,204,209,214,218,222,226,230,233,236,239,242,244,246,248,250,251,253,253,254,254,255}   '  duty 0 - 255
 
b0 VAR BYTE   ' array's pointer
Dir VAR BIT       ' pointer direction 
Selector VAR BIT       ' phisical branch selection
RB2 -> Selector  
 
MAXIT = [MAX SineWave Count]   '
dir =0   
b0=0  
´Apagar PINs pendiente
 
 
MAIN:
  'BRANCH 1
  Selector = 0
  DO HALF_CYCLE
  pauseus 40   'histéresis para OFF de IGBTs
 
  'BRANCH 2
  Selector = 1
  Do HALF_CYCLE
  pauseus 40   'histéresis
 
GOTO MAIN
 
HALF_CYCLE:         ' each cycle = 1/195 pulses
  FIN=0
  WHILE FIN=0
    ON= SineWave[b0]
    
    HPWM chan1, ON, 11718    ' send pulse by chan1, duty as table elem. 
                                               'pulse width 1/11,700 + calc   
 
    IF Dir = 0 THEN      ' increment or decrement pointer
      b0 = b0 + 1
    ELSE
      b0 = b0 - 1
    ENDIF
 
    IF (b0 = MAXIT)  THEN   'changes pointer direction or ends half second of one branch
      Dir = 1
    ENDIF
    IF (b0 = 0) AND (Dir = 1) THEN
      Dir = 0
      FIN = 1  
    ENDIF
 
  WEND
RETURN
 
RESUME
 
'--------------------

So, what do you think about this last version?
 
Last edited by a moderator:

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top