ADXL345: Different between RPi Pico and RPi 3B

To your process:

  1. ACCELEROMETER_MEASURE CHIP=adxl345 - this is a start of the measurements
  2. Wait 20 sec → manually timed with a stopwatch
  3. ACCELEROMETER_MEASURE CHIP=adxl345 NAME=... this ends the measurements and writes the data - overall 20 seconds worth of data.

So, why do you expect to measure 10 seconds worth of data?

Ok, this clears it up already. My understanding was simply wrong:

  1. ACCELEROMETER_MEASURE CHIP=adxl345Start a “warm-up” phase
  2. Wait 20 sec → manually timed with a stopwatch
  3. ACCELEROMETER_MEASURE CHIP=adxl345 NAME=...Start the actual measurement
  4. Wait 10 sec
  5. FIRMWARE_RESTARTEnd the measurement started in step 7
  6. Start over with next test

:innocent:

Yep, admittedly, the behavior of ACCELEROMETER_MEASURE might be a bit confusing. The first invocation for the chip starts the measurements, and the second - finishes it and writes the data, at which point you can provide a filename. It does not continuously write the data. But it is a good idea to give some time at step 8 to let it write all the data before the restart. 10 seconds should be more than enough.

1 Like

I mounted the ADXL tilt in every axes:

The same process, as already detailed, now yields following results:

  • @koconnor and @dmbutyugin your analysis was fully correct: It depends on the orientation and zero-crossing
  • When the board has separate 3V3 and Vin inputs it is better (almost mandatory) to use the Vin
  • When having to use RPi Picos 3V3 output (because the board has level shifter) it is beneficial to toggle GPIO23 high
  • When using the RPi Pico with a board that has voltage regulator but no level shifter it is preferable to use Vbus Pin 40 (5V) → See first measurement campaign No 7 vs. No 16

Following two histograms show the distribution of samples, i.e. number of samples within a bin of 200 units, for above tests No 1 and No 2, i.e. 3V3 input vs. Vin on an Adafruit board

3V3 input shows a quite random distribution while Vin a nice normal distribution.

Do you agree with this conclusion?

Interesting. Thanks.

When using the adafruit boards with the Vin pins - did you apply 5V to Vin or 3.3V to Vin? If it was 5V, I’m curious what would happen if you applied 3.3V to Vin. If it was 3.3V, I’d be curious what would happen if 3.3V was applied to both the “Vin” and “3.3” pins.

FWIW, I’d recommend never putting 5V anywhere near these boards if at all possible. Unless I’m misunderstanding your results, the improvement seems to be minor. It’s easy to damage the adxl345 and it’s easy to damage the rpi (and/or micro-controller). Seems simpler to recommend “always use 3V when you can”. YMMV.

Cheers,
-Kevin

See the table above:

  • pico3V3 → Pico pin 36, 3V3 output
  • adafruit2_3V3 → Input to the board via 3V3 in (input is simply bypassing voltage regulator)
  • adafruit2_Vin → Input to the board via Vin via the voltage regulator

Didn’t test. Will do.

Well, you have a point there. If the board is not 5V tolerant, you might fry the board, if it has a level shifter, then it might kill the RPi

I collected some additional data:

The tests No 9 and 10 apply 5V to Vin. This only works with the Chinese board as it has no level shifter. The Adafruit has level shifter, so this would output 5V on SDA and SCL.
Test No 9 corresponds to No 4 and 8 with 3.3V
Test No 10 corresponds to No 13 with 3.3V

See test No 3 and 7. Depending on GPIO23 the results are quite bad (GPIO low) or even the best when GPIO23 is high.
I’m curious: Did you expect such a result? How did you come up with this idea?


To have a complete overview, I also added some results with the tilt Chinese board, which where missing in the table above (previous post). The tests are No 4, 5, 9, 10 and 13.

In fact the tests with 5V (9, 10) seem to provide slightly better results, but this may also be well below the error margin and it might not be worth the risk.

A note, I forgot to mention all along: In my Excel a comma is used as decimal separation. Sorry for this.

