Fast pwmout to create a 50Hz Sine Wave

Sten Martin

New Member
Fast pwmout to create a 50Hz Sine Wave

I want to test if I can use a PICAXE 08M2 or 08X2 to pulse a Sine-wave with a H-Bridge fast enough. I need some help with the code.

The output data is 200 - 256 bytes (the resolution/duty of the period).
The output frequency of the period Sine-wave is 50 Hz.

So, the PWM frequency = 256 (resolution) x 50Hz = 12.8 kHz or = 10kHz with a resolution of 200.

256 updates per 20mS (50Hz) would be an update every 78uS or 100uS (@ 200 updates)

I have had a suggestion from "hippy" to poke the duty register sfr direct for speed.

This is the suggestion:

#Picaxe 08M2

Symbol CCPR1L = $B1 ' $291

SetFreq X32
PwmOut 2, 100, 0 // pin, period, duty

Do
PokeSfr CCPR1L, 80 // hex
PokeSfr CCPR1L, 83
PokeSfr CCPR1L, 86
256 times for all the output data
Loop

Use some PAUSEUS padding to get it close to 50Hz.

I need som help with this code. Where can I read about the CCPR1L, I assume it is the duty register. How did you obtain the period and duty in the pwmout command?

What is the pwmout doing with the output data? Is it doing an analog signal with the output voltage corresponding to the given sine wave data? What format can I use in the data (hex, binary and decimal)?
Code:
const int sinewave_length=256;
const unsigned char sinewave_data[] PROGMEM = {

0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c, 0x9f,0xa2,0xa5,0xa8,0xab, 0xae,0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9, 0xcc,0xce,0xd1, 0xd3, 0xd5,0xd8,0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec, 0xed,0xef 0xf0, 0xf2, 0xf3,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe, 0xfe,0xff,0xff,0xff,0xff,0xff,

0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc, 0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,
0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8, 0xe6,0xe4,0xe2,0xe0,0xde,0xdc,0xda,0xd8,0xd5,0xd3,0xd1,0xce, 0xcc,0xc9,0xc7, 0xc4, 0xc1,0xbf,0xbc,0xb9,0xb6,0xb3,0xb0,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x98,0x95, 0x92,0x8f,0x8c,0x89, 0x86,0x83,

0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a,0x67,0x63, 0x60,0x5d,0x5a,0x57,0x54,0x51,0x4f,0x4c,0x49,0x46,0x43,0x40,0x3e,0x3b,0x38,0x36,  0x33,0x31,0x2e,0x2c,0x2a,0x27,0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15, 0x13, 0x12,0x10,0x0f,0x0d,0x0c,0x0a, 0x09,0x08,0x07,0x06,0x05,0x04,0x03, 0x03,0x02,0x01, 0x01,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0c,0x0d,0x0f,0x10,0x12,0x13,0x15,0x17, 0x19, 0x1b,0x1d,0x1f,0x21,0x23,0x25,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36,0x38,0x3b, 0x3e 0x40,0x43, 0x46, 0x49,0x4c,0x4f,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,0x67,0x6a, 0x6d,0x70, 0x73, 0x76,0x79,0x7c}
 
Last edited by a moderator:

nick12ab

Senior Member
What is the pwmout doing with the output data? Is it doing an analog signal with the output voltage corresponding to the given sine wave data? What format can I use in the data (hex, binary and decimal)?
Do you understand how the PWM output works? It does not produce an analogue signal, it produces a square wave output where the duty cycle (amount of the period that it is high) is set by the variable that you specify in the pwmduty command.

It does not matter what format you use (hex,dec,bin) as they are just different ways of displaying the number in the PICAXE Editor and they are stored on the PICAXE chip in exactly the same way as each other.
 

rossko57

Senior Member
What is the pwmout doing with the output data? Is it doing an analog signal with the output voltage corresponding to the given sine wave data?
No. I think you need to revisit the principles of PWM.
A PWM is digital, either fully on or fully off. The trick is switching it off and on very fast; the more time it spends on compared to off, the higher the average signal level out. That's the duty cycle, the proportion of on-time to off-time in a continuous square wave pulse stream.

