-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEncoder.cpp
127 lines (105 loc) · 2.37 KB
/
Encoder.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*
*
Author: Diogo Guilherme Garcia de Freitas
*
*/
#include <sys/io.h>
#include <iostream>
#include "Encoder.h"
using namespace std;
Encoder::Encoder()
{
Base = 0x200;
IndexBase = 0x800;
Channel = 0;
Counter.value = 0;
Angle = 0;
Rotations = 0;
FullRotation = 4096; //Approximate value on the counter on a full rotation
}
void Encoder::SetBase(int b, int ib)
{
Base = b;
IndexBase = ib;
}
void Encoder::SetChannel(int c)
{
Channel = c;
}
int Encoder::GetCounterValue()
{
return Counter.value;
}
int Encoder::GetRotations()
{
//Handles rotation counting
//Compares Counter.value to keep track of COMPLETE roations done
//A negative value will mean a counter clockwise rotation
Rotations = Counter.value / FullRotation;
return Rotations;
}
int Encoder::GetFullRotation()
{
return FullRotation;
}
bool Encoder::GetPermissions()
{
//Ask for IO permissions
if((ioperm(IndexBase, 8, 1) != 0) || (ioperm(Base, 16, 1) != 0))
{
return true;
}
else
{
return false;
}
}
bool Encoder::DetectIndexPulse()
{
//Acquire data from IndexBase and mask MSB to detect the index pulse
bool index = (bool) (inb(IndexBase) & 0x080);
if(index)
{
return true;
}
else
{
return false;
}
}
void Encoder::Reset()
{
outb(0x00, Base + Channel); //Write 0x00 to reset counter on Channel
}
void Encoder::ReadCounter()
{
//Acquire bytes form encoder counter
for(int i = 0 ; i < 4 ; i++)
Counter.byte[i] = inb(Base + (Channel*4) + i);
usleep(100);
}
void Encoder::Calibrate()
{
while(this->DetectIndexPulse() != true){} //Wait for the first pulse
this->Reset(); //Reset to start counting from zero
usleep(10000); //Sleep so the program won't be fast enough to detect the same pulse twice
while(this->DetectIndexPulse() != true) //Read the counter while waitin for the next pulse
{
this->ReadCounter();
}
FullRotation = Counter.value; //Value on counter becomes the value of a full rotation
this->Reset(); //Reset again
}
void Encoder::operator!() //Overload operator ! to reset on all channels
{
//Originally should loop till channel 3, but it doesn't exist so loop till channel 2
for(int ch = 0 ; ch < 4 ; ch++) //Loops thorugh all possible channels
{
outb(0x00, Base + ch); //Write zeros to the counter address
}
}
double Encoder::ConvertToDegrees()
{
Angle = (double) ((Counter.value*360)/FullRotation); //Use proportionality to reset encoder counter
return Angle;
}