Raw Data and more detailed Excel: Google Drive

I had no real expectations one way or another. The adafruit board lists 3v3 as an output, and as you’ve shown, feeding power into it causes bad results. So, power needs to be fed via Vin. However, using Vin will cause a voltage drop that I wasn’t sure how the level shifters would handle.

In summary though, it seems:

  1. Always use “Vin” and not “3V3” on the adafruit boards.
  2. The 3.3V source on the rpi pico is not powerful enough to run the adxl345. Either set gpio23 high or use 5V (if absolutely sure the adxl345 board has a regulator and does not have level shifters).

Did I get that correct?

Thanks.
-Kevin

From the tests it would seem that it might be preferable to power adafruit boards via VIN pin, as this seems to have no downsides and improves the performance in some other cases (like when powering from pico board). Maybe we should update the documentation to reflect that. Separately, I’d like to write some info about connecting adxl345/343 to the MCU boards, but this is a complicated topic due to 5V tolerances / level shifting, and so it’ll take some time.

FWIW, I’m not sure that 3.3V source on pico isn’t powerful enough: setting gpio23 high causes the power source to go into high-performance mode rather than power saving mode. Note that if the power draw is high, it goes into high-performance mode regardless of the value of that pin. This suggests that adxl345 does not draw enough current from pico, so its power source stays in the power saving mode by default. And this mode is known to cause more ripples on the 3.3V line, which apparently affects adxl345 readings.

Separately, I have a pico, and I will run some experiments with it and the accelerometer to confirm these findings when I have some time (probably this weekend). I’d like to confirm that this is a common trend and not an issue of a specific pico (or a specific batch of picos).

Added some additional information on various boards here: Raspberry Pi Pico + ADXL345: Portable resonance measurement

After validation by @dmbutyugin, I will add some information on wiring and GPIO23 as well


For the existing documentation:

Update of the fritzing to reflect VIN as preferable port.

OK, I’ve run some tests with an Adafruit Pico and a couple of adxl343 (adxl0 and adxl1) I had lying around. Note that I purchased them together, so they were probably from the same batch.

For the reference, the powerchain looks like 24V PSU → 5V buck converter (calibrated with a multimeter) → RPi3 → USB cable → RPi Pico → 3.3V → ADXL343. I assembled the test kit on the breadboard. The relevant configuration:

[mcu pico]
serial: /dev/serial/by-id/usb-Klipper_rp2040...

[adxl345 test]
cs_pin: pico:gpio15
spi_bus: spi0a

[output_pin pico_pwm]
pin: pico:gpio23

Note that adxl343s were always connected to the 3v3 pin on the picos, as they have logic level shifter and it is not safe to connect them to 5V (and generally doesn’t make sense for this test).

The results for the ‘axes noise’ are as follows:

  • adxl0 3v3 pwm0: 158.724319 (x), 195.224866 (y), 228.974836 (z)
  • adxl0 3v3 pwm1: 14.953473 (x), 14.886611 (y), 20.392768 (z)
  • adxl0 VIN pwm0: 81.184757 (x), 123.383230 (y), 143.410439 (z)
  • adxl0 VIN pwm1: 4.411249 (x), 12.015821 (y), 14.759913 (z)

  • adxl1 3v3 pwm0: 136.179466 (x), 166.567422 (y), 188.101471 (z)
  • adxl1 3v3 pwm1: 8.425748 (x), 16.422798 (y), 21.540496 (z)
  • adxl1 VIN pwm0: 91.346866 (x), 161.891714 (y), 134.605346 (z)
  • adxl1 VIN pwm1: 4.496813 (x), 10.224438 (y), 15.316827 (z)

For some reference, here’s the noise of a chinese adxl345 connected to the RPi3 as suggested by the official Klipper documentation (via VCC pin): 18.360854 (x), 20.781346 (y), 22.685117 (z)

So, it seems it is definitely beneficial to put a pico’s power source in the pwm mode prior to running the measurements. Connecting the accelerometer via VIN pin is also beneficial, though not as critical (even with a 3v3 pin, the noise is comparable to a board connected to RPi3 via VCC, at lest in my setup). But it likely won’t hurt. Though in the previous tests done by Sineos connecting the accelerometer to the RPi3 via VIN pin there were no statistically significant improvements vs using 3v3 pin.

