Mr RB

Well-Known Member
TheElectrician, I did notice the bump in the chart you made when the 82mH inductor was added. When I tried some different inductors I saw some distortion from (my) bad choice of LC values, that was part of my reason for sticking with a too-small inductor that would attenuate the 50kHz a lot but not have too much effect on the 1kHz sine. Because that PIC push-pull output will drive a lot of current it can tend to destabilise the LC.

MrAl, similar to my above comment on the inductor properties. With a smaller inductor in the first RC filter the inductor (hopefully) is affecting the 50kHz mainly and the RC is still the main filter. And (again hopefully!) the inductor properties should not cause too much problem. That was part of my filter components choice as hobbyists may have limited parts values and limited test equipment to diagnose problems.

Re the cap meter, it goes down to 0.00pF and the lower range is displayed as "nnppp.00" and is used for caps less than 18nF. It will measure a 0.01pF cap if you have one. Actually, putting my fingertip half inch from the lead is more than 0.01pF haha.

Hardware is done, built and tested. It uses a PIC 16F628 and a 16x2 LCD. The cap test oscillator is built using the PIC's internal comparator so it is a one-chip device. The cap determines the period, which is measured against the xtal, then the PIC does some careful multi digit scaling of the data; period->capacitance.

Last edited:

MrAl

Well-Known Member
Hello MrRB,

Oh i thought you said you were building a cap meter, not that you had one built already.

MrAl

Well-Known Member
Hi again,

I almost forgot to mention that i did the analysis with and without the inductor because i wanted to compare the THD with and without the inductor to see just how much adding that inductor would help (or not). What i found out i posted previously, but what i wanted to mention also was that because the difference is so small (0.015 percent and yes that is 15 thousandths of a percent not 1.5 percent or 15 percent) i have to wonder if the non linearity of the inductor might actually introduce more distortion in real life than it takes away in theory. This really should be looked into because it's a big waste if it doesnt help or actually makes it worse, and we can not do that kind of analysis in theory because we dont know the characteristics of the inductor.

BTW taking out the inductor and replacing with another 0.068uf cap and 100 ohm inductor knocks the THD down another bit, to 0.075 which is down another 0.01 percent!
The 1kHz output doesnt drop much either.

Last edited:

The Electrician

Active Member
Hi again,

..... i have to wonder if the non linearity of the inductor might actually introduce more distortion in real life than it takes away in theory. This really should be looked into because it's a big waste if it doesnt help or actually makes it worse, and we can not do that kind of analysis in theory because we dont know the characteristics of the inductor.
Did you not read post #99? That was with an 82 mH inductor.

The distortion generated by the inductor depends on the input voltage. For the results given in post #99 I used 1 volt RMS.

I made a couple of additional measurements. I used a 10 mH inductor and measured the distortion using the analyzer's own sine wave generator (approx .001% distortion). With 3 volts RMS input to the 10 mH inductor, followed by the 3 R/C stages, the distortion due to the inductor is about .025%. With 1 V RMS input, the distortion is about .01%.

With a 2.2 mH inductor, the additional distortion is below .005%.

These inductors are rather small, about the size of a 2 watt resistor, stocked by Digikey and Mouser here in the U.S.

Using physically larger inductors, the generated distortion is much smaller, essentially undetectable.

Mr RB

Well-Known Member
MrAl, please confirm which size inductor you are referring to in post #103?

TheElectrician, thanks for the info!

...
These inductors are rather small, about the size of a 2 watt resistor, stocked by Digikey and Mouser here in the U.S.

Using physically larger inductors, the generated distortion is much smaller, essentially undetectable.
I deliberately avoided using any of those tiny resistor-shaped inductors for that reason. That is part of what limits the "hobbyist" inductor choice, as the better performing inductors like toroids etc are hard to find in 10's of mH range! The ones I used in the prototype are two 1/2" toroids of 1.15mH each.

MrAl's suggestion is quite valid, people with less access to the exact parts are probably better off with just the pure RC filter...

Slightly new challenge - digital error to analog filter...

