Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

ZEZJ zero error zero jitter period algorithm

Status
Not open for further replies.
Hi Roman,

I'm confused about how you're getting outputs on the GP0 and GP2 pins. GP2 can only be used as the PWM 'CCP1' output or the comparator 'COUT' output (but not both). How are you getting output onto the GP0 pin?
 
Whoops! That does throw a spanner in the works. :( For some reason I was convinced the CCP1 output was on GP0, I didn't even check it on the 12F683 datasheet.

I swear Microchip do that deliberately; ie put the 2 most useful outputs both on the same pin so if you need both features you have to buy a more expensive PIC! Like the way they tend to put the ADC in one PIC and the USART in another... ;)

Thanks for catching that mistake Mike. Unfortunately it means that 2 really nice simple projects now need a messy external inverter. I'll edit the code above. Well anyway now it seems much more worthwhile to do the PWM in software, so it gives 2 benefits; being able to use a cheaper PIC and will give push-pull outputs.

I'd like to put those waveform pictures on my website in the section on frequency conversion. With your permission I would like to also put up that "Hybrid" code which is your sinewave code with my frequency conversion added. Of course I would mention that it was your code and all I have done is add in the extra bit that does the conversion, and a link back to this thread so people can see how it came about. If you like I can give you a mention on the second diagram too as that will go with the code example.
 
Hi Roman,

You're welcome to use my code in any way you wish Sir, without restriction.

Thank you very much for the synapse stimulation (grin).

Happy Holidays.

Kind regards, Mike
 
Ok I got a free couple of hours after lunch and put this together. I felt I owed people a PWM sinewave inverter after the problems above. ;)

It's a full PWM sinewave generator (50Hz or 60Hz) with push-pull outputs and will work on any of the low-end PICs like 12F675 or 12F629 etc.

The PWM was manually generated in 20 PWM code loops (was easy enough as most are copies of each other). A very simple zero-error TMR1 interrupt generates int periods of exactly 2500 PIC instructions, used to increment the one RAM variable which is used to sequence the PWM step.

It should be easy enough to slot in the freq conversion code later, I may do that tomorrow as I have other work to do tonight. But the push-pull sine inverter is finished and tested;

**broken link removed**
Dual outputs filtered into RC (39k, 0.1uF) giving 3v peak to peak sines;

**broken link removed**
Showing one PWM output as digital, you can just see the 20 PWM steps.

Full project and C source is here.
 
Very nice Roman (push-pull sine generator). Never occurred to me to vary the PWM frequency. I'm working on my version (grin).

Thank you for mentioning me on you web page.

Happy Holidays everyone.

Regards, Mike
 
Last edited:
What's the frequency of the crystal the PIC is running on?
 
Sceadwian- The dual sine generator above was running 10MHz xtal and making 50Hz output. With a 12MHz xtal the same code makes 60Hz output. (If you are referring to the CRO timebase I usually turn the vernier to get a better onscreen display)

Pasanlaksiri- It's not gum its blu-tak!! Every electronics workshop needs globs of blu-tak within handy reaching distance.

I did the 50Hz to 60Hz mains locked converter this morning. It so hot here I was getting up every few minutes for refreshments so it took twice as long as expected.

However the result was excellent. Here is the dual output push-pull manually generated PWM sinewaves at 60Hz, sync-locked to the 50Hz mains;

**broken link removed**

**broken link removed**

The top trace is my 50Hz mains input, from a 12v AC transformer (and fed into the simple filter shown in the schematic)
into PIC pin GP2. The pulses are about 0v-4v.

The bottom trace is the rock solid mains locked 60Hz sine output (one of the 2 outputs).

The code is set up for a 8MHz xtal as they are more common than 10MHz, and I fine tuned the "virtual pulse" period in the interrupt to compensate for the 16 inst interrupt latency.

Code:
void interrupt()
{
  //-----------------------------------------------------
  // This is a TMR1 overflow interrupt for 23 of 24 cases.
  // on 1 of 24 cases it acts as a GP2 interrupt on \ edge.
  // This is used to generate exactly 24 virtual pulses,
  // synchronised to the 50Hz mains input (GP2 \ edge).
  //-----------------------------------------------------
  if(!vpulse)  // if it is last vpulse0
  {
    // just leave TMR1 free running, this allows easy first sync!
    vpulse = 23;
  }
  else      // else is vpulse1-23
  {
    TMR1L = (256 - (PERLO - 3 - 16));   // load TMR1 for 1 vpulse period
    TMR1H = (256 - (PERHI + 1));
    vpulse--;         // sequence the next virtual pulse
    INTCON.INTF = 0;  // clear GP2 \ edge int flag
  }
  step++;             // sequence the next 60Hz PWM step
  PIR1.TMR1IF = 0;
}

The interrupt system generates ONE interrupt from the edge of the 50Hz mains cycle and then 23 interrupts (virtual pulse periods) generated from TMR1. So it generates exactly 24 equally spaced pulses for every 50Hz mains cycle.

Then the 60Hz dual PWM outputs are sequenced from 20 virtual pulses, the same basic system as the code example and diagram further up the page.

The full project and source code is here.
 
Last edited:
Mr RB out of curiosity how's the long term stability?
 
Last edited:
Mike- I'm in Queensland Australia, right up north practically in the tropics. Christmas day here is gonna be ice cold beers and chilled ham and turkey salads. :)

Be80be- yep that's the good stuff.

Sceadwian- stability of the 50Hz to 60Hz converter is excellent, it doesn't have any choice really. On the 24th pulse it MUST wait for the mains \ edge to occur, so it has to sync to the mains input and is only possible to make 24 virtual pulses from each mains input so the freq conversion must always be 50->60 and can't have any error.

The only possible failure mode would be if the GP2 detects a false \ mains edge say mid cycle, like from a big spike or something. That's very unlikely as the input transformer is a very severe low pass filter and then the RC values on GP2 were chosen to form another very severe RC filter so the chance of a little spike or anything getting through is practically nil. I also changed this one to trigger on the \ edge because that happens close to the zero-crossing point of the mains cycle and it's very rare to get any significant mains spikes there.

And in the event that it did false trigger it would only cause an extra interrupt (ie input period =23 instead of =24), so the output freq would move maximum 1/24th of a cycle out of phase, then recorrect perfectly on the end of that mains cycle so even that glitch would not actually cause a frequency error.

So all in all the long term freq out is as good as the mains national grid which is maintained by atomic clocks.
 
Hi Roman

I have studied your first code in this thread & wrote an assembly version.

Is my code ok? What do you mean by XTAL locked?

Code:
;OSC=4Mhz

		org	0x0004
		;
		movf	pcount,W
		btfss	STATUS,Z
		goto	Update_TMR0
		;
Toggle_Pin	movlw	0x01		; toggle PIC pin
		xorwf	GPIO,F
		movlw	.100
		movwf	pcount
Update_TMR0	movlw	.97		; make another 100 tick delay
		subwf	TMR0,F		
		;
Update_pcount	decf	pcount,F	;
		bcf	INTCON,T0IF
		retfie

My other problem is I want to make an inverter. But I’m confused whether it needs a very accurate square wave or a sine wave? Can I use a square wave & make a 1KW inverter?
The load will be monitors, fans & filament lamps.

Thanks
 
At a first glance, your code looks like it would toggle the PIC pin every 100 interrupts, and each interrupt is 100 TMR0 ticks.

There is already an assembly version in post #3 that allows for any period length but if you are happy with a fixed 10000 ticks then your simplified code should work.

If you need PIC code to drive an inverter then you are better off with the code in post #8 as it makes a modified push-pull squarewave.

If you want to build an inverter and need help with the electronics side it would be best to search the forum for the many inverter threads or start a "please help me with 1000w inverter" thread. :)
 
Hi Mr RB thanks for your reply.

I'm going to make a push pull inverter.I don't know why you need an 8 levels to control the two transistors?

It needs to be turn on one transistor 10mS & switch on the next on next 10mS !!!

Whats that 8 level requirement?

Thanks
 
Last edited:
It needs the 10 periods to generate what is called a "modified square wave";

Code:
Output A;     .HHH......
Output B;     ......HHH.

This has a "dead period" between turning each output on, and gives better energy transfer through the transformer than just toggling the 2 outputs.

If you are serious about making a 1000W inverter (which is difficult!) you shoudl do some searching for 1000W inverter designs and/or start a 1000W inverter thread. Doing the PIC part is only a tiny part of making a 1000W inverter!
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top