Getting Vario (m/s) from a bmp180
If you add an accelerometer to the project, a Kalman filter can give a good estimation of vertical speed.

With only a barometric sensor, I don't think it's possible to reduce the lag below 1 second.



import numpy as np
import matplotlib.pyplot as plt
import random

from filterpy.kalman import KalmanFilter
from filterpy.common import Q_discrete_white_noise

random.seed(65537)

# Standard deviation of simulated sensor data
std_a = 0.075
std_h = 0.42

# Earth gravity
g_n = 9.80665

# Sensor sample period, s
dt = 0.05

kf1 = KalmanFilter(dim_x=2, dim_z=1)
kf1.H = np.array([[1, 0]])
kf1.F = np.array([[1, dt], [0, 1]])

kf2 = KalmanFilter(dim_x=3, dim_z=2)
kf2.H = np.array([[1, 0, 0], [0, 0, 1]])
kf2.F = np.array([[1, dt, dt * dt * 0.5], [0, 1, dt], [0, 0, 1]])

# initial process covariance
kf1.P = np.array([[1, 0], [0, 0.01]])
kf2.P = np.array([[std_h * std_h, 0, 0], [0, 0.0001, 0], [0, 0, std_a * std_a]])

# Process noise matrix
std = 0.0039
var = std * std
kf1.Q = Q_discrete_white_noise(dim=2, dt=dt, var=0.0625)
kf2.Q = Q_discrete_white_noise(dim=3, dt=dt, var=var)

# Measurement covariance
kf1.R *= np.array([[std_h * std_h]])
kf2.R *= np.array([[std_h * std_h, 0], [0, std_a * std_a]])

n = 300
r_n = 1.0 / n

t = np.zeros(n)
h_sim = np.zeros(n)
v_sim = np.zeros(n)
a_sim = np.zeros(n)
measured_h = np.zeros(n)
measured_a = np.zeros(n)
v_est_kf1 = np.zeros(n)
v_est_kf2 = np.zeros(n)

v0 = 0
v = v0
h = 0

for i in range(n):
    t[i] = (i * dt)
    a = 1.0 / 32 * g_n * np.sin(4 * np.pi * i * r_n)
    a_sim[i] = (a)
    v += a * dt
    v_sim[i] = v
    h += v * dt + (a * dt * dt) / 2
    h_sim[i] = h
    measured_a[i] = a + random.gauss(0, std_a)
    measured_h[i] = h + random.gauss(0, std_h)

# Compute the speed estimations

for i in range(n):
    kf1.predict()
    kf1.update(np.array([measured_h[i]]))
    v_est_kf1[i] = kf1.x[1]

    kf2.predict()
    kf2.update(np.array([[measured_h[i]], [measured_a[i]]]))
    v_est_kf2[i] = kf2.x[1]

# Plot the results

plt.figure(1, figsize=(8, 12), dpi=80)

plt.subplot(311)
plt.axis([0, n * dt, -0.75, 0.75])
plt.plot(t, measured_a, 'y+')
plt.plot(t, a_sim, 'r')
plt.title('Vertical acceleration - gravity, m/s^2')
plt.legend(('Measured', 'True (simulation)'), loc='best')

plt.subplot(312)
plt.axis([0, n * dt, -1, 7])
plt.plot(t, measured_h, 'c+')
plt.plot(t, h_sim, 'b')
plt.title('Altitude, m')
plt.legend(('Measured', 'True (simulation)'), loc='best')

plt.subplot(313)
plt.axis([0, n * dt, -0.5, 1.0])
plt.plot(t, v_sim, 'b')
plt.plot(t, v_est_kf1, 'r')
plt.plot(t, v_est_kf2, 'c')
plt.title('Vertical speed, m/s')
plt.legend(('True (simulation)', 'Kalman filter (1 sensor)', 'Kalman filter (2 sensors)'), loc='best')

plt.savefig('kalman_vsi.svg')
plt.show()


After some experiments with simulated sensor data, I wrote an Android app that uses smartphone sensors. Source code on GitHub