Making a controller - Do I need to take the low pass filter into account?

Hi everyone :slight_smile:

This is something that's been on my mind for a few days. I have a low pass filter to convert the Arduino's PWM output (I will be changing the setting for Timer1 to increase the PWM frequency), with a settling time under 0.01s. The transfer function according to this page is 454.54545/(s + 454.54545), and I was just wondering if it was absolutely necessary to take it into account when I select my controller gains. I ask this because I don't know how to work out gains for third-order systems! (I will be controlling a motor; its position [1st order TF] and velocity [2nd order TF], and including the low-pass filter would add another order =( )

Thanks,
+-

I really have no idea what you're asking [????], and your link didn't seem to work,
but after some massaging I got to here, which shows a different transfer
function:

http://sim.okawa-denshi.jp/en/PWMtool.php

However, the other link above the text on that page is much more straightforward,
and is the formula I've used for many years to compute 1st-order 3dB rolloff
frequency:

http://sim.okawa-denshi.jp/en/CRlowkeisan.htm

F3dB = 1 / (2 * PI * R * C)

Basically this is a simple low-pass filter that smooths out the PWM signal to give
a DC voltage with some small ripple riding on top.

Is your motor controller supposed to be taking a DC voltage input? Most motor
controllers, it seems to me, actually use the PWM directly. ????

oric_dan(333):
I really have no idea what you're asking [????], and your link didn't seem to work,
but after some massaging I got to here, which shows a different transfer
function:

(Sample)RC Low-pass Filter Design for PWM - Result -

However, the other link above the text on that page is much more straightforward,
and is the formula I've used for many years to compute 1st-order 3dB rolloff
frequency:

RC Low-pass Filter Design Tool

F3dB = 1 / (2 * PI * R C)

Basically this is a simple low-pass filter that smooths out the PWM signal to give
a DC voltage with some small ripple riding on top.

Is your motor controller supposed to be taking a DC voltage input? Most motor
controllers, it seems to me, actually use the PWM directly. ????

Hello, sorry about the link! Fixed it now :stuck_out_tongue:

The link doesn't use the same values that I'm using (for the record, I used 976 Hz, R = 22k, C = 100n).

I was under the impression that it took a DC voltage input, I have not found any documentation regarding PWM. I intend to plug the Arduino into a pre-amp unit which provides a push-pull output to the servo amplifier, to allow rotation in both directions. I believe the pre-amp sums several inputs, so there is an op-amp in there, which should be able to handle PWM, right? Now, I'm not sure if the servo amplifier could handle PWM...

Let me try to find a picture of the servo amp... please see page 2: http://www.ee.hacettepe.edu.tr/~solen/ELE356/exp2.pdf

I don't think PWM would work with it, because it will be going in both directions, which implies a negative voltage (while in reverse). In this case, we return to my original question.

I have not found any documentation regarding PWM.

What sort? Have you seen this basic introduction:-
http://www.thebox.myzen.co.uk/Tutorial/PWM.html

It is not clear what you are trying to do. It sounds like you have a more theoretical question than a practical one.
Are you implementing a closed loop servo system?

Now it begins to make a little more sense. You are driving a real servo-motor
amplifier, and not an h-bridge type of motor, as I had thought might be the
case. Your system does take an analog input.

I probably shouldn't even be commenting here, as I'm not a graduate control
engineer, and you have a real systems engineering situation here. Maybe
someone else will comment [who knows better what they're talking about !!!].

You have to know what sort of dynamic response you want from the servo-motor,
and then choose an input signal that is in line with that. You need to choose the
gains and solve the equation shown in sections 1 and 2 of your pdf file, and
determine the Bode Plot response characteristics for the motor system. Then
you need to produce the correct input response using the Arduino.

Do you know how fast the servo-motor is supposed to sweep? Do you know
the step-response and frequency characteristics of the system under different
loading conditions?

With your R,C values, the time-constant of the low-pass filter = 2.2 msec. I
would guess that, IF your motor response time is roughly 100X slower than that,
then the Arduino analog.write might do the job. The problem is, as mentioned,
there is a good deal of ripple on the smoothed analog signal out of the filter,
and when fed into a servo-control system, that might produce a lot of jitter.
Also, you might not be able to change the analog.write output fast enough to
produce the system resposne that you need.

I would imagine a better solution would be to get a true D/A [digital to analog]
converter and connect that to the Arduino pins, rather than trying to use the
analog.write function.

Aside from that, to me, this is the sort of problem one solves by knowing all
the parameters, having the hardware in front of you, experimentally testing the
servo-motor, measuring its dynamic response, hooking a driver up and testing
it some more until it's working how you want it to.

IOW, this is a non-trivial problem, except maybe for a graduate control
engineer. That's about all I can say [probably should not have even opened
my mouth, ???]. Good luck.