While this is correct, another look on the data reveals some differences and would even point to an advantage when using 3V3 on the Adafruits.

  • Measurement repeated with two Adafruits in tilt mounting
  • Noise measurement done 6 times for each test and then averaged
  • Noise measurement does halfway match with standard deviation
  • There are differences between the two boards
  • The differences for one given board and between VIN or 3V3 seem statistically not relevant

Graphing the data:

  • blue is VIN and orange 3V3
  • Here clearly 3V3 seems preferable
  • Compared to the graph, the values for noise and standard deviation are not conclusive
  • Also matches the previous results here: ADXL345: Different between RPi Pico and RPi 3B - #10 by Sineos (note: this test has been done with the ADXL in horizontal alignment)

Histogram of the same data:

  • Left VIN, right 3V3
  • X-Axis: Range between 1200 and 8200, divided in bins of 100
  • Y-Axis: Number of measurements that fall within a specific bin
  • The spread of the 3V3 is smaller (less scatter), whereas VIN is more centered (see scale of the Y-Axis) → Maybe this explains the low difference in terms of standard deviation

Edit:
To highlight another small result from this measurement:

  • Average samples/s for Adafruit1 across 64k samples: 3026 (VIN) / 3061.5 (3V3)
  • Average samples/s for Adafruit2 across 64k samples: 3213.7 (VIN) / 3214.1 (3V3)
  • I noticed such differences in my previous measurements as well

Do those differences affect the outcome of auto-tuning?

If you look at the data, it seems that there happens to be a slightly different noise on different axes. E.g. adafruit1_Vin shows larger StaDev on X, and adafruit1_3V3 - on Z. There is a somewhat similar pattern for adafruit2 sensor. So that’s why I say that these results to not demonstrate statistically significant advantage of one connection over the other one. On the chart, you show X axis only, but if you plotted also the Z axis for adafruit1, or Y for adafruit2, you’d likely see the opposite effect.

The fact that adafruit2 produces more samples/s than adafruit1 is certainly odd. What you could do is run Klipper data logging with one sensor connected, e.g.

~/klipper/scripts/motan/data_logger.py /tmp/klippy_uds adafruit1

until it disconnects, then connect the other sensor, and repeat that command with adafruit2 param, and then upload the generated gz files for further analysis. Unfortunately, the mainline Klipper code no longer reports ‘overflows’ and ‘errors’ anywhere in the logs anymore, so that would be the only way to obtain that data. Might be at the end of the day that somehow the adxl345 internal clocks are not very precise, and not a problem of transmissions.

It does not appear to be the case.

Different characteristics, but seems repeatable for y and z.

Will try this.

I agree. If you look at the very first post of this story, the differences seem below error margin.
Nevertheless, when running this, I’d like to do it in the best possible configuration / accuracy.


I think, we agree on the Pico 3V3 and GPIO23 recommendation. Is there a difference (if yes, what) between:

[output_pin pico_3V3pwm]
pin: pico:gpio23
static_value: 1

and

[static_digital_output pico_3V3pwm]
pin: pico:gpio23

No real difference. The static_digital_output section is useful when one needs to specify many pins (eg, see config/generic-rambo.cfg ).

-Kevin

I took yet another approach at looking at the data (the last one - I promise) and I think the results are interesting to share.

Approach:

  • Assume the noise data should be normally distributed (normal population)
  • Calculate 1st and 3rd Quartile (Q1 / Q3) of the data
  • The range between 1st and 3rd Quartile (IQR - Inter Quartile Range) statistically encompasses the middle 50% of normally distributed data
  • Calculate a “Lower Fence”: Q1 - 1.5 x IQR
  • Calculate a “Upper Fence”: Q3 + 1.5 x IQR
  • The range between “Lower Fence” and “Upper Fence” statistically encompasses the middle 99.3% of normally distributed data
  • Data points outside of Lower / Upper Fence boundaries are considered Outliers

