Нужно доработать скетч

otwertka
Offline
Зарегистрирован: 14.09.2014

Ищу исполнителя по доработке скетча. Нужно сделать вариометр альтиметр на базе BMP180+LCD Nokia1100.

Имеется

#include <Wire.h> // i2c library
#include <BMP085.h> // bmp085 library, download from url link (1)
#include <Tone.h> // tone library, download from url link (3)
#include <stdlib.h> // we need that to use dtostrf() and convert float to string
#include <stdarg.h>

#define UART_SPEED 9600
short SPEAKER_PIN1 = 11; // Speaker output -
short SPEAKER_PIN2 = 12; // Speaker output +
short LED_PIN = 13;

Tone speaker1, speaker2;
BMP085 bmp085 = BMP085(); // BMP085 sensor

const float SEA_LEVEL_PRESSURE = 101325; // Pressure at sea level (Pa)
const float KF_VAR_MEASUREMENT = 0.1; // Variance of pressure measurement noise.
const float KF_VAR_ACCEL = 0.75; // Variance of pressure acceleration noise input.

float CLIMB_TONE2_MULT;
float SINK_TONE2_MULT;

float kf_x_abs,
kf_x_vel,
kf_p_abs_abs,
kf_p_abs_vel,
kf_p_vel_vel,
kf_var_accel;

#define VARIOS_LEN 5
int varios[VARIOS_LEN];
int varios_pos = 0, varios_sum = 0;

void p(char *fmt, ... ){
char tmp[128]; // resulting string limited to 128 chars
va_list args;
va_start (args, fmt );
vsnprintf(tmp, 128, fmt, args);
va_end (args);
Serial.print(tmp);
}

void kf_reset(float abs_value, float vel_value) {
kf_x_abs = abs_value;
kf_x_vel = vel_value;
kf_p_abs_abs = 1000000000;
kf_p_abs_vel = 0;
kf_p_vel_vel = KF_VAR_ACCEL;
kf_var_accel = KF_VAR_ACCEL;

varios_sum = 0;
for (int i = 0; i < VARIOS_LEN; i++) varios[i] = 0;
varios_pos = 0;
}

void setup() {
Serial.begin(UART_SPEED); // set up arduino serial port
Wire.begin(); // lets init i2c protocol
speaker1.begin(SPEAKER_PIN1); // piezo speaker output -
speaker2.begin(SPEAKER_PIN2); // piezo speaker output +
digitalWrite(SPEAKER_PIN2, LOW);

bmp085.init(MODE_ULTRA_HIGHRES, SEA_LEVEL_PRESSURE, false);

kf_reset(SEA_LEVEL_PRESSURE, 0);

CLIMB_TONE2_MULT = pow(2, 9/12);
SINK_TONE2_MULT = pow(2, 1/12);

welcome(); //everything is ready, play "welcome" sound
}

void welcome() {
speaker1.play(300, 50); // (note, duration)
delay(100);
speaker2.play(300, 50); // (note, duration)
delay(100);
Serial.println("Vario is ready");
}

float pressure2altitude(float pressure) {
return (float)44330 * (1 - pow(((float)(pressure)/SEA_LEVEL_PRESSURE), 0.190295));
}

float last_time = 0;
void update_pressure() {
long pressure;
bmp085.calcTruePressure(&pressure);

float time = millis();
float dt = (time - last_time) / 1000;
last_time = time;

/* Kalman Filter code */
kf_x_abs += kf_x_vel * dt;

kf_p_abs_abs += (float)2 * dt * kf_p_abs_vel + dt * dt * kf_p_vel_vel + kf_var_accel * dt * dt * dt * dt / (float)4;
kf_p_abs_vel += dt * kf_p_vel_vel + kf_var_accel * dt * dt * dt / (float)2;
kf_p_vel_vel += + kf_var_accel * dt * dt;

// Update state covariance. The last term mixes in acceleration noise.
float y = pressure - kf_x_abs; // Innovation.
float s_inv = 1.0 / (kf_p_abs_abs + KF_VAR_MEASUREMENT); // Innovation precision.
float k_abs = kf_p_abs_abs * s_inv; // Kalman gain
float k_vel = kf_p_abs_vel * s_inv;

// Update state estimate.
kf_x_abs += k_abs * y;
kf_x_vel += k_vel * y;

// Update state covariance.
kf_p_vel_vel -= kf_p_abs_vel * k_vel;
kf_p_abs_vel -= kf_p_abs_vel * k_abs;
kf_p_abs_abs -= kf_p_abs_abs * k_abs;
}