Grumpy_Mike:

oric_dan(333):
Now it begins to make a little more sense. You are driving a real servo-motor
amplifier, and not an h-bridge type of motor, as I had thought might be the
case. Your system does take an analog input.

I probably shouldn't even be commenting here, as I'm not a graduate control
engineer, and you have a real systems engineering situation here. Maybe
someone else will comment [who knows better what they're talking about !!!].

You have to know what sort of dynamic response you want from the servo-motor,
and then choose an input signal that is in line with that. You need to choose the
gains and solve the equation shown in sections 1 and 2 of your pdf file, and
determine the Bode Plot response characteristics for the motor system. Then
you need to produce the correct input response using the Arduino.

Do you know how fast the servo-motor is supposed to sweep? Do you know
the step-response and frequency characteristics of the system under different
loading conditions?

With your R,C values, the time-constant of the low-pass filter = 2.2 msec. I
would guess that, IF your motor response time is roughly 100X slower than that,
then the Arduino analog.write might do the job. The problem is, as mentioned,
there is a good deal of ripple on the smoothed analog signal out of the filter,
and when fed into a servo-control system, that might produce a lot of jitter.
Also, you might not be able to change the analog.write output fast enough to
produce the system response that you need.

I would imagine a better solution would be to get a true D/A [digital to analog]
converter and connect that to the Arduino pins, rather than trying to use the
analog.write function.

Aside from that, to me, this is the sort of problem one solves by knowing all
the parameters, having the hardware in front of you, experimentally testing the
servo-motor, measuring its dynamic response, hooking a driver up and testing
it some more until it's working how you want it to.

IOW, this is a non-trivial problem, except maybe for a graduate control
engineer. That's about all I can say [probably should not have even opened
my mouth, ???]. Good luck.

Hello, thanks for your reply! I came in here to bump and I noticed you had replied :stuck_out_tongue:

I will be doing system identification in the next couple of days to get the plant transfer function, and from that I can look at the frequency response. I will be using a function generator to produce a swept wave with frequencies of between 0.1 and 10 Hz (I doubt the motor could go much further than that).

I have been reading about the Arduino's built-in Timers, which I can use to increase the frequency of the PWM (to 976 Hz, 3906 Hz for example), and this will decrease the ripple voltage. I was thinking of having the control loop run for 10 ms an iteration, maybe 100. I will calculate a sampling interval after I have a plant TF.

But... as useful as all of this is, I think these issues are all separate from this control issue, and I will have to consider this after system identification :stuck_out_tongue:

I have not found any documentation regarding PWM.

What sort? Have you seen this basic introduction:-
http://www.thebox.myzen.co.uk/Tutorial/PWM.html

It is not clear what you are trying to do. It sounds like you have a more theoretical question than a practical one.
Are you implementing a closed loop servo system?

