closed loop motor control

Ok,
Now that my newbie brain will allow me to post in the correct place I have a question.

This is more than likely due to the fact that I'm searching for information with a $29 phone but I can't seem to find a complete sketch or circuit for closed loop dc motor control with a break beam tach.
In my search I have located plenty of circuits for break beam tachometers and for dc motor control but I cannot find them together in one project.

Just like a car motor or a turntable I need to be able to get a motor to maintain or at least correct speed reasonably quickly when a load is changed using information from the break beam tach. I have no interest in PID because I need it to be a consistent and smooth speed. I'll need a pretty big dc to pull this load and I probably won't want a stepper. Simple syncronus or bldc should be easiest.
I'm sure this circuit exists with a sketch somewhere but I've only been searching Google and this site over and over so I haven't ran accros one.
I'm trying to write my own sketch and make my own circuit but I have already fried one motor and one bord so perhaps it's time to start asking questions..
Any reply will be appriciated,
Thanks

I have no interest in PID because I need it to be a consistent and smooth speed.

Yes, PID is the way to do this consistently and smoothly. Who told you PID isn't smooth?

Instead of searching for "break beam" try "optical" or "hall effect" Those kinds of sensors are often used for sensing the rotation of a shaft. The actual sensor technology doesn't matter too much: a program written for a hall effect sensor will work with a break beam.

C-Looper:
I'm looking at this site with a $29 phone so I'm having trouble starting this topic in the right place. I'm not getting all the options.

Do me a favor. Use something functional next time.

Cross-posts removed.

The opinions about PID came from reading this forum. I'm only repeating what I read. Having not had a PID controlling a motor in front of me I cannot support or deny this forums claims.
I did not say witch type of motor because that has not been decided yet and will be determined by my low budget, the needs of the circut, the load, and what is available.
Information about getting any motor to work in this kind of closed loop would be helpful and appriciated. I can start small with an old 12V brush drill motor to learn about the code and the circut then move up to bigger more expensive motors that will require shields and relays as need be.

These variables can be modified to work best for whatever motor I can get to work. As I stated. This information is surely being discussed on this forum. I will just have to wait till someone kind enough to point me in that direction comes along. Its a little far fetched to suggest that we will need to determin load and rpm before we can research how to build a circut or find a similar code to study. I'm just trying to get info about how to get a motor to run and give feedback to keep its speed. That should be here somewhere.

As I pointed out above I haven't put a hall effect or an encoder on a motor and seen what they do either but I will be happy to listen give it and the PID a try and post all the mesurments and documented outcomes of my experiments right here if I can just get someone to direct me to an example involving any motor receiving it's closed loop feedback.
Thanks again,

Funny,
When I Google "arduino closed loop motor control" I find three people complaining that they can't find any complete help either. Guess I'll have to keep looking on my own. Thanks for all the "help" lol. If anyone can manage to lift a finger other than to tell me to Google it myself I would really appriciate it.
Beleave it or not I would not subject myself to all this public forum ridicule if Google had not failed. I have searched every combination arduino closed loop motor control I can come up with and if it is well documented it must be a couple pages down.

So the best anyone can offer is keep looking? Wow,
Thanks,

The best advice I got was the Question, "Who told you PID wasn't smooth?"
While frought with ridicule at the very least this is actual advice.

This led me to follow the only other excuse for advice I have received. To sod off and go Google it myself. Leading me to watch this annoying video.

In this video quite a funny old chap explains that PID May in fact be the only way to do this in a smooth manner. in light of the "hunting" around that can occur with simple pin on pin off high low control.

Due to the nature of the responses I have received I will be posting my entire project here with code and circut to aid anyone who runs into the same problem.

Ok then, tell,us more about your project so that we can suggest an appropriate motor and controller. You have given us almost less information than you used on google.

What is it?
How much torque? (Do you know how to measure torque?)
How fast?
What precision?
What is your power supply?

Here is a nice 12V brushless motor with a built in tach. The tach is open collector and the controls (pwm, direction, & stop) are low active. This means that you can control everything with a 5V circuit.

I've been experimenting and learning about PID with this motor and it's going well.

I have a sketch if you are interested.

John

Thank you Mr Hogan. you are too kind. I would be quite interested in a sketch and I will check out your motor.