So your inverter design will be switching the H-bridge on and off at several kHz continuously, the duty cycle varying "slowly" over a period of tens of mS to allow the _average_ output to look like a sine.
In Hippy's suggestion, a look-up table is used for the sequence of PWM values for this, the value being used gets updated at fixed intervals.
You don't need anything like 256 steps to get a reasonable approximation of a sine related output.

Neither the PWM generator nor the H-bridge sees anything that looks like a real sinewave; the H-bridge output is a stream of kHz pulses of varying width too.
So you need a big filter after the H-bridge to smooth the kHz pulses out into much slower average 50Hz.

If there is any regulation to be done, you would do it by modifying the looked-up PWM value by a proportion, up or down. (I think this is where the Picaxe based project will fail, no time to do that)

With that in mind, you might like to review the existing designs you found earlier to see how they work.

It's outside the scope of this forum, but for other readers - designing a 300V 20A H-bridge capable of switching at 10 or 20kHz is serious engineering.
 
Last edited:

AllyCat

Senior Member
Hi,

No. I think you need to revisit the principles of PWM.

You don't need anything like 256 steps to get a reasonable approximation of a sine related output. .......
So you need a big filter after the H-bridge to smooth the kHz pulses out into much slower average 50Hz

It's outside the scope of this forum, but for other readers - designing a 300V 20A H-bridge capable of switching at 10 or 20kHz is serious engineering.
Certainly, I agree with the first and last statements, but not with the middle pair. The basic idea of using PWM is to generate a "pure" 50 Hz sine wave, which then means that it is not necessary to use "low frequency" (i.e. large) filter components.

However, this (and the previous related) thread puzzles me. The OP makes some "impressive" statements, but mixed with absolute "schoolboy errors". For example the reference to connecting capacitors in series (very risky when power is involved) and the request to provide code simply to POKE data into a SFR. :confused:

To me, one fundamental question is at what PWM frequency this is intended to be used? I believe the only figure (now) in the (previous) thread is 3 kHz, which IMHO is far too low. To use small filter components I would expect at least an "ultrasonic" frequency, which is outside the (useful) capability of a PICaxe.

Cheers, Alan.
 

rossko57

Senior Member
The basic idea of using PWM is to generate a "pure" 50 Hz sine wave, which then means that it is not necessary to use "low frequency" (i.e. large) filter components.
Okay, lost me there (but I am no power designer). How is the output from say a 10kHz chopper to become a 50Hz sine without a filter? You can get away with it on say a motor drive, where the inductive motor load does its own job. But a general purpose inverter may have any kind of load (or none) ... won't there be a 10kHz pulse stream?
Perhaps we're all thinking of completely different functional blocks.
 

AllyCat

Senior Member
Hi,

In principle, the filter is only required to remove the switching frequency from the outrput, not to couple the 50 Hz. Hence the higher the switching frequency, the "easier" (or at least smaller) the filter components can become.

As an analogy, consider a PWM variable bench power supply. You could wind the "voltage pot" up and down over a period of perhaps ten seconds to produce a "sine wave" output at 0.1 Hz. The wave is of course superimposed on a dc bias, but a "bipolar" sine wave could* be produced between two identical supplies with inverted control signals (i.e. an H bridge). The point is that the output filter is only needed to remove switching ripple, it doesn't matter whether the "modulation" signal is 1 Hz, 0.0001 Hz or effectively dc.

But continuing the analogy, if the power supply had only switched voltage selectors (e.g. rotary switches or thumbwheels) then the output would change in jumps. If the user requires a "smooth" output, then an enormous output filter would be needed. That is why I am suggesting that high quality PWM modulation/encoding may be required. The first few harmonics (100 Hz, 150 Hz, etc.) are probably not of great concern, but if the PWM changes in "jumps" then there may be harmonics up to tens of kHz. The aspect of this project which worries me most is that it's potentially a 3 kW radio transmitter, which involves very significant "legal" (compliance) and fundamental safety issues.