Sorry! To clarify, I meant documentation related to my servo amp being able to use PWM (which suggests that it doesn't)

Yes, I'd say my question was almost purely theoretical. Yes, I am using my Arduino as a controller in the closed loop. The problem I have is that I am converting the PWM, 'analog output' to a (relatively) smooth signal using an RC filter... but the RC filter has its own transfer function. So I am not sure if, when I am calculating my gains (for say, a PID controller), I need to include the transfer function of the LP filter, as it would effectively add another order to the plant transfer function. :astonished:

Thank you both
:wink:

Well then theoretical the filter response will just become another part of the whole loop's response including process delay. That is why you will hardly ever find someone able to calculate the final tuning values for the P,I, and D terms, but rather manually adjusting them and watching the loop's response until optimized.

retrolefty:
Well then theoretical the filter response will just become another part of the whole loop's response including process delay. That is why you will hardly ever find someone able to calculate the final tuning values for the P,I, and D terms, but rather manually adjusting them and watching the loop's response until optimized.

Gah, it's not telling me when I have unread replies any more!

I think what could be interesting is if I calculate my gains for a first-order (velocity) or second-order system (position), ignoring the transfer function of the low-pass filter, and then comparing it to an adaptive control scheme, to see if the results are drastically different. If I find out how to work out the PID gains for a third order system (position with low-pass filter) I will try it, but I know nothing beyond second order at the moment.

Thank you for your reply! :slight_smile:

So I am not sure if, when I am calculating my gains (for say, a PID controller), I need to include the transfer function of the LP filter, as it would effectively add another order to the plant transfer function.

Yes, putting together what you said before about the PWM LPF, which I computed
had a 2-msec time-constant, and your wish to have 10-msec loop updates, I
think you are close to having a problem. The LPF will not really settle in 10-msec.

Also, as mentioned previously, I seriously doubt the servo-amp in the PDF file you
gave will take a direct PWM input, those things are made for analog driving.

Also, from what you say, I'll re-iterate that I think you'd be better off getting
a true D/A converter and using it to drive the servo-amp. With an Arduino,
you should be able to get DAC updates of 10KHZ or better I should think,
then you can stick a LPF on that signal which is much faster than the current
one, and have really low ripple.

oric_dan(333):

So I am not sure if, when I am calculating my gains (for say, a PID controller), I need to include the transfer function of the LP filter, as it would effectively add another order to the plant transfer function.

Yes, putting together what you said before about the PWM LPF, which I computed
had a 2-msec time-constant, and your wish to have 10-msec loop updates, I
think you are close to having a problem. The LPF will not really settle in 10-msec.

Also, as mentioned previously, I seriously doubt the servo-amp in the PDF file you
gave will take a direct PWM input, those things are made for analog driving.

Also, from what you say, I'll re-iterate that I think you'd be better off getting
a true D/A converter and using it to drive the servo-amp. With an Arduino,
you should be able to get DAC updates of 10KHZ or better I should think,
then you can stick a LPF on that signal which is much faster than the current
one, and have really low ripple.

Yes, a proper DAC sounds so much better! I will have to ask if there's one I could borrow in the workshop tomorrow. It's a little late for me to order one now as my project is coming to an end, but I'll see what I can do =(

Thanks for your reply

oric_dan(333):

So I am not sure if, when I am calculating my gains (for say, a PID controller), I need to include the transfer function of the LP filter, as it would effectively add another order to the plant transfer function.

Also, from what you say, I'll re-iterate that I think you'd be better off getting
a true D/A converter and using it to drive the servo-amp. With an Arduino,
you should be able to get DAC updates of 10KHZ or better I should think,
then you can stick a LPF on that signal which is much faster than the current
one, and have really low ripple.

Hello, I'm just seeking some clarification.

When you say D/A converter, do you mean a chip? Like these? For some reason I was thinking a D/A converter was a big machine! But if this is what you mean, I will order one and put it on some stripboard.

I feel so silly!

That's what I meant. Microchip is a good source, and they're also made
by National Semiconductor, Maxim, etc. Some have parallel interface,
some SPI, choose whatever is most convenient.

oric_dan(333):
That's what I meant. Microchip is a good source, and they're also made
by National Semiconductor, Maxim, etc. Some have parallel interface,
some SPI, choose whatever is most convenient.

http://uk.rs-online.com/web/p/dac/7263885/ I'm thinking of going for this one.

But I don't understand why it needs SPI? And would I be able to use it with an Ethernet Shield (05)?

I'm reading about Arduino, SPI and DAC chips right now, but it's not making much sense right now.

SPI is simply an interface protocol, invented lightyears before there
was Arduino or ethernet shields. See

You could wire the DAC chip on a prototyping shield or just regular fiberboard
and jumper across. If you have an ethernet shield on the same Arduino
board, you will not be able to use the MOSI/MISO,etc pins, and will have
to use shiftout [I think ???].

oric_dan(333):
SPI is simply an interface protocol, invented lightyears before there
was Arduino or ethernet shields. See

SPI - Arduino Reference

You could wire the DAC chip on a prototyping shield or just regular fiberboard
and jumper across. If you have an ethernet shield on the same Arduino
board, you will not be able to use the MOSI/MISO,etc pins, and will have
to use shiftout [I think ???].

That's a unit of distance! :stuck_out_tongue:

On that page (end of the 3rd paragraph) it says that multiple devices can use the same 'lines'. I have just taken a look at a sketch I have, which uses the Ethernet Shield, and the SS pin is set to high. Would that conflict with the DAC?

edit: Tutorial: Arduino and the SPI bus | tronixstuff.com Aha! So they just need different SS pins, no? Does this mean I have to specify a pin for the chip in my sketch?

edit: Tutorial: Arduino and the SPI bus | tronixstuff.com Aha! So they just need different SS pins, no? Does this mean I have to specify a pin for the chip in my sketch?

I don't know. You'll have to ask someone else to get a definitive answer on that.

oric_dan(333):

edit: Tutorial: Arduino and the SPI bus | tronixstuff.com Aha! So they just need different SS pins, no? Does this mean I have to specify a pin for the chip in my sketch?

I don't know. You'll have to ask someone else to get a definitive answer on that.

I've stumbled upon a couple of interesting topics, I will read those after a break and see if I understand. Thank you so much for your help!

Update: I think I have a slightly better idea of how to use a DAC chip with SPI. I have found a library for a similar chip here: https://bitbucket.org/iorodeo/iorodeo_arduino_libs/src/0b7fd752e2b1/mcp4822/. The main differences are that this is a 12-bit chip, with 2 DAC channels, and an internal reference voltage, while the MCP4911 which I have ordered is 10-bit, single channel with an external reference voltage. Nevertheless, I will try to edit the library to make it work for me.

But I'm still not entirely sure how I connect and use the DAC. I am still wary of having the shield and DAC share MISO/MOSI/SCK pins, as I intend to be writing to file every 10 - 50 ms (I'm still reading up on that!) and I don't want to disturb it!, so I think I would use completely different MOSI/SCK pins for the DAC.