One of the other signal generator projects I'm finishing up is a PIC xtal-based squarewave generator with very fine (digital) freq adjust. So it can be adjusted in 0.01Hz steps, ie; set to 10000.01 Hz and it produces exactly 10000.01 Hz (as accurate as the xtal is calibrated).

This uses a Bresenham variation of "DDS" to generate any frequency from the PIC timer freq of 10 MHz.

But that system introduces a jitter of 0-100nS (or +/- 50nS) on every rising and falling edge of the squarewave.

Example 20003 Hz = period alternating between 499 and 500 units (each unit is 100nS).
Example 1.00007 Hz = alternating 9999300 and 9999301 units

I think you get the idea. Is there some easy analog filter solution for greatly reducing this phase edge jitter (which is always 0-100nS), allowing for the unit producing a very wide frequency range? (maybe 0.1Hz to 20kHz)

Last edited:

The Electrician

Active Member
TheElectrician, thanks for the info!
I deliberately avoided using any of those tiny resistor-shaped inductors for that reason. That is part of what limits the "hobbyist" inductor choice, as the better performing inductors like toroids etc are hard to find in 10's of mH range! The ones I used in the prototype are two 1/2" toroids of 1.15mH each.
The inductors I used aren't the "tiny resistor-shaped" inductors. I don't think you can get inductances as high as 82 mH in those.

The ones I'm referring to are these:

http://www.mouser.com/MobileCatalog.aspx?page=2391

Specifically, the O2 and O3 series on the top right of the page.

If it's in the Mouser catalog, I don't consider it to have limited availability, and the price is right.

But, as we have all concluded, for your purpose ultimate performance filtering is not needed.

However, for those projects where a mH size inductor of reasonable size and price is needed, these fit the bill.

MrAl

Well-Known Member
Hello again,

Electrician:
Ok thanks for the inductor information. So without knowing the spec's of the inductor it's hard to determine what it will do without a real bench test.

MrRB:
The inductor was the original 2.3mH.

Mr RB

Well-Known Member
Sorry TheElectrician, I misunderstood. I have plenty of those ferrite types too. They are still a higher distortion than I would have chosen.

MrAl, thanks for confirming which inductor size.

No comments on the other filter in post #105?

MrAl

Well-Known Member
Hi again MrRB,

You are trying to 'filter' a square wave?
What is causing the 100ns jitter?

Once you calibrate the freuquency, do you come back say a week or a month later and check it again?

Last edited:

Mr RB

Well-Known Member
The 100nS jitter is caused by the PIC whose timer runs at 10MHz. So to generate any period which does not evenly divide into 10 million requires a jitter.

As a simple example; the PIC needs to generate an average period of 1000.25 counts, so it generates a repeating cycle of 1001, 1000, 1000, 1000 which has an average period of exactly 1000.25. The cycle is handled mathematically and always gives a good average preiod (hence exact average freq) but in most cases there is always that 100nS edge jitter on any pulse edge.

So I have been looking at analog ways to reduce the jitter. As an obvious idea it can filter into multistage RC and provided the RC does not run out of headroom it will reduce the jitter, and then the output goes through a comparator and is back to digital squarewave but with greatly reduced jitter. Of course the problem is the massive range of frequency 0.1Hz to 20kHz which rules out any simple RC filter (that must be tuned for a fairly narrow range of frequencies). Ie; the problem is that for lower frequencies the RC will max out at 0v/5v and then 100% of the jitter is transferred through the filter.

If there was a "magic" active filter that never maxed out it could be do-able. Maybe something like the thermistor stabilisation used in a wien bridge that can never max out?

Or maybe there is some analog way to deal with the "tuned" error which must always be 0-100nS? I'm just throwing out ideas here...

MrAl

Well-Known Member
Hi MrRB,

Oh ok i think i understand now. The output is being dithered so there are artifacts.
The filter (of some sort) and comparator is an interesting idea, this deserves some thought.

