DC motor controller - Page 1
Forum section: electronics / projects

author: OM222O
author_rank: Frequent Contributor
timestamp: July 26, 2020, 10:04:22 pm
content: HiI'm working on a project where I need to control two motors. I need to implement a PID controller that sets the positions of the motors. I am currently using 2 arduino nanos and a 2 channel H bridge driver + High resolution encoders directly on the motors. The motors are geared down 51:1 which means the numbers get very big, very fast (4096 PPR encoders).I think it's worth upgrading to a 32 bit micro controller running at higher frequencies, for example a teensy 4.1 which runs at 600MHz compared to 16 of the arduino and proccesses larger numbers better. I find that arduinos are also really glitchy and sometimes do weird things, but that might just be my code so I won't blame them for now. I wonder if there exist off the shelf motor controllers or if I should roll my own using a teensy and an H bridge shield (the current one really under performs so I'd like to design my own).Also the arduinos are working via USB serial and getting position and configuration daat from a raspberry pi which is less than ideal as it uses many ports (there are other devices other than the motor controller, each taking up 1 USB port). Is there something more suitable? I know can bus is pretty popular but I have never used it before so I'm not sure where to start.Any suggestions on how to go about this or possible flaws in my idea?

author: H.O
author_rank: Frequent Contributor
timestamp: July 27, 2020, 06:56:21 am
content: What size motor is it you're using, voltage, current? What sort of interface do you want/need to actually control the position of the motor(s)? An analog input, step/direction, quadrature signals, or is it to be controlled by some high level host like a PC or PLC so you want some sort of bus interface which, in turn, can be anything from simple serial to something like EtherCAT?Budget?A microcontroller running at 600MHz sound like massive overkill for a basic motor control application, personally I've used the PIC18F2431. Key here is that it has a dedicated peripheral that handles the encoder counting so you don't have to use polling or interrupts for that. If you want to keep using the Arduino I'd look at offloading the encoder count to an external chip (LS7166 springs to mind but that might be obsolete now).

author: OM222O
author_rank: Frequent Contributor
timestamp: July 27, 2020, 07:55:39 am
content: The motors are 12v 80 watts.I already mentioned using raspberry pi amd usb serial for coomunication and the need for a simpler bus. CAN has a lot of features like CRC check, high immunity to noise, etc so I will probably choose that in the end.I'm not sure which CAN transciever to use however so feel free to recommend some chips. I'm going through a few datasheets as we speak.Budget is not important at all, can cost a few hundred £.Yes a 600MHz micro is overkill but simplifies a lot of things and I need this ready by october, so I think throwing money at the problem here would be a good compromise. I was just wondering if there are better approaches (in terms of ease of use and robustness, not small things like interrupt handling or external chips for encoders), for example off the shelf controller modules (similar to O drive but for brushed motors) or dedicated controller ICs perhaps.

author: Siwastaja
author_rank: Super Contributor
timestamp: July 27, 2020, 09:57:00 am
content: No, a more complex microcontroller is not going to "simplify" things, seeing you have issues writing stable code even on the AVR. All those "glitchy" "weird" things are because of your code, and changing into a more complex, more capable MCU increases the number of problems.The higher-end MCU is not only faster, it has more traps.And I'm 99% sure you won't need the speed. If you need large numbers, int64_t is fast enough on a 16MHz AVR. Say, approx a million of operations per second. You need maybe 10000.If you only have time until October, the only way you can do it is to keep using what you are familiar with, i.e., that would be your current Arduino.The performance of the 16MHz AVR should be definitely enough.Start by looking at your code, debugging it, fixing things until you can figure out why it doesn't work properly. If the performance runs out, look why this happens and fix it. This way, and only this way, you'll be able to do this in a few weeks.

author: Zero999
author_rank: Super Contributor
timestamp: July 27, 2020, 11:25:13 am
content: What you're proposing seems sensible. I echo the concens above about using a more complex MCU.Are you looking for a different, more useable H-bridge? A quick Google found the VNH5180A, for which a cheap evaluation board is available from RS Components.https://uk.rs-online.com/web/p/power-management-development-kits/8463452/https://www.st.com/en/automotive-analog-and-power/vnh5180a-e.html

