Is there a way to convert from rpm to the 0-255 range for a motor?
I've got a small chunk of code from my project:
if (LEFTcm!=1.000 || RIGHTcm !=1.000){
float RPMIncrease = abs(((RIGHTcm + LEFTcm)-100)/100)+1;
int RPMmultiplier = RPMIncrease * 16;
//Note that 16 is the motor rpm at the correct distance.
digitalWrite(b_dir1_pin, LOW);
digitalWrite(b_dir2_pin, HIGH); //Motor 2 rotation direction and rpm
analogWrite(b_pwm_pin, RPMmultiplier);
digitalWrite(a_dir1_pin, HIGH);
digitalWrite(a_dir2_pin, LOW); //Motor 1 rotation direction and rpm
analogWrite(a_pwm_pin, RPMmultiplier);
Basically the code increases the rpm of my motors based on the distance detected from 2 sensors. If there is an x% change in distance then there will be an x% change in motor rpm.
Now the issue I'm having is with the analogWrite lines. I know that in the place of RPMmultiplier you need to use a value between 0-255 or HIGH/LOW, so how would I go about changing lets say 20 rpm into that range of values?
Any help is appreciated and I'm sorry if this is a dumb question.
Motor RPM depends on the motor power supply voltage, the load on the motor, the motor driver, the PWM frequency and the PWM value in a complicated way. There is no simple conversion.
Consider posting the details of the setup and perhaps forum members can help.
Example of a PWM/RPM plot, taken at random from the web:
// Pins for left Motor
const int a_pwm_pin = 9;
const int a_dir1_pin = 8;
const int a_dir2_pin = 7;
// Pins for right Motor
const int b_pwm_pin = 10;
const int b_dir1_pin = 11;
const int b_dir2_pin = 12;
// Pins for left sensor
const int Ltrig_pin = 6;
const int Lpw_pin = 6;
// Pins for right sensor
const int Rtrig_pin = 5;
const int Rpw_pin = 5;
void setup()
{
// Set up pins for left motor
pinMode(a_pwm_pin, OUTPUT);
pinMode(a_dir1_pin, OUTPUT);
pinMode(a_dir2_pin, OUTPUT);
// Set up pins for right motor
pinMode(b_pwm_pin, OUTPUT);
pinMode(b_dir1_pin, OUTPUT);
pinMode(b_dir2_pin, OUTPUT);
Serial.begin(9600);
}
void loop()
{
//Set up pins for left sensor
float LEFTcm;
long LEFTduration;
pinMode(Ltrig_pin, OUTPUT);
digitalWrite(Ltrig_pin, HIGH);
pinMode(Lpw_pin, INPUT);
LEFTduration=pulseIn(Lpw_pin, HIGH);
LEFTcm=LEFTduration/58.8; //Distance to object in cm
//set up pins for right sensor
float RIGHTcm;
long RIGHTduration;
pinMode(Rtrig_pin, OUTPUT);
digitalWrite(Rtrig_pin, HIGH);
pinMode(Rpw_pin, INPUT);
RIGHTduration=pulseIn(Rpw_pin, HIGH);
RIGHTcm=RIGHTduration/58.8; //Distance to object in cm
if (LEFTcm!=50.000 || RIGHTcm !=50.000){
float RPMIncrease = abs(((RIGHTcm + LEFTcm)-100)/100)+1;
float RPMmultiplier = RPMIncrease * 16;
int z = map(RPMmultiplier, 0, 1024, 0, 255);
digitalWrite(b_dir1_pin, LOW);
digitalWrite(b_dir2_pin, HIGH); //Motor 2 rotation direction and rpm
analogWrite(b_pwm_pin, z);
digitalWrite(a_dir1_pin, HIGH);
digitalWrite(a_dir2_pin, LOW); //Motor 1 rotation direction and rpm
analogWrite(a_pwm_pin, z);
Serial.println("Right cm");
Serial.println(RIGHTcm);
Serial.println("Left cm");
Serial.println(LEFTcm);
Serial.println("Multiplier");
Serial.println(RPMmultiplier);
Serial.println("Z");
Serial.println(z);
delay(2000);
}else{
digitalWrite(b_dir1_pin, LOW);
digitalWrite(b_dir2_pin, HIGH); //Motor 2 rotation direction and rpm
analogWrite(b_pwm_pin, 16);
digitalWrite(a_dir1_pin, HIGH);
digitalWrite(a_dir2_pin, LOW); //Motor 1 rotation direction and rpm
analogWrite(a_pwm_pin, 16);
}
}
groundFungus recommended the map function so I added it in the code above. Still messing around with it so not entirely sure if it worked.
I have the impression that you are operating in the dark. I suggest to measure the RPM for different values of PWM, so you have some idea how the setup could work.
For example, there is usually a non-zero value of PWM, below which the motor won't even start to run.