[ATMEGA328] Recommend me a fast PID library? - brushless servo control - Page 1
Forum section: electronics / general

author: Photon939
author_rank: Regular Contributor
timestamp: March 04, 2020, 06:03:49 pm
content: For a while now I have been working on converting my 3d printer to brushless servo motors and finally have everything nailed down pretty well.I salvaged some servos with control boards out of a TV studio camera pan/tilt mount (found at junkyard) and made my own PCBs housing an ATMEGA328 that I program using the Arduino IDE.The architecture is as follows:Self-contained brushless servo motor drive handles all the commutation and power driving, just feed power and a differential signal to drive the motor in a direction with torque proportional to the voltage differenceServo motor with an encoder bolted onto the back It has something like 4096PPRQuadrature decoder and 12 bit counter IC with parallel interface. Salvaged from the original control board.-Step pulses from the printer board fire an interrupt to increment or decrement the servo position setpoint in memory based on the state of the direction bit-Main loop runs a PID loop using current position read from the encoder counter chip versus the setpoint held in memory-ATMEGA328 outputs the result on two fast PWM pins (62KHz PWM) which is filtered with a small RC filter then fed into an op amp with a voltage gain of 2 to drive the servo motor controllerSo basically the faster I can execute the PID loop the tighter control I should have, resulting in increased print quality.I am looking for suggestions on a PID library with the lowest execution time to start, then begin optimizing my hardware interface code as much as possible. Last I checked my main loop was running at about 2KHz.

author: retrolefty
author_rank: Super Contributor
timestamp: March 04, 2020, 06:09:16 pm
content: The only Arduino PID library I've seen uses floating point to calculate the pid values. You need to verify/measure and prove that would not be fast/good enough for the application. Otherwise you need to find an integer pid which as I said I haven't come across. Perhaps others have?

author: lucazader
author_rank: Regular Contributor
timestamp: March 04, 2020, 06:20:49 pm
content: As just said, most of them will likely be very slow on the atmega328.You could look into if there is a fixed point algorithm? This should significantly speed up the calculations compared to a float.Or you could run the PID algorithm on a separate, faster arduino, like a teensy, or due, or other 32 bit based arduino. Then just send the control signals to the 328p

author: langwadt
author_rank: Super Contributor
timestamp: March 04, 2020, 07:58:35 pm
content: linuxcnc and the likes doesn't run the control loop much faster than a few kHz.Consider how little things can change in 1ms with the inertia of the mechanical parts and how few counts you will get from the encoder in 1ms at anything but max rpm

author: brucehoult
author_rank: Super Contributor
timestamp: March 05, 2020, 01:22:12 am
content: Quote from: retrolefty on March 04, 2020, 06:09:16 pmYou'd have to be really really sure of the range of every variable to use fixed point.From memory FP add/sub/mul on a 16 MHz AVR take around 10 us. I count around 16 FP operations in Compute() in Arduino-PID-Library (counting a compare the same as a subtract), so it's probably going to take around 0.15 ms plus a few us of general overhead.Rough guess, that PID code by itself should run at around 6 kHz.I doubt there's any benefit in trying to control motors at any more than a couple of hundred Hz.

author: SiliconWizard
author_rank: Super Contributor
timestamp: March 05, 2020, 02:25:13 am
content: Quote from: Photon939 on March 04, 2020, 06:03:49 pmAre you sure you'll get better results than with stepper motors?

author: Photon939
author_rank: Regular Contributor
timestamp: March 05, 2020, 01:28:52 pm
content: Quote from: brucehoult on March 05, 2020, 01:22:12 amThe servo I have is pretty high performance and can easily oscillate at several hundred Hz if the PID isn't tuned well.Although based on what you're saying it sounds like I may be able to significantly increase my loop speed just from optimizing my hardware interface code (eliminating digitalWrite, reducing variable sizes, etc)I'm still learning on how to wean myself off the slow built in functions from Arduino world.Quote from: SiliconWizard on March 05, 2020, 02:25:13 amI'm not so much looking to get better quality than steppers but I was hoping for faster speed and quieter operation. My printer is an abomination of metal lead screws and was very loud with stepper motors. I could hear it from the floor above when it was printing. It is much quieter now and doesn't have the tones and resonances you get from steppers driving metal structures. Pretty much now I just need to get the loop speed up so I can increase the PID parameters without the motor going nuts.It prints well now and at a higher speed than the steppers I had before but the quality is a bit lower.

