This program samples the inputs from a 10 bit encoder by sampling GPIO 0 to 31 as a single read. The IO are scattered through the GPIO due to many IO not being available for this use). Masks make the transition to gray code, then binary and finally degrees rotation. It all works well except that the loop cycle time slows remarkably occasionally. This means that encoder positions can be missed.
Would anyone have a suggestion as to why this may be.
// Encoder Information
int Offset = 152; // Encoder Offset = 152 for 720 encoder
float DegVal = 0.0; // Final degree value
float EncoderNoPosn = 720.00; // No of increments on this encoder
unsigned int EncoderGrayCount = 0; // Gray count from encoder
unsigned int EncoderCount = 0; // From Encoder 0 to 719 = 720 divisions
unsigned int IOCapture; // captures 0-31 GPIO states
byte Mask1; // Mask for encoder counts
byte Mask2;
byte Mask3;
byte Mask4;
byte Mask5;
/* This function converts a reflected binary
* Gray code number to a binary number.
* Each Gray code bit is exclusive-ored with all
* more significant bits.
*/
unsigned int GrayToBinary(unsigned int num)
{
unsigned int mask = num >> 1;
while (mask != 0)
{
num = num ^ mask;
mask = mask >> 1;
}
return num;
}
/*
Applies the masks to the IO and converts to degrees
*/
float GetDeg()
{
IOCapture=~gpio_input_get(); // 0 to 31 GPIO states
Mask1 = (IOCapture & 0b00000000000000000000000000110000)>>4; // bits at locations 4,5
Mask2 = (IOCapture & 0b00000000000000001100000000000000)>>14; // bits at locations 14,15
Mask3 = (IOCapture & 0b00000000000011000000000000000000)>>18; // bits at locations 18,19
Mask4 = (IOCapture & 0b00000000111000000000000000000000)>>21; // bits at locations 21,22,23
Mask5 = (IOCapture & 0b00000010000000000000000000000000)>>25; // bits at locations 25
EncoderGrayCount=Mask1 | Mask2<<2 | Mask3<<4 | Mask4<<6 | Mask5<<9; // ors masks and moves right to correct location
EncoderCount = GrayToBinary(EncoderGrayCount)- Offset; // 0 to 719
return 360.00*EncoderCount/EncoderNoPosn;
}
void setup()
{
Serial.begin(115200); // Debug
}
void loop()
{
DegVal = GetDeg();
Serial.println(micros());
}