I looked in W5100.h to see which of the SPI functions it uses, but the only one I saw was SPI.begin(). Does this mean I am free to use SPI functions in my sketch as in this example? - I read some of Nick Gammon's post on DACs, and the data mode and bit order are the default values.

I still don't know what to do with the LDAC pin... but the bar above the name suggests that it needs to be LOW, like the CS pin. Yes, this article says LDAC should be set to ground, but the library has it set high. I'll go with the library for now...

This all sounds quite incoherent, I apologise.

Current issue: I'm a little concerned that the main function (of the library) only uses the CS and LDAC pins, will I need to add the other pins since they will not be the standard SPI pins?

I've attached the edited library and example.

MCP4911.zip (7.44 KB)

I have edited (and attached) the library and example again. Now I can define a total of 4 pins for the DAC (SS/CS, MOSI/SDI, SCK, LDAC), separate from the pins used by the Ethernet Shield, so it does not assume that I am using the default pins. Well, that's what I hope my code will do. Are there any huge mistakes in there? :.

Thanks,
+-

edit: I read Nick Gammon's post again, it seems I should be using the existing SCK and MOSI pins, for hardware SPI. I'm just a little concerned because it might affect my data logging and/or internet connection.

edit2: I have an idea! Would it be possible to use the Ethernet Shield in software SPI mode, and then leave the actual SPI pins for my DAC? I got the idea from here: Arduino Forum

MCP4911.zip (7.61 KB)