int avg_vario() {
float altitude = pressure2altitude(kf_x_abs);
int vario = (int)((altitude - pressure2altitude(kf_x_abs - kf_x_vel)) * 100);

varios_sum += vario;
varios_sum -= varios[varios_pos];
varios[varios_pos] = vario;

if (++varios_pos == VARIOS_LEN) varios_pos = 0;
return varios_sum / VARIOS_LEN;
}

int CLIMB_RATE_START = 25,
SINK_RATE_START = -80;

int loop_id = 0;
unsigned long next_signal_time = 0;
void loop() {
update_pressure();
int vario = avg_vario();

unsigned long time = millis();
if (time >= next_signal_time) {
if (vario > CLIMB_RATE_START) {
long beep_period = 350 - vario / 2;
if (beep_period < 20) beep_period = 20;

int silence_period = beep_period / 16;
int tone = 1300 + vario;
if (tone > 2300) tone = 2300;

next_signal_time = time +
beep_period + silence_period;
speaker1.play(tone, beep_period);

Serial.print("CLIMB beep:");
Serial.print(beep_period);
Serial.print(" silence:");
Serial.print(silence_period);
Serial.print(" vario: ");
Serial.println(vario);
} else if (vario < SINK_RATE_START) {
// int beep_period = 350 * 50 / (-vario);
// int silence_period = beep_period / 5;
int beep_period = 350 + vario / 2;
if (beep_period < 20) beep_period = 20;
int silence_period = beep_period / 16;
int tone = 1000 + vario;
if (tone < 300) tone = 300;

next_signal_time = time + beep_period + silence_period;
speaker1.play(tone, beep_period); // (note, duration)

Serial.print("SINK beep:");
Serial.print(beep_period);
Serial.print(" silence:");
Serial.print(silence_period);
Serial.print(" vario: ");
Serial.println(vario);
}
}

loop_id++;
if ((loop_id % 10) == 0) {
Serial.print("vario: ");
Serial.println(vario);
}

if ((loop_id % 10) == 0) {
digitalWrite(LED_PIN, LOW);
}
if ((loop_id % 10) == 5) {
digitalWrite(LED_PIN, HIGH);
}
}

Нужно чтобы на дисплей выводились данные о температуре в цельсиях, скороподъемности м/сек, высоте над уровнем моря H1, так же имелась высота H2 которую можно обнулять кнопкой.  Диод 13 должен мигать при наборе высоты , но при этом не мигать при сливе. Более подробное тех задание  в личку. 

otwertka_kam@mail.ru

faraddin
Offline
Зарегистрирован: 11.08.2013

Параплан?

Я сейчас глянул цены. Получается вариометр можно за сущие компейки собрать.. Надо попробовать сделать. Спасибо за идею. Если я это реализую и код к тому времени Вам все еще будет нужен - вышлю.

otwertka
Offline
Зарегистрирован: 14.09.2014

Да параплан! Спасибо, может к тому времени и у меня будет какой информацией поделиться!

korbus
Offline
Зарегистрирован: 27.07.2016

Здравствуйте, скажите, получилось ли у Вас собрать прибор?

korbus
Offline
Зарегистрирован: 27.07.2016

Здравствуйте, скажите, получилось ли у Вас собрать прибор?