author: OM222O
author_rank: Frequent Contributor
timestamp: July 27, 2020, 03:42:06 pm
content: An H bridge doesn't seem too hard to implement. A few logic components to allow for sign/magnitude control and 4 mosfets + a bit of filtering using ferites and capacitors. I'm having more issues on the software side of things and EMI which should be solved with shielded cables and better H bridge.

author: max_torque
author_rank: Super Contributor
timestamp: July 27, 2020, 04:44:19 pm
content: The tail is wagging the dog on this one!Start by defining your targets:1) Maximum output speed2) required ouput positional resolution3) Define the load, so you can decide on control strategy (position, speed or torque) and how the various control loops will interactThere is no problem doing this in an 8bit AVR running at 16Mhz, i've done it numerous times

author: OM222O
author_rank: Frequent Contributor
timestamp: July 27, 2020, 04:59:36 pm
content: The exact motors are these:https://uk.rs-online.com/web/p/dc-motors/3213192/connected to PLS36 planetary gearboxes with 51:1 reduction ratio which drives the wheels and moves the robot.I have no idea how to calculate maximum speed, torque etc as the robot isn't fully designed and can weigh more / less than estimates. It certainly is more powerful than needed and so far I've been using position control without any issues as the wheels slipping seems to be the bottle neck so either have to find wheels with better grip or slow down the motors.the only high resolution (i.e: >20PPR encoders meant for operation by hand as knobs) were 4096 PPR high resolution optical encoders. given the maximum RPM of 8311, it means 34,041,856 counts per second at max speed. I may actually end up using frequency dividers as this seems way too high and even on paper there will be more mechanical slop as that is about 200 micro degrees of accuracy at the wheel!I will try to make it work with the arduinos since everyone suggests it should be good enough but perhaps for other revisions I go with only 1 teensy and 1 raspberry pi, instead of multiple arduinos and a raspberry pi. multi threading and communication between different sensors / wheels, etc already adds a lot of overhead to the pi which I do no like, as well as the mentioned ports issues.

author: james_s
author_rank: Super Contributor
timestamp: July 27, 2020, 05:09:57 pm
content: Even a low end AVR can do this, seehttp://elm-chan.org/works/smc/report_e.htmlfor an example.

author: OM222O
author_rank: Frequent Contributor
timestamp: July 27, 2020, 05:32:59 pm
content: Quote from: james_s on July 27, 2020, 05:09:57 pmIt was a nice read, especially the code examples, but their circuit is quite a lot simpler, using a pot / much lower resolution encoder, which alone used up 27% of the micro controller time!

author: H.O
author_rank: Frequent Contributor
timestamp: July 27, 2020, 05:46:52 pm
content: If you wan't something COTS that does the hard work I'd look at something like the 3C20 fromMESA Electronics. For an even more packaged solution you have products from vendors like Galil or even more industrial stuff like from Beckhoff. Another semi option is something like the IONI versatile servo drive from Granite Devices but it's more expensive than it needs to be based on what you've specified so far.There are SO many options available in this power range.

author: thm_w
author_rank: Super Contributor
timestamp: July 27, 2020, 10:29:20 pm
content: Quote from: OM222O on July 27, 2020, 04:59:36 pmYou forgot to divide 8311 RPM by 60s, so the rate should be 567kHz (signal of 1.1MHz on two pins, plus index pin, interrupt rate would be even higher than that).I agree others are overestimating things here, it can be difficult to fit this all into an 8bit running at 16MHz along with PID loop and whatnot. Especially without a dedicated quadrature peripheral.And if you want something that "works" buy off the shelf controller, as suggested above. If you want a project, then do it yourself.I like the AMT encoders, although the price has come up quite a bit ($80):https://www.cuidevices.com/product/resource/amt20.pdfThey let you choose from 96 to 1024 PPR in software. This would let you get away with using the lower end micro. If you are dead set on the Teensy, then that has 4 hardware quadrature inputs, maybe you could get away with running two motors off of one board.edit: 3C20 mentioned above is $80 and supports up to 2MHz quad counts (http://store.mesanet.com/index.php?route=product/product&path=65&product_id=129) seems reasonable. But I think that won't meet your existing 2.2MHz (if I am calculating that correctly) using the 4,096 PPR.

