ARDUINO Альтиметр и пороговое значение...

Mefistophel

✩✩✩✩✩✩✩
16 Авг 2018
25
0
Актюбинск
Здравствуйте!
Задача альтиметра, дать сигнал на определённой высоте, но проблема в том, что эта высота будет зафиксирована дважды. Как проигнорировать первую регистрацию? Я не прошу готового кода, но буду благодарен за объяснение, желательно "на пальцах"))
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,272
1,303
Москва
Почти готовое решение.
f=false
if (высота=порог)
{
if (f) дать сигнал;
f=true
}

Самое простое, но мне оно не нравится. Альтиметр может проскочить точный порог. Поэтому нужно округление. Но как пример пойдет.
 
Изменено:

Mefistophel

✩✩✩✩✩✩✩
16 Авг 2018
25
0
Актюбинск
Почти готовое решение.
f=false
if (высота=порог)
if (f) дать сигнал
f=true

Самое простое, но мне оно не нравится. Альтиметр может проскочить точный порог. Поэтому нужно округление. Но как пример пойдет.
не пойдёт, условие - высота будет пересечена ДВАЖДЫ, а отработать нужно только второе прохождение...
у меня, пока, реализовано как обработка до (≤Х), потом переход в обработку (≥Х), но это костылинг... наверняка есть более изящное решение...
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,272
1,303
Москва
Поставил скобки, торопился, отходил. вот посмотри что будет по примеру
f равно фальш
тогда при высоте равной порогу сигнала не будет. будет f равно истина, и только после 2-го прохождения f будет истина. Смотрите ширше. и начально значение должно быть до цикла. Что ж все разжевывать то надо
 

Mefistophel

✩✩✩✩✩✩✩
16 Авг 2018
25
0
Актюбинск
Для начала - схема:
фкв.jpg
И некоторые уточнения. Это модуль системы спасения летательного аппарата, а точнее, уже вторая его ступень - выброс парашюта. Первая ступень, на выбросе ленты, реализована на определении начала снижения аппарата. Тут затруднений не возникло (хоть и лютый пионер с этом).
Скорость отрыва аппарата - 93км/ч, скорость в пике - 1028км/ч. Учитывая, что датчик может 157 раз в секунду, до на скоростях, близких к максимальным - разница показаний, между замерами, будет достигать 1,8 метра...
Получается, что и округление несильно поможет, нужно именно ≤ .

Добавлено:
Несколько раз просмотрел ваш пример... Разве не два условия должно быть? Первое для фол, второе для тру?
 
Изменено:

Старик Похабыч

★★★★★★★
14 Авг 2019
4,272
1,303
Москва
Для тру есть, вот оно if (f) дать сигнал;
а для фол какое ? ничего не делать ? Ну можно добавить если "фол", то f=тру. Но даже и без условия оно будет тру. Это если пороговое значение меняется только 2 раза.
Но я бы сделал условие на изменение высоты, если высота уменьшается и пороговое значение меньше критического. А так же можно еще скорость уменьшения вычислять.
 

Mefistophel

✩✩✩✩✩✩✩
16 Авг 2018
25
0
Актюбинск
Уж простите, но никак не пойму...

мы задали f=false,
аппарат улетел, пересек пороговую высоту,
сработало условие if (высота=порог) if (f) дать сигнал
переменная приняла (true)
Получается, что аппарат продолжает подниматься, но сигнал на срабатывание системы торможения уже дан...
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,272
1,303
Москва
if (f) сработает тлько если f== true. И далее в этом же блоке f станет true но позже. Срабатываение будет на 2-ой раз.
Если с логическими переменным сложно , то берите числа

при объявлении переменных
тестовое число равно 0

в рабочем цикле :
если высота равна порогу, то тестовое число увеличить на 1.
если тестовое число больше 1 то сработать парашюту.
 

bort707

★★★★★★✩
21 Сен 2020
3,067
916
@Mefistophel, вы не точно формулируете задачу. Посмотрите на это под другим углом. Смысл ведь не в том, чтобы отследить ВТОРОЕ пересечение высоты. Смысл в том, чтобы устройство сработало при падении.
Условие падения очень простое - каждая следующая высота меньше предыдущей. Вот на это и ориентируйтесь. То есть вам нужно отследить такой момент, когда предыдущая высота была больше "высоты Х", а текущая - меньше. А второе это будет пересечение или первое - совершенно не важно.
 
Изменено:
  • Лойс +1