Given I'm just asking for an example of
closed loop motor control working somewhere, just like the blink project we have all seen before, there is just no need to bully me about why I want it.
I'm going to go ahead and postulate the theory that explaining my project won't change any of the bad attitudes I'm having thrown at me but here we go anyway. Why not?

I'm just trying to build a project turntable. Its not like I'm working on some revolutionary prototype.

No I don't have any idea how to measure torq but I guess I won't be surprised if I'll have to look that up my self too. Is that a function of amperage and voltage?

33&1/3 wants to lead us to some extremely unfriendly numbers so let's start with a 45player. Experiment one can be to see how bad this old motor from a 78 player can be speed controlled without too much whine..lol

Parts I have available are for a direct drive table so the presicion may need to be pretty tight. The motor jumping around or whining would become amplified so I don't want to modify speed too much from 100% duty cycle.
This may lead me to a different motor and I am open to suggestion.
Power supply will be determined by the motor. How could it not be? Most motors won't run well without the correct power supply.

I have an old turntable motor we can use as an example. Maybe that will make things relatively simple.

We have here an ancient General electric ac motor with an information plate. It runs at 1550 rpms at 12 Watt 60hz. It has two wires and a half inch post that will hopefully make for easy math and wiring.

I would like to point out that it is not a sure thing that I will use this motor for the project. I just want to see if I can control it because it's here and it's cheep.
I'm just tinkering around trying to learn. I've had this chip for a while and I'd like to stop googling it and start using it.
I also have a sugar cube relay and a l298 motor control shield for this UNO so maybe they can be put to work with this ac motor.

You can only vary the speed of an ordinary AC motor much by changing the drive frequency.

There were special highly skewed rotor designs as used by REVOX in their tape recorders which you could control by varying the voltage - but I bet your motor isn't one of those.

You might be better off with a brushless DC motor as mentioned above.

You would need to have eg a belt drive to smooth out the motor pulses.

regards

Allan

Just to exit this somewhat contentious loop, I'll post the code for the motor I mentioned.

I'm unsure about its suitability to drive a turntable or if the OP is interested in a DC alternative. My sense is that it does a great job compensating for torque and voltage but there are small changes in speed around the setpoint. Perhaps the PID tuning can be improved.

However, this motor has made it easy to experiment with PID in the real world.

/* PID Motor Control Example           7834 (25%) / 362 (17%)                  bHogan 7/27/16
 * Using eBay "DC 12V Brushless Motor CW/CCW PWM Speed Control Urgent Stop With Drive Circuit"
 * #172168676210 with Pro-Mini. 12V to motor, all signals work directly with 5V logic, (nice!)
 * Recommended PWM freq - 20-30kHz (native PWM freq = 490Hz - changed to 31.2kHz))
 * Stop = YELLOW->GND, CCW = BLUE->GND. PWM=WHITE, Speed=BROWN (open collector - pull high)
 *
 *DEVELOPMENT NOTES:
 * - PWM freq of 31kHz is important - motor runs smother and closer to set speed
 * - some gap is due to fluctuations in the pot setting
 * - PID works best in DIRECT mode - PWMval is inverted so it can run in this mode.
 *
 * WHAT IS NEW since last:
 * - (v1e) release with auto-tune and attempt at strobe
 * - removed auto-tune - no luck with it
 *
 * TODO
 * - use Timer1 for roll your own PWM (like Mini) ?
 * - more experiments with tuning parameters?
 *
 
------------------------------------------------------------------------------------------------*/

#include <PID_v1.h>                     // http://playground.arduino.cc/Code/PIDLibrary
//#include <PID_AutoTune_v0.h>          // http://playground.arduino.cc/Code/PIDAutotuneLibrary

#define DEBUG            true           // allow serial print

#define SPEED_PIN        2              // speed signal from motor creates INT - BROWN wire
#define MOTOR_ON         3              // LOW to stop motor - YELLOW wire
#define MOTOR_DIR        4              // LOW to turn CCW - GREEN wire
#define PWM_PIN          9              // best PWM for motor speed - WHITE wire
#define POT_PIN          A1             // 10k pot across gnd and 5V to set speed

#define MIN_RPM          100            // minimum motor speed
#define MAX_RPM          4800           // maximum motor speed
#define MOTOR_CCW        false          // true to run motor CCW