author: langwadt
author_rank: Super Contributor
timestamp: July 27, 2020, 11:52:55 pm
content: Quote from: OM222O on July 27, 2020, 03:42:06 pmhardly worth messing with that when you can get an hbridge with all the bells and whistles including protecting against most abusefor a few dollars

author: H.O
author_rank: Frequent Contributor
timestamp: July 28, 2020, 08:55:44 am
content: The 3C20 that I suggested might not be suitable for that motor after all. After looking more closely at the specs of the particular motor it doesn't match the output current of the 3C20 very well - bummer. MESA have a lot of stuff though so it's worth looking around there website.As others have said, if you want a project go ahead and make DIY solution - it's fun and trust me, it's totaly doable with an 8bit micro* but again, "outsourcing" the encoder counting to a dedicated peripheral or external chip is key at these high frequencies.BUT if the motor drive is just one part of a bigger project then just buy something and get on with the big project.* Here's alinkto my project.

author: OM222O
author_rank: Frequent Contributor
timestamp: July 28, 2020, 09:33:11 am
content: Do you know any encoder counters that can keep up with high frequency and numbers? Or at least something that allows for cascading of counters to 64 bits or similar? I'm not even sure which chips to search for when doing parametric search.Edit: also looking at the teensy datasheet, it suggests 4x hardware based quadrature encoder inputs, but I can't find any reference on them in the datasheet. no max speeds, no designated pins, no registers, nothing! maybe I'm just blind but please let me know if you found some info on this.

author: Siwastaja
author_rank: Super Contributor
timestamp: July 28, 2020, 10:20:11 am
content: The elephant question in the room is, why in the world would you want to use a 4096-step encoder on a DC motor axis? The control of the motor will never be even in the same ballpark of accuracy. The brushes energizing windings causes torque ripple, inductance of the windings limit the rate of change when you want to feedback current, and inertia prevents sudden changes in speed - all in all, if you want the motor to run at an exact speed, or feedback it to track a certain position, you are at least two orders of magnitude away from that 4096 steps per revolution.I'd understand if that 4096 step encoder would be on the output shaft of a 1:256 reduction gear; or if you used, say, a 16-step encoder on the motor shaft (equivalent thing).Everybody is ignoring the 500kHz pulse rate because it sounds so strange. What are you going to do with a pulse every 2 microseconds when just changing the motor current by any meaningful amount takes some 100 microseconds? I mean, this is like measuring a kettle temperature every 1ms to adjust a heating element when it takes a minute for the water to heat up by any significant amount.Usually, the feedback loops run at something like 10% to 50% of the PWM frequency, and the PWM frequency is somewhere around 10-20kHz.Try to run the feedbacks at 1kHz first and only if you can show a responsitivity problem, go for maybe 2kHz, still just fine on an 8-bitter; not 500kHz.What comes to the encoder itself, hardware timers/counters are used for this. The AVR should have 16-bit counters available, but even if you must use a 8-bit counter, this already divides your 500kHz rate to around 2kHz; this would be the overflow interrupt in which you increment or decrement a software counter. At 2kHz, you can easily handle a 64-bit counter, for a total of 72 bits.

author: langwadt
author_rank: Super Contributor
timestamp: July 28, 2020, 11:05:32 am
content: Quote from: Siwastaja on July 28, 2020, 10:20:11 amoverflow interrupt quickly gets messy to do safely, use a timer interrupt that you are sure is faster than the counter can wrapfour quad decoders, two on 32bit timers and two on 16bit timers extended to 32bit,https://github.com/langwadt/nucleo_quad4

author: OM222O
author_rank: Frequent Contributor
timestamp: July 28, 2020, 11:08:36 am
content: I already answered your "elephant in the room" as that encoder was the only one available to me, other than the mechanical "knobs" that come with 13PPR. I can't wait 2 months for stuff to ship from china since this project needs to be ready by october (first post). I also mentioned that I would probably go with some sort of frequency divider.All in all, it still doesn't answer either of the questions I asked about dedicated encoder ICs / teensy's built in decoders without any detail in the datasheet. Please let me know what chips I should be searching for this application, I will try reducing the pulses to reasonable levels.

