Vibrating Motor Encoder

Hi!

I currently have a micro gear motor with a CPR encoder attached using hall sensors. Currently I have the motor controlled by two buttons for different directions and the code has it so that I can control its step size. However, when no button is pressed, the motor is supposed to stop completely. But, instead it seems to be as if the encoder is vibrating. Any help would be appreciated!!

Sounds like your code has a problem. Not much we can do if you don't post it here.

Unstable voltage or speed regulator?

Hi,
Can you please post a copy of your sketch, using code tags?
They are made with the </> icon in the reply Menu.
See section 7 http://forum.arduino.cc/index.php/topic,148850.0.html

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks… Tom… :slight_smile:

But, instead it seems to be as if the encoder is vibrating. Any help would be appreciated!!

90% chance your code is messed up and it's going in a loop.

Post your code (and a schematic) if you want help with this.

Here is my code ( you can tell whats connected from the pins defined earlier)

#define PWMA0 6
#define PWMB0 5
#define enable0 13   //pins for first MegaMoto

#define switch0 7   //Up button
#define switch1 8   //Down button

#define hall0 2 //interrupt pins for hall effect sensors
//#define hall1 3 //interrupt pins for hall effect sensors

int enable = 0; //enable pin for megaMoto

int count[] = {0};//Actuator

int sw[] = {1, 1}; //switch up, switch down
int prev[] = {0, 0};//previous switch state

int currentPos = 0;//current position
int threshold = 1;
int destination = 0;

bool forwards = false;
bool backwards = false;// motor states

void setup() {
  pinMode(PWMA0, OUTPUT);
  pinMode(PWMB0, OUTPUT);//set PWM outputs

  pinMode(enable0, OUTPUT);
  digitalWrite(enable0, LOW);//set enable and turn board OFF

  pinMode(switch0, INPUT);
  pinMode(switch1, INPUT);
  digitalWrite(switch0, HIGH);
  digitalWrite(switch1, HIGH);//set up/down switch, enable enternal relays

  pinMode(hall0, INPUT);
//  pinMode(hall1, INPUT);
  digitalWrite(hall0, LOW);//set hall, set low to start for rising edge
 // digitalWrite(hall1, LOW);//set hall, set low to start for rising edge

  attachInterrupt(0, speed0, RISING); //enable the hall effect interupts

  Serial.begin(9600);
}//end setup

void loop() {
  ReadInputs();//check input button, calculate speeds

  if (sw[0] == 0 && sw[1] == 1 && backwards == false) destination = currentPos - 200;
  else if (sw[0] == 1 && sw[1] == 0 && forwards == false) destination = currentPos + 200;

  if ((destination >= (currentPos - threshold)) && (destination <= (currentPos + threshold))) stopMoving();
  else if (destination > currentPos) goForwards();
  else if (destination < currentPos) goBackwards();

  Serial.print("Counts:      "); Serial.println(count[0]);
  Serial.print("currentPos:  "); Serial.println(currentPos);
  Serial.print("Destination: "); Serial.println(destination);

  for (int i = 0; i <= 1; i++) prev[i] = sw[i]; //store switch values as previous values
}//end loop

void speed0() {
  //Serial.println("Update 1");
  if (forwards == true) count[0]++; //if moving forwards, add counts
  else if (backwards == true) count[0]--; //if moving back, subtract counts
}//end speed0

void ReadInputs() {

  sw[0] = digitalRead(switch0), sw[1] = digitalRead(switch1);//check switches
  currentPos = count[0];
}//end read inputs

void goForwards()
{
  forwards = true;
  backwards = false;
  //Serial.println("Moving forwards");
  digitalWrite(enable0, HIGH);//enable board
  //Serial.print(" Speeds "), Serial.print(spd[0]), Serial.print(", "), Serial.print(spd[1]);
  //Serial.print(" Counts "), Serial.println(count[0]);
  analogWrite(PWMA0, 175);
  analogWrite(PWMB0, 0);//apply speeds
}//end goForwards