Реакции: Mefistophel

DAK

★★★✩✩✩✩
8 Окт 2020
517
137
Почти готовое решение.
f=false
if (высота=порог)
{
if (f) дать сигнал;
f=true
}

Самое простое, но мне оно не нравится. Альтиметр может проскочить точный порог. Поэтому нужно округление. Но как пример пойдет.
Может немного непонятно человеку...
До цикла loop нужно сделать f=false;
В цикле
C++:
if (!f){
  if (высота>порог)
    {
    f=true
    }
}else{
  if (высота<порог)
  {
  Дать сигнал на торможение
  }
}
 
Изменено:

Nikanor

★★✩✩✩✩✩
1 Окт 2020
178
51
может так понятнее будет.
на картинке выше три участка полёта - до порога. выше порога - падение ниже порога.

C++:
byte state = 0;

if (state == 0 && высота>порог)
    {
    state = 1;
    }
else if if (state == 1 && высота<=порог)
  {
    state = 2;
    Дать сигнал на торможение
  }
 
Изменено:
  • Лойс +1
Реакции: Mefistophel

Старик Похабыч

★★★★★★★
14 Авг 2019
4,272
1,303
Москва
Видимо это по мотивам амперки строиться ракет. Ну или без мотивов. Тогда там точно будет только 2 пересечения пороговой высоты. Я то в голове представлял самолет, который может летать туда-сюда, а вот ракета тогда точно попадает под указанные параметры. тогда цикл надо делать примерно так:

переменные
порог=какое то значение
старая_высота=0
высота=0

цикл луп
высота=считатьвысотус_альтиметира
если (высота-старая_высота) меньше 0 то // опускаемся!
{
если высота меньше или равна порогу то выкинуть парашют!
}
конец цикла луп
 
  • Лойс +1
Реакции: Mefistophel

Mefistophel

✩✩✩✩✩✩✩
16 Авг 2018
25
0
Актюбинск
Всем большое спасибо, пойду разбираться...

Ещё вопрос, что вы думаете за Ardublock, он зло - или добро?
 

Mefistophel

✩✩✩✩✩✩✩
16 Авг 2018
25
0
Актюбинск
Для меня зло злющее.
Но кому то в пользу.
40 лет, всю жизнь работал "в цеху" строитель, водитель, грузчик. Обучаться уже трудно, уже не та гибкость ума, но стараюсь. Леплю в Ardublock и анализирую Arduino-код, ищу причинно-следственные связи.
Делаю с потомками самолёты на любительском уровне. Требуют ракету, ну, если уж будем делать ракету, то, почему бы не собрать и "бортовой самописец"?))
Пока имеем это:
C++:
#include <iarduino_Pressure_BMP.h>
iarduino_Pressure_BMP sensor(0x77);
float bmppressure;
float bmptemperature;
float bmpaltitude;
float bmppressure2;
#include <SPI.h>
#include <SD.h>
#include <iarduino_RTC.h>
float  Alt_Start;
float  Alt_Moment;
long  Time;
float  Press;
float  Temp;
iarduino_RTC time(RTC_DS1302, 8,6,7);
void sd_print(String file, String texttoprint, boolean lf)
  {
   File sd_file;
    sd_file = SD.open(file, FILE_WRITE);
  if(sd_file){
    if(lf)sd_file.println(texttoprint);
    else sd_file.print(texttoprint);
    sd_file.close();
  }
}
void setup()
{
   Alt_Start = 0;
   Alt_Moment = 0;
   Time = 0;
   Press = 0;
   Temp = 0;
  sensor.begin();
  SD.begin(10);
     time.begin();
   Time = time.gettime("H:i:s");
     if(sensor.read(1)){
      bmppressure = sensor.pressure;
      bmptemperature = sensor.temperature;
      bmpaltitude = sensor.altitude;
    }
        if(sensor.read(2)){
      bmppressure2 = sensor.pressure;
     }
   Alt_Moment = bmpaltitude;
   Temp = bmptemperature;
   Press = bmppressure2;
}
void loop()
{
    sd_print("fly_logs.txt",(String(Time) + String(Alt_Moment) + String(Press) + String(Temp)),true);
    if (Alt_Moment > Alt_Start) {
      if (Alt_Moment < Alt_Start) {
        if (Alt_Moment <= 50) {
          pinMode(21, OUTPUT);
           digitalWrite(21,HIGH);
           Alt_Start = Alt_Moment;
        }
         Alt_Start = Alt_Moment;
      }
      pinMode(20, OUTPUT);
       digitalWrite(20,HIGH);
       Alt_Start = Alt_Moment;
    }
     Alt_Start = Alt_Moment;
}
Уже понятно, что со скоростями ракеты - переменная "Time" будет меняться не часто, а хотелось бы отслеживать динамику. Есть ли возможность отслеживания долей секунды?
 

