Quantcast
Channel: Arduino Forum - Latest topics
Viewing all articles
Browse latest Browse all 15454

Encoder data wrongly indicating very high rotation speed

$
0
0

Noob here. As the title suggests, I am getting very high rotational speeds and I think my calculations are correct, so I am really confused. I am using a GA25-371 geared motor with encoders. The motor is labelled 360 CPR and the gear ratio is 1:34. Therefore the encoder cnts per shaft rev should be 360x34=12240. I have verified the cnts per rev by printing the cnts as I manually turn the shaft one revolution. I am pretty much following the basic tutorials found on youtube for using motor encoders and an l298n motor driver.
Link to my motor kit.
I have tried commanding the motor full voltage instead of PWMing it to make sure it just not noise from other cable that might be triggering the interrupts, but that has not helped. I am really stumped here. Any input would be really helpful. Thanks.
Heres my code:

int int1 = 8;
int int2 = 9;
int enA = 2;
int enB = 3;
volatile long int pos = 0;
long int prevPos = 0;
int pwmPin = 10;
int countsPerRev = 12240;
float Pi = 3.14159;
float radiansPerRev = 2*Pi; 
int kp = 20;
int ki = 0;
int kd = 0;
unsigned long loopTime;
float AngularVelocity_rps = 0;   // Init the angular velocity.
float radPerCnt = radiansPerRev/countsPerRev;     // Radians per encoder cnt
float setPoint_rps = 2;          // Setpoint for angular vel
int printSerial = 0;


/**
Setup pins
**/
void setup()
{
  Serial.begin(9600);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(enA, INPUT);
  pinMode(enB,INPUT);
  pinMode(pwmPin,OUTPUT);
  attachInterrupt(digitalPinToInterrupt(enA),readEncoders,RISING);
  delay(3000);
  loopTime = micros();
}

/**
Function to set motor command
**/
void setMotorCommand(int pwmVal)
{
  if(pwmVal > 0)
  {
    analogWrite(pwmPin, pwmVal);
    digitalWrite(int1, HIGH);
    digitalWrite(int2, LOW);  
  }
  else if(pwmVal < 0)
  {
    analogWrite(pwmPin, pwmVal);
    digitalWrite(int2, HIGH);
    digitalWrite(int1, LOW);  
  }
  else
  {
    digitalWrite(int1, LOW);
    digitalWrite(int2, LOW);  
  }
}

/**
ISR for encoder pin
**/
void readEncoders(void)
{
  int tmp  = digitalRead(enB);
  if(tmp > 0)
  {
    pos++;
  }
  else
  {
    pos--;
  }
}

/**
Main loop. Calculates rotational speed every millisecond and prints data every 100ms
**/
void loop()
{
  unsigned long currTime = micros();
  unsigned long dt = (currTime  - loopTime);
  if(dt >= 1000)
  {
    printSerial++;
    int tmpPos = pos;
    long int deltaPos = 0;
    if(prevPos != tmpPos)
    {
      deltaPos = tmpPos - prevPos;
      AngularVelocity_rps = float(deltaPos)*(radPerCnt*1000); // This is executed every millisecond so velocity in radiansPesSecond is deltaEncoderCnts*radPerEncoderCnts*1000
    }
    // float error = setPoint_rps - AngularVelocity_rps;
    // int cmd = kp*error;             // Calculate motor command
    // cmd = constrain(cmd,-255,255);
    // setMotorCommand(cmd);
    setMotorCommand(100);     // Giving a test command that is ~40% max command
    prevPos = tmpPos;
    loopTime = currTime;
    if(printSerial >= 500)
    {
      Serial.print(dt);
      Serial.print(" ");
      Serial.println(tmpPos);
      printSerial = 1;
    }
  }
  else
  {
    // Do nothing 
  }
}

4 posts - 2 participants

Read full topic


Viewing all articles
Browse latest Browse all 15454

Trending Articles