byte PWMval;                            // PWM setting for motor speed
volatile unsigned long duration, freq, RPM; // from speed signal output from motor
volatile unsigned long prevMicroSec = 0;    // to calc RPM in ISR

//Define PID Variables
double Setpoint, Input, Output;
//double Kp = 0.01, Ki = 0.15, Kd = 0.0;  // tuning bnenchmark
double Kp = 0.01, Ki = 0.4, Kd = 0.0;     // TESTING - higher I (.4)  = faster start

//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT); // PWM inverted so use DIRECT


void setup() {
  Serial.begin(115200);                 // for DEBUG and speed read
  pinMode(MOTOR_ON, OUTPUT);            // setup motor on pin
  pinMode(MOTOR_DIR, OUTPUT);           // setup motor direction pin
  pinMode(SPEED_PIN, INPUT);            // setup speed pin
  digitalWrite(MOTOR_ON, LOW);          // start with motor off
  digitalWrite(MOTOR_DIR, HIGH);        // start with CW rotation
  digitalWrite(SPEED_PIN, HIGH);        // set 20K pullup on it
  Serial.println("Begin");

  setPwmFrequency(9, 1);                // increase default PWM freq from 490Hz to 31.2kHz

  //initialize the PID variables
  Setpoint = checkPot();                // PID setpoint comes from pot
  Input = RPM;                          // PID input is the calculated speed of the motor

  //turn the PID on
  myPID.SetMode(AUTOMATIC);             // PID is always on
  myPID.SetSampleTime (100);            // how often the PID evaluates - default is 200mS.

#if (MOTOR_CCW)
  digitalWrite(MOTOR_DIR, LOW);          // run with CCW rotation
#endif

  digitalWrite(MOTOR_ON, HIGH);         // start motor
  attachInterrupt(0, GetSpeed, FALLING); // count the time between pulses to calc RPM
}


void loop() {
  Setpoint = checkPot();                // get the setpoint from the pot
  Input = RPM;                          // get the current current RPM
  myPID.Compute();                      // compute the output
  setSpeed (Output);                    // adjust PWM duty to set speed


#if (DEBUG)
  int gap = abs(Setpoint - Input);      // calc distance away from setpoint
  Serial.print("Setpoint: ");
  Serial.print(Setpoint, 0);
  Serial.print("\tRPM: ");
  Serial.print(RPM);
  Serial.print("   Gap: ");
  Serial.print(gap);
  Serial.print("\t\tOutput: ");
  Serial.print(Output);
  Serial.print("   PWMval: ");
  Serial.println(PWMval);
#endif
}


unsigned long checkPot() {  // 4.6 RPM / division
  unsigned int potVal;
  potVal = analogRead(POT_PIN);
  // return 2500;                       // for DEBUG - constant setpoint bypassing the pot
  return map(potVal, 0, 1023, MIN_RPM, MAX_RPM);
}


void setSpeed (int setPWM) {
  PWMval = map(setPWM, 0, 255, 255, 0); // invert output so we can use DIRECT PID (not REVERSE)
  analogWrite(PWM_PIN, PWMval);         // set the PWM for the motor speed
}


/*----------------------------------------------------------------------------------------------+
 * setPwmFrequency - Divides a given PWM pin frequency by a divisor.
 *             ** Pins 9 & 10 safest to use - 31.250 kHz if divide by 1 **
 * The resulting frequency is equal to the base frequency divided by the given divisor:
 *   - Base frequencies:
 *      o The base frequency for pins 3, 9, 10, and 11 is 31250 Hz.
 *      o The base frequency for pins 5 and 6 is 62500 Hz.
 *   - Divisors:
 *      o The divisors available on pins 5, 6, 9 and 10 are: 1, 8, 64,
 *        256, and 1024.
 *      o The divisors available on pins 3 and 11 are: 1, 8, 32, 64,
 *        128, 256, and 1024.
 *
 * PWM frequencies are tied together in pairs of pins. If one in a pair is changed,
 * the other is also changed to match:
 *   - Pins 5 and 6 are paired on timer0
 *   - Pins 9 and 10 are paired on timer1
 *   - Pins 3 and 11 are paired on timer2
 *
 * Note that this function will have side effects on anything else that uses timers:
 *   - Changes on pins 3, 5, 6, or 11 may cause the delay() and
 *     millis() functions to stop working. Other timing-related
 *     functions may also be affected.
 *   - Changes on pins 9 or 10 will cause the Servo library to function
 *     incorrectly.
 *
/-----------------------------------------------------------------------------------------------*/

void setPwmFrequency(int pin, int divisor) {
  byte mode;
  if (pin == 5 || pin == 6 || pin == 9 || pin == 10) {
    switch (divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 64: mode = 0x03; break;
      case 256: mode = 0x04; break;
      case 1024: mode = 0x05; break;
      default: return;
    }
    if (pin == 5 || pin == 6) {
      TCCR0B = TCCR0B & 0b11111000 | mode;
    } else {
      TCCR1B = TCCR1B & 0b11111000 | mode;
    }
  } else if (pin == 3 || pin == 11) {
    switch (divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 32: mode = 0x03; break;
      case 64: mode = 0x04; break;
      case 128: mode = 0x05; break;
      case 256: mode = 0x06; break;
      case 1024: mode = 0x7; break;
      default: return;
    }
    TCCR2B = TCCR2B & 0b11111000 | mode;
  }
}

//----------------------------------------------------------------------------------------------+
//                                        ISR
//----------------------------------------------------------------------------------------------+

void GetSpeed() {  // ISR triggered for each pulse (6 pulses /revolution)
  duration = micros() - prevMicroSec;   // using micros() in an ISR despite the warning
  freq = (1000000L / duration);         // convert uS duration to Hz
  RPM = freq * 10;                      // 6 pulses / revolution and convert to minutes
  prevMicroSec = micros();              // reset the period time
}

BTW, "bHogan" is a nickname I got in college after having way too much Crown Royal. So it sounds funny to me to be preceded by "Mr."! But thanks!

a project turntable.

So is that a turntable for projects (like product photography or 3D scanning) or a record player?

In the end Delta may have been the most helpfull. I'm going to rig this up and learn the code and circut just for the sake of learning this chip, but if there is in fact just going to be a warble with all types of motor speed control then this May not be an arduino project. I'm pretty interested in hearing this warble. I bet it would make for some cool samples!
I'm also curious if it will translate through a big rubbery belt. If Its audible it probably will though. (I'm immediately reminded of my serpentine belt squeeking)
I May not be using the arduino for it's best purpose in this application. There are other things it can do. It defiantly makes the best tacho to data log deck speed.

Hi all...

Surely the whole point of a PID design is that it integrates the setpoint error to zero. And if the other parameters are set correctly there will be no perceptible speed variation except with variations in load quicker than it can respond. I've designed such systems.

A good example was the control system used by REVOX, and their (professional) parent STUDER, who made some of the best tape recoders ever, with much better performance than the standard semi-synchronous motors used by some of their competitors.

I think that UHER and STELLAVOX, who made beautiful portable recorders also used such an approach with DC motors.

regards

Allan.

Still Trying to gear out this turntable motor. Gear math sucks. Finding the exact ratio to turn a turntable at the correct speed should take my dunce hat a great long while. I have a 1550 rpm motor with a convenient half inch post. The turntable I'm using has also been milled to a friendly 1 foot diameter. gearing it out to 33 and 1/3 and rpm 45 could be extremely difficult and take a lot of trial and error but at least its obvious the machinists wanted this to be easy math. This is pre WW2 tech so they probably didn't even have a calculator. Originally this big old clunky device ran at 78 rpm but the world has moved on and most people don't have a 78 player anymore.The way I have seen it done in old turntables is different idler drive wheels for different speeds. Then i can press one button to engage each speed. I am going to try this first due to the advice received here.
The last thing i will want is any sort of warble.
Thanks a gain for pointing me in a direction. Arduino may not be the best way to control speed this quietly and consistently. Trying it this way leaves my Arduino open to do other stuff.

Allan,
I am defiantly familiar with Studer, but only from the recording end. Learning the electronics end of this is tough for me and implicating some level of smooth PID control that will get the table back up to the correct speed when a load (like the needle) is introduced is a very interesting option. Studer tape rigs rival even TEAC in their smooth recording speed. If you have any information on how to wire something like that up I would greatly appreciate it. They probably didn't need much chipage.