|
what is this place? I'm new here and I don't know what to do. 
|
|
|
|
|
Cowboys used to hang lanterns from their saddles at night to help them find their way home.
This is the earliest example of saddle light navigation on record!
🥼🚪
If you can't laugh at yourself - ask me and I will do it for you.
|
|
|
|
|
|
good one.
"A little time, a little trouble, your better day"
Badfinger
|
|
|
|
|
|
Yes it was. Aren’t most of them?
If you can't laugh at yourself - ask me and I will do it for you.
|
|
|
|
|
DRHuff wrote: Yes it was.
By me. M'colleagues enjoyed it....
|
|
|
|
|
For the non-native speakers like me, in American English "satellite" is pronounced with "tuh" or "d". Same as in "better" -> "bedder".
Advertise here – minimum three posts per day are guaranteed.
|
|
|
|
|
I was just thinking about this today when I was retooling my IoT button library.
I use template-instance statics to get around not being able to pass an argument to an interrupt routine (which must be void () ) under the Arduino framework
template<uint8_t Pin>
class button {
static button* m_this;
static IRAM_ATTR void isr() { m_this->... }
};
...
like that.
It's really useful but it makes me kinda wanna puke too, even though there's absolutely nothing wrong with it, technically speaking, since it doesn't make sense to have two buttons on one pin anyway, and you're not dealing in a pre-emptively threaded environment in 80% of all cases on 80% of all platforms.
Template-instance statics (i don't know what else to call them) are something I have to rely on way more than I wish I had to, but I am glad they are there.
What's your go to coding technique that nevertheless makes you uncomfortable?
To err is human. Fortune favors the monsters.
|
|
|
|
|
I had a number of buttons on my Arduino project that needed to do similar (but slightly different) things.
I had all this code to handle the button debouncing.
So then I discovered a nice way to pass a pointer to a function (button press handler) so that the code was the same no matter which button was pressed, but the specific function for the correct button is called.
And, all the debouncing for each button is wrapped up nicely.
typedef void (*ButtonPressHandler) (void);
void checkButton(const int BUTTON, bool &last, bool ¤t, ButtonPressHandler handler ){
current = debounce(last, BUTTON); if (last == LOW && current == HIGH) {
handler();
}
last = current; }
boolean debounce(boolean last, int button)
{
boolean current = digitalRead(button); if (last != current) {
delay(5); current = digitalRead(button); }
return current; }
Now you just call it with whichever button is pressed so it can all be handled:
checkButton(ROOM_BTN,roomBtnPrev,roomBtnCurrent,checkChangeRoomButton);
checkButton(DATA_BTN, dataBtnPrev, dataBtnCurrent, checkWriteDataButton);
Now they are both handled the same way and all the debouncing is wrapped up.
What do you think?
|
|
|
|
|
I think I need more coffee, because I don't get it yet. I will look again when my eyes are focusing properly. For some reason it's a lot easier to look at my own code in the morning than other people's. I didn't think about that when I wrote my OP.
Edit: Okay, I get it. That's interesting. It's an approach I'd be more inclined to take in C. That's part of why I didn't grok it at first, because I was expecting something kinda C++ish.
That works great for buttons, but less so with more complicated widgets, like display drivers, because then you run into having an entire API of "callbacks" you have to source.
I'd certainly adopt this approach in a C project. With C++ I tend to prefer to encapsulate things to a containing class, but then that invites all the complication that comes with it, of course.
To err is human. Fortune favors the monsters.
|
|
|
|
|
Yeah, it's a simple thing that makes it so:
1. Debouncing is handled for all buttons in one place.
2. The specific functionality for the button is run.
Otherwise you have button debouncing code all over the place.
It definitely cleans it up. And, yes, C++ could do this a bit cleaner via encapsulation (in it's own class) but I find that Arduino C++ is more like a hybrid of C & C++ because C++ class overhead does use some memory so there are places in Arduino where you often do more C-like and other places where you may do more C++-like (include classes). 
|
|
|
|
|
Just to be difficult, classes don't use memory in C++ intrinsically, with the exception of classes with vtbls.
It's just a way to structure your code. C++ doesn't introduce overhead compared to C unless you write it so that it does.
To err is human. Fortune favors the monsters.
|
|
|
|
|
True, they don't use more memory.
However, they use program space which can be very limiting.
For example an Arduino Nano utilizes an ATMega328 which has 32K Flash, but this is even smaller with the bootloader included.
So, if you create a large number of classes in code on an Arduino you will find that much of your program memory is eaten up. I wrote an extensive Arduino program which :
1. allows writes to SD Card -- requires code
2. has a Bluetooth component which transmits data to phone
3. contains a tmp36 (temperature module)
4. displays info to oled screen
5. contains a real-time clock for recording time temp was taken
That pushes the limits of program memory (requires more code to handle things, thus eating more flash) and I moved to the ATMega4809 (which includes 48K flash).
You can see the entire schematic here[^].
So, if you write more code (which includes all those class wrappers) you'll run out of code space more quickly.
You can see the code at my github[^].
|
|
|
|
|
I'd argue that it's *easier* to write compact code in C than it is in C++, but I challenge anyone to come up with a realistic C construct that can't be reflected using C++isms and result in functionally the same assembly code.
One thing people forget is that types don't exist. They are like concrete molds that set your data in a form, but then that mold is tossed during compilation as it's no longer needed in the resulting code.
So as long as you know what stuff generates what ASM, you can write lean C++ code.
Now if you're relying on the STL or just being casual about it, you'll definitely see C++ as more bloated.
But there's an actual pattern to creating classes that's replicated in C all the time.
Any time you see a "handle" in fact, that's a "class pointer" except in C lingo.
Now, you'll find if you want to make lean C++ code you'll be using statics a lot - any time you don't need "handles"
You'll also probably prefer the C malloc/free paradigm to new and delete for several reasons.
But within parameters, you can write C++ code that's every bit as lean as C code. You just have to know what your compiler is going to be creating.
At the end of the day, that means C is probably the best choice for enforcing lean code. But an experienced C++ developer need not do away with many of their C++ niceties for want of RAM or even program space.
off my soapbox now.
To err is human. Fortune favors the monsters.
|
|
|
|
|
As an aside, I noticed you are using the Arduino IDE.
Forgive me if this has been suggested before, or if you've otherwise tried it, but you may want to consider VS Code + Platform IO as an alternative development IDE and toolchain.
Arduino is sort of like a fisher price toy, and it doesn't do a lot for you as a developer.
Platform IO supports:
- Microsoft's intellisense/autocomplete goodness, and all their fancy VS Code IDE wizardry
- Per project settings and libraries, in an INI file rather than forcing you to mess with menus (but you can use menus to edit the ini file if you want)
- A nice library repository system using semantic versioning
- Several frameworks and platforms, including Arduino, ESP-IDF, and others.
- Autodetection of the right COM port to use. Yay!
- and other stuff I'm forgetting right now.
Arduino IDE's sole advantage is the bleeding edge releases of the framework tend to be supported on it a little earlier.
And Platform IO is a Ukrainian project, so there have been some rough points over the past year in terms of maintenance - understandably so! - but it's been solid lately.
To err is human. Fortune favors the monsters.
|
|
|
|
|
You could do that with a virtual function, couldn't you?
"In testa che avete, Signor di Ceprano?"
-- Rigoletto
|
|
|
|
|
|
raddevus wrote: I'm not sure. What is a virtual function? Well that's a big topic (but what you remember is in the right direction). See, for instance Virtual Function in C++ - GeeksforGeeks[^].
Roughly speaking, you have a base button class and then some derived classes. The base class declares (and possibly define) the handler method. The derived classes, in turn provide their own implementation of the same method. A call to p->handler() at runtime resolves to the proper call to the actual derived class object.
Quote: Can you create a virtual function in Arduino code? Well, is C++ code, after all.
"In testa che avete, Signor di Ceprano?"
-- Rigoletto
|
|
|
|
|
A virtual function is a function that can be overloaded by a derived class.
In C# you mark such a function as virtual, IIRC - same as you do in C++.
To err is human. Fortune favors the monsters.
|
|
|
|
|
raddevus wrote: What do you think?
If we wouldn't be in the lounge where programming topics are off-limits, I'd call your solution sub-optimal: waiting 5 ms or more for each button, on a non-preemptive system like Arduino, is just asking for trouble. My favorite debouncing solution is a loop that reads all buttons and feeds them to software shift registers. When a shift register is filled with the same value, button is debounced.
But, as I said, here in the lounge I'll just keep my big mouth shut
Mircea
|
|
|
|
|
If I were to respond to your message, which I won't, I would say something along hte lines of:
1. Programmers and the like are the most abysmal people of all. They cannot enjoy any solution other than the ones they understand.
2. The OP asked for code samples which they found useful -- and I replied with code I found useful and interesting -- but never intimated that it was the _best_ solution. I am a hobbyist on Arduino. Nothing more.
3. It is comments exactly like yours that make the internet such an abysmal experience for everyone.
4. And I thought of another -- the debounce code that you don't like was actually taken from Jeremy Blum's fantastic book, Exploring Arduino[^]. So take it up with him. See his github and do a code review on him there (GitHub - sciguy14/Exploring-Arduino-2nd-Edition: Companion Code for the Second Edition of "Exploring Arduino," the book by Jeremy Blum[^]).
But I will not respond here. 
modified 8-Jan-23 17:19pm.
|
|
|
|
|
I sincerely apologize if my post rubbed you the wrong way. My old boss once said that I have the same level of empathy as Catbert, the evil HR director.
To make amends, here is a good post about debouncing that I've perused for many years: Debounce Code – One Post To Rule Them All | Hackaday[^]
Mircea
|
|
|
|
|
Thanks, that was very nice and I accept your apology.
I will take a look at the post. I honestly was offering the original code just as an interesting thing.
I was probably triggered by your post because I started out in IT back in '91 and since then it has always been a "my code is better than yours" pissing war with Devs.
I started out in Tech Support and knew I was a slug in the IT world.
Worked my way into QA and was there for 5 years or so and remember when this Dilbert came out[^].
Oh, it's funny now.
I finally made worked my way into Dev and have been here for about 22 years but I find that Devs are (and have always been) so competitive and are "always right". it just kind of triggers me.
When I was in QA if a dev ticked me off, I would just test his code, find a critical bug and then post it Friday afternoon. 
|
|
|
|
|
raddevus wrote: When I was in QA if a dev ticked me off, I would just test his code, find a critical bug and then post it Friday afternoon.
That is evil.
I love it 
|
|
|
|