author: Photon939
author_rank: Regular Contributor
timestamp: March 05, 2020, 01:42:23 pm
content: My hardware setup

author: SiliconWizard
author_rank: Super Contributor
timestamp: March 05, 2020, 02:25:09 pm
content: Quote from: Photon939 on March 05, 2020, 01:28:52 pmI'm surprised you get lower noise with your servo motors, but I get the idea.One way I know of to lower noise with stepper motors is to use micro-stepping. That basically requires specific drivers for the stepper motors, but that change alone can make a real difference.

author: Photon939
author_rank: Regular Contributor
timestamp: March 05, 2020, 02:42:24 pm
content: Quote from: SiliconWizard on March 05, 2020, 02:25:09 pmMy printer runs off the Reprap RAMPS v1.4 board which uses an Allegro stepper controller with microstepping, I think I was running it at 1/16th mode. The servos are still an order of magnitude quieter. They are basically silent. The only noise the X/Y axes make now is mechanical. The extruder stepper makes some noise but it's a fairly constant whir and isn't as rigidly mounted to the frame as the X/Y lead screws.The Z axis still uses steppers, no real advantage to switching them out as they move so infrequently.

author: langwadt
author_rank: Super Contributor
timestamp: March 05, 2020, 02:52:25 pm
content: Quote from: Photon939 on March 05, 2020, 02:42:24 pmtried switching to TMC stepper drivers?

author: techman-001
author_rank: Frequent Contributor
timestamp: March 05, 2020, 08:27:47 pm
content: Quote from: SiliconWizard on March 05, 2020, 02:25:09 pmI believe it may be an ac servo with quadrature encoder and not a stepper judging from the OP's picture.

author: rstofer
author_rank: Super Contributor
timestamp: March 05, 2020, 11:34:46 pm
content: If you're willing to give up on the Arduino libraries, why not give up on the ATmega32P version of the Arduino and go for an ARM-M4 board that has a FPU, runs at 120 MHz and is (more or less) form factor compatible with the Arduino?https://os.mbed.com/platforms/GD32-F307VG/That's just the first board I came across, there are many on the market.There are definite advantages to using the MBED infrastructure in terms of library code and the toolchain.It is not possible to have too much speed or too much memory.

author: brucehoult
author_rank: Super Contributor
timestamp: March 05, 2020, 11:59:21 pm
content: Quote from: rstofer on March 05, 2020, 11:34:46 pmI'm having trouble finding a price for that.I'm sure it's a lot more than the Teensy 4.0, with 600 MHz (overclockable to 1 GHz, but it gets warm) Cortex M7 for $20. Works great with the Arduino IDE and standard sketches. I have one and it rockshttps://www.pjrc.com/store/teensy40.htmlIt's not Arduino Uno form factor but if you solder on headers (which takes 2 minutes) you can plug it into a breadboard.Or if you like Uno form-factor there's SiFive HiFive1 with 320 MHz RISC-V RV32IMAC (no FPU) plus an ESP32 wifi/BT chip for $59.Or Sipeed Maixduino with Uno form factor, dual core 400 MHz RV64IMAFDC, with Neural Network processor, FFT accelerator, SHA256 accelerator, AES accelerator,. And an ESP32. $22.90 on Amazon. Crazy.https://www.amazon.com/dp/B07T4N2NK9The Teensy and Maixduino have got to do floating point at least a thousand times faster than an AVR ATmega328 or Atmega2560 (more commonly used for 3D printers). But the AVR should do the job just fine.

author: rstofer
author_rank: Super Contributor
timestamp: March 06, 2020, 01:35:26 am
content: I had forgotten about the Teensy 4.0 having an FPU. I have a couple but haven’t used them yet. Definitely a good choice.

author: towe96
author_rank: Contributor
timestamp: March 06, 2020, 07:31:11 am
content: FP operations on the Teensy 4.0 are indeed extremely fast. You may run into issues with the limited available pins though.Anyways, this is an X -> Y problem. The issue aren't the stepper drivers, it's the bad drivers - the way they drive the steppers is wayyy too choppy.Consider getting a modern board with modern drivers instead - SKR 1.3, Fysetc S6; with TMC2209 or TMC5160 drivers.