void goBackwards()
{
  forwards = false;
  backwards = true;
  //Serial.println("Moving backwards");
  digitalWrite(enable0, HIGH);//enable board
  //Serial.print(" Speeds "), Serial.print(spd[0]), Serial.print(", "), Serial.print(spd[1]);
  //Serial.print(" Counts "), Serial.println(count[0]);
  analogWrite(PWMA0, 0);
  analogWrite(PWMB0, 175);//apply speeds
}//end goBackwards

void stopMoving()
{
  forwards = false;
  backwards = false;
  Serial.println("Stopped");
  analogWrite(PWMA0, 0);
  analogWrite(PWMB0, 0);//set speeds to 0
  delay(1);

  digitalWrite(enable0, LOW);//disable board
}//end stopMoving

S/W is not my specialty but just at first glance I se s problem becauss you're using interrupts snd have not declared your variables "volatile,".

Hi,
Ahha;

int count[] = {0};//Actuator

Without working out your sketch, I would say you are using a stepper motor to turn an encoder that is part of an actuator, your encoder indicates movement.

But you are only using one encoder output, the other is commented out, so you assume your rotator rotates in the right direction when you press the appropriate button and the sketch adds or subtracts.

A you are not reading the absolute position of the stepper output. So your feedabck does not indicate direction of rotation.

#define hall0 2 //interrupt pins for hall effect sensors
//#define hall1 3 //interrupt pins for hall effect sensors

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Tom..... :slight_smile:

You are using the comma operator in ReadInputs in a statement context - not sure that's
the clearest way to code in C, the comma operator is a rich source of confusion.

But anyway I think you just have too small a threshold value to let the system stop. So you
overshoot and retrigger the motor, so it constantly reverses.

Another approach to this hysteretical one is a PID style feedback loop with a PWM drive level
allowing gradual deceleration on approach to the target position.

Also not having the correct direction information from the encoder isn't going to help, I'd
recommend using the full quadrature signal, especially if you are have reversals in direction.

I’ve updated the code. The code seems to control the stepsize and doesn’t vibrate, however, it doesn’t seem to use the inputs of my buttons.

Attached is the code and picture of the schematic.

#define InA1            10                      // INA motor pin
#define InB1            11                      // INB motor pin 
#define PWM1            6                       // PWM motor pin
#define encodPinA1      3                       // encoder A pin
#define encodPinB1      8                       // encoder B pin

#define LOOPTIME        100                     // PID loop time
#define FORWARD         1                       // direction of rotation
#define BACKWARD        2                       // direction of rotation

unsigned long lastMilli = 0;                    // loop timing 
unsigned long lastMilliPrint = 0;               // loop timing
long count = 0;                                 // rotation counter
long countInit;
long tickNumber = 0;
boolean run = false;                                     // motor moves

void setup() {
 pinMode(InA1, OUTPUT);
 pinMode(InB1, OUTPUT);
 pinMode(PWM1, OUTPUT);
 pinMode(encodPinA1, INPUT); 
 pinMode(encodPinB1, INPUT); 
 digitalWrite(encodPinA1, HIGH);                      // turn on pullup resistor
 digitalWrite(encodPinB1, HIGH);
 attachInterrupt(1, rencoder, FALLING);
}

void loop() {
 moveMotor(FORWARD, 50, 175);                        // direction, PWM, ticks number
 delay(3000);
 moveMotor(BACKWARD, 50, 50);                           // 464=360°
 delay(3000);
}

void moveMotor(int direction, int PWM_val, long tick)  {
 countInit = count;    // abs(count)
 tickNumber = tick;
 if(direction==FORWARD)          motorForward(PWM_val);
 else if(direction==BACKWARD)    motorBackward(PWM_val);
}

void rencoder()  {                                    // pulse and direction, direct port reading to save cycles
 if (PINB & 0b00000001)    count++;                  // if(digitalRead(encodPinB1)==HIGH)   count_r ++;
 else                      count--;                  // if (digitalRead(encodPinB1)==LOW)   count_r --;
 if(run)  
   if((abs(abs(count)-abs(countInit))) >= tickNumber)      motorBrake();
}

