Timers Technical Report (ENTER NAME AND NET ID HERE)

BME554L - Fall 2025 - Palmeri

Lab
Author

Dr. Mark Palmeri, M.D., Ph.D.

Methods

Briefly describe what your did for each type of data acquisition (e.g., how did you capture the logging data and save data from the oscilloscope).

The code below is just starter / example code that you can use to help guide how you approach doing this analysis. Feel free to use other analysis approaches if you are more comfortable with them, as long as you can draw the same conclusions from your testing.

Data Analysis

# import useful packages for data analysis
import numpy as np
import scipy as sp
import matplotlib.pyplot as plt
import pandas as pd

Logging Data

# import data from CSV or similar files
# DO NOT copy/paste raw data into the notebook directly (!); data should be independent on this notebook
timing_data = pd.read_csv('log_data.csv')

# consider showing a snippet of the raw data too
timing_data.head(20)
Ideal Period (ms) Measurement Period (ms)
0 1000 1005
1 1000 1003
2 1000 1001
3 1000 990
4 1000 995
5 500 490
6 500 495
7 500 497
8 500 492
9 500 491
10 2000 2100
11 2000 2000
12 2000 2300
13 2000 1900
14 2000 1950
# display a plot or table of the data, along with the nominal values
timing_data.groupby('Ideal Period (ms)')['Measurement Period (ms)'].describe() 
count mean std min 25% 50% 75% max
Ideal Period (ms)
500 5.0 493.0 2.915476 490.0 491.0 492.0 495.0 497.0
1000 5.0 998.8 6.180615 990.0 995.0 1001.0 1003.0 1005.0
2000 5.0 2050.0 158.113883 1900.0 1950.0 2000.0 2100.0 2300.0
# calculate the 95% confidence interval for the mean timing interval
confidence_interval = timing_data.groupby('Ideal Period (ms)')['Measurement Period (ms)'].apply(
    lambda x: sp.stats.t.interval(0.95, len(x)-1, loc=np.mean(x), scale=sp.stats.sem(x))
)
print(confidence_interval)
Ideal Period (ms)
500      (489.3799584784563, 496.6200415215437)
1000    (991.1257530463614, 1006.4742469536385)
2000    (1853.675683852244, 2246.3243161477562)
Name: Measurement Period (ms), dtype: object

Oscilloscope Data

# import data from CSV or similar files
# DO NOT copy/paste raw data into the notebook directly (!); data should be independent on this notebook
timing_data = pd.read_csv('oscope_data.csv')

# consider showing a snippet of the raw data too
timing_data.head(20)
Ideal Period (ms) Measurement Period (ms)
0 1000 1005
1 1000 1003
2 1000 1001
3 1000 990
4 1000 995
5 500 490
6 500 495
7 500 497
8 500 492
9 500 491
10 2000 2100
11 2000 2000
12 2000 2300
13 2000 1900
14 2000 1950
# display a plot or table of the data, along with the nominal values
timing_data.groupby('Ideal Period (ms)')['Measurement Period (ms)'].describe() 
count mean std min 25% 50% 75% max
Ideal Period (ms)
500 5.0 493.0 2.915476 490.0 491.0 492.0 495.0 497.0
1000 5.0 998.8 6.180615 990.0 995.0 1001.0 1003.0 1005.0
2000 5.0 2050.0 158.113883 1900.0 1950.0 2000.0 2100.0 2300.0
# calculate the 95% confidence interval for the mean timing interval
confidence_interval = timing_data.groupby('Ideal Period (ms)')['Measurement Period (ms)'].apply(
    lambda x: sp.stats.t.interval(0.95, len(x)-1, loc=np.mean(x), scale=sp.stats.sem(x))
)
print(confidence_interval)

Discussion

How do your logging-based data and oscilloscope data compare to the nominal timing intervals?

Which measurement approach is more accurate?