Using a HDD motor as RotaryEncoder.

Use this schematic: Instructables HDDJ Use for: R11, R12, R13 100 Ohms and for: R14, R15, 13 20kOhms so you get a better resolution.

This rotary encoder uses none interrups. The INPUT pins are polled in the main loop. So use no delay functions. When the main loop needs to much time the encoder can't read the rotary.

Lib: Rotary Encoder download

// Declaration of RotaryEncoder RotaryEncoder rotaryEncoder = RotaryEncoder(2,3,4);

// Pins for LED's show the Toward int pinTowardLeft = 12; int pinTowardRight = 10;

void setup() {

  pinMode(pinTowardLeft, OUTPUT);
  pinMode(pinTowardRight, OUTPUT);

}

void loop() {

  int toward = rotaryEncoder.getToward();

  switch(toward)
  {
    case -1:
      digitalWrite(pinTowardLeft, HIGH); 
      digitalWrite(pinTowardRight, LOW);
      delay(1);
      break;

   case 0:
      digitalWrite(pinTowardLeft, LOW); 
      digitalWrite(pinTowardRight, LOW);
      break;
   case 1:
      digitalWrite(pinTowardLeft, LOW); 
      digitalWrite(pinTowardRight, HIGH);
      delay(1);
      break;
  }

}

The cpp file.

  1. include <RotaryEncoder.h>
  2. include "WProgram.h"

RotaryEncoder::RotaryEncoder(int phaseOne, int phaseTow, int phaseThree) {

  PINS_Phases[0] = phaseOne;            // Pin Number where digtal signal of phase one 
  PINS_Phases[1] = phaseTow;            // Pin Number where digtal signal of phase two 
  PINS_Phases[2] = phaseThree;          // Pin Number where digtal signal of phase three 

  pinMode(phaseOne, INPUT);  
  pinMode(phaseOne, INPUT);  
  pinMode(phaseOne, INPUT); 

  for(int i = 0; i < 3; i++)
  {
    for(int j = 0; j < 3; j++)
    {
       flankMap[i][j] = false; 
    }
  }

}

int RotaryEncoder::getToward() {

  // return -1 for rotating left
  // return 0 for none rotating
  // return 1 for rotating right
  int rotation = 0;
  int firstHigh = -1;
  fillData();

  for(int i = 0; i < 3; i++)
  {
    if(flankMap[0][i])
    {
      firstHigh = i;
    }
  }

  if(firstHigh > -1)
  {
    int pos[3] = {0,0,0};
    pos[0] = firstHigh;
    pos[1] = nextPosition(firstHigh,true);
    pos[2] = nextPosition(pos[1],true);

    // if last state filled the map will shift one to left
    if(flankMap[0][pos[0]] && flankMap[1][pos[1]] && flankMap[2][pos[2]])
    {
      rotation = 1;
      shiftMapLeft();
    }
    else
    {
      pos[0] = firstHigh;
      pos[1] = nextPosition(firstHigh,false);
      pos[2] = nextPosition(pos[1],false);

      if(flankMap[0][pos[0]] && flankMap[1][pos[1]] && flankMap[2][pos[2]])
      {
        rotation = -1;
        shiftMapLeft();
      }
    }
  }
  return rotation;

}

bool RotaryEncoder::risePin(int pinNumber, int lastState) // search rises on a pin {

  int currentState = digitalRead(pinNumber);
  bool  retrunVal = false;

  if(currentState == HIGH && lastState == LOW)
  {
    retrunVal = true;
  }
  return retrunVal;

}

void RotaryEncoder::shiftMapLeft() // shift the map one to left {

  for(int i = 0; i < 3; i++)
  {
    flankMap[i][0] = flankMap[i][1];
    flankMap[i][1] = flankMap[i][2];
    flankMap[i][2] = false;
  }

}

void RotaryEncoder::fillData() // fill the flankMap with data {

  bool wasFlank[3] = {false, false, false};
  for(int i = 0; i < 3; i++)
  {
    wasFlank[i] = risePin(PINS_Phases[i], lastStates[i]);
    lastStates[i] = digitalRead(PINS_Phases[i]);
  }
  int countFlanks = 0;
  int phaseFlank = -1;
  for(int i = 0; i< 3;i++)
  {
    if(wasFlank[i])
    {
      countFlanks++;
      phaseFlank = i;
    }
  }
  if(countFlanks == 1)
  {
    if(flankMap[0][2] || flankMap[1][2] || flankMap[2][2])
    {
        shiftMapLeft();
    }
    for(int i = 0; i < 3; i++)
    {
      flankMap[i][2] = wasFlank[i];  
    }
  }

}

int RotaryEncoder::nextPosition(int startPos, bool right) {

    int pos = 0;
    if(right)
    {
        switch(startPos)
        {
          case 0: 
            pos = 1;
            break;
          case 1: 
            pos = 2;
            break;
         case 2: 
            pos = 0;
            break;
        }
    }
    else
    {
        switch(startPos)
        {
          case 0: 
            pos = 2;
            break;
          case 1: 
            pos = 0;
            break;
         case 2: 
            pos = 1;
          break;
        }
    }
  return pos;

}

The header file:

  1. ifndef RotaryEncoder_h
  2. define RotaryEncoder_h

  3. include <inttypes.h>
  4. include "WProgram.h"

class RotaryEncoder {

    private:
        int PINS_Phases[3];
        int lastStates[3];
        bool flankMap[3][3];

        bool risePin(int pinNumber, int lastState);
        void shiftMapLeft();
        void fillData();
        int nextPosition(int startPos, bool right);

    public:
        RotaryEncoder(int phaseOne, int phaseTow, int phaseThree);
        int getToward();

};

  1. endif

Share