Offhand though all i can suggest is that instead of a constant dithered output pattern that a random dither be used instead. That will help a little because there will no longer be any systematic deviation. In other words, instead of generating 1001 1000 1000 1000 repeatedly, generate 1001 1000 1000 1000 and then randomize the location where the 1001 occurs for the next cycle, so it comes out randomly to say 1000 1000 1001 1000 and then randomize again for the next cycle. This might require a pseudo random lookup table i guess if you dont have the time to do it in the PIC as a calculation.

Mr RB

Well-Known Member
Very interesting! I had been messing with an idea of adding analog noise to the (ramped) digital output. Basically a similar result but done post in hardware rather than pre in firmware.

The firmware option may pay off. I'll check it out. In many cases depending on the frequency the dither pattern may already be very complex (especially compared to the very simple repeating pattern of that example!).

My frequency generating system uses a Bresenham remainder so there is a fixed base period, and only the last extra count needs to be dithered (one operation for each period). So it would be quite easy to insert the dithered counts into a small array and then randomly extract them for use. As long as no array position is used more than once it would maintain the same average over time just randomly distribute WHEN the bit is used.

It's a cool idea, but it does still leave me with 100nS jitter on any pulse edge...

KamalS

New Member
Congratulations on this wonderful project!

Some questions:

1. Could you share the excel sheet/program that computes the PWM lookup table given the frequency (and desired amplitude?)

2. If I wanted to generate both the sine and cosine waves at once, I would need a PIC with two PWM modules(pins) and the firmware would share a single lookup table? (since the lookup table is for a complete 360 degree rotation, the lookup table pointers to generate the waves need to be 1/4th of the size apart always)

3. Have you found an easy way using which I could compute the RLC values of the output filter, like you did, for any fixed freq. between 1 KHz to 40 KHz?
(The active filter designs I am aware of use multiple stages)

Last edited:

Mr RB

Well-Known Member

1. My Excel spreadsheet is a bit messy and on my other computer. It's a bit messy as the old version of Excel I have will NOT do degrees, it has to use radians and needs extra conversion. I'll get some time later to tidy it up a bit and post it here.

2. Generating sine and cosine requires 2 PWM modules (easy enough on some larger PICs) and a lookup table that can be divided by 4, to get the required 90' phase shift. My 50 entry table does not divide by 4 but you could make another size sine table (say 40 entries) and change the PIC xtal to 16MHz to still give 1.0000 kHz.

3. There's no easy way to get the RC filter values as the PWM freq will remain fixed and the output freq has varied. Also it is unrealistic to think of getting high frequencies using this method, even if Nyquist says you can get a sine from only a few sample points I wouldn't try to do it with PWM! Even with 10kHz output that is a sine table of only 4 entries (assuming you want sine and cosine) and 4 entries is NOT a sine wave.

If you really need 1kHz to 40kHz then just forget about this method and go to a much faster processor and use a DAC output.

KamalS

New Member
3. There's no easy way to get the RC filter values as the PWM freq will remain fixed and the output freq has varied. Also it is unrealistic to think of getting high frequencies using this method, even if Nyquist says you can get a sine from only a few sample points I wouldn't try to do it with PWM! Even with 10kHz output that is a sine table of only 4 entries (assuming you want sine and cosine) and 4 entries is NOT a sine wave.
Oh - I am not trying to make a DDS using the PIC.

What I was asking was if I wanted my PIC to generate a predetermined fixed freq. 'X' between 1 KHz to 40 KHz.

That is, the freq. would not change at runtime, but the circuit would be tuned for X (for example, in your case X = 1KHz for this thread)

What I was wondering is after all the discussions in this thread, have you found an easy way using which I could compute the RLC values of the output filter, like you did, but applicable for any X (not only 1KHz - the values for which we now have)?

Mr RB

Well-Known Member
Hi again, it's not at all suitable for 40kHz, even a fixed 40kHz as the PWM frequency is 50kHz.

If you wanted to generate a low freq signal say between 1kHz and 5kHz it can be ok, just use the filter values as shown as they will JUST remove the 50kHz pwm and leave you with the largest possible amplitude sinewave. Obviously at 5kHz your output sinewave will be smaller than 1kHz sine with the same filter.

