PortableBalanceLab / PBL

Learn how to create your own balance lab using python and a Raspberry Pi
4 stars 1 forks source link

Ensure `S4` EMG lab as-written actually samples at the correct rate (etc.) #15

Open adamkewley opened 1 year ago

adamkewley commented 1 year ago

High-prio: the lab was delivered in 2022, but it required sampling at a much lower frequency than desired because the library/hardware that was used was faulty.

The S4 lab experiment worked in 2022 but students consistently reported that their sampling rate was lower than expected. The reason (we think) was that the software library used in S4 was not able to sample at the rate that the hardware was advertized to sample at.

Whoever works this ticket has to:

adamkewley commented 1 year ago

@JanneLuijten I've only recently had time to look into the code behind the EMG. You probably already know this information, but, based on the source code, the recommendation I'd have is:

# BEFORE
ads = ADS.ADS1115(i2c)

# AFTER: change mode
from adafruit_ads1x15.ads1x15 import Mode
ads = ADS.ADS1115(i2c, mode=Mode.CONTINUOUS)

# ALTERNATIVELY: change data rate (default is 128: https://github.com/adafruit/Adafruit_CircuitPython_ADS1x15/blob/main/adafruit_ads1x15/ads1115.py#L69)
ads = ADS.ADS1115(i2c, data_rate=256)

Notes:

The ADS1115 class (parent class: ADS1x15) can take a data rate:

Which seems to affect non-continuous mode:

(the mode flag is):

So, for students in 2023, I'd recommend:

Example fixes:

# BEFORE
ads = ADS.ADS1115(i2c)

# AFTER: change mode
from adafruit_ads1x15.ads1x15 import Mode
ads = ADS.ADS1115(i2c, mode=Mode.CONTINUOUS)

# AFTER: change data rate (default is 128: https://github.com/adafruit/Adafruit_CircuitPython_ADS1x15/blob/main/adafruit_ads1x15/ads1115.py#L69)
ads = ADS.ADS1115(i2c, data_rate=256)

I also looked at the lower-level I2C class, but that is deeper inside Adafruit_Blinka. The relevant class code is in busio:

It internally allocates a concrete i2c connection based on what it has detected as connected to the Pi, but we're really digging into the weeds to figure out where, if anywhere, there's an optimization route:

The only recommendation I'd have for I2C is to try different frequency arguments: