Hello,
I would like to regulate a DC motor to a desired speed using a PID controller. The speed is measured via rotary encoder.
That's why I want to measure and calculate the speed first
I have an error in the code
I would be grateful if someone could help me.
//Encoder pin
const int encoderPinA = 2;
// MD30C PWM connected to pin 10
#define PWM 12
// MD30C DIR connected to pin 12
#define DIR 10
//Encoder variables
volatile unsigned long encoder_Position;
unsigned long newposition_encoder;
unsigned long oldposition_encoder = 0;
//Time variables
unsigned long newtime = 0;
unsigned long oldtime = 0;
float encoder_rpm;
float Input;
float Output= 250;
int PPR = 100;// From encoder How Many Pulses Pur Revolution
const int interval = 1000; //choose interval is 1 second (1000 milliseconds)
void setup() {
// DC motor
pinMode(PWM, OUTPUT);
pinMode(DIR, OUTPUT);
pinMode (encoderPinA, INPUT_PULLUP);
attachInterrupt (digitalPinToInterrupt (encoderPinA), doEncoderA, FALLING);
Serial.begin (115200);
}
float read_speed(void)
{
if(millis() - newtime > interval)
{
newposition_encoder = encoder_Position;
newtime = millis();
encoder_rpm = ((newposition_encoder - oldposition_encoder)*60 * 1000UL) /PPR/(newtime-oldtime);
oldposition_encoder = newposition_encoder;
oldtime = newtime;
}
return encoder_rpm;
}
void doEncoderA()
{
encoder_Position++;
}
void loop() {
Input = read_speed();
analogWrite(PWM, Output);
digitalWrite(DIR, LOW);
Serial.print(" Input = ");
Serial.print(Input);
Serial.print(" Output = ");
Serial.print(Output);
Serial.println();
}
The RPM versus PWM percentage curve will depend on your motor, the load on the motor, the motor driver, the motor power supply voltage, the PWM frequency and the PWM percentage.
You will have to determine the curve yourself.
Here is a typical example for a free running motor:
Note the millis() when you see the 1st pulse. Subtract it from the millis() at the start of the next pulse. Inverse of period is frequency. Divide by pulses per revolution.
You never modify the variable 'Output'. It looks like you modified the code without mentioning it, because in the posted code, it's initialized to 50.0 and in the printout it's 40. In any case, if you expect the output to change, you have to write code that changes it.
Apart from that, the program doesn't do any speed curve translation as mentioned in reply #11. There is no theoretical linear relationship between a PWM value and some RPM. You have to estimate, calibrate, or compute one.