As I said before, this was optimised for 1kHz and is a trade off of a number of factors including sine table entries, pwm frequency and filter values.

If you need higher output frequency than a couple of kHz then you should really look at a DAC output system not a pwm system.

KamalS

New Member
Hi again, it's not at all suitable for 40kHz, even a fixed 40kHz as the PWM frequency is 50kHz.

If you wanted to generate a low freq signal say between 1kHz and 5kHz it can be ok, just use the filter values as shown as they will JUST remove the 50kHz pwm and leave you with the largest possible amplitude sinewave. Obviously at 5kHz your output sinewave will be smaller than 1kHz sine with the same filter.
Oh I see - I read this thread carefully this time and see that what you did here was plain old Pulse-code modulation (where in theory you need to sample at least at twice the Nyquist criteria, but in reality perhaps more than thrice)?

This would mean we could generate sines from 1kHz to 10kHz using the 628 and more using a 18F series?

:-D

As I said before, this was optimised for 1kHz and is a trade off of a number of factors including sine table entries, pwm frequency and filter values.

If you need higher output frequency than a couple of kHz then you should really look at a DAC output system not a pwm system.
I was looking into modifying your cap meter project to sample at 120Hz, 1Khz, 10Khz (possible by the current PIC 628) and add an ESR feature.

Mr RB

Well-Known Member
Sorry for that delay! Here is the data you need to make the Excel file, it is is the text format below.

The formulas used in the spreadsheet cells are included, it should all make sense and should be easy enough to adapt to other size tables than the 50 entry table I used. I have provided it in this form as it can be entered into any spreadsheet (not just excel).

Note! The last column "integer" relies on Excel's normal process to round numbers in it's cells up or down to get the right integer, and the fact that it keeps all cells in a (annoyingly hidden) floating point format.

