Code:
#include "Arduino.h"
#include "attachInterruptEx.h"
const uint8_t UMASK = 0b00000110;
const uint8_t WMASK = 0b00000101;
const uint8_t VMASK = 0b00000011;
const uint8_t UPOS = 0;
const uint8_t WPOS = 1;
const uint8_t VPOS = 2;
uint8_t CWNEXTSTATE[]{0, 3, 6, 2, 5, 1, 4, 0};
uint8_t CCWNEXTSTATE[]{0, 5, 3, 1, 6, 4, 2, 0};
const bool CW(false);
const bool CCW(true);
class ThreePhaseMotorEncoder
{
public:
ThreePhaseMotorEncoder() //::public MotorEncoder this stub only shows how to embedd pin interrupts...
{
//...
}
void begin(uint8_t phaseVPin, uint8_t phaseWPin, uint8_t phaseUPin)
{
attachInterruptEx(phaseUPin, [this, phaseUPin] { handleInterrupt(phaseUPin, UMASK, UPOS); }, CHANGE);
attachInterruptEx(phaseVPin, [this, phaseVPin] { handleInterrupt(phaseVPin, VMASK, VPOS); }, CHANGE);
attachInterruptEx(phaseWPin, [this, phaseWPin] { handleInterrupt(phaseWPin, WMASK, WPOS); }, CHANGE);
}
int32_t read(void);
int32_t write(int32_t value);
int32_t readFaults(void);
private:
void setEncoder(void);
void handleInterrupt(uint8_t pin, u_int8_t mask, uint8_t pos)
{
// Immediately capture the pin state
uint8_t pinValue = digitalRead(pin);
uint8_t newState = (state & mask) + (pinValue << pos);
if (newState == CWNEXTSTATE[state])
{
count++;
direction = CW;
state = newState;
}
else if (newState == CCWNEXTSTATE[state]) // If the new state is in the CCW array, then going CCW
{
count--;
direction = CCW;
state = newState;
}
else // This is noise to be ignored, but recorded
{
faultCount++;
}
}
int32_t count = 0;
uint32_t faultCount = 0;
uint32_t direction;
uint8_t state;
};
//-----------------------------
ThreePhaseMotorEncoder encoder1, encoder2, encoder3;
void setup()
{
encoder1.begin(0, 1, 2); // you can have as many encoders as you like...
encoder2.begin(7, 8, 9);
encoder3.begin(12, 11, 10);
}
void loop()
{
}