author: H.O
author_rank: Frequent Contributor
timestamp: July 28, 2020, 04:48:07 pm
content: If you're controlling position using the quadrature encoder signals as feedback then forget about using a simple frequency divider(s) to divide down the high frequency quadrature signal from the encoder - it's not as simple as just slapping a divide-by-n on each of the two signals.Like I said earlier, the LS7166 is a "classic" quadrature counter IC but I don't know how easy it is purchase now. Another one that pops up when searching is the iCHausic-MDbut I don't know how easy it is to actually purchase. I believe most people that know that what they're doing either roll there own counter in a CPLD or FPGA or use a a uC with the required peripheral.I'm surpised you weren't able to find an encoder with a resolution other than 4096PPR. The CUI Inc encoder with programmable resoultion mentioned earlier are availble from Digikey and you have manufacturers like US Digital, Avago, Scancon, Hengstler, Heidenhein, Omron etc etc offering all sorts of enocders.Finally, if you can live with 1/4th the resoulution of the encoder you should be able to quite easily convert what you have into into two discrete up/down pulses using some basic 74 series logic ICs. Then feed those signals into two separate timer/counter inputs on the uC and differentiate them each loop to get the relative distance moved since last time.If you can't wait two months for "stuff" to arrive I stronlgy you suggest you shop around for something that does what you need. You'll spend a lot of time rolling your own solution which - again - is not wrong but in this case it feels like the actual motor control part is just a small piece of a bigger picture.

author: Siwastaja
author_rank: Super Contributor
timestamp: July 28, 2020, 05:00:11 pm
content: IMHO, 500kHz encoder signal shouldn't be a problem for the 16MHz AVR hardware timer/counter module, that's the point. Have you tried it? Are you having a problem, and if yes, what kind?So you don't need toprocessevery pulse in software.The counters count the pulses for you; you only add extra bits in overflow interrupts (500kHz/256 is manageable interrupt rate because the ISR is very short). Then you can do actual calculations at 1kHz, for example, looking at the counter values.

author: OM222O
author_rank: Frequent Contributor
timestamp: July 28, 2020, 06:17:12 pm
content: it looks like that timer 1 allows for counting external signals. I don't think it's possible to use both singals on the same counter however. That makes me wonder how I can find the direction of rotation? I'm setting it in software when the motor is moving but if there is external forces like another robot colliding with us, that would be hard to check. should I just check it when the timer for the first signal has overflown and caused an interrupt?I'm still looking at the datasheet and trying to figure out the details of the timers since I haven't used them outside of the normal PWM before, so please if you have an example using it as a pulse counter, share it.P.S: yes, the drive train is only a small portion of the whole project.

author: max_torque
author_rank: Super Contributor
timestamp: July 28, 2020, 07:38:34 pm
content: It would be easy to count the encoder pulses over some fixed time period with an external counter IC, and the controller can just read those pulses when it wants an update.Something like a SN74LV8154 can be used as 16b counters or a cascaed 32b counter, and the counts can be read v quickly from the parrallel output.. Use an AVR timer to generate a gating output at a suitable frequency, and read the pulse counts at each of those intervals. To avoid "Missed" counts, don't reset the counter, just let it overflow and deal with that in s/w (if new counts < old counts, counts = New+(65535-old))https://www.ti.com/lit/ds/symlink/sn74lv8154.pdf?ts=1595964924282&ref_url=https%253A%252F%252Fwww.google.com%252FBecause the puse counting is handled externally the AVR is free to run the motor control loops

author: langwadt
author_rank: Super Contributor
timestamp: July 28, 2020, 07:48:14 pm
content: Quote from: max_torque on July 28, 2020, 07:38:34 pmwhy make a hairball of logic and all the issues that come with that when you can just pick one of the many MCUs can that easily do it all?

author: thm_w
author_rank: Super Contributor
timestamp: July 28, 2020, 08:42:05 pm
content: Quote from: Siwastaja on July 28, 2020, 05:00:11 pmMaybe I'm missing something here, how are you counting the quadrature pulses using a plain timer/counter peripheral? If the motor is going forward or backward, the count will increase on both channels.Normally you'd have dedicated logic to decode this:http://ww1.microchip.com/downloads/en/DeviceDoc/70063b.pdf