Code:
Here is the spreadsheet data to make the "PWM compensated" sine table
using my simplified natural sampled PWM compensation system (see description
Open source - RomanBlack 19th June 2011.

Columns         Description             Excel formula

B7 Step		steps in table		=B6+1
C7 Degrees	sine degrees 		= C6 + (360 / 50)
D7 sine value	sin			=SIN( C7 *PI()/180)
E7 Table value  scaled to 72 high  	=(72 / 2) + (D7 * (72 / 2)) + 14
F7 Comp         adds PWM compensation	= E7 + (((E7+E8)/200)  * (E8-E7))
G7 Int          rounded to integer      =F7

-----------------------------------------------------------
Step	Degrees	Sine value      Table   Comp    Int 	Int

0	0	0               50.0	52.4	52	52
1	7.2	0.125333234	54.5	57.1	57	57
2	14.4	0.248689887	59.0	61.6	62	62
3	21.6	0.368124553	63.3	66.0	66	66
4	28.8	0.481753674	67.4	70.0	70	70
5	36	0.587785252	71.2	73.8	74	74
6	43.2	0.684547106	74.7	77.1	77	77
7	50.4	0.770513243	77.8	79.9	80	80
8	57.6	0.844327926	80.5	82.3	82	82
9	64.8	0.904827052	82.7	84.1	84	84
10	72	0.951056516	84.3	85.3	85	85
11	79.2	0.982287251	85.5	85.9	86	86
12	86.4	0.998026728	86.0	86.0	86	86
13	93.6	0.998026728	86.0	85.5	86	86
14	100.8	0.982287251	85.5	84.5	85	85
15	108	0.951056516	84.3	82.9	83	83
16	115.2	0.904827052	82.7	80.9	81	81
17	122.4	0.844327926	80.5	78.4	78	78
18	129.6	0.770513243	77.8	75.4	75	75
19	136.8	0.684547106	74.7	72.2	72	72
20	144	0.587785252	71.2	68.6	69	69
21	151.2	0.481753674	67.4	64.7	65	65
22	158.4	0.368124553	63.3	60.7	61	61
23	165.6	0.248689887	59.0	56.5	56	56
24	172.8	0.125333234	54.5	52.2	52	52
25	180	0	        50.0	47.8	48	48
26	187.2	-0.125333234	45.5	43.5	44	44
27	194.4	-0.248689887	41.0	39.3	39	39
28	201.6	-0.368124553	36.7	35.3	35	35
29	208.8	-0.481753674	32.6	31.4	31	31
30	216	-0.587785252	28.8	27.8	28	28
31	223.2	-0.684547106	25.3	24.6	25	25
32	230.4	-0.770513243	22.2	21.6	22	22
33	237.6	-0.844327926	19.5	19.1	19	19
34	244.8	-0.904827052	17.3	17.1	17	17
35	252	-0.951056516	15.7	15.5	15	15
36	259.2	-0.982287251	14.5	14.5	14	14
37	266.4	-0.998026728	14.0	14.0	14	14
38	273.6	-0.998026728	14.0	14.1	14	14
39	280.8	-0.982287251	14.5	14.7	15	15
40	288	-0.951056516	15.7	15.9	16	16
41	295.2	-0.904827052	17.3	17.7	18	18
42	302.4	-0.844327926	19.5	20.1	20	20
43	309.6	-0.770513243	22.2	22.9	23	23
44	316.8	-0.684547106	25.3	26.2	26	26
45	324	-0.587785252	28.8	30.0	30	30
46	331.2	-0.481753674	32.6	34.0	34	34
47	338.4	-0.368124553	36.7	38.4	38	38
48	345.6	-0.248689887	41.0	42.9	43	43
49	352.8	-0.125333234	45.5	47.6	48	48
50.0

Last edited:

KamalS

New Member
I am having issues replicating your dataset.

The formulas used in the spreadsheet cells are included, it should all make sense and should be easy enough to adapt to other size tables than the 50 entry table I used. I have provided it in this form as it can be entered into any spreadsheet (not just excel).

Note! The last column "integer" relies on Excel's normal process to round numbers in it's cells up or down to get the right integer, and the fact that it keeps all cells in a (annoyingly hidden) floating point format.
Your table looks a bit weird. I am having issues replicating your dataset.

Here are my observations:

1. The last two columns seems to be copies of each other

2. The table values do not seem to follow a uniform rounding strategy.

For the same set of columns you have the mapping:

Code:
	2	14.4	0.248689887	59.0	61.6	62	62
13	93.6	0.998026728	86.0	85.5	86	86
14	100.8	0.982287251	85.5	84.5	85	85
This would imply that you have rounded up the 5th column (F7)

However, these values imply that you have rounded down

Code:
	23	165.6	0.248689887	59.0	56.5	56	56
35	252	-0.951056516	15.7	15.5	15	15
36	259.2	-0.982287251	14.5	14.5	14	14
The first is rounded up and the other rounded down?
(in fact, it might make sense to round values up from the amplitides that correspond to 0 - 180 degrees and round down from 180 - 360 degrees; however, this is not what your formula indicates)

Mr RB

Well-Known Member
Sorry I don't have excel on this computer to check the data, but the rounding is done in excel. The data in my post #118 was cut and pasted from the spreadsheet.

Excel keeps the data in a floating point format (which I mentioned) and then you select "column number formatting" which is applied to the native number and then *displayed* truncated. In that column.

So for this row;
Code:
23   165.6   0.248689887   59.0   56.5   56   56
The actual value may have been 56.47000 which excel rounded up (for display) to 56.5 as that is the correct rounding to 0.1 resolution, then when asked to round it to integer 56.47000 was properly rounded down to 56.

Personally I hate Excel, it's so "Microsoft" in that it hides things from the user and does things that it wants regardless of what the user wants. That's part of the reason I have supplied the spreadsheet calcs in text form.

That answers your question 1. Just to get Excel to display the sine graph correctly requires pasting the integers into notepad and back into Excel, to make them real integers. Otherwise Excel keeps charting the original non-rounded data. If you know a way to force it to truncate the native data please tell me, as I don't use it often enough to have found out that trick.