In all honesty I understand the very basics of the low pass filtering but I am still at a loss of what values I am plugging in or trying to achieve.
The one thing I do know is that pin3 has a PWM frequency of 490hz
Using one of the calculators, I have come up with a 1k ohm resistor and a 330pf cap, this will give me a cut off frequency of 500hz, does this sound right?
Hi Adam
Does that simulator simulate an RC filter? I don’t know that one. Unfortunately my simulator (Tina) is out of action at the moment du to my Windows laptop not playing the game. However I have a filter calculator on my phone. I believe KiCad has a simulator of sorts but I have not got my head around that one yet.
That combination gives a result of 482 kHz. To arrive at 482Hz you need 330nF. You are out by 3 zeros. 1pF is one millionth of iµF which is one millionth of 1F, nano is half way between micro and pico.
You have not indicated how much ripple you can tolerate. If you want a “clean” voltage you might need an RL filter following the RC filter. With a 1k resistor and the same frequency cut off you will need 330mH inductor.
If I get time over the next day or so I will check the ripple with that 1k/330nF combination or if you have a function generator and oscilloscope you can do it yourself.
This will not overcome the fact that using the Arduino native PWM your 0 to 5V will be in 255 steps of 19.6mV. It will not be continuous.
Cheers Bob
Hi Adam
One other question. When in the calibrate mode do you need the 0 to 5V connected to your other device or are you only using the display.
Cheers Bob
Hi Adam,
There are also some off-the-shelf modules, while they dont use PWM and instead some other protocol they will output a cleaner analog signal.
(and might use a different microcontroller)
Makerverse 10-bit R2R DAC | Core Electronics Australia - an in-house built R2R DAC designed for the Pico, this uses individual IO pins to ramp up the voltage.
Overview | MCP4725 12-Bit DAC Tutorial | Adafruit Learning System - a compact module that uses I2C, with support for Arduino
For some reason the spam filter was picking up your posts, I’ve just pulled those through!
Liam
Hi Liam
This will require up to 10 I/O pins which I don’t think Adam has. This will also finish up being 1023 steps of about 5mV which is a big improvement over 255 steps but still not smooth. I still think the only way he is going to get “smooth” transitions is directly out of the sensor.
Cheers Bob
Hi Liam, Adam
That 2nd device from Adafruit would be worth a look.
MCP4725 12 Bit DAC
I wonder how well and accurately it tracks. The weak link here is the 10 bit Arduino ADC. That would have to be multiplied by 4 to fit in with the 12 bit DAC. Still giving 0 to 5V in 1023 steps (the resolution of the Arduino ADC) of 4.9mV. No way around that. You have got to work with the weakest or poorest resolution device,
Cheers Bob
I think people are attacking this from the wrong direction. The main parameter to use is how quickly the filtered PWM signal has to respond to changes of input. If that value is 1 second (for instance) then that’s the cutoff value to use to design the filter. The reason is the lower the cutoff frequency (1 second is 1Hz) the less residual PWM signal gets through. There always is a residual PWM signal, the aim is to reduce this to be insignificant.
The second parameter is the input impedance of the device that takes the filtered PWM. If it is high (say > 1 MegOhm) then an RC filter is OK. If it is low (say 1Kohm), a more expensive LC filter can be used. Or the filter can be followed by an OP amp with high input impedance and low output impedance.
Within reason, using small R and large C is preferred. For example, 1kohm/100µF has the same cutoff as 10kohm/10µF. The first is preferred as it is less sensitive to outside influences.
It is also OK to cascade two RC filters eg 1Kohm/10µF followed by another 1Kohm/10µF will reduce a 500Hz PWM to almost nothing with a response time less than 1 second and would drive input impedance > 100kohm without the need for an OP amp.
Hi Alan, Adam
Agree with all of that. There are still a couple of outstanding things that would be handy to know.
1)The input impedance of the “other thing” that the 0 to 5V is applied to.
2) The current capability of the sensor.
1 will determine if an OP amp is required
2 will determine the minimum value of resistor as the cap will be a short circuit at switch on.
Adam said earlier that a long time constant is OK as in practice changes will be slow but it would be handy to know what the limit is.
I did some physical checks with a function generator and oscilloscope yesterday and got to 10k and 1µF which still leaves about 200mV of ripple so further filtering would be required.
I have got my head around the simulator in KiCad enough for this simple circuit and so far results agree with what I observed yesterday. I will try to post different scenarios later to-day.
Referring to larger capacitors. I think they should be Tantalums as “conventional” electrolytic could have some embarrassing inductance built in. Particularly larger values. This could limit the value as I don’t know how far tantalums go these days. Readily obtainable ones anyway. Jaycar catalog says 47µF/16V and 10µF for the higher voltages are the highest value they stock.
Cheers Bob
Just realised we are dealing with the Arduino output (which is known) in this set up so the remarks about sensor current capability do not apply
Such an interesting problem to solve, and of course there’s no absolutely right way to go about it. The solutions raised are electronically very simple but I might add that it’s feeling a bit like an esoteric rabbit hole. I guess it depends what you want out of this project - do you want to ‘just get it done’ or do you relish the opportunity to design and experiment? Designing a simple RC circuit and characterising it is certainly a great way to learn more about electronics and build intuition.
If I were to approach this problem and just wanted to get my project done I think i’d opt for an eg. I2C DAC. Something with arduino support and great examples so i can just generate the voltage I desire using setVoltage(value, storeflag)
and move on with my project. Sure it’s a lot pricier than a few passives, but I feel like the end-to-end effort and time would be greatly reduced.
Yes, the DAC has a higher resolution than the Arduino’s ADC so you will waste two of its bits - but is it fit for purpose? You will still have 1023 steps which is already better than (static) 8-bit PWM control.
Let us know how you go!
PS. I actually love these kinds of topics in the forum → it’s exactly what we’re all here for
Hi, there are a few approaches to generating an analogue output voltage from a microcontroller.
One approach is to use a microcontroller which has a built-in DAC (Digital to Analogue Converter). The resolution of DACs varies with how many “bits” they convert - for N bits, they have 2 to the power N output voltage levels. It sounds like your current microcontroller doesn’t have a DAC facility, but some microcontrollers do have them.
Another approach is to use an external DAC chip, connected to your microcontroller by either SPI or I2C. This gives more flexibility in the DAC specifications, at the cost of some extra complication. For example, an instrument which I’ve designed uses an AD5761RBRUZ chip connected via SPI to get accurate (16 bit) DAC output with a choice of output voltage ranges. There are many different DAC chips to choose from.
A third approach is shown by the PWM-to-Analogue Converter which you linked. It presumably averages the PWM signal with a low-pass RC filter to give an analogue output. This approach sounds quite viable - it should work OK. The limitations may be (1) a little ripple in the output signal at the PWM frequency and (2) it might not respond to changes quite as fast as a DAC would respond. However if it’s an easy way for your to solve your Analogue-Output problem, then it could be a good solution for you. Note that its output voltage range is 0 to 10V, so you may need to limit your PWM signal to 0 to 50% timing ratio, if you want 0 to 5V out of that converter.
It’s always fun and a great learning experience, going through these issues and finding a solution.
Best wishes.
Hi Adam, Alan
Add on to my previous post. I have come to grips with the KiCad simulator enough to produce some pertinent graphs anyway
I think that one would be a non starter.
Getting better.
Getting there
The best result using a single filter stage
This result the best so far achieved by using a 10k / 1µF combination and adding an identical filter using the same values after the first.
All these with a 50% duty cycle, pulse amplitude of 5V. This is not a bad compromise with a settling time of about 150mS (about 5 time constants)
Adam, I hope this helps to get you where you want o go. The simulations are set at 500Hz as this is about what the native Arduino PWM operates at using the analogWrite command. You will still be limited to 255 steps of 19.6mV using that system.
Cheers Bob
I am pleased Robert put pictures to my words. Much more informative. My simulator of choice is LTspice - I use KiCad but didn’t realise it had a simulator! Although a bit off topic I offer another solution for DAC. I was stuck with a similar problem some time ago. The parameters were somewhat different but the solution similar. The PWM output is 10bit (rather than Arduino 8 bit) at 40kHz. An interrupt dithered the output on every pulse, selected pulses are made 25ns (1 bit) longer. Averaging with a filter over a second gives output to better than 1µV over 0 to 5V. The filter is 3 stage 10kohm+10µF; 1kohm+10µF; 1kohm+10µF. The 10µF are standard electrolytics, not tantalum and give no trouble.
The interrupt routine for this is written in assembler (when called 40,000 a second it pays to be quick). It is called every 250 instruction clocks and uses around 20 clock cycles so less than 10% of CPU time.
It’s not your everyday solution, but with microprocessors costing less than DAC chips (especially ones capable of 1µV resolution) it may be useful to someone. An ATtiny could do something similar as a dedicated DAC, taking values in through the serial port(s).
Hi Alan
Tried that but could not get it to work. And I think the spice libraries are limited to Analog Device bits. Over the years i have found Tina to be cost effective for home use and I started using it at Version 6 then progressed to Ver 10. Currently up to 14. But they don’t have a Mac version except on the cloud which runs in a browser on any platform. Problem is it has become quite expensive and for the times I would use it these days i can’t justify this expense (being on a pension doesn’t help). Tried Parallels but Parallels itself was a dismal failure. Had some nasties and Bitdefender’s drastic fix was to hide the hard drive from Windows and denying access. Drastic but effective. Couldn’t even start Windows.
Open a schematic and click “inspect” on the top tool bar.
Adam could always generate his own PWM by doing as you suggested to me some time ago. Write directly to the registers. But would still be restricted to the 1023 steps of the Arduino ADC. By the way, your suggestions worked nicely and I was able to research enough information to get a workable pulse generator using rotary encoders. Intend to post soon with acknowledgement to yourself. Keep a look out.
Cheers Bob
Thanks all for your advice, I think Michaels solution looked the goods but after reading about the Lowpass filters, seeing some screen shots from Robert and Allans comment about cascading the filters, I dug up some 1K resistors and 10uf caps de-soldered of some random PCB’s I had. It also gave me an excuse to use the USB O-Scope I was given a few years ago (took me half a day to find some software for it also had to learn how to disable digital signature authentication on its driver). And wollah! I went from squares to a line. Only downside is I cant get below ~1.5v but that wont be an issue for my first trial as the DP sensor static output is ~2.5v and in normal function will only go up from there. Couple more weeks and I should be able to install and test.
Hi Adam
Good to see some results.
You should get down to very near zero. There might be some issue discharging the 10µF cap. Try 10k and 1µF, same time constant but you never know. I did not try 10µF in the real world (only simulation) but I did check the 10k/1µF combination using a function generator from 0% to 100% in 10% steps and the result was quite linear from near zero to 5V.
Cheers Bob
Hi Adam.
Just repeated the real world filter. 2 X 10k resistors and 2 X 1µF caps arranged like so.
No problem getting down to near zero. Can’t happen in theory anyway as due to resistors involved the caps will NEVER charge 100% and NEVER discharge to Zero. But will get very close.
Tabulated results. First column %, 2nd column V (Multimeter) and 3rd column V (oscilloscope)
0% … . 0.048V … 0.08V
10% … 0.536V … 0.60V
20% … 1.023V … 1.04V
30% … 1.509V … 1.56V
40% … 1.997V … 2.08V
50% … 2.482V … 2.52V
60% … 2.970V … 3.00V
70% … 3.459V … 3.52V
80% … 3.942V … 4.00V
90% … 4.428V … 4.48V
100% … 4.914V … 5.00V
As you can see all very close. I would not guarantee the accuracy of either instrument and I think the oscilloscope is some millivolts on the high side, multimeter is fairly new Multicomp Pro Model MP730624.
Small errors but I think useable.
Cheers Bob
Hi Adam
I have graphed the measurements I made yesterday as follows
The blue line is the theoretical values while the red is as measured.
The interesting bit is that both are a straight line but the measured results have a slight tilt. I don’t think this is a percentage measurement error as if it were the red line would be all above or below the blue one.
I don’t know how close you need to be to the original values but if you need to be any closer you are going to have to find a way to get the original analog figure directly to its destination. You are going through too many conversions.
Firstly you have the first ADC, 1023 steps of 4.9mV, Then you convert this to 255 probably with the map facility. Finally you have what is left as 255 steps of 19.6mV
The way to really check would be to apply a 0-5V signal to an Arduino then output this to a PWM pin, apply to the 10k/1µF 2 stage filter and measure the result.USING THE SAME DMM which would be the only fair comparison (in the absence of lab equipment). This would provide a better idea of what is going on over the whole signal path.
Might do that in the next few days if I get a chance using a UNO R3.
Cheers Bob