void motorForward(int PWM_val)  {
 analogWrite(PWM1, PWM_val);
 digitalWrite(InA1, LOW);
 digitalWrite(InB1, HIGH);
 run = true;
}

void motorBackward(int PWM_val)  {
 analogWrite(PWM1, PWM_val);
 digitalWrite(InA1, HIGH);
 digitalWrite(InB1, LOW);
 run = true;
}

void motorBrake()  {
 analogWrite(PWM1, 0);
 digitalWrite(InA1, HIGH);
 digitalWrite(InB1, HIGH);
 run = false;
}

Nice schematic ! I like the attention to detail.

Right now the code only allows for backwards motion, although the forwards code is the same thing

// MD03A_Motor_basic + encoder

#define InA1            10                      // INA motor pin
#define InB1            11                      // INB motor pin 
#define PWM1            6                       // PWM motor pin
#define encodPinA1      3                       // encoder A pin
#define encodPinB1      8                       // encoder B pin

#define LOOPTIME        100                     // PID loop time
#define FORWARD         12                      // direction of rotation
#define BACKWARD        13                       // direction of rotation

int button = 0;

unsigned long lastMilli = 0;                    // loop timing
unsigned long lastMilliPrint = 0;               // loop timing
long FORWARD_HELD;
long BACKWARD_HELD;
long current_time;
long count = 0;                                 // rotation counter
long countInit;
long tickNumber = 0;
boolean run = false;                                     // motor moves

void setup() {
  Serial.begin(9600);
  pinMode(InA1, OUTPUT);
  pinMode(InB1, OUTPUT);
  pinMode(PWM1, OUTPUT);
  pinMode(encodPinA1, INPUT);
  pinMode(encodPinB1, INPUT);
  digitalWrite(encodPinA1, HIGH);                      // turn on pullup resistor
  digitalWrite(encodPinB1, HIGH);
  attachInterrupt(1, rencoder, FALLING);
}

void moveMotor(int direction, int PWM_val, long tick)  {
  countInit = count;    // abs(count)
  tickNumber = tick;
  if (direction == FORWARD) {
    motorForward(PWM_val);
    Serial.println("motorForward");
  }
  else if (direction == BACKWARD) {
    //  Serial.println("motorBackward initiated");
    motorBackward(PWM_val);
  }
}

void motorForward(int PWM_val)  {
  analogWrite(PWM1, PWM_val);
  digitalWrite(InA1, LOW);
  digitalWrite(InB1, HIGH);
  run = true;
}

void motorBackward(int PWM_val)  {
  analogWrite(PWM1, PWM_val);
  // Serial.println(InA1);
  // Serial.println(InB1);
  digitalWrite(InA1, HIGH);
  // Serial.println(InA1);
  // Serial.println(InB1);
  digitalWrite(InB1, LOW);
  Serial.println(InB1);
  run = true;
}

void motorBrake()  {
  analogWrite(PWM1, 0);
  digitalWrite(InA1, HIGH);
  digitalWrite(InB1, HIGH);
  run = false;
}

void loop() {
  button = digitalRead(FORWARD);
  Serial.println(button);
  if ( digitalRead(FORWARD) == 0) {
    Serial.print("forward button pressed");
    moveMotor(FORWARD, 255, 50);
    FORWARD_HELD = millis();
    if (FORWARD_HELD == 3000) {
      digitalWrite(InA1, HIGH);
      digitalWrite(InB1, HIGH);
    }
  }

  else if ( digitalRead(BACKWARD) == 0) {
    Serial.println("backward button pressed");
    moveMotor(BACKWARD, 255, 50);
    BACKWARD_HELD = millis();
    if (BACKWARD_HELD == 3000) {
      digitalWrite(InA1, HIGH);
      digitalWrite(InB1, HIGH);
    }
  }
}

void rencoder()  {                                    // pulse and direction, direct port reading to save cycles
  if (PINB & 0b00000001)    count++;                  // if(digitalRead(encodPinB1)==HIGH)   count_r ++;
  else                      count--;                  // if (digitalRead(encodPinB1)==LOW)   count_r --;
  if (run)
    if ((abs(abs(count) - abs(countInit))) >= tickNumber)      motorBrake();
}