I have a Motor with hall sensor encoders that I am using for a project. I want to be able to precisely control the position of the motor via the encoders. I was able to get the encoder to work fine with an arudino motor shield but this did not provide enough power for my application.
I have an external power supply that I hooked up to a BTS7960 which increases my max power output to the motor. I have the encoder pins for the motor wired directly to the arduino on digital pins and I have an encoder library which takes the readings in my code.
the issue: If I give the motor a pmw value of 255 the encoders work great, if I slow the speed down however say around 123, the encoders hardly count at all and at times will even go negative even if spinning in the same direction.
My question: What could potentially be the issue here? I wouldn't be surprised to find out that I have made an error in my assumptions of how something should work as I am pretty new. Any assistance or resources that would be helpful to me would be greatly appreciated, let me know if additional information is needed in regards to my setup.
equipment:
Arduino Rev 3
Motor: FIT0185 Datasheet by DFRobot | Digi-Key Electronics
Motor driver: Amazon.com
Schematic:
[code]
#include <Encoder.h> //encoder library
int rpwm = 5; //clockwise rotation
int lpwm = 3; //counterclockwise rotation
int r_en = 0; //clockwise break? manual says forward drive enable input Active High/Lod Disable
int l_en = 1; //counter clockwise break?
Encoder myEnc(7, 8);
void setup() {
Serial.begin(115200);
//Setup Channel A
pinMode(rpwm, OUTPUT); //Initiates rpwm forward
pinMode(lpwm, OUTPUT); //initiates lpwm backwards
pinMode(r_en, OUTPUT); //cw break
pinMode(l_en, OUTPUT); //ccw break
}
void loop()
{
float counts = 0, revolutions = 0, modifier = 0;
int pace = 0, cycles = 0;
counts = myEnc.read();
Serial.println(counts);//print check to ensure starting at a value of 0
delay(4000);
modifier = -2096; //gets the encoder counts closer to physical rotations still not perfect
revolutions = counts / modifier; //equation for true revolutions
pace = 255; //pwm speed variable set it to full speed intially
delay (1000);
digitalWrite(r_en, HIGH);// From what I understand this establishes Clockwise motion
while (revolutions < .5) // turn the motor on till have a rotation is reached
{
counts = myEnc.read(); //updates counts with each cycle
revolutions = counts / modifier;
analogWrite(rpwm, pace); //determines the speed of the motor
Serial.println(revolutions); //displays revolutions
if (revolutions >= 0.25)// slows the motor down after reaching the halfway point
{
pace = 175; // the encoder does not like this pace and begins stalling or even back tracking and giving negative & 0 values.
}
}
analogWrite(rpwm, 0); //Stops the motor
// *** At this point you can continue to read if you would like but it is only a repeat of this first while loop with different number of rotations and directions
//*** For the above code I get expected values up until the if statement becomes true at which point it incrementally goes from 25 to 15 to 7 then 0 and sometimes even - small negative values
delay(1000);
pace = 255;
while (revolutions < 1)
{
counts = myEnc.read();
revolutions = counts / modifier;
analogWrite(rpwm, pace);
Serial.println(revolutions);
if (revolutions >= .75)
{
pace = 175;
}
}
analogWrite(rpwm, 0);
digitalWrite(r_en, LOW);
delay(1000);
digitalWrite(l_en, HIGH);
pace = 255;
while (revolutions > .5)
{
counts = myEnc.read();
revolutions = counts / modifier;
analogWrite(lpwm, pace);
//analogWrite(3, pace);
Serial.println(revolutions);
if (revolutions <= 0.75)
{
pace = 175;
}
}
analogWrite(lpwm, 0);
digitalWrite(l_en, LOW);
delay(1000);
pace = 255;
digitalWrite(l_en, HIGH);
while (revolutions > 0)
{
counts = myEnc.read();
revolutions = counts / modifier;
analogWrite(lpwm, pace);
Serial.println(revolutions);
if (revolutions <= .25)
{
pace = 200;
}
}
analogWrite(lpwm, 0); //Disengage the Brake for Channel A
digitalWrite(l_en, LOW);
delay(1000);
}
[/code]