Cheers, Alan.

*EDIT: With hindsight, the two power supplies are far from a perfect analogy, since most power supplies don't like power fed into their outputs (because they have nowhere to dispose of the energy). So really, four supplies would be required, two with positive outputs and two negative.

Also, the instantaneous output power potentially cycles between 0 and 6 kW at a 100 Hz rate; if there is no major energy storage in an output "filter" then the input power must vary correspondingly. That might not be a problem with a battery source, but otherwise large reservoir capacitors could be needed, particularly if there is no control loop (feeback or feedforward) to correct for the (100 Hz) input voltage ripple.
 
Last edited:

Sten Martin

New Member
I have been able to program the code I want on PIC16F877A with PWM (C-code). It seems to have the same registers as PICAXE. Since PICAEXE is much easier to program and use I still want to try to solve my problem on PICAXE if possible. I am a little bit rosty in C-programming, it was more than 30 years last time. Is it possible at all to use C-code in final stage on PICAXE? I can of cource use the C-Code as a reference. I will do a 12V test system with LED to test the PWM output before I try the chopping with a H-Bridge.
 

Sten Martin

New Member
Is this all I need in the code to produce 50Hz output sine-wave and will the 28X2 be fast enough?
Please help.

PWM Inverter Code - HPWM

// This test-code is intended to create a PWM signal on pin13, 23, 22 and 25 with
reversed output every 40 mS?
************************************************************************************************

// An 28X2 at 32MHz has to be able to update a PWM duty every 78us?

// HPWM PWMDIV4,mode, polarity, setting, period, duty

// HPWM PWMDIV4, 2, 1, 0, 155, 312

// configure 28X2 module as 12.8 kHz PWM output

// pin 13 HPWM A, pin 23 HPWM B, pin 22 HPWM C, pin 25 HPWM D

// The PWMLHLH sets polarity for pins DCBA; D=Low, C=High, B=Low, A=High
when the PWM is high.


// PICAXE 28X2 Code

HPWM PWMDIV4, pwmfull_f, pwmLHLH, 0, 155, 312
Do: Loop
 
Last edited:

hippy

Technical Support
Staff member
Is this all I need in the code to produce 50Hz output sine-wave
No. You will need to vary the PWM duty over time.

I have been able to program the code I want on PIC16F877A with PWM (C-code) ... I can of cource use the C-Code as a reference.
Post the C code and your circuit diagram then people will have a much better understanding of what the PICAXE actually needs to do.
 

Sten Martin

New Member
PIC Inverter Code - PWM output on PORTC

/* This test example smoothly blinks LEDs on RC1 and RC2 and will be used
to test the function of the real Inverter.
/*

#define USE_OR_MASKS
#include <p18cxxx.h>
#include "pwm.h"

/*

* PWM registers configuration
*
* Fosc = 32MHz
* Fpwm = 12820.51 Hz (Requested : 12800 Hz)
* Duty Cycle = 50 %
* Resolution is 10 bits
* Prescaler is 16
* Ensure that your PWM pin is configured as digital output
* source code example for mikroC
* target : PIC18F1230, 32 Mhz
* HS clock, no watchdog.
*
*******************************************************************************
*/
void main()
{
unsigned char dc ;

TRISC = 0 ; // set PORTC as output
PORTC = 0 ; // clear PORTC
/*
* configure CCP module as 12.8 kHz PWM output
*/

PR2 = 0b00100110 ;
T2CON = 0b00000111 ;
CCPR1L = 0b00010011 ;
CCP1CON = 0b00011100 ;

for(;;) // forever

{
/*
* PWM resolution is 10 bits
* we don't use last 2 less significant bits CCPxCON,
* so only CCPRxL have to be touched to change duty cycle

*/
for(dc = 0 ; dc < 256 ; dc++)
{
CCPR1L = dc ;
CCPR2L = 256 - dc ;
Delay_ms(10) ;
}
for(dc = 256 ; dc > 0 ; dc--)
{
CCPR1L = dc ;
CCPR2L = 256 - dc ;
Delay_ms(10) ;
}
}
}