Interpreting the Data

  • IQR is a measure how “compact” the samples are centered around their median. The higher the value the more the top 50% of the samples are scattered
  • Median and Average: Comparing these two will give an idea how skewed the data field is in general
  • Outliers: The number of samples outside of the “Fences” are an indication, how noisy the data is

RPi 3B

Adafruits (two different ADXL345)

  • When supplied via VIN input, the IQR is very small → Very dense 50% of the sample
  • When supplied via VIN input, the number of Outliers increase 10 fold or more
  • When supplied via 3V3 input, the IQR triples → Our normal population is spread >3 times as much as with VIN
  • When supplied via 3V3 input, the number of outliers are factor 10+ less compared to VIN

Chinese

  • The best of both worlds
  • IQR a bit worse than Adafruits VIN
  • Outliers a bit worse than Adafruits 3V3
  • Supplying the board with 3V3 or 5V makes no difference on the RPi 3B

My recommendation

  • Don’t use an Adafruit
  • If you have an Adafruit, connect it via 3V3

RPi Pico

I will omit the screenshot as it contains 41 measurements and is virtually unreadable. Refer to the attached data if you want a closer look.

Adafruits

  • The same as shown for the RPi 3B is true for the Pico as well with some additional quirks
  • When supplied via VIN input, the IQR is comparable to the RPi 3B
  • When supplied via VIN input, toggling GPIO23 high will negatively impact the number of Outliers and positively impact the IQR
  • When supplied via 3V3 input, the IQR is drastically higher compared to the RPi 3B
  • When supplied via 3V3 input, toggling GPIO23 high will negatively impact IQR but positively impact the number of Outliers (the exact opposite of the VIN behavior)
  • When supplied via 3V3 AND VIN: Very good results in both IQR and number of Outliers (@koconnor’s “strange” idea)
  • When supplied via 3V3 AND VIN, toggling GPIO23 high will negatively impact IQR but positively impact the number of Outliers (the same as the 3V3 behavior)

Chinese

  • When supplied via Pico’s 3V3 output, toggling GPIO23 high will negatively impact the number of Outliers and positively impact the IQR
  • When supplied via Pico’s 5V output, the IQR improves at the expense of the number of Outliers. I consider the results worse than 3V3 with GPIO23 high

My recommendation

  • Adafruit: Connect via 3V3 AND VIN with GPIO23 high
  • Chinese: Connect via 3V3 with GPIO23 high

Final words

  • I’m really surprised how significantly the behavior is impacted by the supply voltage and way of connecting
  • Also there seem to be significant differences between the boards (of course, these results are now my equipment, YMMV)
  • A question, which is not answered by the data: In real world measurements, is it better to have a low IQR and live with the Outliers or vice versa. In my recommendation I tried to chose either a clear winner or some middle ground.
  • Cross Check by additional people would be highly welcome
  • Doing such analysis is a pain in the back. Some support in the software would also be highly welcome (hint @dmbutyugin :wink:)

Raw Data / Spread Sheets:
Google Drive

Have you tried to bypass the level shifters on Adafruit boards? Not that end-users would do that, but to try to identify the cause.