author: brucehoult
author_rank: Super Contributor
timestamp: March 06, 2020, 08:08:54 am
content: Quote from: towe96 on March 06, 2020, 07:31:11 amIt's got *forty* digital IO pins! 23 available on the holes/headers on the long edges, the other 17 from pads on the bottom of the board.That's more than the 20 on the ATmega328 / Arduino Uno the OP is using (14 dedicated digital, plus you can use the six "analog" pins as digital too).

author: SiliconWizard
author_rank: Super Contributor
timestamp: March 06, 2020, 02:36:15 pm
content: Quote from: techman-001 on March 05, 2020, 08:27:47 pmThey are brushless servo motors as the OP stated - read a bit again to understand better what I was more specifically discussing with them.The OP is basically using servo motors to replace stepper motors on a 3D printer, and the main reason apparently is to lower noise.So, I was discussing noise specifically and how surprised I was that they got significantly lower noise with the servo motors (as these usually contain reduction gears, which adds some noise), and was talking about how micro-stepping stepper motors would make rotation smoother and was an usual way of reducing noise, as the main cause of noise in stepper motors are the discrete steps. My point was - is it really necessary to use servo motors here just for that?Apparently, the original controller already used micro-stepping (with 1/16 - which looks decent), so the OP was just observing that it didn't seem to help. I'm still a bit puzzled, and at this point, I think that it may be due to how the controller (software-wise) works. Micro-stepping is all fine (gets you smoother rotation between integer steps), but if the software controller itself controls the motors with significant jitter (which I wouldn't be hugely surprised about on an ATMEGA328 unless it's very well coded), that may still cause extra noise due to jitter between integer steps, which micro-stepping can't cure.Another possible cause of noise could be that the stepper motors didn't have quite enough torque - maybe just barely enough not to skip steps, which would make them force a bit and make a lot more noise.

author: Photon939
author_rank: Regular Contributor
timestamp: March 06, 2020, 03:56:24 pm
content: Thanks everyone to your suggestions.I'll try to clarify some points:The servos are Elcom/Pittman direct drive, 3 phase, permanent magnet rotor servos. There is a high resolution quadrature encoder on the back of the servo motor. No gearbox, the motor's output shaft is connected to my lead screws directly with a flexible coupling.One of the main reasons my printer was so loud is that everything is metal and uses lead screws. Most printers use belts which help absorb a lot of the vibration you normally get with a stepper motor.Here are some videos of my printer running before during and after the servo upgrade:Original (X and Y axes are both stepper)https://www.dropbox.com/s/phzbukpatqysmqc/20190112_214905.mp4?dl=0Half and half (X is stepper, Y is servo)https://www.dropbox.com/s/tf70g6trvc4c2hw/20190115_214738.mp4?dl=0After (X and Y are both servo)https://www.dropbox.com/s/tiubqt9gkgt4wqn/20190117_215957.mp4?dl=0

author: brucehoult
author_rank: Super Contributor
timestamp: March 06, 2020, 09:03:05 pm
content: To my complete lack of surprise, that's using an ATmega2560 to control it, as is normal for 3D printers, not the 4x smaller in I/Os and 8x smaller in program flash ATmega328 mentioned in the title.Of course the CPU and CPU speed are the same.

author: ogden
author_rank: Super Contributor
timestamp: March 06, 2020, 09:05:43 pm
content: Check Atmel appnote "AVR221: Discrete PID Controller on tinyAVR and megaAVR devices". Well-written article with source code provided.

author: Photon939
author_rank: Regular Contributor
timestamp: March 06, 2020, 10:50:40 pm
content: Quote from: brucehoult on March 06, 2020, 09:03:05 pmThe videos are older from before I had the PCBs made.I did my proof-of-concept stage with the atmega2560 as it was convenient, all it was doing is running the servo motors. As you already mentioned the CPU is basically the same. I already posted images above for the PCBs I had made for this project.The printer has its own atmega2560 running Marlin firmware and two remaining stepper drivers to run the extruder and Z axis. It handles all the PC communication, G-code interpretation, heater control, etc.My boards just accept the dumb step/dir interface that the original stepper drivers had and run PID control of the servo.