I'm currently working on a project that has 4 TM1637 displays. I have to change them very often in the code, and which one I have to change depends on where the program is at. I'm using the library located at:
This was easy in the beginning, because you just set up the different objects, but things are getting complicated and the code is getting extremely convoluted, slow and messy as every different time I need to change them, I also have to run something to determine which display I actually want to change so it can be addressed individually.
It's kind of confusing to explain, so will try to psuedo it out, the follow constructs the object for each display
SevenSegmentExtended disp1(Disp1Ck, Disp1Io);
SevenSegmentExtended disp2(Disp2Ck, Disp2Io);
SevenSegmentExtended disp3(Disp3Ck, Disp3Io);
SevenSegmentExtended disp4(Disp4Ck, Disp4Io);
so now when I want to write to one display, I have to do something like the following:
switch (x) {
case 0:
disp1.print(potVal[0]);
break;
case 1:
disp2.print(potVal[1]);
break;
case 2:
disp3.print(potVal[2]);
break;
case 3:
disp4.print(potVal[3]);
break;
}
and I'd like it to be something like this:
dispArray[x].print(potVal[x]);
I'm guessing there is a way to do this, and I've been searching for a while, but not sure if I'm looking for the right thing. Any pointers would be incredibly helpful.
I think this will work.
SevenSegmentExtended *dispArray[] = {
&disp1,
&disp2,
.
.
};
Pete
Do you mean like:
SevenSegmentExtended disp1(Disp1Ck, Disp1Io);
SevenSegmentExtended disp2(Disp2Ck, Disp2Io);
SevenSegmentExtended disp3(Disp3Ck, Disp3Io);
SevenSegmentExtended disp4(Disp4Ck, Disp4Io);
SevenSegmentExtended *dispArray[] = {
&disp1,
&disp2,
&disp3,
&disp4
};
that gives me an error when I try to use something like:
unsigned long currentMillis = millis();
dispArray[1].print("yay");
It says expression must have a class type
it also won't let me do:
SevenSegmentExtended *dispArray[] = {
&disp1(Disp2Ck, Disp2Io),
&disp2(Disp2Ck, Disp2Io),
.
.
};
for that I get:
call of an object or a class type without an appropriate opperator() or conversion functions to pointer-to-function type.
The array is of pointers so you would use:
dispArray[1]->print("yay");
Pete
Or:
SevenSegmentExtended dispArray[] = {
{Disp1Ck, Disp1Io},
{Disp2Ck, Disp2Io},
{Disp3Ck, Disp3Io},
{Disp4Ck, Disp4Io}
};
dispArray[1].print("yay");
Pieter
SevenSegmentExtended displays[] =
{
SevenSegmentExtended(Disp1Ck, Disp1Io)
, SevenSegmentExtended(Disp2Ck, Disp2Io)
, SevenSegmentExtended(Disp3Ck, Disp3Io)
, SevenSegmentExtended(Disp4Ck, Disp4Io)
};
Remember to call the 'begin' method for each item in the 'displays' array in your 'setup' before attempting to USE them.
EDITT: This creates an array of 'SevenSegmentExtended' objects so these are not pointers to the objects.
lloyddean:
Remember to call the 'begin' method for each item in the 'displays' array in your 'setup' before attempting to USE them.
and try References instead of pointers and make you life easier by not having to dereference.
SevenSegmentExtended& dispArray[] = {
disp1,
disp2,
.
.
};
Well if we're goin to get fancy forget the above and let the new 'for' loop do the hard work of making the reference for you with -
for (auto display : displays)
{
display.begin();
}
.. but this might be harder to explain, and, or, understand at his level of experience.
Although it does make it much easier to use the CURRENT element of the array within the loop!
OMG IT WORKS!! Thank you all so much for the help! I ended up using PeiterP's idea, but that's mostly because it's the one that I mostly understood HOW it actually worked.
My schooling is in electronics, and as a result, our coding lessons were much simpler then I think they should have been. I'm hoping to go back and learn everything properly when the kids are out of the house and I have some actual free time, but in the meantime, these forums are a lifesaver!
Thank you all so much for the help. After this project, I will likely be trying the other implementations, to figure out how and why they work, so might have some more questions in a month or two.
lloyddean:
Well if we're goin to get fancy forget the above and let the new 'for' loop do the hard work of making the reference for you with -
for (auto display : displays)
{
display.begin();
}
.. but this might be harder to explain, and, or, understand at his level of experience.
Although it does make it much easier to use the CURRENT element of the array within the loop!
That's incorrect.
Your code creates 4 copies of the original displays, begins each copy, then destroys the copies. The original displays are still in their same, uninitialized state.
You have to use references to the array elements returned by the iterator:
for (SevenSegmentExtended &display : displays) {
display.begin();
}
or
for (auto &&display : displays) {
display.begin();
}
if you're the lazy type.
Code demonstrating the problem:
#include <iostream>
using namespace std;
class C {
public:
void increment() {
c++;
}
int get() const {
return c;
}
private:
int c = 0;
};
template <size_t N>
void print(const C (&arr)[N]) {
for (const C &c : arr)
cout << ' ' << c.get();
cout << endl;
}
int main() {
C arr[4];
cout << "Initial" << endl;
print(arr);
for (C c : arr)
c.increment();
cout << "Incremented using `C c : arr`" << endl;
print(arr);
for (C &c : arr)
c.increment();
cout << "Incremented using `C &c : arr`" << endl;
print(arr);
for (auto &&c : arr)
c.increment();
cout << "Incremented using `auto &&c : arr`" << endl;
print(arr);
return 0;
}
Output:
Initial
0 0 0 0
Incremented using `C c : arr`
0 0 0 0
Incremented using `C &c : arr`
1 1 1 1
Incremented using `auto &&c : arr`
2 2 2 2
As you can see, using C c : arr does not increment the c value of the elements in the array.