My few cents:

  1. In most of your experiments, improving IQR makes outliers worse and vice versa. It may indicate that a model ‘Assume the noise data should be normally distributed (normal population)’ does not accurately represent the actual process. For example, it is possible that acceleration A(t) = G + V(t) + N(t), where V(t) is the random noise related to power of adxl345, and N(t) - random ambient noise independent of the powering schema (e.g. thermal noise, ambient noise of the room, etc.). Under some conditions, it could be that as you improve V(t) (make it more ‘tight’), most of the outliers out of the fence end up being from N(t). Then naturally, as you decrease IQR, the number of outliers could increase rapidly vs the wide IQR. But that wouldn’t indicate that distribution with a smaller IQR is worse, because ‘outliers’ in both cases follow the same distribution, just as you tighten the allowed range, you find more outliers from that range. I’m not saying it is necessarily like that, but at least the presented results do not exclude that possibility. It would be interesting to see how many outliers you’d get if you took a sample with small IQR, used the fence bounds from a corresponding data set with high IQR (and small number of outliers), and checked how many outliers you get then. This could help compare the cases when IQR1 < IQR2 and outliers1 > outliers2 more fairly.
  2. ‘Also there seem to be significant differences between the boards’, you are talking about Adafruit1 and Adafruit2, right? I wonder how much the results are repeatable within one board though? E.g. if you run the same test multiple times, I’d expect that you could get some different results, and this may make results of the two boards more comparable (or maybe not).
  3. ‘Don’t use an Adafruit or If you have an Adafruit, connect it via 3V3’. You seem to prefer smaller outliers and higher IQR. However, in light of (1), I may have preferred the reverse: lower IQR and potentially higher number of outliers (their number is comparatively small anyway, I understand), and in this case Adafruit boards may be more preferable. Besides, there are other considerations besides the noise: e.g. QC. With Adafruit boards, you are less likely to get a board where the chip or a capacitor are soldered the wrong way :slight_smile:
  4. ‘Connect via 3V3 AND VIN’ granted, I’m not sure why this is different that 3v3, perhaps the latter has some issues with the logic level shifters and floating VIN. However, I’d be leery of generally recommending something that is unclear why it should work (it does exclude voltage regulator from the schema altogether, and also affects the logic level shifter, but the effect of that on the noise is hard to understand). However, pure VIN variant often gives smaller IQR (at least, for adafruit1 board) on pico, so it might be more preferable.
  5. Ideally, I’d recommend the same connection schema for Pico and full RPis. If we can, say, always recommend to connect the boards via VIN/VCC - input of the voltage regulator - that would be preferable as this reduces the amount of the documentation and confusion from the users. It also makes user mistakes less likely to occur, because this has smaller mental load - you only need to remember one possible connection. Then, of course, there are printer MCUs with SPI buses, but that requires a different level of expertise from the users anyway.
  6. If the random noise is high frequency, that won’t affect the results of the resonance testing that much, if at all. Averaging the frequency response over many windows (~0.5 sec currently) reduces the noise, and high-frequency harmonics are ignored in our scripts anyway.

I took the tests basically one board at a time and in succession. The results of the boards match in their general tendency. I’d be surprised if there was a significant impact of N(t) and if then it should have been “stable” across one board

Looking at the histogram data would contradict this (forgot to mention on the diagram: X-Axis):

While VIN is more sharply centered, it has outliers in the range of 1200 to > 8200
The 3V3 is more spread (higher IQR) but outliers only between 3200 to 6200

See the attached spread-sheet. I did two additional runs with Adafruit1, Adafruit2 and Chinese.
Interesting thing is:

  • Adafruit1_0, Adafruit2_0 and Chinese_0 is from the run above
  • Adafruit2_1 and Adafruit2_2 2 days ago, taken in succession
  • Adafruit1_1, Adafruit1_2, Chinese_1, Chinese_2 yesterday in succession

Repeatability is almost spooky. Here the differences might really be ambient noise, as today my room lighting (50W LED panel) was on.
The test for repeatability also showed that derived values like IQR etc do match.

This statement was not exactly fair: Above tests omitted VIN AND 3V3 on the RPi 3B. Now in the data attached. Improvement is the same as for the Pico. Basically on par with the Chinese board.

Well, why it works is beyond my pay grade, but it works for both Pico and 3B with my two boards.
For comparison, this is the histogram between VIN and VIN AND 3V3 (This time the Y Axis, to show that the effects are comparable on all axes)

Similar to the above behavior.

I also did take a closer look at the Skew, which for sake of simplicity, I defined as abs(average - median):

  • no clear trend for the RPi 3B
  • On the Pico with GPIO23 low, the data is significantly skewed (factor 5 to 6)
  • VIN and VIN AND 3V3 are clearly better than 3V3 input only

Overall, I’d stick with my above recommendation with the exception that generally on my Adafruit boards the combined VIN AND 3V3 input is preferable

Amended RPi 3B data: Google Drive