-
Notifications
You must be signed in to change notification settings - Fork 143
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[driver] Add best practice driver for soft graycode / quadrature decoding #580
Conversation
Example follows as soon as a future in the codebase is approved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alternative implemention of getValue() as functor: operator()(). To integrate the latest changes to a local variable v, one would type: v += encoder(); instead of v += encoder.getValue();
Meh, we don't use operator() for anything else, so it would not be consistent with the rest of modm. I would actually prefer the getter, since it's explicit, otherwise it looks like a function call.
Easy fixes done... let's generalize the Dividor |
What is the use-case for this driver? With this driver you have to call |
Hi Raphael. On small MCUs there's no such support. I've noted this in the opening message: "Many modern MCUs have builtin quadrature-decoding support. However encoders alias rotary knobs kept being so usefull in small projects with small chips." Another case is, when you want an encoder on the fly, just for a quick debugging and no sufficient timer-pins are free. |
I don't know how this works on other microcontrollers (AVR, SAM, ....). In my opinion this driver belongs to the "bitbang" category (like e.g. the |
Which MCU are you using? |
Various ATmega... still. I like them somehow |
That's a thing i would give in your hands! Edit: Keeping it in :driver, encoder and encoder_output hang up together so the familiarity is exposed. encoders docs will tell you, that it's a Soft version and anyone who cares for the performance-drawbacks knows, there's hardware support. |
I propose to call this driver Unsure if this driver belong to And maybe we should rename |
In
Yes, let's rename them. |
modules are renamed. How will the classes be named? Same for the preamble structs ... this should become encoder_[input/output] too, right? |
Yeah… kind of an eyesore, but it's consistent. |
38ca7a3
to
65fc036
Compare
It entlightens one fair enough about the hidden gems from software-encoding. |
83eb468
to
ce2b908
Compare
aa02245
to
0b91ea0
Compare
The module-names are prefixed with the bitbang-classifier:
That's it from my side 😏 All implemented ✅ and tested ✅ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice! Let's merge once the CI passes.
"DeltaType is to small for POSTSCALER."); | ||
|
||
using Phases = modm::platform::SoftwareGpioPort<SignalA, SignalB>; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
static_assert(Phases::number_of_ports() == 1, "Signal A/B must be on the same GPIO port to prevent signal tearing!"); |
Otherwise the atomic read properties may not be true.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice mechanism.. Damn i ♥ love ♥ the way you've implemented the low level stuff
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually think it's just Phases::number_of_ports
without a function call… I don't even remember the code I wrote.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Damn i ♥ love ♥ the way you've implemented the low level stuff
Thanks, half of the credit goes to C++17 with the relaxed constexpr rules:
#19 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually think it's just
Phases::number_of_ports
without a function call… I don't even remember the code I wrote.
It is and has already been concidered in the last commits ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, half of the credit goes to C++17 with the relaxed constexpr rules:
Thanks for the interresting background!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the magic spell to get these shift maps?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
8a379a5
to
e6ffb6a
Compare
If and how can i prevent in unittests-linux-generic ?
|
python3 tools/scripts/synchronize_docs.py |
Shame on me... |
CI stucks with...
... and i wonder how - if any - i could have messed this up 🙄 |
Ugh, CircleCI has made some recent changes in their free plan and now it's making us so much trouble. I'll try to rerun it, or we'll simply merge it without the F7 job. You're contributions didn't touch the HAL anyways. |
You're #588 hunting for an alternative... No worries on my side :) |
Why did you close this pull request? @TomSaw |
Thanks @TomSaw for sticking around for our review, it's a very beatiful driver now! |
The pleasure is on my side. I've learned a lot and feels good to dive deeper into the catacombs of contribution. |
Excuse the little disasters due to my github-newbieness @rleh , do you mean, it was a bad thing to delete the encoder branch after it has been merged into develop? |
That's good to hear, because I was worried we scared you off by descending on you like a plague of judgemental locusts…
Emphasis on AFTER 😜 I think you mistook my force push to your encoder branch with a merge into develop, but I wanted to check the CI after the rebase, which was good, because I messed it up and had to fix it. |
I think any generic concept benefits from perfection. Forget the Pareto-principle here: The expensive fine-works pay out squared^squared^squared when you later build applications! out of the generic puzzle-pieces. I also find lot's of satisfaction, making one thing perfect rather than going for quantity. You have my fullest respect when judging my lines cause it's for the good! - Amen |
Hi ✋, missed the gentle communication - here's my next 💢
Many modern MCUs have builtin quadrature-decoding support. However encoders alias rotary knobs kept being so usefull in small projects with small chips. Raphael commited the complement in 2019: modm/driver/encoder/encoder_output.hpp. So, let's don't discriminate the roots:
It's a port of well known, best practice solution: mikrocontroller.net/articles/Drehgeber.
Things to discus
I've redundantly added static_assert checking < UnderlyingType> in two methods: update() and getValue(). I found, this makes the compiler printing the assert-failure-string always on top. There may be a better technique.
getValue() could have been specialized for each value in < DIVISION >. Because of the difference of just 3 tiny lines, i found the it better using a switch-statement.
Alternative implemention of getValue() as functor: operator()(). To integrate the latest changes to a local variable v, one would type: v += encoder(); instead of v += encoder.getValue();
Following an example i've seen in another modm-module, i've put the credits to Peter Dannegger's ANSI-C foundation into encoder.lb ... but this may not be sufficient.