JMotor
Loading...
Searching...
No Matches
JEncoderQuadrature.h
Go to the documentation of this file.
1#ifndef J_ENCODER_QUADRATURE_H
2#define J_ENCODER_QUADRATURE_H
3#include "JEncoder.h"
4#include <Arduino.h>
14
15protected:
18
19private:
20 int8_t reverse; //can be 1 or -1
21 float distPerCountFactor;
22
23 volatile bool velNew;
24 volatile long tickCounter;
25 volatile bool encForwards;
26 volatile unsigned long lastEncoderTickMicros;
27 volatile unsigned long encoderIntervalMicros;
28 bool newSpeed;
29 unsigned long slowestIntervalMicros;
30 bool wasTimedOut;
31
32protected:
42 JEncoderQuadrature(byte _encoderAPin, byte _encoderBPin, float _distPerCountFactor = 1.0, bool _reverse = false, unsigned long _slowestIntervalMicros = 100000UL)
43 {
44 encoderAPin = _encoderAPin;
45 encoderBPin = _encoderBPin;
46 if (_reverse) {
47 reverse = -1;
48 } else {
49 reverse = 1;
50 }
51 distPerCountFactor = _distPerCountFactor;
52 slowestIntervalMicros = _slowestIntervalMicros;
53
54 velNew = false;
55 tickCounter = 0;
56 encForwards = true;
57 encoderIntervalMicros = 0;
58 lastEncoderTickMicros = 0;
59 newSpeed = false;
60 wasTimedOut = false;
61 }
67 virtual void setUpInterrupts(void (*_isrAPointer)(void), void (*_isrBPointer)(void));
72 virtual void turnOffInterrupts();
73
74public:
76 {
77 long tempCounter = tickCounter * reverse;
78 tickCounter = 0;
79 return tempCounter;
80 }
81 float getVel()
82 {
83 //store temporary copies of variables set by ISR since they may be changed at any time
84 unsigned long tempEncoderTickMicros = lastEncoderTickMicros;
85 unsigned long tempInterval = encoderIntervalMicros;
86
87 //occasionally micros seems to be smaller than tempEncoderTickMicros and there's an overflow
88 // adding tempInterval fixes the problem (looking back one more tick)
89 if ((micros() - tempEncoderTickMicros + tempInterval) > slowestIntervalMicros) {
90 return 0.0; //set to zero if it's been a while since a tick
91 }
92 if (tempInterval == 0) { //avoid divide by zero
93 return 0.0;
94 }
95
96 if (encForwards) {
97 return reverse * 1000000.0 / (tempInterval)*distPerCountFactor * 4;
98 } else {
99 return reverse * -1000000.0 / (tempInterval)*distPerCountFactor * 4;
100 }
101 }
103 {
104 return tickCounter * reverse;
105 }
106 float getPos()
107 {
108 return tickCounter * distPerCountFactor * reverse;
109 }
111 {
112 return distPerCountFactor;
113 }
114 void setDistPerCountFactor(float _factor)
115 {
116 distPerCountFactor = _factor;
117 }
123 void setReverse(bool _reverse)
124 {
125 if (_reverse) {
126 reverse = -1;
127 } else {
128 reverse = 1;
129 }
130 }
132 {
133 return true;
134 }
135 bool isVelNew()
136 {
137 //occasionally micros seems to be smaller than tempEncoderTickMicros and there's an overflow
138 // adding tempInterval fixes the problem (looking back one more tick)
139
140 unsigned long tempEncoderTickMicros = lastEncoderTickMicros;
141 unsigned long tempInterval = encoderIntervalMicros;
142 if ((micros() - tempEncoderTickMicros + tempInterval) > slowestIntervalMicros) {
143 if (!wasTimedOut) {
144 wasTimedOut = true;
145 return true;
146 }
147 } else {
148 wasTimedOut = false;
149 }
150
151 if (newSpeed) {
152 newSpeed = false;
153 return true;
154 }
155 return false;
156 }
157 void run() { }
158
159 void ISRA(void)
160 {
161 if (digitalRead(encoderAPin) == HIGH) { //once a cycle save values used for speed calculations
162 unsigned long tempMicros = micros();
163 encoderIntervalMicros = tempMicros - lastEncoderTickMicros;
164 lastEncoderTickMicros = tempMicros;
165 newSpeed = true;
166 }
167 encForwards = (digitalRead(encoderAPin) == digitalRead(encoderBPin));
168 if (encForwards) {
169 tickCounter++;
170 } else {
171 tickCounter--;
172 }
173 }
174 void ISRB(void)
175 {
176 encForwards = (digitalRead(encoderAPin) != digitalRead(encoderBPin));
177 if (encForwards) {
178 tickCounter++;
179 } else {
180 tickCounter--;
181 }
182 }
183};
184#endif
defines common interface for JEncoder
Definition JEncoder.h:33
reads a quadrature (incremental) encoder
Definition JEncoderQuadrature.h:13
void setReverse(bool _reverse)
reverse readings of encoder
Definition JEncoderQuadrature.h:123
long zeroCounter()
reset the counter of how far the encoder has turned
Definition JEncoderQuadrature.h:75
float getDistPerCountFactor()
returns a conversion factor between encoder ticks and distance that can be set for the encoder
Definition JEncoderQuadrature.h:110
float getVel()
calculates velocity in distance per second where distance was set by setdistPerCountFactor()
Definition JEncoderQuadrature.h:81
byte encoderBPin
Definition JEncoderQuadrature.h:17
void ISRB(void)
Definition JEncoderQuadrature.h:174
virtual void setUpInterrupts(void(*_isrAPointer)(void), void(*_isrBPointer)(void))
set up pins and interrupts
JEncoderQuadrature(byte _encoderAPin, byte _encoderBPin, float _distPerCountFactor=1.0, bool _reverse=false, unsigned long _slowestIntervalMicros=100000UL)
constructor, sets pins and settings
Definition JEncoderQuadrature.h:42
bool hasDirection()
can this encoder measure direction or just speed
Definition JEncoderQuadrature.h:131
float getPos()
returns how far the encoder has turned from the zero position converted to distance
Definition JEncoderQuadrature.h:106
void run()
if an encoder needs to have some code called each loop (like absolute encoder polling encoder and cal...
Definition JEncoderQuadrature.h:157
bool isVelNew()
could be useful for only recalculating a control loop if there's new velocity data
Definition JEncoderQuadrature.h:135
virtual void turnOffInterrupts()
disable interrupts and stop monitoring encoder
long getCounter()
returns how far the encoder has turned from the zero position
Definition JEncoderQuadrature.h:102
byte encoderAPin
Definition JEncoderQuadrature.h:16
void ISRA(void)
Definition JEncoderQuadrature.h:159
void setDistPerCountFactor(float _factor)
set the conversion factor between encoder ticks and distance
Definition JEncoderQuadrature.h:114