If you like using the arrow operator, C/C++'s intimate relationship between pointer and arrays can be exploite, viz:
long encoderNewPosition[i] = (encoderObjects + i) -> readAndReset();
It seems that fashion is to use the object and the dot operator, not an address and arrow.
I tested the code I posted just now. Compiling doesn't always mean it functions correctly and I was not 100 percent sure I had it right. TBH I am never 100 percent sure about anything.
When I find I need to have multiple arrays of the same size because the same index will hold related stuff, I tend to create a class to gather them together
For example if you want an Encoder object, keep the last position before reset and have a name (ie 3 attributes for an object), then that could look like this:
#include <Encoder.h>
class EncoderWithMemory : public Encoder {
public:
EncoderWithMemory(const char * name, uint8_t pin1, uint8_t pin2) : Encoder(pin1, pin2), name(name), lastPosition(0) {}
long readAndResetWithMemory() {return lastPosition = readAndReset();}
long getLastPosition() const {return lastPosition;}
const char * getName() const {return name;}
private:
const char * name;
long lastPosition;
};
// Create encoder objects using the subclass
EncoderWithMemory encoders[] = {{"Right", 2, 6}, {"Left", 3, 7}};
void setup() {
Serial.begin(115200);
}
void loop() {
// check each encoder to see if it has moved since we last checked
for (auto& ewm : encoders) {
if (ewm.read() != 0) {
Serial.print("Encoder ");
Serial.print(ewm.getName());
Serial.print(" : ");
Serial.println(ewm.readAndResetWithMemory());
}
}
}
Nice. This is the single most important line in the sketch you posted:
class EncoderWithMemory : public Encoder {
which when understood is to open doors unimaginable.
The name you give it is good for printing and stuff, but I would still use an enum when there is enough need in terms of referring to individual objects by, um, name to warrant doing.
FWIW, I would present this without using an automatic for loop. I'm sure that auto is just the thing in some circumstances, but it refuses to go into my coding vocabulary - I think it is too much of a step away from code that says what it does and does what it says. Perhaps we could call it simply too sweet, as much as I like syntactic sugar or whatever you might call this language feature.
My opinion from down here programming in C near the metal.
Thank you for the kind words. I haven't the least intention of using anything from the C++ library, if by that you refer to the giant bag of stuff attached to C++ and more or less considered a inseparable part of the language as used on larger machines.
There are some things in C++ that are worth knowing and using, and being able to read it for dealing with Arduino libraries is good.
At some point on the C++ curve it becomes less enjoyable, a point not too far from a similar one I see many who would call themselves C++ programmers also losing traction.
I am not a programmer, but if I was and was forced to say in what language I work, it would be C, something late 20th century by way of version.
Well, it certainly is massive and admittedly, I only use a very small number of its features. But it is nice to have a professionally-written, efficient, and thoroughly-tested library implementing things like vectors, queues, maps, linked lists, sets, etc that automatically adapt to hold just about any datatype or object. On top of that, there’s an entire library of algorithms for searching, sorting, copying, iterating, etc. Again, these functions handle just about any datatype you care to throw at it. I spent countless hours in college writing code for such structures and algorithms in C. I’m now happy to use these canned C++ solutions.
Yes those are often under appreciated / unknown by C developers
We also need to appreciate that on small microcontrollers it’s often key to understand how memory is used, if you have dynamic allocation etc. So sometimes it’s better to rely on your own code if this is an important feature.
True, but many times the structures are global and of a known size at compile time meaning you don't have to worry about the dreaded "memory fragmentation". You can also pre-allocate the memory first thing at run time. Your coding experience and style may also come into play. And of course, processors with more and more resources are constantly entering the Arduino ecosystem.
I wasn't going to take time to say, but for me the UNO is several orders of magnitude (you choose the radix) more powerful than the toys I played with in the 20th century.
So I'll keep in mind for a day that might never come when I outgrow it the things real C++ on larger machines can provide.
true - but it's not just the fragmentation. for a simple (may be far fetched) example do you know how much dynamic memory is used by all the sorting algorithms or if they use recursion ➜ size of stack then matters (and is dependent on your container's content) ?
All the sorting algorithms I had to write in school required in-situ sorting (and perhaps a small side buffer). Don't remember all of them ... Quick Sort, Heap Sort, Bubble Sort, etc. Some did use recursion. They were worthwhile exercises in turning algorithms into working code, but wouldn't want to go through that again.
Anyway, point taken. Enough hijacking the OP's thread.