*Formula for Period and Duty cycle calculatio
*
* PWM period = [(period ) + 1] x 4 x Tosc x TMR2 prescaler
*
* PWM x Duty cycle = (DCx<9:0>) x Tosc
*
* Resolution (bits) = log(Fosc/Fpwm) / log(2)


Initiatiating registers etc

void main(void)

{
* char period = 0x00;
* unsigned char outputconfig = 0, outputmode = 0, config = 0;
* unsigned int duty_cycle = 0;

//------------------Configure pwm ----------------------------------------

* * * * period = 0xFF;
* * * * OpenPWM1( period); * * * * * * * // Configure PWM module and initialize PWM period

//---------------------set duty cycle---------------------------------------------------------

* * * * * * * * duty_cycle = 0x0F00;
* * * * * * * * SetDCPWM1(duty_cycle); * * * * *//set the duty cycle

//-------------------set pwm output---------------------------------------------------------.

* * * * outputconfig = FULL_OUT_FWD ;
* * * * outputmode = PWM_MODE_1;

* * * * SetOutputPWM1 (outputconfig, outputmode); * *// output PWM in respective modes

* * * * while(1); * * * * * * * * * * * * * * * * * * * //observe output on CCP1 pin * *

//--------------------------close pwm---------------------------------------- *

* ClosePWM1();
}
 

hippy

Technical Support
Staff member
That code seems to repeatedly linearly ramp the duty cycle of one PWM from 0% to 100% and back down again to 0%, changing duty cycle every 10ms, while also ramping another PWM 100% down to 0% and back up to 100%.

Taking the PWM outputs through RC circuits would produce a triangle wave voltage of 2.56s cycle duration, 0.4Hz. Taking the PWM outputs directly to LED+R will have them fading in and out, opposite to each other.

This appears to be a hardware test program to check PWM is controllable and behaves as expected rather than a sine wave generator.

Not sure how it helps, and untested, but the equivalent for a PICAXE-14M2 would be something like -

Code:
#Picaxe 14M2

Symbol CCPR1L           = $B1   ' $291
Symbol CCPR1H           = $B2   ' $292
Symbol CCPR2L           = $B8   ' $298
Symbol CCPR2H           = $B9   ' $299

SetFreq M32
PwmOut PWMDIV4, C.0, 255, 0
PwmOut PWMDIV4, C.2, 255, 0
Do
  For b1 = 0 To 254
    b2 = 255-b1
    PokeSfr CCPR1L, b1
    PokeSfr CCPR2L, b2
    Pause 80
  Next
  For b0 = 255 To 1 Step -1
    b2 = 255-b1
    PokeSfr CCPR1L, b1
    PokeSfr CCPR2L, b2
    Pause 80
  Next
Loop
 

Sten Martin

New Member
Thank you hippy, you saved my day again. This is what I was looking for to do the tests. Time to start programming and testing the behavior of the system. Any suggestion about what test system and board is optimal for this?
 

rossko57

Senior Member
Can you specify what it is you want to test? Presumably you're still on the 3kW mains inverter project?
From the picaxe side, I guess you could check/tune for an accurate 50Hz cycle time in the PWM. You'd probably need a scope for that.
 

Sten Martin

New Member
Yes I will need a scope. But currently I am using the simulator. I can use data from my sine table to test the
shape of the sine wave. I will toggle the output pins every full Loop (half wave). If the speed is not enough I will only use the PICAXE to test the function and with low voltage. I can probebly generate assembler Code for most of the PICAEXE code and install on a PIC chip if needed? The final tests will be done in Kailua with a friend specialist in analog design and filters.
 
Top