Mefistophel

✩✩✩✩✩✩✩
16 Авг 2018
25
0
Актюбинск
Выбросил переменную "Time", 51 строка изменена как:
sd_print("fly_logs.txt",(String(time.gettime("H:i:s")) + String(Alt_Moment) + String(Press) + String(Temp)),true);
 

Эдуард Анисимов

★★★★★★✩
23 Сен 2019
2,412
978
58
Марий-Эл
Есть ли возможность отслеживания долей секунды?
Вместо DS1302 возьмите DS3231.
У него есть выход, который можно запрограммировать на 1Гц, 1024Гц, 4096Гц, 8192Гц и 32768Гц.
Подключается на прерывания микроконтроллера и в прерывании можно поднять флаг а в теле цикла при появлении этого флага запомнить где то то что Вам нужно. Лишь бы эта операция заканчивалась раньше, чем появится новое прерывание.
 
  • Лойс +1
Реакции: Mefistophel

DAK

★★★✩✩✩✩
8 Окт 2020
517
137
Код не могу понять, если условие в 52 строчке сработает, то вложенное условие в 53 строчке вроде не должно работать.. Что именно должен делать чёрный ящик кроме чтения параметров и записи их на sd?
 

Mefistophel

✩✩✩✩✩✩✩
16 Авг 2018
25
0
Актюбинск
Код не могу понять, если условие в 52 строчке сработает, то вложенное условие в 53 строчке вроде не должно работать.. Что именно должен делать чёрный ящик кроме чтения параметров и записи их на sd?
Там идёт постоянное сравнивание и перезапись данных, так что, рано ли поздно, условие выполнится...
Назначение: отслеживать начало снижения (выброс тормозной ленты) и пороговой высоты (выброс парашюта). После правок ошибок имеем:
C++:
#include <iarduino_Pressure_BMP.h>
iarduino_Pressure_BMP sensor(0x77);
float bmppressure;
float bmptemperature;
float bmpaltitude;
float bmppressure2;
#include <SPI.h>
#include <SD.h>
#include <iarduino_RTC.h>
float  Alt_Start;
float  Alt_Moment;
float  Press;
float  Temp;
iarduino_RTC time(RTC_DS1302, 8,6,7);
void sd_print(String file, String texttoprint, boolean lf)
  {
   File sd_file; sd_file = SD.open(file, FILE_WRITE);
  if(sd_file){if(lf)sd_file.println(texttoprint); else sd_file.print(texttoprint); sd_file.close();}
}
void setup()
{
   Alt_Start = 0; //Базовая высота
   Alt_Moment = 0; //Текущая высота
   Press = 0; //Текущее давление
   Temp = 0; //Текущая температура
  sensor.begin();
  SD.begin(10);
     time.begin();
}
void loop()
{
       if(sensor.read(1)){bmppressure = sensor.pressure; bmptemperature = sensor.temperature; bmpaltitude = sensor.altitude;}
          if(sensor.read(2)){bmppressure2 = sensor.pressure;}
     Temp = bmptemperature; //Получение текущей температуры
     Press = bmppressure2; //Получение текущего давления
     Alt_Moment = bmpaltitude; //Получение текущей высоты
   //Если текущая высота больше базовой (идёт подъём)
    if (Alt_Moment > Alt_Start) {
   //Если текущая высота меньше базовой (идёт спуск)
      if (Alt_Moment < Alt_Start) {
   //Если текущая высота меньше пороговой
        if (Alt_Moment <= 50) {
          pinMode(21, OUTPUT); digitalWrite(21,HIGH); //Сигнал на выброс парашюта
          Alt_Start = Alt_Moment;}
         Alt_Start = Alt_Moment;}
      pinMode(20, OUTPUT); digitalWrite(20,HIGH); Alt_Start = Alt_Moment;} //Сигнал на выброс тормозной ленты
     Alt_Start = Alt_Moment;
    sd_print("fly_logs.txt",(String(time.gettime("H:i:s")) + String(Alt_Moment) + String(Press) + String(Temp)),true); //Записываем текущие данные
    delay(10);
}
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,272
1,303
Москва
Вы опять запутались. Смотрим условие подробно и подтсавляем конкретные тестовые числа:

C++:
if (Alt_Moment > Alt_Start) {
    if (Alt_Moment < Alt_Start) {
      if (Alt_Moment <= 50) {
        pinMode(21, OUTPUT);
        digitalWrite(21, HIGH);
        Alt_Start = Alt_Moment;
      }
      Alt_Start = Alt_Moment;
    }
    pinMode(20, OUTPUT);
    digitalWrite(20, HIGH);
    Alt_Start = Alt_Moment;
  }
  Alt_Start = Alt_Moment;
Alt_Start=0
АльтМомент=0 (буду писать так, что бы не переключаться)
цикл 1. АльтМомент Больше АльтСтарта ? нет. В условие не заходим.
АльтСтарт=АльтМомент
цикл 2. АльтМомент Больше АльтСтарта ? нет. В условие не заходим.
АльтСтарт=АльтМомент
И так до бесконечности.
Допустим в какой то момент, который тут надо предусмотреть ракета полетела и АльтМомент будет скажем 10. Что будет ?
АльтМомент больше АльтСТратр ? Да! Заходим в условие
АльтМомент меньше АльтСТрать? Нет! и в условие уже не заходим. И никогда не зайдем!
А далее по кругу
 
  • Лойс +1
Реакции: DAK

DAK

★★★✩✩✩✩
8 Окт 2020
517
137
Вряд ли условие в 40 строчке сможет сработать. Я с телефона, жутко неудобно, но надо бы подправить, я бы всё вычисления делал только в случае чтения параметров датчика альтиметра, что будет, если вдруг датчик не прочитается.... А по поводу условия... Для запуска условия в 40 строке, надо, чтобы условие в 38 было истиной. А если в 38 строке будет true, то в 40 будет false

Вы опять запутались. Смотрим условие подробно и подтсавляем конкретные тестовые числа:

C++:
if (Alt_Moment > Alt_Start) {
    if (Alt_Moment < Alt_Start) {
      if (Alt_Moment <= 50) {
        pinMode(21, OUTPUT);
        digitalWrite(21, HIGH);
        Alt_Start = Alt_Moment;
      }
      Alt_Start = Alt_Moment;
    }
    pinMode(20, OUTPUT);
    digitalWrite(20, HIGH);
    Alt_Start = Alt_Moment;
  }
  Alt_Start = Alt_Moment;
Alt_Start=0
АльтМомент=0 (буду писать так, что бы не переключаться)
цикл 1. АльтМомент Больше АльтСтарта ? нет. В условие не заходим.
АльтСтарт=АльтМомент
цикл 2. АльтМомент Больше АльтСтарта ? нет. В условие не заходим.
АльтСтарт=АльтМомент
И так до бесконечности.
Допустим в какой то момент, который тут надо предусмотреть ракета полетела и АльтМомент будет скажем 10. Что будет ?
АльтМомент больше АльтСТратр ? Да! Заходим в условие
АльтМомент меньше АльтСТрать? Нет! и в условие уже не заходим. И никогда не зайдем!
А далее по кругу
Помоги человеку, подправь, пусть с мужиками ракету запустят....
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,272
1,303
Москва
Ну он пока справляется почти. Надо чуть подсказывать. А это лучше чем сделать все за него. Если будет трудно -скажет, я думаю.
 

Mefistophel

✩✩✩✩✩✩✩
16 Авг 2018
25
0
Актюбинск
АльтМомент меньше АльтСТрать? Нет! и в условие уже не заходим. И никогда не зайдем!
А далее по кругу
ну почему не зайдём? рано или поздно, ракета начнёт снижение... В каждом цикле, после сравнения, идёт перезапись АльтСтарт данными из АльтМомент:
0 равно 0
10 больше 0
перепишем
20 больше 10
перепишем
30 больше 20
перепишем
.........................
1000 больше 900
перепишем
900 меньше 1000
входим во вложенное условие:
800 меньше 900
перепишем
......................
100 меньше 200
перепишем

Чёрт... в цикле, я не обновляю Альт_Момент! Нужно это исправить...
А вот дальше, действительно, затык... Как подключить третий уровень вложенности? Ведь второй просто будет ЛУПить до падения...

Помоги человеку, подправь, пусть с мужиками ракету запустят....
Категорически против, так ничему не научишься, от толчка в нужную сторону - не откажусь... Но готового кода - не приму...