JMotor
Loading...
Searching...
No Matches
JEncoderSingle.h
Go to the documentation of this file.
1#ifndef J_ENCODER_ATTACH_INTERRUPT_SINGLE_H
2#define J_ENCODER_ATTACH_INTERRUPT_SINGLE_H
3#include "JEncoder.h"
4#include <Arduino.h>
5
15class JEncoderSingle : public JEncoder {
16
17protected:
18 unsigned char encoderPin;
20
21private:
22 bool rev;
23 signed char reverse;
24 float distPerCountFactor;
25
26 volatile bool velNew;
27 volatile long tickCounter;
28 volatile unsigned long lastEncoderTickMicros;
29 volatile unsigned long encoderIntervalMicros;
30 bool newSpeed;
31 unsigned long slowestIntervalMicros;
32 bool wasTimedOut;
33 unsigned long switchBounceIntervalMicros;
34
35protected:
45 JEncoderSingle(byte _encoderPin, float _distPerCountFactor, bool _reverse, unsigned long _slowestIntervalMicros, unsigned long _switchBounceIntervalMicros, byte _interruptType)
46 {
47 rev = false;
48 encoderPin = _encoderPin;
49 distPerCountFactor = _distPerCountFactor;
50 slowestIntervalMicros = _slowestIntervalMicros;
51 switchBounceIntervalMicros = _switchBounceIntervalMicros;
52 if (_reverse) {
53 reverse = -1;
54 } else {
55 reverse = 1;
56 }
57 interruptType = _interruptType;
58
59 velNew = false;
60 tickCounter = 0;
61 encoderIntervalMicros = 0;
62 lastEncoderTickMicros = 0;
63 newSpeed = false;
64 wasTimedOut = false;
65 }
70 virtual void setUpInterrupts(void (*_isrPointer)(void));
75 virtual void turnOffInterrupts();
76
77public:
82 bool getRev()
83 {
84 return rev;
85 }
90 void setRev(bool _rev)
91 {
92 rev = _rev;
93 }
94
96 {
97 long tempCounter = tickCounter * reverse;
98 tickCounter = 0;
99 return tempCounter;
100 }
101 float getVel()
102 {
103 // store temporary copies of variables set by ISR since they may be changed at any time
104 unsigned long tempEncoderTickMicros = lastEncoderTickMicros;
105 unsigned long tempInterval = encoderIntervalMicros;
106
107 // occasionally micros seems to be smaller than tempEncoderTickMicros and there's an overflow
108 // adding tempInterval fixes the problem (looking back one more tick)
109 if ((micros() - tempEncoderTickMicros + tempInterval) > slowestIntervalMicros) {
110 return 0.0; // set to zero if it's been a while since a tick
111 }
112 if (tempInterval == 0) { // avoid divide by zero
113 return 0.0;
114 }
115 return (rev ? -1 : 1) * reverse * 1000000.0 / tempInterval * distPerCountFactor;
116 }
118 {
119 return tickCounter * reverse;
120 }
121 float getPos()
122 {
123 return tickCounter * distPerCountFactor * reverse;
124 }
126 {
127 return distPerCountFactor;
128 }
129 void setDistPerCountFactor(float _factor)
130 {
131 distPerCountFactor = _factor;
132 }
138 void setReverse(bool _reverse)
139 {
140 if (_reverse) {
141 reverse = -1;
142 } else {
143 reverse = 1;
144 }
145 }
147 {
148 return false;
149 }
150 bool isVelNew()
151 {
152 // occasionally micros seems to be smaller than tempEncoderTickMicros and there's an overflow
153 // adding tempInterval fixes the problem (looking back one more tick)
154
155 unsigned long tempEncoderTickMicros = lastEncoderTickMicros;
156 unsigned long tempInterval = encoderIntervalMicros;
157 if ((micros() - tempEncoderTickMicros + tempInterval) > slowestIntervalMicros) {
158 if (!wasTimedOut) {
159 wasTimedOut = true;
160 return true;
161 }
162 } else {
163 wasTimedOut = false;
164 }
165
166 if (newSpeed) {
167 newSpeed = false;
168 return true;
169 }
170 return false;
171 }
172 void run() { }
173
174 void encoderISR(void)
175 {
176 if (micros() - lastEncoderTickMicros >= switchBounceIntervalMicros) {
177 unsigned long tempMicros = micros();
178 encoderIntervalMicros = tempMicros - lastEncoderTickMicros;
179 lastEncoderTickMicros = tempMicros;
180 newSpeed = true;
181 tickCounter += (rev ? -1 : 1);
182 }
183 }
184};
185#endif
defines common interface for JEncoder
Definition JEncoder.h:33
reads a single channel (incremental) encoder
Definition JEncoderSingle.h:15
virtual void turnOffInterrupts()
disable interrupts and stop monitoring encoder
void setReverse(bool _reverse)
reverse readings of encoder
Definition JEncoderSingle.h:138
byte interruptType
Definition JEncoderSingle.h:19
bool hasDirection()
can this encoder measure direction or just speed
Definition JEncoderSingle.h:146
void setDistPerCountFactor(float _factor)
set the conversion factor between encoder ticks and distance
Definition JEncoderSingle.h:129
void setRev(bool _rev)
set which direction the encoder is moving (if you have external information about direction (like mot...
Definition JEncoderSingle.h:90
long zeroCounter()
reset the counter of how far the encoder has turned
Definition JEncoderSingle.h:95
void run()
if an encoder needs to have some code called each loop (like absolute encoder polling encoder and cal...
Definition JEncoderSingle.h:172
float getDistPerCountFactor()
returns a conversion factor between encoder ticks and distance that can be set for the encoder
Definition JEncoderSingle.h:125
unsigned char encoderPin
Definition JEncoderSingle.h:18
virtual void setUpInterrupts(void(*_isrPointer)(void))
set up pins and interrupts
float getVel()
calculates velocity in distance per second where distance was set by setdistPerCountFactor()
Definition JEncoderSingle.h:101
void encoderISR(void)
Definition JEncoderSingle.h:174
bool getRev()
get whether the encoder is told it's going backwards currently
Definition JEncoderSingle.h:82
JEncoderSingle(byte _encoderPin, float _distPerCountFactor, bool _reverse, unsigned long _slowestIntervalMicros, unsigned long _switchBounceIntervalMicros, byte _interruptType)
constructor, sets pins and settings
Definition JEncoderSingle.h:45
float getPos()
returns how far the encoder has turned from the zero position converted to distance
Definition JEncoderSingle.h:121
long getCounter()
returns how far the encoder has turned from the zero position
Definition JEncoderSingle.h:117
bool isVelNew()
could be useful for only recalculating a control loop if there's new velocity data
Definition JEncoderSingle.h:150