Conversation
|
Hey @Citrullin! Thanks for your contribution! One idea / question that came into my mind while reading over your code: Are there use cases that require one application to acquire different amounts of measurements for averaging? It might be also good to split the driver into two separat commits: One for the driver itself and one for the |
It changes the accuracy of the results. With 200 it is accurate, but also really slow. I think the test takes 2 minutes or something like this. |
So it might be useful to average more measurements during tare process than the actual measurement?! |
Is an option, yes. Will change. One for normal ones and one for taring. |
| @@ -0,0 +1 @@ | |||
| include $(RIOTBASE)/Makefile.base No newline at end of file | |||
There was a problem hiding this comment.
newline missing. (This is a configuration issue in your text editor. A correctly configured editor should never safe a text file without the newline. You might want to fix the configuration, so that you don't need to worry about this anymore.)
| value.u8.data[2] = gpio_util_shiftin(dout, sck); | ||
| value.u8.data[1] = gpio_util_shiftin(dout, sck); | ||
| value.u8.data[0] = gpio_util_shiftin(dout, sck); |
There was a problem hiding this comment.
How are timing constraints of the hardware are enforced? The datasheet says a clock speed of at most 20 MHz is supported.
If this driver happens to be used on a faster board (e.g. lets say an ESP32 or an STM32F4xx or STM32F7xx) and the application is compiled with LTO enabled, a gpio_set(), a gpio_read() and a gpio_clear() are performed in a single CPU cycle each. Let's assume 8 CPU cycles are required per bit with LTO=1 on an ESP32 clocked at 240 MHz: gpio_util_shiftin() would then run with a clock of 30 MHz.
I think we can be pretty sure that any currently supported board with the current GPIO implementation would not get anywhere near the 20 MHz without LTO being used. But once all issues with LTO are resolved, it might get enabled by default.
Making the GPIO API inline-able is also something that could result in drastic speed ups of the GPIOs; and this is something that is not so unlikely to happen.
There was a problem hiding this comment.
That's a really good point and would lead to an issue. They are not enforced. I need to think about this. Do you have an idea?
There was a problem hiding this comment.
IMO, this issue could arise to all users of gpio_util_shiftin(), if LTO is enabled. So maybe the best is to extend it to also take a third argument specifying the maximum speed. This could be implemented using xtimer_periodic_wakeup()
If the GPIO ABC API proposed in #12015 would already be available, it would be even possible to provide a clock frequency argument (instead of a maximum clock frequency argument): With GPIO ABC it would be possible to match the clock frequency quite well. Maybe I should invest some time to polish that API and add "killer applications" on top of it to motivate the API.
So for now: The xtimer_periodic_wakeup() is the best option IMO. But I don't think that an API change will make it into the upcoming release, as this is not something usually merged during the feature freeze. But it is not too long until the next development cycle starts and PRs can of course be opened and reviewed at any point in time, only the merging is limited during feature freeze.
| for (unsigned i = 0; i < gain; i++) { | ||
| gpio_set(sck); | ||
| gpio_clear(sck); | ||
| } |
There was a problem hiding this comment.
Here again the clock frequency could easily exceed the allowed maximum depending on the performance of the GPIO implementation
| if (value.u8.data[2] & 0x80) { | ||
| value.u8.fill_byte = 0xFF; | ||
| } |
There was a problem hiding this comment.
sign extending 24 bits to 32 bits? If so, maybe add a comment
|
|
||
| int32_t hx711_get_units(hx711_t *dev, int8_t times) | ||
| { | ||
| return (int32_t) (hx711_get_value(dev, times) / dev->params.divider); |
There was a problem hiding this comment.
| return (int32_t) (hx711_get_value(dev, times) / dev->params.divider); | |
| return hx711_get_value(dev, times) / dev->params.divider; |
| #endif | ||
|
|
||
| #endif /* HX711_H */ | ||
| /** @} */ No newline at end of file |
| int32_t hx711_read_average(hx711_t *dev, uint8_t times) | ||
| { | ||
| int32_t sum = 0; | ||
| uint8_t i = times; | ||
|
|
||
| while (i--) { | ||
| sum += hx711_read(dev); | ||
| } | ||
|
|
||
| return sum / times; | ||
| } |
There was a problem hiding this comment.
Is it needed to expose this function in the public API? If I don't miss anything, a user would call hx711_get_units() or hx711_tare() and never call this function directly, right? If so, please add static as qualifier
| CFLAGS += "-DHX711_PARAM_SCK=GPIO_PIN(1, 13)" | ||
| CFLAGS += "-DHX711_PARAM_DOUT=GPIO_PIN(1, 14)" | ||
|
|
||
| include $(RIOTBASE)/Makefile.include No newline at end of file |
| include ../Makefile.tests_common | ||
|
|
||
| BOARD ?= bluepill | ||
| FEATURES_REQUIRED += periph_gpio |
There was a problem hiding this comment.
| FEATURES_REQUIRED += periph_gpio |
The driver depends on periph_gpio already. So no need to specify this twice
|
|
||
| expect(value_before > value_after); | ||
| expect(value_after <= 1); | ||
|
|
There was a problem hiding this comment.
Maybe drop to the shell afterwards so that the SAUL integration can be tested using the saul command?
|
ping @Citrullin :) |
This comment has been minimized.
This comment has been minimized.
|
@tperchoc: Care to adopt this PR? (E.g. by opening a new PR based on this and keeping the copyright. Of course, extend the copyright and author list as needed.) |
|
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions. |
|
@tperchoc Should I just close this issue and you open another PR? |
|
@Citrullin I found this PR by looking for a way to use the HX711 in RIOT-OS. Do we need to wait for this PR to be merged or can I already use the HX711 somehow? |
|
Hello, im alive just i didnt remember what i did here sry ;) just do has you want |
Would be great, if you just fork @tperchoc repo, pull the most recent main branch and create a new PR. I am happy to test it. :D |
|
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions. |
|
Good point. I am just talking to someone about it ^^ |
Contribution description
HX711 ADC driver for weigh scales. Including SAUL implementation.
Testing procedure
tests/driver_hx711tests/drvier_hx711and change the values ofHX711_PARAM_SCK,HX711_PARAM_DOUT. If you use another board, change it as well.SAUL
examples/sauland add the following to the Makefile. Change the values accordingly.term.saul write [ID] 200to tare the scale.saul read [TIMES]where[TIMES]is the number of reads. It should show the correct weight. If not, you have to adapt the divider. It is the value ofHX711_PARAM_DIVIDER. If the weight result is too high, set a higher divider. If it is too low, you have to lower the divider. Until you have the correct value. You should use standardized weights in order to get precise results.Issues/PRs references
Previous PR: #11416