Byte Sized Encoder Decoder
Loading...
Searching...
No Matches
byte-sized-encoder-decoder.h
Go to the documentation of this file.
1#ifndef BYTE_SIZED_ENCODER_DECODER_H
2#define BYTE_SIZED_ENCODER_DECODER_H
3#include <Arduino.h>
4#include <Wire.h>
9protected:
13 uint8_t address;
17 int16_t encoderCount[8];
21 int16_t encoderOverflows[8];
25 int16_t lastEncoderCount[8];
33 TwoWire* wire;
41 unsigned long lastReadMicros[8];
45 int16_t encoderVelocity[8];
57 boolean isVelNewVal[8];
61 inline void write(uint8_t data)
62 {
63 wire->beginTransmission(address);
64 wire->write(data);
65 wire->endTransmission();
66 }
67
68public:
76 ByteSizedEncoderDecoder(TwoWire* _wire, uint8_t _address = 14, int16_t _encoderSlowestInterval = 0, int16_t _encoderEnoughCounts = 0)
77 {
78 wire = _wire;
79 address = _address;
81
82 // memset encoderCount[] all 0
83 memset(encoderCount, 0, 8 * sizeof(int16_t));
84 memset(encoderOverflows, 0, 8 * sizeof(int16_t));
85 memset(lastEncoderCount, 0, 8 * sizeof(int16_t));
86 memset(lastVelocityEncoderCount, 0, 8 * sizeof(int16_t));
87 memset(lastReadMicros, 0, 8 * sizeof(unsigned long));
88 memset(encoderVelocity, 0, 8 * sizeof(int16_t));
89 memset(encoderSlowestInterval, _encoderSlowestInterval, 8 * sizeof(int16_t));
90 memset(encoderEnoughCounts, _encoderEnoughCounts, 8 * sizeof(int16_t));
91 memset(isVelNewVal, 0, 8 * sizeof(boolean));
92 }
98 void setEncoderSlowestInterval(uint8_t n, int16_t interval)
99 {
100 if (n > 8) {
101 return;
102 }
103 if (n == 0) {
104 for (byte i = 0; i < 8; i++) {
105 encoderSlowestInterval[i] = interval;
106 }
107 return;
108 }
109 encoderSlowestInterval[n - 1] = interval;
110 }
116 void setEncoderEnoughCounts(uint8_t n, int16_t counts)
117 {
118 if (n > 8) {
119 return;
120 }
121 if (n == 0) {
122 for (byte i = 0; i < 8; i++) {
123 encoderEnoughCounts[i] = counts;
124 }
125 return;
126 }
127 encoderEnoughCounts[n - 1] = counts;
128 }
129
136 boolean isVelNew(uint8_t n)
137 {
138 if (n > 8 || n < 1) {
139 return false;
140 }
141 boolean temp = isVelNewVal[n - 1];
142 isVelNewVal[n - 1] = false;
143 return temp;
144 }
145
152 void begin(boolean resetEncoders = true)
153 {
154 setWhichEncoders(255);
155 if (resetEncoders) {
157 }
158 }
163 void run()
164 {
165 wire->beginTransmission(address);
166 wire->write(whichEncodersMask);
167 wire->endTransmission(true);
168 delayMicroseconds(50); // time for the board to prepare to respond
169 for (byte i = 0; i < 8; i++) {
170 if (bitRead(whichEncodersMask, 7 - i) == 0) {
171 continue;
172 }
173 int high = -1;
174 int low = -1;
175 wire->requestFrom(address, (uint8_t)1);
176 if (wire->available())
177 high = wire->read();
178 wire->requestFrom(address, (uint8_t)1);
179 if (wire->available())
180 low = wire->read();
181 if (high == -1 || low == -1) {
182 // we didn't get data
183 } else {
185 encoderCount[i] = (((uint16_t)high) << 8 | ((uint16_t)low));
186 if (abs(encoderCount[i] - lastEncoderCount[i]) > (1 << 15)) {
187 encoderOverflows[i] += (encoderCount[i] > lastEncoderCount[i]) ? -1 : 1;
188 }
189 // calculate velocity
190 unsigned long mic = micros();
191 int32_t hundredMicrosSinceLastRead = (mic - lastReadMicros[i]) / 100; // using a time interval of 100 microseconds (won't overflow int32)
192 if (hundredMicrosSinceLastRead > (int32_t)(encoderSlowestInterval[i] * 10) || abs(encoderCount[i] - lastVelocityEncoderCount[i]) > encoderEnoughCounts[i]) {
193 lastReadMicros[i] = mic;
194 encoderVelocity[i] = (int32_t)10000 * (encoderCount[i] - lastVelocityEncoderCount[i]) / hundredMicrosSinceLastRead;
196 isVelNewVal[i] = true;
197 }
198 }
199 }
200 }
207 int32_t getEncoderPosition(uint8_t n, boolean read = false)
208 {
209 if (read) {
210 run();
211 }
212 if (n > 8 || n < 1) {
213 return 0;
214 }
215 return (int32_t)encoderCount[n - 1] + (int32_t)encoderOverflows[n - 1] * 65536;
216 }
224 int16_t getEncoderPositionWithoutOverflows(uint8_t n, boolean read = false)
225 {
226 if (read) {
227 run();
228 }
229 if (n > 8 || n < 1) {
230 return 0;
231 }
232 return encoderCount[n - 1];
233 }
240 int16_t getEncoderVelocity(uint8_t n, boolean read = false)
241 {
242 if (read) {
243 run();
244 }
245 if (n > 8 || n < 1) {
246 return 0;
247 }
248 return encoderVelocity[n - 1];
249 }
254 void resetEncoderPositions(boolean resetVariables = true)
255 {
256 write(0);
257 if (resetVariables) {
258 for (byte i = 0; i < 8; i++) {
259 encoderCount[i] = 0;
260 encoderOverflows[i] = 0;
261 lastEncoderCount[i] = 0;
262 encoderVelocity[i] = 0;
263 }
264 }
265 }
271 void setWhichEncoders(uint8_t mask)
272 {
273 if (mask != 0) {
274 whichEncodersMask = mask;
275 write(mask);
276 }
277 }
283 boolean isEncoderActive(uint8_t n)
284 {
285 if (n > 8 || n < 1) {
286 return false;
287 }
288 return bitRead(whichEncodersMask, 7 - (n - 1));
289 }
290};
291#endif // BYTE_SIZED_ENCODER_DECODER_H
class for communicating with the firmware on a Byte Sized Encoder Decoder board
Definition byte-sized-encoder-decoder.h:8
void resetEncoderPositions(boolean resetVariables=true)
resets all encoder positions to 0
Definition byte-sized-encoder-decoder.h:254
int16_t encoderVelocity[8]
array of 8 numbers representing the velocity of each encoder (steps per second)
Definition byte-sized-encoder-decoder.h:45
int16_t lastVelocityEncoderCount[8]
array of 8 numbers representing the last encoder count read from the board for velocity calculation
Definition byte-sized-encoder-decoder.h:29
boolean isEncoderActive(uint8_t n)
whether you have set to read data from a specific encoder
Definition byte-sized-encoder-decoder.h:283
int16_t getEncoderPositionWithoutOverflows(uint8_t n, boolean read=false)
gets the position of an encoder as the 16 bit number that the board returns (it loops around and over...
Definition byte-sized-encoder-decoder.h:224
int16_t encoderEnoughCounts[8]
enough counts to calculate velocity from
Definition byte-sized-encoder-decoder.h:53
void run()
reads the encoder positions from the board
Definition byte-sized-encoder-decoder.h:163
uint8_t whichEncodersMask
bit mask of which encoders to read from
Definition byte-sized-encoder-decoder.h:37
uint8_t address
I2C address of the Byte Sized Encoder Decoder board (as selected by the jumpers)
Definition byte-sized-encoder-decoder.h:13
boolean isVelNewVal[8]
array of 8 booleans representing whether the velocity was just calculated
Definition byte-sized-encoder-decoder.h:57
void setEncoderEnoughCounts(uint8_t n, int16_t counts)
set the value of encoderEnoughCounts
Definition byte-sized-encoder-decoder.h:116
int16_t getEncoderVelocity(uint8_t n, boolean read=false)
gets the velocity of an encoder
Definition byte-sized-encoder-decoder.h:240
int16_t encoderCount[8]
array of 8 numbers representing the number of steps each encoder has taken
Definition byte-sized-encoder-decoder.h:17
TwoWire * wire
I2C bus to communicate over.
Definition byte-sized-encoder-decoder.h:33
int32_t getEncoderPosition(uint8_t n, boolean read=false)
gets the position of an encoder as a 32 bit signed integer (it counts how many times the 16 bit numbe...
Definition byte-sized-encoder-decoder.h:207
int16_t encoderSlowestInterval[8]
after this many milliseconds without an encoder tick velocity is set to zero.
Definition byte-sized-encoder-decoder.h:49
int16_t encoderOverflows[8]
array of 8 numbers representing the number of times each encoder's counter variable has overflowed
Definition byte-sized-encoder-decoder.h:21
void setWhichEncoders(uint8_t mask)
set which encoders you want to receive data from
Definition byte-sized-encoder-decoder.h:271
boolean isVelNew(uint8_t n)
whether the velocity was just calculated
Definition byte-sized-encoder-decoder.h:136
void write(uint8_t data)
helper function to write a byte to the board
Definition byte-sized-encoder-decoder.h:61
void setEncoderSlowestInterval(uint8_t n, int16_t interval)
set the value of encoderSlowestInterval
Definition byte-sized-encoder-decoder.h:98
unsigned long lastReadMicros[8]
the last time the encoders were read (microseconds)
Definition byte-sized-encoder-decoder.h:41
int16_t lastEncoderCount[8]
array of 8 numbers representing the last encoder count read from the board
Definition byte-sized-encoder-decoder.h:25
ByteSizedEncoderDecoder(TwoWire *_wire, uint8_t _address=14, int16_t _encoderSlowestInterval=0, int16_t _encoderEnoughCounts=0)
Constructor for the Byte Sized Encoder Decoder class.
Definition byte-sized-encoder-decoder.h:76
void begin(boolean resetEncoders=true)
sets up the Byte Sized Encoder Decoder board all it really does is tell the board to read from all en...
Definition byte-sized-encoder-decoder.h:152