Высотомер

gmurvs
Offline
Зарегистрирован: 15.04.2014

Конфигурация - nano + bmp085 + lipo
Предназначение - запись последовательности 500 значений высоты в EEPROM после преодоления минимального порога высоты. В Serial выводится лог при подключении к ПК.

//nano + bmp085 + lipo
//запись последовательности 500 значений высоты в EEPROM
//после преодоления минимального порога высоты
//в Serial выводится лог


#include <EEPROM.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>

const int altitudeArrSize = 500;
int altitudeArr[altitudeArrSize]; //массив 500 измерений высоты, приведенной к int (2-а байта), измерения делаются каждые 1/10 секунды
int altitudeArrC = 0; //счетчик измерений
unsigned long altitudeArrTimer;

Adafruit_BMP085 bmp;

int altitude;
int altitudeNorm;
const byte altitudeJmp = 2;
int maxAltitude;
int maxAltitudeEEPROM;
byte altitudeMode;

void EEPROMWriteInt(int p_address, int p_value)
{
  byte lowByte = EEPROM.read(p_address);
  byte highByte = EEPROM.read(p_address + 1);
  int val = ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);

  if (val != p_value) {
    byte lowByte = ((p_value >> 0) & 0xFF);
    byte highByte = ((p_value >> 8) & 0xFF);

    EEPROM.write(p_address, lowByte);
    EEPROM.write(p_address + 1, highByte);
  }
}

//This function will read a 2 byte integer from the eeprom at the specified address and address + 1
int EEPROMReadInt(int p_address)
{
  byte lowByte = EEPROM.read(p_address);
  byte highByte = EEPROM.read(p_address + 1);

  return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
}


void setup(void) //**************************************************************************************************************
{
  //for(int i = 0; i < 1024; i++) EEPROMWriteInt(i,0); // иногда нужно обнулить память для отладки

  Serial.begin(9600);

  bmp.begin();

  // чтение максимальной высоты из EEPROM
  maxAltitudeEEPROM = EEPROMReadInt(0);

// запоминаем начальное значение высоты
  altitudeNorm = bmp.readAltitude();
  
  //выводим 500 значений лога высоты предыдущего полета

  Serial.print("max altitude of previos fly is    ");
  Serial.print(maxAltitudeEEPROM);
  Serial.println(" meter");
  Serial.println();
  Serial.println("altitude of previos fly is    ");
  float j = 0;
  for(int i = 2; i < 1020; i+=2) {
    Serial.print("time ");
    Serial.print(j);
    j+=1/20.00;
    Serial.print(" - ");
    Serial.print(EEPROMReadInt(i));    
    Serial.println();
  }
  //переводимся в режим ожидания взлета
  altitudeMode = 1;
}

void loop(void) //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{
  altitude = bmp.readAltitude() - altitudeNorm;

  if (altitude > maxAltitude) {
    maxAltitude = altitude;
  }

  if (maxAltitude > maxAltitudeEEPROM){
    maxAltitudeEEPROM = maxAltitude;
    EEPROMWriteInt(0, int(maxAltitudeEEPROM));
  }

  switch (altitudeMode) {
  case 0:
    // do nothing
    break;
  case 1://ждем взлет
    if (altitude > altitudeJmp){ //значит начали лететь, переводимся из режима ожидания в режим записи высоты
      altitudeMode = 2;
    }
    break;
  case 2:
    if (altitudeArrTimer < millis()){
      altitudeArrTimer = millis() + 50; 
      //запись в массив
      //сохраняем высоту каждые 50 миллисекунд
      altitudeArr[altitudeArrC] = int(altitude);
      altitudeArrC++;
      if (altitudeArrC == altitudeArrSize){
        //запись массива в EEPROM
        for(int i = 0; i < altitudeArrSize; i++) EEPROMWriteInt(2+i+i,altitudeArr[i]);
        altitudeMode = 0;
      }
    }
    break;
  }


}


 

gmurvs
Offline
Зарегистрирован: 15.04.2014
#include <Adafruit_BMP085.h>

#include <EEPROM.h>
#include <Wire.h>

#include  <avr/sleep.h>
#include  <avr/wdt.h>

const byte RF_PIN = 13;
const byte SPLITTER = 200;
const int DURATION_0 = 550;
const int DURATION_1 = 350;
const int DURATION_R = 1000;
const byte PIN_SSR_LINE_1 = 8;
const byte PIN_SSR_LINE_2 = 10;

const byte PIN_BEEP = 9;
const byte PIN_LED = 3;

const byte stage2StartAltitude = 6;
//const int measureQuantity = 470;
const int measureQuantity = 400;

const byte startEEPPROMWriting = 20;

unsigned long beepTimer = 0;
unsigned long flyTimeStart = 0;
unsigned long timer_line_1 = 0;
unsigned long timer_line_2 = 0;

boolean couldBeep = false;
boolean beepStatus = false;
boolean mode1BeepStatus = false;
boolean mode1Beep2Status = false;
boolean keyWorked = false;
boolean recordsSecTimerFlg = false;
boolean ssr_line_1_worked = false;
boolean ssr_line_2_worked = false;
boolean ssr_line_1_init = false;
boolean ssr_line_2_init = false;



boolean sleepMode = false;
boolean rocketFlyBack = false;
boolean eepromWritingComplete = false;
boolean turn3Mode = false;

int myAltitude;
int altitudeNorm;
int maxAltitude = 0;
int beepTimerDuration = 48;
int measureCurrent = 0;

int altitudes[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int altitudesSorted[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int dA[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
byte currentAltitudesInd = 0;
const byte FILTER_SIZE = 11;


byte tempF;


byte rocketMode = 1;

Adafruit_BMP085 bmp;

#define adc_disable() (ADCSRA &= ~(1<<ADEN))
#define adc_enable()  (ADCSRA |=  (1<<ADEN))
#define KEY_LINE_1_PROC_DURATION 3000
#define KEY_LINE_2_PROC_DURATION 3000

int testDA[400] = {0,0,1,1,2,4,4,5,7,12,16,18,18,21,24,27,29,32,36,40,43,48,52,56,56,61,66,71,77,77,83,88,94,99,105,110,110,116,122,129,136,141,141,146,146,150,154,159,159,163,163,166,170,170,172,172,175,175,177,181,183,183,199,194,194,205,209,209,214,220,227,223,223,248,252,252,259,256,264,257,268,268,275,274,278,278,285,288,288,295,296,296,297,304,304,307,310,310,311,316,315,315,319,324,324,328,328,330,332,333,333,334,336,336,339,343,344,347,347,348,348,349,352,354,357,358,361,362,363,364,366,366,368,369,369,371,372,372,372,376,376,376,376,376,378,380,380,382,382,383,383,384,384,384,386,387,388,388,388,389,390,390,391,390,390,390,392,392,392,393,392,394,393,393,394,393,394,394,394,394,394,394,394,393,393,393,392,392,392,391,391,391,390,390,390,389,389,389,387,388,387,387,386,385,384,384,384,384,383,381,382,382,379,379,377,376,376,374,373,372,372,371,369,368,366,364,364,363,363,363,361,361,361,358,355,353,353,351,349,346,346,343,343,340,338,335,334,334,332,330,329,326,323,323,320,319,315,315,312,310,308,305,305,303,300,298,298,296,292,291,289,289,286,284,284,282,278,277,277,273,271,268,268,262,258,257,257,254,252,250,249,249,245,242,242,236,235,232,230,230,227,224,224,221,219,219,215,213,211,211,208,208,205,203,203,198,195,192,189,185,182,179,176,173,170,170,167,163,161,159,159,154,152,152,150,147,142,142,138,138,135,132,132,129,125,125,123,120,115,111,111,110,106,101,98,98,96,92,92,90,85,85,82};

int testDAInd = 0;


void setup(void)
{

  //for(int i = 0; i < 1024; i++) EEPROMWriteInt(i,0); // иногда нужно обнулить память для отладки

  Serial.begin(9600);

  pinMode(A1, INPUT);
  int ar = analogRead(A1);
  if (ar != 0) couldBeep = true;

  checkSerial();

  pinMode(PIN_LED, OUTPUT);
  pinMode(PIN_SSR_LINE_1, OUTPUT);
  pinMode(PIN_SSR_LINE_2, OUTPUT);
  pinMode(PIN_BEEP, OUTPUT);

  digitalWrite(PIN_LED, HIGH);
  if (couldBeep) {
    digitalWrite(PIN_BEEP, HIGH);
    delay(200);
    digitalWrite(PIN_BEEP, LOW);
    delay(500);
    digitalWrite(PIN_BEEP, HIGH);
    delay(500);
    digitalWrite(PIN_BEEP, LOW);

  }
  else
  {
    delay(1000);
  }

  digitalWrite(PIN_LED, LOW);
  digitalWrite(PIN_BEEP, LOW);


  if (!bmp.begin()) {
    digitalWrite(PIN_LED, HIGH);
    digitalWrite(PIN_BEEP, HIGH);
    while (1);
  }

  altitudeNorm = bmp.readAltitude();

}


void loop() {

  pinMode (RF_PIN, OUTPUT);

  float mAA;
  int aSm;

  int i;
  int j;
  int h;


  if (sleepMode) {

    proc1();

    digitalWrite(PIN_LED, HIGH);
    if (couldBeep) digitalWrite(PIN_BEEP, HIGH);
    delay(30);
    digitalWrite(PIN_LED, LOW);
    digitalWrite(PIN_BEEP, LOW);

    pinMode (RF_PIN, INPUT);

    adc_disable();
    MCUSR = 0;
    WDTCSR = bit (WDCE) | bit (WDE);
    WDTCSR = bit (WDIE) | bit (WDP2) | bit (WDP1);
    wdt_reset();
    set_sleep_mode (SLEEP_MODE_PWR_DOWN);
    sleep_enable();
    MCUCR = bit (BODS) | bit (BODSE);
    MCUCR = bit (BODS);
    sleep_cpu ();
    sleep_disable();
  }
  else
  {
    if (beepTimer < millis()) {

      beepTimer = millis() + beepTimerDuration;

      //myAltitude = bmp.readAltitude() - altitudeNorm;

      myAltitude = testDA[testDAInd];
      testDAInd++;

      if (myAltitude > maxAltitude) {
        maxAltitude = myAltitude;
      }

      altitudes[currentAltitudesInd] = myAltitude;

      //sort altitudes array
      switch (currentAltitudesInd) {
        case 0:
          altitudesSorted[FILTER_SIZE - 1] = altitudes[0];
          for (i = 0; i < FILTER_SIZE - 1; i++) {
            altitudesSorted[i] = altitudes[i + 1];
          }
          break;
        case FILTER_SIZE:
          for (i = 0; i < FILTER_SIZE; i++) {
            altitudesSorted[i] = altitudes[i];
          }
          break;
        default:
          j = 0;
          for (i = currentAltitudesInd + 1; i < FILTER_SIZE; i++) {
            altitudesSorted[j] = altitudes[i];
            j++;
          }
          h = 0;
          for (i = j; i < FILTER_SIZE; i++) {
            altitudesSorted[i] = altitudes[h];
            h++;
          }
      }

      for (i = 1; i < FILTER_SIZE; i++) {
        dA[i - 1] = altitudesSorted[i] - altitudesSorted[i - 1];
        h++;
      }

      for (i = 0; i < FILTER_SIZE - 1; i++) {
        aSm = aSm + dA[i];
      }

      mAA = (float)aSm / (FILTER_SIZE - 1);

      Serial.println(mAA);

      currentAltitudesInd++;

      if ( currentAltitudesInd > FILTER_SIZE - 1) {
        currentAltitudesInd = 0;
      }

      switch (rocketMode) {
        case 1:

          beepStatus = !beepStatus;
          if (beepStatus) {
            mode1BeepStatus = !mode1BeepStatus;
          }
          if (mode1BeepStatus) {
            mode1Beep2Status = !mode1Beep2Status;
          }

          if (mode1Beep2Status) {
            digitalWrite(PIN_LED, HIGH);
            tone(RF_PIN, 540);
          }
          else
          {
            digitalWrite(PIN_LED, LOW);
            tone(RF_PIN, 440);
          }

          if (mAA > 0) {
            maxAltitude = 0;
            EEPROMWriteInt(0, 0);
            EEPROMWriteInt(10, 0);
            EEPROMWriteInt(4, 0);
            EEPROMWriteInt(6, 0);
            EEPROMWriteInt(8, 0);

            measureCurrent = FILTER_SIZE;

            flyTimeStart = millis();
            rocketMode = 2;

            for (i = 0; i < FILTER_SIZE; i++) {
              EEPROMWriteInt(startEEPPROMWriting + i + i, altitudesSorted[i]);
            }
          }

          break;
        case 2:

          beepStatus = !beepStatus;
          if (beepStatus) {
            digitalWrite(PIN_LED, HIGH);
          }
          else
          {
            digitalWrite(PIN_LED, LOW);
          }

          tone(RF_PIN, myAltitude);

          if ((mAA < 0) && !rocketFlyBack) {
            rocketFlyBack = true;
            EEPROMWriteInt(0, maxAltitude);
            int timeToCheckAppogeyInMillis = millis() - flyTimeStart;
            EEPROMWriteInt(4, timeToCheckAppogeyInMillis);

            digitalWrite(PIN_SSR_LINE_2, LOW);
            delay(10);
            ssr_line_2_worked = true;

            EEPROMWriteInt(10, myAltitude);
            digitalWrite(PIN_SSR_LINE_1, HIGH);
            delay(10);
            ssr_line_1_init = true;
            timer_line_1 = millis() + KEY_LINE_1_PROC_DURATION;
          }

          if ((myAltitude > stage2StartAltitude) && !ssr_line_2_init) {
            digitalWrite(PIN_SSR_LINE_2, HIGH);
            delay(10);
            timer_line_2 = millis() + KEY_LINE_2_PROC_DURATION;
            ssr_line_2_init = true;
          }

          if ((timer_line_1 < millis()) && !ssr_line_1_worked) {
            digitalWrite(PIN_SSR_LINE_1, LOW);
            delay(10);
            ssr_line_1_worked = true;
            turn3Mode = true;
          }

          if ((timer_line_2 < millis()) && !ssr_line_2_worked ) {
            digitalWrite(PIN_SSR_LINE_2, LOW);
            delay(10);
            ssr_line_2_worked = true;
          }

          if (!eepromWritingComplete) {
            EEPROMWriteInt(startEEPPROMWriting + measureCurrent + measureCurrent, myAltitude);
            measureCurrent++;
            if (measureCurrent > measureQuantity) {
              eepromWritingComplete = true;
              int recordsTime = (millis() - flyTimeStart);
              EEPROMWriteInt(6, recordsTime);
              int speedOfRecordInSec = recordsTime / measureQuantity;
              speedOfRecordInSec = 1000 / speedOfRecordInSec;
              EEPROMWriteInt(8, speedOfRecordInSec);
            }
          }

          if ( turn3Mode && eepromWritingComplete ) {
            rocketMode = 3;

            tone(RF_PIN, 540);
            digitalWrite(PIN_LED, HIGH);
            delay(500);
            digitalWrite(PIN_LED, LOW);
            tone(RF_PIN, 440);
            delay(500);
            digitalWrite(PIN_LED, HIGH);
            tone(RF_PIN, 340);
            delay(500);
            digitalWrite(PIN_LED, LOW);
            tone(RF_PIN, 440);
            delay(500);
            digitalWrite(PIN_LED, HIGH);
            tone(RF_PIN, 540);
            delay(1000);
            digitalWrite(PIN_LED, LOW);
            noTone(RF_PIN);
            delay(2000);

            sendAltitude();
            delay(5000);

            sendAltitude();
            delay(5000);

            sendAltitude();
            delay(5000);

            sendAltitude();
            delay(5000);

            sendAltitude();
            delay(5000);
          }

          break;
        case 3:
          sleepMode = true;
          break;
      }

    }
  }
}

void proc0() {
  tone(RF_PIN, 450);
  delay(DURATION_0);
  noTone(RF_PIN);
}

void proc1() {
  tone(RF_PIN, 550);
  delay(DURATION_1);
  noTone(RF_PIN);
}

void checkSerial() {
  delay(3000);

  if (Serial.available()) {
    int maxAltitudeEEPROM = EEPROMReadInt(0);
    int line_1_InitiatedAltitude = EEPROMReadInt(10);
    int timeToCheckAppogeyInMillis = EEPROMReadInt(4);
    int recordsTimeInMillis = EEPROMReadInt(6);
    int recordsRate = EEPROMReadInt(8);

    Serial.println();

    Serial.print("max altitude:    ");
    Serial.print(maxAltitudeEEPROM);
    Serial.println(" m");
    Serial.println();

    Serial.print("line_1_InitiatedAltitude:    ");

    Serial.print(line_1_InitiatedAltitude);
    Serial.println(" m");
    Serial.println();

    Serial.print("timeToCheckAppogeyInMillis:    ");
    Serial.print(timeToCheckAppogeyInMillis);
    Serial.println(" millis");
    Serial.println();

    Serial.print("recordsTimeInMillis:    ");
    Serial.print(recordsTimeInMillis);
    Serial.println(" millis");
    Serial.println();

    Serial.print("recordsRate:    ");
    Serial.print(recordsRate);
    Serial.println(" records/sec");
    Serial.println();


    Serial.println("log:   ");
    float j = 0;
    for (int i = 0; i < (measureQuantity + measureQuantity + 1); i += 2) {
      Serial.print(EEPROMReadInt(i));
      Serial.println();
      delay(50);
    }
  }
}


void EEPROMWriteInt (int p_address, int p_value)
{
  byte lowByte = EEPROM.read(p_address);
  byte highByte = EEPROM.read(p_address + 1);
  int val = ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
  if (val != p_value) {
    byte lowByte = ((p_value >> 0) & 0xFF);
    byte highByte = ((p_value >> 8) & 0xFF);
    EEPROM.write(p_address, lowByte);
    EEPROM.write(p_address + 1, highByte);
  }
}

int EEPROMReadInt(int p_address)
{
  byte lowByte = EEPROM.read(p_address);
  byte highByte = EEPROM.read(p_address + 1);
  return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
}

ISR (WDT_vect)
{
  wdt_disable();
}

void sendAltitude() {
  String beaconData = String(maxAltitude);
  String oneStr = "";

  delay(1000);
  int d2RF;
  for (int i = 0; i < beaconData.length(); i++ ) {
    d2RF = 0;
    oneStr += beaconData.charAt(i);
    d2RF = oneStr.toInt();
    send_d2RF(d2RF);
    delay(1000);
    oneStr = "";
  }
}

void send_d2RF(int d2RF) {
  switch (d2RF) {
    case 0:
      proc0();
      break;
    case 1:
      proc1();
      break;
    case 2:
      proc1();
      delay(SPLITTER);
      proc0();
      break;
    case 3:
      proc1();
      delay(SPLITTER);
      proc1();
      break;
    case 4:
      proc1();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc0();
      break;
    case 5:
      proc1();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc1();
      break;
    case 6:
      proc1();
      delay(SPLITTER);
      proc1();
      delay(SPLITTER);
      proc0();
      break;
    case 7:
      proc1();
      delay(SPLITTER);
      proc1();
      delay(SPLITTER);
      proc1();
      break;
    case 8:
      proc1();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc0();
      break;
    case 9:
      proc1();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc1();
      break;
  }
}

Версия 2

 

 

gmurvs
Offline
Зарегистрирован: 15.04.2014
#include <Adafruit_BMP085.h>

#include <EEPROM.h>
#include <Wire.h>

#include  <avr/sleep.h>
#include  <avr/wdt.h>

const byte RF_PIN = 11;
const byte SPLITTER = 200;
const int DURATION_0 = 550;
const int DURATION_1 = 350;
const byte PIN_SSR_LINE_1 = 8;
const byte PIN_SSR_LINE_2 = 10;

const byte PIN_BEEP = 9;
const byte PIN_LED = 3;

const byte cAltitude = 5;
const byte cS2Altitude = 6;
const int measureQuantity = 480;

const byte startEEPPROMWriting = 20;

unsigned long beepTimer = 0;
unsigned long flyTimeStart = 0;
unsigned long timer_line_1 = 0;
unsigned long timer_line_2 = 0;

boolean couldBeep = false;
boolean beepStatus = false;
boolean mode1BeepStatus = false;
boolean mode1Beep2Status = false;
boolean keyWorked = false;
boolean recordsSecTimerFlg = false;
boolean ssr_line_1_worked = false;
boolean ssr_line_2_worked = false;
boolean ssr_line_1_init = false;
boolean ssr_line_2_init = false;



boolean sleepMode = false;
boolean rocketFlyBack = false;
boolean eepromWritingComplete = false;
boolean turn3Mode = false;

int myAltitude;
int altitudeNorm;
int maxAltitude = 0;
int beepTimerDuration = 50;
int measureCurrent = 0;

int altitudes[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int altitudesSorted[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int dA[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
byte currentAltitudesInd = 0;
const byte FILTER_SIZE = 11;



byte rocketMode = 1;

Adafruit_BMP085 bmp;

#define adc_disable() (ADCSRA &= ~(1<<ADEN))
#define adc_enable()  (ADCSRA |=  (1<<ADEN))
#define KEY_LINE_1_PROC_DURATION 3000
#define KEY_LINE_2_PROC_DURATION 3000

void setup(void)
{

  //for(int i = 0; i < 1024; i++) EEPROMWriteInt(i,0);

  Serial.begin(9600);

  pinMode(A1, INPUT);
  int ar = analogRead(A1);
  if (ar != 0) couldBeep = true;

  checkSerial();

  pinMode(PIN_LED, OUTPUT);
  pinMode(PIN_SSR_LINE_1, OUTPUT);
  pinMode(PIN_SSR_LINE_2, OUTPUT);
  pinMode(PIN_BEEP, OUTPUT);

  digitalWrite(PIN_LED, HIGH);
  if (couldBeep) {
    digitalWrite(PIN_BEEP, HIGH);
    delay(200);
    digitalWrite(PIN_BEEP, LOW);
    delay(500);
    digitalWrite(PIN_BEEP, HIGH);
    delay(500);
    digitalWrite(PIN_BEEP, LOW);

  }
  else
  {
    delay(1000);
  }

  digitalWrite(PIN_LED, LOW);
  digitalWrite(PIN_BEEP, LOW);


  if (!bmp.begin()) {
    digitalWrite(PIN_LED, HIGH);
    digitalWrite(PIN_BEEP, HIGH);
    while (1);
  }

  altitudeNorm = bmp.readAltitude();

}


void loop() {

  pinMode (RF_PIN, OUTPUT);

  int mAA;
  int aSm;

  int i;
  int j;
  int h;


  if (sleepMode) {

    proc1();

    digitalWrite(PIN_LED, HIGH);
    if (couldBeep) digitalWrite(PIN_BEEP, HIGH);
    delay(30);
    digitalWrite(PIN_LED, LOW);
    digitalWrite(PIN_BEEP, LOW);

    pinMode (RF_PIN, INPUT);

    adc_disable();
    MCUSR = 0;
    WDTCSR = bit (WDCE) | bit (WDE);
    WDTCSR = bit (WDIE) | bit (WDP2) | bit (WDP1);
    wdt_reset();
    set_sleep_mode (SLEEP_MODE_PWR_DOWN);
    sleep_enable();
    MCUCR = bit (BODS) | bit (BODSE);
    MCUCR = bit (BODS);
    sleep_cpu ();
    sleep_disable();
  }
  else
  {
    if (beepTimer < millis()) {

      beepTimer = millis() + beepTimerDuration;

      myAltitude = bmp.readAltitude() - altitudeNorm;

      if (myAltitude > maxAltitude) {
        maxAltitude = myAltitude;
      }

      altitudes[currentAltitudesInd] = myAltitude;

      //sort altitudes array
      switch (currentAltitudesInd) {
        case 0:
          altitudesSorted[FILTER_SIZE - 1] = altitudes[0];
          for (i = 0; i < FILTER_SIZE - 1; i++) {
            altitudesSorted[i] = altitudes[i + 1];
          }
          break;
        case FILTER_SIZE:
          for (i = 0; i < FILTER_SIZE; i++) {
            altitudesSorted[i] = altitudes[i];
          }
          break;
        default:
          j = 0;
          for (i = currentAltitudesInd + 1; i < FILTER_SIZE; i++) {
            altitudesSorted[j] = altitudes[i];
            j++;
          }
          h = 0;
          for (i = j; i < FILTER_SIZE; i++) {
            altitudesSorted[i] = altitudes[h];
            h++;
          }
      }

      for (i = 1; i < FILTER_SIZE; i++) {
        dA[i - 1] = altitudesSorted[i] - altitudesSorted[i - 1];
        h++;
      }

      for (i = 0; i < FILTER_SIZE - 1; i++) {
        aSm = aSm + dA[i];
      }

      mAA = aSm / (FILTER_SIZE - 1);

      currentAltitudesInd++;

      if ( currentAltitudesInd > FILTER_SIZE - 1) {
        currentAltitudesInd = 0;
      }

      switch (rocketMode) {
        case 1:

          beepStatus = !beepStatus;
          if (beepStatus) {
            mode1BeepStatus = !mode1BeepStatus;
          }
          if (mode1BeepStatus) {
            mode1Beep2Status = !mode1Beep2Status;
          }

          if (mode1Beep2Status) {
            digitalWrite(PIN_LED, HIGH);
            tone(RF_PIN, 540);
          }
          else
          {
            digitalWrite(PIN_LED, LOW);
            tone(RF_PIN, 440);
          }

          if (mAA > 0 && myAltitude > cAltitude) {
            maxAltitude = 0;
            EEPROMWriteInt(0, 0);
            EEPROMWriteInt(10, 0);
            EEPROMWriteInt(4, 0);
            EEPROMWriteInt(6, 0);
            EEPROMWriteInt(8, 0);

            measureCurrent = FILTER_SIZE;

            flyTimeStart = millis();
            rocketMode = 2;

            for (i = 0; i < FILTER_SIZE; i++) {
              EEPROMWriteInt(startEEPPROMWriting + i + i, altitudesSorted[i]);
            }
          }

          break;
        case 2:

          beepStatus = !beepStatus;
          if (beepStatus) {
            digitalWrite(PIN_LED, HIGH);
          }
          else
          {
            digitalWrite(PIN_LED, LOW);
          }

          tone(RF_PIN, myAltitude);

          if ((mAA <= 0) && !rocketFlyBack && myAltitude > cAltitude) {
            rocketFlyBack = true;
            EEPROMWriteInt(0, maxAltitude);
            int timeToCheckAppogeyInMillis = millis() - flyTimeStart;
            EEPROMWriteInt(4, timeToCheckAppogeyInMillis);

            digitalWrite(PIN_SSR_LINE_2, LOW);
            delay(10);
            ssr_line_2_worked = true;

            EEPROMWriteInt(10, myAltitude);
            digitalWrite(PIN_SSR_LINE_1, HIGH);
            delay(10);
            ssr_line_1_init = true;
            timer_line_1 = millis() + KEY_LINE_1_PROC_DURATION;
          }

          if ((myAltitude > cS2Altitude) && !ssr_line_2_init) {
            digitalWrite(PIN_SSR_LINE_2, HIGH);
            delay(10);
            timer_line_2 = millis() + KEY_LINE_2_PROC_DURATION;
            ssr_line_2_init = true;
          }

          if ((timer_line_1 < millis()) && !ssr_line_1_worked && ssr_line_1_init) {
            digitalWrite(PIN_SSR_LINE_1, LOW);
            delay(10);
            ssr_line_1_worked = true;
            turn3Mode = true;
          }

          if ((timer_line_2 < millis()) && !ssr_line_2_worked && ssr_line_2_init) {
            digitalWrite(PIN_SSR_LINE_2, LOW);
            delay(10);
            ssr_line_2_worked = true;
          }

          if (!eepromWritingComplete) {
            EEPROMWriteInt(startEEPPROMWriting + measureCurrent + measureCurrent, myAltitude);
            measureCurrent++;
            if (measureCurrent > measureQuantity) {
              eepromWritingComplete = true;
              int recordsTime = (millis() - flyTimeStart);
              EEPROMWriteInt(6, recordsTime);
              int speedOfRecordInSec = recordsTime / measureQuantity;
              speedOfRecordInSec = 1000 / speedOfRecordInSec;
              EEPROMWriteInt(8, speedOfRecordInSec);
            }
          }

          if ( turn3Mode && eepromWritingComplete ) {
            rocketMode = 3;

            tone(RF_PIN, 540);
            digitalWrite(PIN_LED, HIGH);
            delay(500);
            digitalWrite(PIN_LED, LOW);
            tone(RF_PIN, 440);
            delay(500);
            digitalWrite(PIN_LED, HIGH);
            tone(RF_PIN, 340);
            delay(500);
            digitalWrite(PIN_LED, LOW);
            tone(RF_PIN, 440);
            delay(500);
            digitalWrite(PIN_LED, HIGH);
            tone(RF_PIN, 540);
            delay(1000);
            digitalWrite(PIN_LED, LOW);
            noTone(RF_PIN);
            delay(2000);

            sendAltitude();
            delay(5000);

            sendAltitude();
            delay(5000);

            sendAltitude();
            delay(5000);

            sendAltitude();
            delay(5000);

            sendAltitude();
            delay(5000);
          }

          break;
        case 3:
          sleepMode = true;
          break;
      }

    }
  }
}

void proc0() {
  tone(RF_PIN, 450);
  delay(DURATION_0);
  noTone(RF_PIN);
}

void proc1() {
  tone(RF_PIN, 550);
  delay(DURATION_1);
  noTone(RF_PIN);
}

void checkSerial() {
  delay(3000);

  if (Serial.available()) {
    int maxAltitudeEEPROM = EEPROMReadInt(0);
    int line_1_InitiatedAltitude = EEPROMReadInt(10);
    int timeToCheckAppogeyInMillis = EEPROMReadInt(4);
    int recordsTimeInMillis = EEPROMReadInt(6);
    int recordsRate = EEPROMReadInt(8);

    Serial.println();

    Serial.print("maxAltitude:    ");
    Serial.print(maxAltitudeEEPROM);
    Serial.println(" m");
    Serial.println();

    Serial.print("line_1_InitiatedAltitude:    ");

    Serial.print(line_1_InitiatedAltitude);
    Serial.println(" m");
    Serial.println();

    Serial.print("timeToCheckAppogey:    ");
    Serial.print(timeToCheckAppogeyInMillis);
    Serial.println(" millis");
    Serial.println();

    Serial.print("recordsTimeInMillis:    ");
    Serial.print(recordsTimeInMillis);
    Serial.println(" millis");
    Serial.println();

    Serial.print("recordsRate:    ");
    Serial.print(recordsRate);
    Serial.println(" records/sec");
    Serial.println();


    Serial.println("log:   ");
    float j = 0;
    for (int i = startEEPPROMWriting; i < (measureQuantity + measureQuantity + 1); i += 2) {
      Serial.print(EEPROMReadInt(i));
      Serial.println();
      delay(50);
    }
  }
}


void EEPROMWriteInt (int p_address, int p_value)
{
  byte lowByte = EEPROM.read(p_address);
  byte highByte = EEPROM.read(p_address + 1);
  int val = ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
  if (val != p_value) {
    byte lowByte = ((p_value >> 0) & 0xFF);
    byte highByte = ((p_value >> 8) & 0xFF);
    EEPROM.write(p_address, lowByte);
    EEPROM.write(p_address + 1, highByte);
  }
}

int EEPROMReadInt(int p_address)
{
  byte lowByte = EEPROM.read(p_address);
  byte highByte = EEPROM.read(p_address + 1);
  return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
}

ISR (WDT_vect)
{
  wdt_disable();
}

void sendAltitude() {
  String beaconData = String(maxAltitude);
  String oneStr = "";

  delay(1000);
  int d2RF;
  for (int i = 0; i < beaconData.length(); i++ ) {
    d2RF = 0;
    oneStr += beaconData.charAt(i);
    d2RF = oneStr.toInt();
    send_d2RF(d2RF);
    delay(1000);
    oneStr = "";
  }
}

void send_d2RF(int d2RF) {
  switch (d2RF) {
    case 0:
      proc0();
      break;
    case 1:
      proc1();
      break;
    case 2:
      proc1();
      delay(SPLITTER);
      proc0();
      break;
    case 3:
      proc1();
      delay(SPLITTER);
      proc1();
      break;
    case 4:
      proc1();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc0();
      break;
    case 5:
      proc1();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc1();
      break;
    case 6:
      proc1();
      delay(SPLITTER);
      proc1();
      delay(SPLITTER);
      proc0();
      break;
    case 7:
      proc1();
      delay(SPLITTER);
      proc1();
      delay(SPLITTER);
      proc1();
      break;
    case 8:
      proc1();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc0();
      break;
    case 9:
      proc1();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc1();
      break;
  }
}

 

bwn
Offline
Зарегистрирован: 25.08.2014

UPS, а что произойдет если одновременно с набором высоты меняется и атмосферное давление?

gmurvs
Offline
Зарегистрирован: 15.04.2014

Проект заточен для использования в системах спасения моделей ракет, а там как раз с одновременным набором высоты меняется давление, алгоритм определяет момент старта и прохождения аппогея. Что конкретно интересует?

bwn
Offline
Зарегистрирован: 25.08.2014

У Вас процесс быстрый, так что все в порядке.
Заинтересовало, если буду пешком подниматься и одновременно меняются метеоусловия, ведь обманет.))))

gmurvs
Offline
Зарегистрирован: 15.04.2014

Если подниматься ооочень долго, то скорее всего, влияние метеоусловий на показания может иметь место, но насколько это может быть существенно?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

на высоте 500 метров над уровнем моря давление меняется в пределах 10 мм ртутного столба ( в районе 714)

bwn
Offline
Зарегистрирован: 25.08.2014

примерно 1мм на 10,5м. При изменении с 760 до 750, ошибка составит 100 метров.
Для ТС не актуально, для альпинистов вопрос.

gmurvs
Offline
Зарегистрирован: 15.04.2014
// MRIA-2


#include <Adafruit_BMP085.h>

#include <EEPROM.h>
#include <Wire.h>

#include  <avr/sleep.h>
#include  <avr/wdt.h>

const byte RF_PIN = 11;
const byte SPLITTER = 200;
const int DURATION_0 = 550;
const int DURATION_1 = 350;
const byte PIN_SSR_LINE_1 = 8; // ключ для инициации первой мортиры (тормозной парашют)
const byte PIN_SSR_LINE_2 = 10; // ключ для инициации второй мортиры (основной парашют), либо запуска второй ступени для режима 2С (b2SPMode = true)
const byte PIN_BEEP = 9;
const byte PIN_LED = 3;

const byte cAltitude = 10; //высота активации режима "полет"
const byte cS2Altitude = 12; //высота активации ключа для запуска второй ступени для режима 2С (b2SPMode = true)
const int measureQuantity = 480; // длина лога данных (ограничена емкостью ПЗУ)

const byte startEEPPROMWriting = 20;

unsigned long beepTimer = 0;
unsigned long flyTimeStart = 0;
unsigned long delay_timer_line_1 = 0;
unsigned long delay_timer_line_2 = 0;
unsigned long delay_timer_line_3 = 0;
unsigned long timer_line_1 = 0;
unsigned long timer_line_2 = 0;
unsigned long timer_line_3 = 0;

boolean couldBeep = false;
boolean beepStatus = false;
boolean mode1BeepStatus = false;
boolean mode1Beep2Status = false;
boolean keyWorked = false;
boolean recordsSecTimerFlg = false;

boolean ssr_line_1_worked = false;
boolean ssr_line_2_worked = false;
boolean ssr_line_3_worked = false;

boolean ssr_line_1_down = false;
boolean ssr_line_2_down = false;

boolean ssr_line_1_init = false;
boolean ssr_line_2_init = false;
boolean ssr_line_3_init = false;

boolean sleepMode = false;
boolean rocketFlyBack = false;
boolean eepromWritingComplete = false;
boolean turn3Mode = false;


boolean b2SPMode = false; //для режима 2С (b2SPMode = true)


int myAltitude;
int altitudeNorm;
int maxAltitude = 0;
int beepTimerDuration = 50;
int measureCurrent = 0;

int altitudes[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int altitudesSorted[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int dA[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
byte currentAltitudesInd = 0;
const byte FILTER_SIZE = 10;



byte rocketMode = 1;

Adafruit_BMP085 bmp;

#define adc_disable() (ADCSRA &= ~(1<<ADEN))
#define adc_enable()  (ADCSRA |=  (1<<ADEN))
#define KEY_LINE_1_PROC_DURATION 3000
#define KEY_LINE_2_PROC_DURATION 3000
#define KEY_LINE_3_PROC_DURATION 3000

//задержки мс инициации ключей после определения прохождения аппогея
#define DELAY_LINE_1 0
#define DELAY_LINE_2 3500


void setup(void)
{

  //for(int i = 0; i < 1024; i++) EEPROMWriteInt(i,0);

  Serial.begin(9600);

  pinMode(A1, INPUT);
  pinMode(A2, INPUT);

  int ar1 = analogRead(A1);
  int ar2 = analogRead(A2);

  //2 STAGE **************
  if (b2SPMode) {
    ar2 = 0;
  }

  //**************

  if (ar1 != 0 || ar2 != 0) couldBeep = true;

  checkSerial();

  pinMode(PIN_LED, OUTPUT);
  pinMode(PIN_SSR_LINE_1, OUTPUT);
  pinMode(PIN_SSR_LINE_2, OUTPUT);
  pinMode(PIN_BEEP, OUTPUT);

  digitalWrite(PIN_LED, HIGH);
  if (couldBeep) {
    digitalWrite(PIN_BEEP, HIGH);
    delay(200);
    digitalWrite(PIN_BEEP, LOW);
    delay(500);
    digitalWrite(PIN_BEEP, HIGH);
    delay(1000);
    digitalWrite(PIN_BEEP, LOW);
  }
  else
  {
    delay(1000);
  }

  if (!bmp.begin()) {
    digitalWrite(PIN_BEEP, HIGH);
    digitalWrite(PIN_LED, HIGH);
    digitalWrite(PIN_BEEP, HIGH);
    while (1);
  }

  digitalWrite(PIN_LED, LOW);
  digitalWrite(PIN_BEEP, LOW);

  altitudeNorm = bmp.readAltitude();

}


void loop() {

  pinMode (RF_PIN, OUTPUT);

  int mAA;
  int aSm;

  int i;
  int j;
  int h;


  if (sleepMode) {

    proc1();

    digitalWrite(PIN_LED, HIGH);
    if (couldBeep) digitalWrite(PIN_BEEP, HIGH);
    delay(30);
    digitalWrite(PIN_LED, LOW);
    digitalWrite(PIN_BEEP, LOW);

    pinMode (RF_PIN, INPUT);

    adc_disable();
    MCUSR = 0;
    WDTCSR = bit (WDCE) | bit (WDE);
    WDTCSR = bit (WDIE) | bit (WDP2) | bit (WDP1);
    wdt_reset();
    set_sleep_mode (SLEEP_MODE_PWR_DOWN);
    sleep_enable();
    MCUCR = bit (BODS) | bit (BODSE);
    MCUCR = bit (BODS);
    sleep_cpu ();
    sleep_disable();
  }
  else
  {
    if (beepTimer < millis()) {

      beepTimer = millis() + beepTimerDuration;

      myAltitude = bmp.readAltitude() - altitudeNorm;

      if (myAltitude > maxAltitude) {
        maxAltitude = myAltitude;
      }

      altitudes[currentAltitudesInd] = myAltitude;

      //sort altitudes array
      switch (currentAltitudesInd) {
        case 0:
          altitudesSorted[FILTER_SIZE - 1] = altitudes[0];
          for (i = 0; i < FILTER_SIZE - 1; i++) {
            altitudesSorted[i] = altitudes[i + 1];
          }
          break;
        case FILTER_SIZE:
          for (i = 0; i < FILTER_SIZE; i++) {
            altitudesSorted[i] = altitudes[i];
          }
          break;
        default:
          j = 0;
          for (i = currentAltitudesInd + 1; i < FILTER_SIZE; i++) {
            altitudesSorted[j] = altitudes[i];
            j++;
          }
          h = 0;
          for (i = j; i < FILTER_SIZE; i++) {
            altitudesSorted[i] = altitudes[h];
            h++;
          }
      }

      for (i = 1; i < FILTER_SIZE; i++) {
        dA[i - 1] = altitudesSorted[i] - altitudesSorted[i - 1];
        h++;
      }

      for (i = 0; i < FILTER_SIZE - 1; i++) {
        aSm = aSm + dA[i];
      }

      mAA = aSm / (FILTER_SIZE - 1);

      currentAltitudesInd++;

      if ( currentAltitudesInd > FILTER_SIZE - 1) {
        currentAltitudesInd = 0;
      }

      switch (rocketMode) {
        case 1:

          beepStatus = !beepStatus;
          if (beepStatus) {
            mode1BeepStatus = !mode1BeepStatus;
          }
          if (mode1BeepStatus) {
            mode1Beep2Status = !mode1Beep2Status;
          }

          if (mode1Beep2Status) {
            digitalWrite(PIN_LED, HIGH);
            tone(RF_PIN, 540);
          }
          else
          {
            digitalWrite(PIN_LED, LOW);
            tone(RF_PIN, 440);
          }

          if (mAA > 0 && myAltitude > cAltitude) {
            maxAltitude = 0;
            EEPROMWriteInt(0, 0);
            EEPROMWriteInt(10, 0);
            EEPROMWriteInt(4, 0);
            EEPROMWriteInt(6, 0);
            EEPROMWriteInt(8, 0);

            measureCurrent = FILTER_SIZE;

            flyTimeStart = millis();
            rocketMode = 2;

            for (i = 0; i < FILTER_SIZE; i++) {
              EEPROMWriteInt(startEEPPROMWriting + i + i, altitudesSorted[i]);
            }
          }
          break;
        case 2:
          beepStatus = !beepStatus;
          if (beepStatus) {
            digitalWrite(PIN_LED, HIGH);
          }
          else
          {
            digitalWrite(PIN_LED, LOW);
          }

          tone(RF_PIN, myAltitude);

          //2 STAGE **************

          if (b2SPMode) {

            if (myAltitude > cS2Altitude && !ssr_line_3_init) { // режим второй ступени, задействован 2-й ключ
              ssr_line_3_init = true;
              delay_timer_line_3 = millis() + KEY_LINE_3_PROC_DURATION;
              digitalWrite(PIN_SSR_LINE_2, HIGH);
            }

            if (ssr_line_3_init && delay_timer_line_3 < millis() && !ssr_line_3_worked) {
              digitalWrite(PIN_SSR_LINE_2, LOW);
              ssr_line_3_worked = true;
            }

          }


          if ((mAA < 0) && !rocketFlyBack && myAltitude > cAltitude) {
            rocketFlyBack = true;
            EEPROMWriteInt(0, maxAltitude);
            int timeToCheckAppogeyInMillis = millis() - flyTimeStart;
            EEPROMWriteInt(4, timeToCheckAppogeyInMillis);

            EEPROMWriteInt(10, myAltitude);


            delay_timer_line_1 = millis() + DELAY_LINE_1;
            ssr_line_1_init = true;

            delay_timer_line_2 = millis() + DELAY_LINE_2;
            ssr_line_2_init = true;
          }

          if (ssr_line_1_init && !ssr_line_1_worked && delay_timer_line_1 < millis()) {
            ssr_line_1_worked = true;
            timer_line_1 = millis() + KEY_LINE_1_PROC_DURATION;
            digitalWrite(PIN_SSR_LINE_1, HIGH);
          }

          if (ssr_line_2_init && !ssr_line_2_worked && delay_timer_line_2 < millis()) {
            ssr_line_2_worked = true;
            timer_line_2 = millis() + KEY_LINE_2_PROC_DURATION;
            if (!b2SPMode) {
              digitalWrite(PIN_SSR_LINE_2, HIGH);
            }
          }

          if ((timer_line_1 < millis()) && ssr_line_1_worked && !ssr_line_1_down) {
            digitalWrite(PIN_SSR_LINE_1, LOW);
            ssr_line_1_down = true;
          }

          if ((timer_line_2 < millis()) && ssr_line_2_worked && !ssr_line_2_down) {
            digitalWrite(PIN_SSR_LINE_2, LOW);
            ssr_line_2_down = true;
          }

          if (ssr_line_1_down && ssr_line_2_down) {
            turn3Mode = true;
          }

          if (!eepromWritingComplete) {
            EEPROMWriteInt(startEEPPROMWriting + measureCurrent + measureCurrent, myAltitude);
            measureCurrent++;
            if (measureCurrent > measureQuantity) {
              eepromWritingComplete = true;
              int recordsTime = (millis() - flyTimeStart);
              EEPROMWriteInt(6, recordsTime);
              int speedOfRecordInSec = recordsTime / measureQuantity;
              speedOfRecordInSec = 1000 / speedOfRecordInSec;
              EEPROMWriteInt(8, speedOfRecordInSec);
            }
          }

          if (turn3Mode && eepromWritingComplete) {
            rocketMode = 3;
          }

          break;
        case 3:
          playExitFlyModeAction();
          sleepMode = true;
          break;
      }
    }
  }
}

void playExitFlyModeAction() {
  tone(RF_PIN, 540);
  digitalWrite(PIN_LED, HIGH);
  delay(500);
  digitalWrite(PIN_LED, LOW);
  tone(RF_PIN, 440);
  delay(500);
  digitalWrite(PIN_LED, HIGH);
  tone(RF_PIN, 340);
  delay(500);
  digitalWrite(PIN_LED, LOW);
  tone(RF_PIN, 440);
  delay(500);
  digitalWrite(PIN_LED, HIGH);
  tone(RF_PIN, 540);
  delay(1000);
  digitalWrite(PIN_LED, LOW);
  noTone(RF_PIN);
  delay(2000);

  sendAltitude();
  delay(5000);

  sendAltitude();
  delay(5000);

  sendAltitude();
  delay(5000);

  sendAltitude();
  delay(5000);

  sendAltitude();
  delay(5000);
}

void proc0() {
  tone(RF_PIN, 450);
  delay(DURATION_0);
  noTone(RF_PIN);
}

void proc1() {
  tone(RF_PIN, 550);
  delay(DURATION_1);
  noTone(RF_PIN);
}

void checkSerial() {
  delay(3000);

  if (Serial.available()) {
    int maxAltitudeEEPROM = EEPROMReadInt(0);
    int line_1_InitiatedAltitude = EEPROMReadInt(10);
    int timeToCheckAppogeyInMillis = EEPROMReadInt(4);
    int recordsTimeInMillis = EEPROMReadInt(6);
    int recordsRate = EEPROMReadInt(8);

    Serial.println();

    Serial.print("maxAltitude:    ");
    Serial.print(maxAltitudeEEPROM);
    Serial.println(" m");
    Serial.println();

    Serial.print("line_1_InitiatedAltitude:    ");

    Serial.print(line_1_InitiatedAltitude);
    Serial.println(" m");
    Serial.println();

    Serial.print("timeToCheckAppogey:    ");
    Serial.print(timeToCheckAppogeyInMillis);
    Serial.println(" millis");
    Serial.println();

    Serial.print("recordsTimeInMillis:    ");
    Serial.print(recordsTimeInMillis);
    Serial.println(" millis");
    Serial.println();

    Serial.print("recordsRate:    ");
    Serial.print(recordsRate);
    Serial.println(" records/sec");
    Serial.println();


    Serial.println("log:   ");
    float j = 0;
    for (int i = startEEPPROMWriting; i < (measureQuantity + measureQuantity + 1); i += 2) {
      Serial.print(EEPROMReadInt(i));
      Serial.println();
      delay(50);
    }
  }
}


void EEPROMWriteInt (int p_address, int p_value)
{
  byte lowByte = EEPROM.read(p_address);
  byte highByte = EEPROM.read(p_address + 1);
  int val = ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
  if (val != p_value) {
    byte lowByte = ((p_value >> 0) & 0xFF);
    byte highByte = ((p_value >> 8) & 0xFF);
    EEPROM.write(p_address, lowByte);
    EEPROM.write(p_address + 1, highByte);
  }
}

int EEPROMReadInt(int p_address)
{
  byte lowByte = EEPROM.read(p_address);
  byte highByte = EEPROM.read(p_address + 1);
  return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
}

ISR (WDT_vect)
{
  wdt_disable();
}

void sendAltitude() {
  String beaconData = String(maxAltitude);
  String oneStr = "";

  delay(1000);
  int d2RF;
  for (int i = 0; i < beaconData.length(); i++ ) {
    d2RF = 0;
    oneStr += beaconData.charAt(i);
    d2RF = oneStr.toInt();
    send_d2RF(d2RF);
    delay(1000);
    oneStr = "";
  }
}

void send_d2RF(int d2RF) {
  switch (d2RF) {
    case 0:
      proc0();
      break;
    case 1:
      proc1();
      break;
    case 2:
      proc1();
      delay(SPLITTER);
      proc0();
      break;
    case 3:
      proc1();
      delay(SPLITTER);
      proc1();
      break;
    case 4:
      proc1();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc0();
      break;
    case 5:
      proc1();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc1();
      break;
    case 6:
      proc1();
      delay(SPLITTER);
      proc1();
      delay(SPLITTER);
      proc0();
      break;
    case 7:
      proc1();
      delay(SPLITTER);
      proc1();
      delay(SPLITTER);
      proc1();
      break;
    case 8:
      proc1();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc0();
      break;
    case 9:
      proc1();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc1();
      break;
  }
}

 

bochkovoy10
Offline
Зарегистрирован: 26.01.2016

В итоге сколько по времени это устройство может записывать высоту? 

gmurvs
Offline
Зарегистрирован: 15.04.2014

в текущей конфигурации 24 секунды, 480 значений и десять параметров работы

bochkovoy10
Offline
Зарегистрирован: 26.01.2016

Вы, наверное, изучали эту тему. Возможно ли увеличить объем EEPROM  памяти в ардуино? И почему бы не использовать модуль для sd карты? 

gmurvs
Offline
Зарегистрирован: 15.04.2014

чем меньше составляющих, тем надежнее работает устройство, и так сталось, для логов полетов моих моделей ракет много памяти не нужно, вот смотрите
http://forum.modelka.com.ua/threads/65988-Запуски-ракет-и-испытания-двигателей/page21?p=749606&viewfull=1#post749606

bochkovoy10
Offline
Зарегистрирован: 26.01.2016

Я вот тоже ракеты клепаю, но времени явно мало для записи всего полета до приземления. Хотя, если замерять дважды в секунду, то можно добится времени до 250 с, что для моего уровня пока что хватит =)  Еще одна проблема- невозможно записать сразу второй полет, пока не скинешь данные с высотомера. 

gmurvs
Offline
Зарегистрирован: 15.04.2014

можно часто писать данные до апогея, затем реже.

gmurvs
Offline
Зарегистрирован: 15.04.2014

лог полета можно передавать по радиоканалу, хотя сливать данные в пк еще проще, непроблема подключить шнур, вбить в сериал что-либо и дождаться лога в мониторе.

gmurvs
Offline
Зарегистрирован: 15.04.2014

да, а есть ссылки на модели?

bochkovoy10
Offline
Зарегистрирован: 26.01.2016

Ага, думаю реализовать возможность подключения bluetooth- модуля для передачи лога прямо на телефон.

bochkovoy10
Offline
Зарегистрирован: 26.01.2016

В моделях ничего необычного нет, все технологии с сайта rocki и serge77. Пока набираюсь опыта =) Я посмотрел на ваши ракеты. Зачем нужен такой огромный калибр (75), можно ведь намного улучшить летные характеристики, уменьшив диаметр? 

gmurvs
Offline
Зарегистрирован: 15.04.2014

все начиналось с малого, но большой калибр лучше видно, т.е. зрелищность, а попробуйте?

gmurvs
Offline
Зарегистрирован: 15.04.2014

и посмотрите на проект Мрия

bochkovoy10
Offline
Зарегистрирован: 26.01.2016

Да, зрелищность на высоте) Что за топливо? Факел хоршоший. 

 

Я сделал высотомер с вашей прошивкой. Спасибо, все отлично работает =) 

gmurvs
Offline
Зарегистрирован: 15.04.2014

если что, там на форуме есть инфа, карамель с титаном

gmurvs
Offline
Зарегистрирован: 15.04.2014
// IRP.1.2 FOR MRIA & 75 2S & 40

//#include <Adafruit_BMP280.h>
#include <Adafruit_BMP085.h>

#include <EEPROM.h>

#include  <avr/sleep.h>
#include  <avr/wdt.h>

const byte PIN_RF = 11;
const byte SPLITTER = 200;
const int DURATION_0 = 550;
const int DURATION_1 = 350;
const byte PIN_SSR_LINE_1 = 8; // ключ для инициации первой мортиры (тормозной парашют)
const byte PIN_SSR_LINE_2 = 10; // ключ для инициации второй мортиры (основной парашют)
const byte PIN_SSR_LINE_3 = 7; // ключ для инициации мотора второй ступени
const byte PIN_BEEP = 9;
const byte PIN_LED = 3;

const byte cAltitude = 10; //высота активации режима "полет"
const byte cS2Altitude = 10; //высота активации ключа для запуска второй ступени
const int measureQuantity = 480; // длина лога данных (ограничена емкостью ПЗУ)

const byte startEEPPROMWriting = 20;

unsigned long beepTimer = 0;
unsigned long flyTimeStart = 0;
unsigned long waiting2StageStart = 0;
unsigned long RF_Beeping = 0;
unsigned long delay_timer_line_1 = 0;
unsigned long delay_timer_line_2 = 0;
unsigned long delay_timer_line_3 = 0;
unsigned long timer_line_1 = 0;
unsigned long timer_line_2 = 0;
unsigned long timer_line_3 = 0;

boolean couldBeep = false;
boolean beepStatus = false;
boolean mode1BeepStatus = false;
boolean mode1Beep2Status = false;
boolean keyWorked = false;
boolean recordsSecTimerFlg = false;

boolean ssr_line_1_worked = false;
boolean ssr_line_2_worked = false;
boolean ssr_line_3_worked = false;

boolean ssr_line_1_down = false;
boolean ssr_line_2_down = false;

boolean ssr_line_1_init = false;
boolean ssr_line_2_init = false;
boolean ssr_line_3_init = false;

boolean sleepMode = false;
boolean rocketFlyBack = false;
boolean eepromWritingComplete = false;
boolean turn3Mode = false;

int myAltitude;
int sUmErMax;
int altitudeNorm;
int maxAltitude = 0;
int beepTimerDuration = 100;
int measureCurrent = 0;

int altitudes[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int altitudesSorted[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int dA[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
byte currentAltitudesInd = 0;
const byte FILTER_SIZE = 10;



byte rocketMode = 1;

//Adafruit_BMP280 bmp;
Adafruit_BMP085 bmp;

#define adc_disable() (ADCSRA &= ~(1<<ADEN))
#define adc_enable()  (ADCSRA |=  (1<<ADEN))
#define KEY_LINE_1_PROC_DURATION 3000
#define KEY_LINE_2_PROC_DURATION 3000
#define KEY_LINE_3_PROC_DURATION 3000

//задержки мс инициации ключей после определения прохождения аппогея
#define DELAY_LINE_1 0
#define DELAY_LINE_2 5000
#define DELAY_WAITING_2STAGE_START 5000
#define DELAY_RF_FLY_START 30000


#define MAX_ALTITUDE_EEPROM 0
#define ALTITUDE_IND_EEPROM 2
#define CHECK_APOGEY_EEPROM 4
#define REC_DURATION_EEPROM 6
#define RECORDS_RATE_EEPROM 8
#define MIDDLE_ALT_I_EEPROM 10


void setup(void)
{

  Serial.begin(9600);

  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);

  pinMode(PIN_LED, OUTPUT);
  pinMode(PIN_SSR_LINE_1, OUTPUT);
  pinMode(PIN_SSR_LINE_2, OUTPUT);
  pinMode(PIN_SSR_LINE_3, OUTPUT);
  pinMode(PIN_BEEP, OUTPUT);

  delay(50);

  if (!bmp.begin()) {
    digitalWrite(PIN_BEEP, HIGH);
    digitalWrite(PIN_RF, HIGH);
    digitalWrite(PIN_LED, HIGH);
    while (1);
  }

  delay(50);

  int ar1 = analogRead(A1);
  int ar2 = analogRead(A2);
  int ar3 = analogRead(A3);

  couldBeep = true;

  if (ar1 > 900) {
    digitalWrite(PIN_BEEP, HIGH);
    digitalWrite(PIN_RF, HIGH);
    digitalWrite(PIN_LED, HIGH);
    delay(1000);
    digitalWrite(PIN_BEEP, LOW);
    digitalWrite(PIN_RF, LOW);
    digitalWrite(PIN_LED, LOW);
    delay(100);

    if (ar2 > 900) {
      digitalWrite(PIN_BEEP, HIGH);
      digitalWrite(PIN_RF, HIGH);
      digitalWrite(PIN_LED, HIGH);
      delay(100);
      digitalWrite(PIN_BEEP, LOW);
      digitalWrite(PIN_RF, LOW);
      digitalWrite(PIN_LED, LOW);
      delay(100);
      digitalWrite(PIN_BEEP, HIGH);
      digitalWrite(PIN_RF, HIGH);
      digitalWrite(PIN_LED, HIGH);
      delay(100);
      digitalWrite(PIN_BEEP, LOW);
      digitalWrite(PIN_RF, LOW);
      digitalWrite(PIN_LED, LOW);
      delay(1000);

      if (ar3 > 900) {
        digitalWrite(PIN_BEEP, HIGH);
        digitalWrite(PIN_RF, HIGH);
        digitalWrite(PIN_LED, HIGH);
        delay(100);
        digitalWrite(PIN_BEEP, LOW);
        digitalWrite(PIN_RF, LOW);
        digitalWrite(PIN_LED, LOW);
        delay(100);
        digitalWrite(PIN_BEEP, HIGH);
        digitalWrite(PIN_RF, HIGH);
        digitalWrite(PIN_LED, HIGH);
        delay(100);
        digitalWrite(PIN_BEEP, LOW);
        digitalWrite(PIN_RF, LOW);
        digitalWrite(PIN_LED, LOW);
        delay(100);
        digitalWrite(PIN_BEEP, HIGH);
        digitalWrite(PIN_RF, HIGH);
        digitalWrite(PIN_LED, HIGH);
        delay(100);
        digitalWrite(PIN_BEEP, LOW);
        digitalWrite(PIN_RF, LOW);
        digitalWrite(PIN_LED, LOW);
        delay(1000);
      }
    }
  }


  checkSerial();


  altitudeNorm = bmp.readAltitude();
  RF_Beeping = millis() + DELAY_RF_FLY_START;
}


void loop() {
  int mAA;
  long aSm;
  int i;
  int j;
  int h;
  long sUmEr;

  pinMode (PIN_RF, OUTPUT);

  if (sleepMode) {

    proc1();

    digitalWrite(PIN_LED, HIGH);
    if (couldBeep) digitalWrite(PIN_BEEP, HIGH);
    delay(30);
    digitalWrite(PIN_LED, LOW);
    digitalWrite(PIN_BEEP, LOW);

    pinMode (PIN_RF, INPUT);

    adc_disable();
    MCUSR = 0;
    WDTCSR = bit (WDCE) | bit (WDE);
    WDTCSR = bit (WDIE) | bit (WDP2) | bit (WDP1);
    wdt_reset();
    set_sleep_mode (SLEEP_MODE_PWR_DOWN);
    sleep_enable();
    MCUCR = bit (BODS) | bit (BODSE);
    MCUCR = bit (BODS);
    sleep_cpu ();
    sleep_disable();
  }
  else
  {
    if (beepTimer < millis()) {

      beepTimer = millis() + beepTimerDuration;

      myAltitude = bmp.readAltitude() - altitudeNorm;

      if (myAltitude > maxAltitude) {
        maxAltitude = myAltitude;
      }

      altitudes[currentAltitudesInd] = myAltitude;

      //sort altitudes array
      switch (currentAltitudesInd) {
        case 0:
          altitudesSorted[FILTER_SIZE - 1] = altitudes[0];
          for (i = 0; i < FILTER_SIZE - 1; i++) {
            altitudesSorted[i] = altitudes[i + 1];
          }
          break;
        case FILTER_SIZE:
          for (i = 0; i < FILTER_SIZE; i++) {
            altitudesSorted[i] = altitudes[i];
          }
          break;
        default:
          j = 0;
          for (i = currentAltitudesInd + 1; i < FILTER_SIZE; i++) {
            altitudesSorted[j] = altitudes[i];
            j++;
          }
          h = 0;
          for (i = j; i < FILTER_SIZE; i++) {
            altitudesSorted[i] = altitudes[h];
            h++;
          }
      }

      for (i = 1; i < FILTER_SIZE; i++) {
        dA[i - 1] = altitudesSorted[i] - altitudesSorted[i - 1];
      }

      sUmEr = 0;
      for (i = 0; i < FILTER_SIZE; i++) {
        aSm = aSm + dA[i];
        sUmEr = sUmEr + altitudes[i];
      }

      mAA = aSm / FILTER_SIZE;

      sUmEr = sUmEr / FILTER_SIZE;

      if (sUmEr > sUmErMax) {
        sUmErMax = sUmEr;
      }

      currentAltitudesInd++;

      if ( currentAltitudesInd > FILTER_SIZE - 1) {
        currentAltitudesInd = 0;
      }

      switch (rocketMode) {
        case 1:

          beepStatus = !beepStatus;
          if (beepStatus) {
            mode1BeepStatus = !mode1BeepStatus;
          }
          if (mode1BeepStatus) {
            mode1Beep2Status = !mode1Beep2Status;
          }

          if (mode1Beep2Status) {
            digitalWrite(PIN_LED, HIGH);
            if (RF_Beeping > millis()) {
              tone(PIN_RF, 540);
            }
          }
          else
          {
            digitalWrite(PIN_LED, LOW);
            noTone(PIN_RF);
          }

          if (myAltitude > cAltitude) {
            maxAltitude = 0;
            EEPROMWriteInt(0, 0);
            EEPROMWriteInt(2, 0);
            EEPROMWriteInt(4, 0);
            EEPROMWriteInt(6, 0);
            EEPROMWriteInt(8, 0);
            EEPROMWriteInt(10, 0);

            measureCurrent = FILTER_SIZE;

            flyTimeStart = millis();
            rocketMode = 2;

            for (i = 0; i < FILTER_SIZE; i++) {
              EEPROMWriteInt(startEEPPROMWriting + i + i, altitudesSorted[i]);
            }

            waiting2StageStart = millis() + DELAY_WAITING_2STAGE_START;
          }
          break;
        case 2:
          beepStatus = !beepStatus;

          if (beepStatus) {
            digitalWrite(PIN_LED, HIGH);
          }
          else
          {
            digitalWrite(PIN_LED, LOW);
          }

          tone(PIN_RF, myAltitude);

          if (myAltitude > cS2Altitude && !ssr_line_3_init) {
            ssr_line_3_init = true;
            delay_timer_line_3 = millis() + KEY_LINE_3_PROC_DURATION;
            digitalWrite(PIN_SSR_LINE_3, HIGH);
          }

          if (ssr_line_3_init && delay_timer_line_3 < millis() && !ssr_line_3_worked) {
            digitalWrite(PIN_SSR_LINE_3, LOW);
            ssr_line_3_worked = true;
          }

          if ((mAA < 0) && !rocketFlyBack && (sUmEr < sUmErMax) && (myAltitude > cAltitude) && (waiting2StageStart < millis())) {
            rocketFlyBack = true;

            EEPROMWriteInt(MAX_ALTITUDE_EEPROM, maxAltitude);
            int timeToCheckAppogeyInMillis = millis() - flyTimeStart;
            EEPROMWriteInt(CHECK_APOGEY_EEPROM, timeToCheckAppogeyInMillis);
            EEPROMWriteInt(ALTITUDE_IND_EEPROM, measureCurrent);
            EEPROMWriteInt(MIDDLE_ALT_I_EEPROM, sUmEr);

            delay_timer_line_1 = millis() + DELAY_LINE_1;
            ssr_line_1_init = true;

            delay_timer_line_2 = millis() + DELAY_LINE_2;
            ssr_line_2_init = true;
          }

          if (ssr_line_1_init && !ssr_line_1_worked && delay_timer_line_1 < millis()) {
            ssr_line_1_worked = true;
            timer_line_1 = millis() + KEY_LINE_1_PROC_DURATION;
            digitalWrite(PIN_SSR_LINE_1, HIGH);
          }

          if (ssr_line_2_init && !ssr_line_2_worked && delay_timer_line_2 < millis()) {
            ssr_line_2_worked = true;
            timer_line_2 = millis() + KEY_LINE_2_PROC_DURATION;
            digitalWrite(PIN_SSR_LINE_2, HIGH);
          }

          if ((timer_line_1 < millis()) && ssr_line_1_worked && !ssr_line_1_down) {
            digitalWrite(PIN_SSR_LINE_1, LOW);
            ssr_line_1_down = true;
          }

          if ((timer_line_2 < millis()) && ssr_line_2_worked && !ssr_line_2_down) {
            digitalWrite(PIN_SSR_LINE_2, LOW);
            ssr_line_2_down = true;
          }

          if (ssr_line_1_down && ssr_line_2_down) {
            turn3Mode = true;
          }

          if (!eepromWritingComplete) {
            EEPROMWriteInt(startEEPPROMWriting + measureCurrent + measureCurrent, myAltitude);
            measureCurrent++;
            if (measureCurrent > measureQuantity) {
              eepromWritingComplete = true;
              int recordsTime = (millis() - flyTimeStart) / 10;
              EEPROMWriteInt(REC_DURATION_EEPROM, recordsTime);
              int speedOfRecordInSec = recordsTime / measureQuantity;
              speedOfRecordInSec = 100 / speedOfRecordInSec;
              EEPROMWriteInt(RECORDS_RATE_EEPROM, speedOfRecordInSec);
            }
          }

          if (turn3Mode && eepromWritingComplete) {
            rocketMode = 3;
          }

          break;
        case 3:
          playExitFlyModeAction();
          sleepMode = true;
          break;
      }
    }
  }
}

void playExitFlyModeAction() {
  tone(PIN_RF, 940);
  digitalWrite(PIN_LED, HIGH);
  delay(500);
  digitalWrite(PIN_LED, LOW);
  tone(PIN_RF, 840);
  delay(500);
  digitalWrite(PIN_LED, HIGH);
  tone(PIN_RF, 740);
  delay(500);
  digitalWrite(PIN_LED, LOW);
  tone(PIN_RF, 640);
  delay(500);
  digitalWrite(PIN_LED, HIGH);
  tone(PIN_RF, 540);
  delay(1000);
  digitalWrite(PIN_LED, LOW);
  noTone(PIN_RF);
  delay(2000);

  sendAltitude();
  delay(5000);

  sendAltitude();
  delay(5000);

  sendAltitude();
  delay(5000);

  sendAltitude();
  delay(5000);

  sendAltitude();
  delay(5000);
}

void proc0() {
  tone(PIN_RF, 450);
  delay(DURATION_0);
  noTone(PIN_RF);
}

void proc1() {
  tone(PIN_RF, 550);
  delay(DURATION_1);
  noTone(PIN_RF);
}

void checkSerial() {
  delay(3000);

  if (Serial.available()) {

    Serial.println();
    Serial.print("maxAltitude:    ");
    Serial.print(EEPROMReadInt(MAX_ALTITUDE_EEPROM));
    Serial.println(" m");
    Serial.println();

    Serial.print("Altitude Index Pyro Initiated:    ");
    Serial.print(EEPROMReadInt(ALTITUDE_IND_EEPROM));
    Serial.println(" ");
    Serial.println();

    Serial.print("Midde Altitude Pyro Initiated:    ");
    Serial.print(EEPROMReadInt(MIDDLE_ALT_I_EEPROM));
    Serial.println(" m");
    Serial.println();

    Serial.print("timeToCheckAppogey:    ");
    Serial.print(EEPROMReadInt(CHECK_APOGEY_EEPROM));
    Serial.println(" millis");
    Serial.println();

    Serial.print("recordsTimeInMillis/10:    ");
    Serial.print(EEPROMReadInt(REC_DURATION_EEPROM));
    Serial.println(" millis");
    Serial.println();

    Serial.print("recordsRate:    ");
    Serial.print(EEPROMReadInt(RECORDS_RATE_EEPROM));
    Serial.println(" records/sec");
    Serial.println();


    Serial.println("log:   ");
    float j = 0;
    for (int i = startEEPPROMWriting; i < (measureQuantity + measureQuantity + 1); i += 2) {
      Serial.print(EEPROMReadInt(i));
      Serial.println();
      delay(50);
    }
  }
}


void EEPROMWriteInt (int p_address, int p_value)
{
  byte lowByte = EEPROM.read(p_address);
  byte highByte = EEPROM.read(p_address + 1);
  int val = ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
  if (val != p_value) {
    byte lowByte = ((p_value >> 0) & 0xFF);
    byte highByte = ((p_value >> 8) & 0xFF);
    EEPROM.write(p_address, lowByte);
    EEPROM.write(p_address + 1, highByte);
  }
}

int EEPROMReadInt(int p_address)
{
  byte lowByte = EEPROM.read(p_address);
  byte highByte = EEPROM.read(p_address + 1);
  return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
}

ISR (WDT_vect)
{
  wdt_disable();
}

void sendAltitude() {
  String beaconData = String(maxAltitude);
  String oneStr = "";

  delay(1000);
  int d2RF;
  for (int i = 0; i < beaconData.length(); i++ ) {
    d2RF = 0;
    oneStr += beaconData.charAt(i);
    d2RF = oneStr.toInt();
    send_d2RF(d2RF);
    delay(1000);
    oneStr = "";
  }
}

void send_d2RF(int d2RF) {
  switch (d2RF) {
    case 0:
      proc0();
      break;
    case 1:
      proc1();
      break;
    case 2:
      proc1();
      delay(SPLITTER);
      proc0();
      break;
    case 3:
      proc1();
      delay(SPLITTER);
      proc1();
      break;
    case 4:
      proc1();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc0();
      break;
    case 5:
      proc1();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc1();
      break;
    case 6:
      proc1();
      delay(SPLITTER);
      proc1();
      delay(SPLITTER);
      proc0();
      break;
    case 7:
      proc1();
      delay(SPLITTER);
      proc1();
      delay(SPLITTER);
      proc1();
      break;
    case 8:
      proc1();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc0();
      break;
    case 9:
      proc1();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc1();
      break;
  }
}

 

gmurvs
Offline
Зарегистрирован: 15.04.2014

оптимизация кода и алгоритма определения апогея, доработано под BMP280

gmurvs
Offline
Зарегистрирован: 15.04.2014
// IRP.1.3 FOR MRIA & 75 2S & 40

//#include <Adafruit_BMP280.h>
#include <Adafruit_BMP085.h>

#include <EEPROM.h>

#include  <avr/sleep.h>
#include  <avr/wdt.h>

const byte PIN_RF = 11;
const byte SPLITTER = 200;
const int DURATION_0 = 550;
const int DURATION_1 = 350;
const byte PIN_SSR_LINE_1 = 8; // ключ для инициации первой мортиры (тормозной парашют)
const byte PIN_SSR_LINE_2 = 10; // ключ для инициации второй мортиры (основной парашют)
const byte PIN_SSR_LINE_3 = 7; // ключ для инициации мотора второй ступени
const byte PIN_BEEP = 9;
const byte PIN_LED = 3;

const byte cAltitude = 5; //высота активации режима "полет"
const byte cS2Altitude = 7; //высота активации ключа для запуска второй ступени
const int measureQuantity = 480; // длина лога данных (ограничена емкостью ПЗУ)

const byte startEEPPROMWriting = 20;

unsigned long beepTimer = 0;
unsigned long flyTimeStart = 0;
unsigned long waiting2StageStart = 0;
unsigned long RF_Beeping = 0;
unsigned long delay_timer_line_1 = 0;
unsigned long delay_timer_line_2 = 0;
unsigned long delay_timer_line_3 = 0;
unsigned long timer_line_1 = 0;
unsigned long timer_line_2 = 0;
unsigned long timer_line_3 = 0;

boolean couldBeep = false;
boolean beepStatus = false;
boolean mode1BeepStatus = false;
boolean mode1Beep2Status = false;
boolean keyWorked = false;
boolean recordsSecTimerFlg = false;

boolean ssr_line_1_worked = false;
boolean ssr_line_2_worked = false;
boolean ssr_line_3_worked = false;

boolean ssr_line_1_down = false;
boolean ssr_line_2_down = false;

boolean ssr_line_1_init = false;
boolean ssr_line_2_init = false;
boolean ssr_line_3_init = false;

boolean sleepMode = false;
boolean rocketFlyBack = false;
boolean eepromWritingComplete = false;
boolean turn3Mode = false;

int myAltitude;
int sUmErMax;
int altitudeNorm;
int maxAltitude = 0;
int beepTimerDuration = 100;
int measureCurrent = 0;

int altitudes[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int altitudesSorted[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int dA[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
byte currentAltitudesInd = 0;
const byte FILTER_SIZE = 10;



byte rocketMode = 1;

//Adafruit_BMP280 bmp;
Adafruit_BMP085 bmp;

#define adc_disable() (ADCSRA &= ~(1<<ADEN))
#define adc_enable()  (ADCSRA |=  (1<<ADEN))
#define KEY_LINE_1_PROC_DURATION 5000
#define KEY_LINE_2_PROC_DURATION 5000
#define KEY_LINE_3_PROC_DURATION 5000

//задержки мс инициации ключей после определения прохождения аппогея
#define DELAY_LINE_1 0
#define DELAY_LINE_2 10000
#define DELAY_WAITING_2STAGE_START 5000
#define DELAY_RF_FLY_START 60000


#define MAX_ALTITUDE_EEPROM 0
#define ALTITUDE_IND_EEPROM 2
#define CHECK_APOGEY_EEPROM 4
#define REC_DURATION_EEPROM 6
#define RECORDS_RATE_EEPROM 8
#define MIDDLE_ALT_I_EEPROM 10


void setup(void)
{

  Serial.begin(9600);

  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);

  pinMode(PIN_LED, OUTPUT);
  pinMode(PIN_SSR_LINE_1, OUTPUT);
  pinMode(PIN_SSR_LINE_2, OUTPUT);
  pinMode(PIN_SSR_LINE_3, OUTPUT);
  pinMode(PIN_BEEP, OUTPUT);

  delay(50);

  if (!bmp.begin()) {
    digitalWrite(PIN_BEEP, HIGH);
    digitalWrite(PIN_RF, HIGH);
    digitalWrite(PIN_LED, HIGH);
    while (1);
  }

  delay(50);

  int ar1 = analogRead(A1);
  int ar2 = analogRead(A2);
  int ar3 = analogRead(A3);

  couldBeep = true;

  if (ar1 > 900) {
    digitalWrite(PIN_BEEP, HIGH);
    digitalWrite(PIN_RF, HIGH);
    digitalWrite(PIN_LED, HIGH);
    delay(1000);
    digitalWrite(PIN_BEEP, LOW);
    digitalWrite(PIN_RF, LOW);
    digitalWrite(PIN_LED, LOW);
    delay(100);

    if (ar2 > 900) {
      digitalWrite(PIN_BEEP, HIGH);
      digitalWrite(PIN_RF, HIGH);
      digitalWrite(PIN_LED, HIGH);
      delay(100);
      digitalWrite(PIN_BEEP, LOW);
      digitalWrite(PIN_RF, LOW);
      digitalWrite(PIN_LED, LOW);
      delay(100);
      digitalWrite(PIN_BEEP, HIGH);
      digitalWrite(PIN_RF, HIGH);
      digitalWrite(PIN_LED, HIGH);
      delay(100);
      digitalWrite(PIN_BEEP, LOW);
      digitalWrite(PIN_RF, LOW);
      digitalWrite(PIN_LED, LOW);
      delay(1000);

      if (ar3 > 900) {
        digitalWrite(PIN_BEEP, HIGH);
        digitalWrite(PIN_RF, HIGH);
        digitalWrite(PIN_LED, HIGH);
        delay(100);
        digitalWrite(PIN_BEEP, LOW);
        digitalWrite(PIN_RF, LOW);
        digitalWrite(PIN_LED, LOW);
        delay(100);
        digitalWrite(PIN_BEEP, HIGH);
        digitalWrite(PIN_RF, HIGH);
        digitalWrite(PIN_LED, HIGH);
        delay(100);
        digitalWrite(PIN_BEEP, LOW);
        digitalWrite(PIN_RF, LOW);
        digitalWrite(PIN_LED, LOW);
        delay(100);
        digitalWrite(PIN_BEEP, HIGH);
        digitalWrite(PIN_RF, HIGH);
        digitalWrite(PIN_LED, HIGH);
        delay(100);
        digitalWrite(PIN_BEEP, LOW);
        digitalWrite(PIN_RF, LOW);
        digitalWrite(PIN_LED, LOW);
        delay(1000);
      }
    }
  }


  checkSerial();


  altitudeNorm = bmp.readAltitude();
  RF_Beeping = millis() + DELAY_RF_FLY_START;
}


void loop() {
  int mAA;
  long aSm;
  int i;
  int j;
  int h;
  long sUmEr;

  pinMode (PIN_RF, OUTPUT);

  if (sleepMode) {

    proc1();

    digitalWrite(PIN_LED, HIGH);
    if (couldBeep) digitalWrite(PIN_BEEP, HIGH);
    delay(30);
    digitalWrite(PIN_LED, LOW);
    digitalWrite(PIN_BEEP, LOW);

    pinMode (PIN_RF, INPUT);

    adc_disable();
    MCUSR = 0;
    WDTCSR = bit (WDCE) | bit (WDE);
    WDTCSR = bit (WDIE) | bit (WDP2) | bit (WDP1);
    wdt_reset();
    set_sleep_mode (SLEEP_MODE_PWR_DOWN);
    sleep_enable();
    MCUCR = bit (BODS) | bit (BODSE);
    MCUCR = bit (BODS);
    sleep_cpu ();
    sleep_disable();
  }
  else
  {
    if (beepTimer < millis()) {

      beepTimer = millis() + beepTimerDuration;

      myAltitude = bmp.readAltitude() - altitudeNorm;

      if (myAltitude > maxAltitude) {
        maxAltitude = myAltitude;
      }

      altitudes[currentAltitudesInd] = myAltitude;

      //sort altitudes array
      switch (currentAltitudesInd) {
        case 0:
          altitudesSorted[FILTER_SIZE - 1] = altitudes[0];
          for (i = 0; i < FILTER_SIZE - 1; i++) {
            altitudesSorted[i] = altitudes[i + 1];
          }
          break;
        case FILTER_SIZE:
          for (i = 0; i < FILTER_SIZE; i++) {
            altitudesSorted[i] = altitudes[i];
          }
          break;
        default:
          j = 0;
          for (i = currentAltitudesInd + 1; i < FILTER_SIZE; i++) {
            altitudesSorted[j] = altitudes[i];
            j++;
          }
          h = 0;
          for (i = j; i < FILTER_SIZE; i++) {
            altitudesSorted[i] = altitudes[h];
            h++;
          }
      }

      for (i = 1; i < FILTER_SIZE; i++) {
        dA[i - 1] = altitudesSorted[i] - altitudesSorted[i - 1];
      }

      sUmEr = 0;
      for (i = 0; i < FILTER_SIZE; i++) {
        aSm = aSm + dA[i];
        sUmEr = sUmEr + altitudes[i];
      }

      mAA = aSm / FILTER_SIZE;

      sUmEr = sUmEr / FILTER_SIZE;

      if (sUmEr > sUmErMax) {
        sUmErMax = sUmEr;
      }

      currentAltitudesInd++;

      if ( currentAltitudesInd > FILTER_SIZE - 1) {
        currentAltitudesInd = 0;
      }

      switch (rocketMode) {
        case 1:

          beepStatus = !beepStatus;
          if (beepStatus) {
            mode1BeepStatus = !mode1BeepStatus;
          }
          if (mode1BeepStatus) {
            mode1Beep2Status = !mode1Beep2Status;
          }

          if (mode1Beep2Status) {
            digitalWrite(PIN_LED, HIGH);
            if (RF_Beeping > millis()) {
              tone(PIN_RF, 540);
            }
          }
          else
          {
            digitalWrite(PIN_LED, LOW);
            noTone(PIN_RF);
          }

          if (myAltitude > cAltitude) {
            maxAltitude = 0;
            EEPROMWriteInt(0, 0);
            EEPROMWriteInt(2, 0);
            EEPROMWriteInt(4, 0);
            EEPROMWriteInt(6, 0);
            EEPROMWriteInt(8, 0);
            EEPROMWriteInt(10, 0);

            measureCurrent = FILTER_SIZE;

            flyTimeStart = millis();
            rocketMode = 2;

            for (i = 0; i < FILTER_SIZE; i++) {
              EEPROMWriteInt(startEEPPROMWriting + i + i, altitudesSorted[i]);
            }

            waiting2StageStart = millis() + DELAY_WAITING_2STAGE_START;
          }
          break;
        case 2:
          beepStatus = !beepStatus;

          if (beepStatus) {
            digitalWrite(PIN_LED, HIGH);
          }
          else
          {
            digitalWrite(PIN_LED, LOW);
          }

          tone(PIN_RF, myAltitude);

          if (myAltitude > cS2Altitude && !ssr_line_3_init) {
            ssr_line_3_init = true;
            delay_timer_line_3 = millis() + KEY_LINE_3_PROC_DURATION;
            digitalWrite(PIN_SSR_LINE_3, HIGH);
          }

          if (ssr_line_3_init && delay_timer_line_3 < millis() && !ssr_line_3_worked) {
            digitalWrite(PIN_SSR_LINE_3, LOW);
            ssr_line_3_worked = true;
          }

          if ((mAA < 0) && !rocketFlyBack && (sUmEr < sUmErMax) && (myAltitude > cAltitude) && (waiting2StageStart < millis())) {
            rocketFlyBack = true;

            EEPROMWriteInt(MAX_ALTITUDE_EEPROM, maxAltitude);
            int timeToCheckAppogeyInMillis = millis() - flyTimeStart;
            EEPROMWriteInt(CHECK_APOGEY_EEPROM, timeToCheckAppogeyInMillis);
            EEPROMWriteInt(ALTITUDE_IND_EEPROM, measureCurrent);
            EEPROMWriteInt(MIDDLE_ALT_I_EEPROM, sUmEr);

            delay_timer_line_1 = millis() + DELAY_LINE_1;
            ssr_line_1_init = true;

            delay_timer_line_2 = millis() + DELAY_LINE_2;
            ssr_line_2_init = true;
          }

          if (ssr_line_1_init && !ssr_line_1_worked && delay_timer_line_1 < millis()) {
            ssr_line_1_worked = true;
            timer_line_1 = millis() + KEY_LINE_1_PROC_DURATION;
            digitalWrite(PIN_SSR_LINE_1, HIGH);
          }

          if (ssr_line_2_init && !ssr_line_2_worked && delay_timer_line_2 < millis()) {
            ssr_line_2_worked = true;
            timer_line_2 = millis() + KEY_LINE_2_PROC_DURATION;
            digitalWrite(PIN_SSR_LINE_2, HIGH);
          }

          if ((timer_line_1 < millis()) && ssr_line_1_worked && !ssr_line_1_down) {
            digitalWrite(PIN_SSR_LINE_1, LOW);
            ssr_line_1_down = true;
          }

          if ((timer_line_2 < millis()) && ssr_line_2_worked && !ssr_line_2_down) {
            digitalWrite(PIN_SSR_LINE_2, LOW);
            ssr_line_2_down = true;
          }

          if (ssr_line_1_down && ssr_line_2_down) {
            turn3Mode = true;
          }

          if (!eepromWritingComplete) {
            EEPROMWriteInt(startEEPPROMWriting + measureCurrent + measureCurrent, myAltitude);
            measureCurrent++;
            if (measureCurrent > measureQuantity) {
              eepromWritingComplete = true;
              int recordsTime = (millis() - flyTimeStart) / 10;
              EEPROMWriteInt(REC_DURATION_EEPROM, recordsTime);
              int speedOfRecordInSec = recordsTime / measureQuantity;
              speedOfRecordInSec = 100 / speedOfRecordInSec;
              EEPROMWriteInt(RECORDS_RATE_EEPROM, speedOfRecordInSec);
            }
          }

          if (turn3Mode &&
          eepromWritingComplete) {
            rocketMode = 3;
          }

          break;
        case 3:
          playExitFlyModeAction();
          sleepMode = true;
          break;
      }
    }
  }
}

void playExitFlyModeAction() {
  tone(PIN_RF, 940);
  digitalWrite(PIN_LED, HIGH);
  delay(500);
  digitalWrite(PIN_LED, LOW);
  tone(PIN_RF, 840);
  delay(500);
  digitalWrite(PIN_LED, HIGH);
  tone(PIN_RF, 740);
  delay(500);
  digitalWrite(PIN_LED, LOW);
  tone(PIN_RF, 640);
  delay(500);
  digitalWrite(PIN_LED, HIGH);
  tone(PIN_RF, 540);
  delay(1000);
  digitalWrite(PIN_LED, LOW);
  noTone(PIN_RF);
  delay(2000);

  sendAltitude();
  delay(5000);

  sendAltitude();
  delay(5000);

  sendAltitude();
  delay(5000);

  sendAltitude();
  delay(5000);

  sendAltitude();
  delay(5000);
}

void proc0() {
  tone(PIN_RF, 450);
  delay(DURATION_0);
  noTone(PIN_RF);
}

void proc1() {
  tone(PIN_RF, 550);
  delay(DURATION_1);
  noTone(PIN_RF);
}

void checkSerial() {
  delay(3000);

  if (Serial.available()) {

    String myStr = Serial.readStringUntil('\n');
    if (myStr.compareTo("clear") == 0) {

      digitalWrite(PIN_BEEP, HIGH);
      delay(2000);

      for (int i = 0 ; i < EEPROM.length() ; i++) {
        EEPROM.write(i, 0);
      }

      digitalWrite(PIN_BEEP, LOW);
    }


    Serial.println();
    Serial.print("maxAltitude:    ");
    Serial.print(EEPROMReadInt(MAX_ALTITUDE_EEPROM));
    Serial.println(" m");
    Serial.println();

    Serial.print("Altitude Index Pyro Initiated:    ");
    Serial.print(EEPROMReadInt(ALTITUDE_IND_EEPROM));
    Serial.println(" ");
    Serial.println();

    Serial.print("Middle Altitude Pyro Initiated:    ");
    Serial.print(EEPROMReadInt(MIDDLE_ALT_I_EEPROM));
    Serial.println(" m");
    Serial.println();

    Serial.print("timeToCheckAppogey:    ");
    Serial.print(EEPROMReadInt(CHECK_APOGEY_EEPROM));
    Serial.println(" millis");
    Serial.println();

    Serial.print("recordsTimeInMillis/10:    ");
    Serial.print(EEPROMReadInt(REC_DURATION_EEPROM));
    Serial.println(" millis");
    Serial.println();

    Serial.print("recordsRate:    ");
    Serial.print(EEPROMReadInt(RECORDS_RATE_EEPROM));
    Serial.println(" records/sec");
    Serial.println();


    Serial.println("log:   ");
    float j = 0;
    for (int i = startEEPPROMWriting; i < (measureQuantity + measureQuantity + 1); i += 2) {
      Serial.print(EEPROMReadInt(i));
      Serial.println();
      delay(50);
    }
  }
}


void EEPROMWriteInt (int p_address, int p_value)
{
  byte lowByte = EEPROM.read(p_address);
  byte highByte = EEPROM.read(p_address + 1);
  int val = ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
  if (val != p_value) {
    byte lowByte = ((p_value >> 0) & 0xFF);
    byte highByte = ((p_value >> 8) & 0xFF);
    EEPROM.write(p_address, lowByte);
    EEPROM.write(p_address + 1, highByte);
  }
}

int EEPROMReadInt(int p_address)
{
  byte lowByte = EEPROM.read(p_address);
  byte highByte = EEPROM.read(p_address + 1);
  return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
}

ISR (WDT_vect)
{
  wdt_disable();
}

void sendAltitude() {
  String beaconData = String(maxAltitude);
  String oneStr = "";

  delay(1000);
  int d2RF;
  for (int i = 0; i < beaconData.length(); i++ ) {
    d2RF = 0;
    oneStr += beaconData.charAt(i);
    d2RF = oneStr.toInt();
    send_d2RF(d2RF);
    delay(1000);
    oneStr = "";
  }
}

void send_d2RF(int d2RF) {
  switch (d2RF) {
    case 0:
      proc0();
      break;
    case 1:
      proc1();
      break;
    case 2:
      proc1();
      delay(SPLITTER);
      proc0();
      break;
    case 3:
      proc1();
      delay(SPLITTER);
      proc1();
      break;
    case 4:
      proc1();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc0();
      break;
    case 5:
      proc1();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc1();
      break;
    case 6:
      proc1();
      delay(SPLITTER);
      proc1();
      delay(SPLITTER);
      proc0();
      break;
    case 7:
      proc1();
      delay(SPLITTER);
      proc1();
      delay(SPLITTER);
      proc1();
      break;
    case 8:
      proc1();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc0();
      break;
    case 9:
      proc1();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc1();
      break;
  }
}

 

gmurvs
Offline
Зарегистрирован: 15.04.2014
// IRP.1.4 FOR MRIA & 75 2S & 40

//#include <Adafruit_BMP280.h>
#include <Adafruit_BMP085.h>

#include <EEPROM.h>

#include  <avr/sleep.h>
#include  <avr/wdt.h>

const byte PIN_RF = 11;
const byte SPLITTER = 200;
const int DURATION_0 = 550;
const int DURATION_1 = 350;
const byte PIN_SSR_LINE_1 = 8; // ключ для инициации первой мортиры (тормозной парашют)
const byte PIN_SSR_LINE_2 = 10; // ключ для инициации второй мортиры (основной парашют)
const byte PIN_SSR_LINE_3 = 7; // ключ для инициации мотора второй ступени
const byte PIN_BEEP = 9;
const byte PIN_LED = 3;

const byte cAltitude = 5; //высота активации режима "полет"
const byte cS2Altitude = 10; //высота активации ключа для запуска второй ступени
const int measureQuantity = 480; // длина лога данных (ограничена емкостью ПЗУ)

const byte startEEPPROMWriting = 20;

unsigned long beepTimer = 0;
unsigned long flyTimeStart = 0;
unsigned long waiting2StageStart = 0;
unsigned long delay_timer_line_1 = 0;
unsigned long delay_timer_line_2 = 0;
unsigned long delay_timer_line_3 = 0;
unsigned long timer_line_1 = 0;
unsigned long timer_line_2 = 0;
unsigned long timer_line_3 = 0;

boolean couldBeep = false;
boolean beepStatus = false;
boolean mode1BeepStatus = false;
boolean mode1Beep2Status = false;
boolean mode1Beep4Status = false;
boolean mode1Beep8Status = false;
boolean keyWorked = false;
boolean recordsSecTimerFlg = false;

boolean ssr_line_1_worked = false;
boolean ssr_line_2_worked = false;
boolean ssr_line_3_worked = false;

boolean ssr_line_1_down = false;
boolean ssr_line_2_down = false;

boolean ssr_line_1_init = false;
boolean ssr_line_2_init = false;
boolean ssr_line_3_init = false;

boolean sleepMode = false;
boolean rocketFlyBack = false;
boolean eepromWritingComplete = false;
boolean turn3Mode = false;
boolean line3Ready = false;

int myAltitude;
int sUmErMax;
int altitudeNorm;
int maxAltitude = 0;
int measureCurrent = 0;

int altitudes[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int altitudesSorted[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int dA[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
byte currentAltitudesInd = 0;
const byte FILTER_SIZE = 10;


byte rocketMode = 1;

//Adafruit_BMP280 bmp;
Adafruit_BMP085 bmp;

#define adc_disable() (ADCSRA &= ~(1<<ADEN))
#define adc_enable()  (ADCSRA |=  (1<<ADEN))
#define KEY_LINE_1_PROC_DURATION 3000
#define KEY_LINE_2_PROC_DURATION 3000
#define KEY_LINE_3_PROC_DURATION 3000

//задержки мс инициации ключей после определения прохождения аппогея
#define DELAY_LINE_1 0
#define DELAY_LINE_2 10000
#define DELAY_WAITING_2STAGE_START 5000


#define MAX_ALTITUDE_EEPROM 0
#define ALTITUDE_IND_EEPROM 2
#define CHECK_APOGEY_EEPROM 4
#define REC_DURATION_EEPROM 6
#define RECORDS_RATE_EEPROM 8
#define MIDDLE_ALT_I_EEPROM 10


void setup(void)
{

  Serial.begin(9600);

  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);

  pinMode(PIN_LED, OUTPUT);
  pinMode(PIN_SSR_LINE_1, OUTPUT);
  pinMode(PIN_SSR_LINE_2, OUTPUT);
  pinMode(PIN_SSR_LINE_3, OUTPUT);
  pinMode(PIN_BEEP, OUTPUT);
  pinMode(PIN_RF, OUTPUT);

  delay(50);

  if (!bmp.begin()) {
    digitalWrite(PIN_BEEP, HIGH);
    digitalWrite(PIN_RF, HIGH);
    digitalWrite(PIN_LED, HIGH);
    while (1);
  }

  delay(50);

  int ar1 = analogRead(A1);
  int ar2 = analogRead(A2);
  int ar3 = analogRead(A3);

  couldBeep = true;



  Serial.println(ar1);
  Serial.println(ar2);
  Serial.println(ar3);

  if (ar1 > 900) {
    digitalWrite(PIN_BEEP, HIGH);
    tone(PIN_RF, 540);
    digitalWrite(PIN_LED, HIGH);
    delay(1000);
    digitalWrite(PIN_BEEP, LOW);
    noTone(PIN_RF);
    digitalWrite(PIN_LED, LOW);
    delay(1000);
  }
  if (ar2 > 900) {
    digitalWrite(PIN_BEEP, HIGH);
    tone(PIN_RF, 540);
    digitalWrite(PIN_LED, HIGH);
    delay(100);
    digitalWrite(PIN_BEEP, LOW);
    noTone(PIN_RF);
    digitalWrite(PIN_LED, LOW);
    delay(100);
    digitalWrite(PIN_BEEP, HIGH);
    tone(PIN_RF, 540);
    digitalWrite(PIN_LED, HIGH);
    delay(100);
    digitalWrite(PIN_BEEP, LOW);
    noTone(PIN_RF);
    digitalWrite(PIN_LED, LOW);
    delay(1000);
  }
  if (ar3 > 900) {

    line3Ready = true;

    digitalWrite(PIN_BEEP, HIGH);
    tone(PIN_RF, 540);
    digitalWrite(PIN_LED, HIGH);
    delay(100);
    digitalWrite(PIN_BEEP, LOW);
    noTone(PIN_RF);
    digitalWrite(PIN_LED, LOW);
    delay(100);
    digitalWrite(PIN_BEEP, HIGH);
    tone(PIN_RF, 540);
    digitalWrite(PIN_LED, HIGH);
    delay(100);
    digitalWrite(PIN_BEEP, LOW);
    noTone(PIN_RF);
    digitalWrite(PIN_LED, LOW);
    delay(100);
    digitalWrite(PIN_BEEP, HIGH);
    tone(PIN_RF, 540);
    digitalWrite(PIN_LED, HIGH);
    delay(100);
    digitalWrite(PIN_BEEP, LOW);
    noTone(PIN_RF);
    digitalWrite(PIN_LED, LOW);
    delay(1000);
  }

  checkSerial();

  altitudeNorm = bmp.readAltitude();
}


void loop() {
  int mAA;
  long aSm;
  int i;
  int j;
  int h;
  long sUmEr;

  beepStatus = !beepStatus;

  if (sleepMode) {
    proc1();
    beeper();
    myWatchdogEnable(0b000100); //0,25 s
  }
  else
  {

    myAltitude = bmp.readAltitude() - altitudeNorm;

    if (myAltitude > maxAltitude) {
      maxAltitude = myAltitude;
    }

    altitudes[currentAltitudesInd] = myAltitude;

    //sort altitudes array
    switch (currentAltitudesInd) {
      case 0:
        altitudesSorted[FILTER_SIZE - 1] = altitudes[0];
        for (i = 0; i < FILTER_SIZE - 1; i++) {
          altitudesSorted[i] = altitudes[i + 1];
        }
        break;
      case FILTER_SIZE:
        for (i = 0; i < FILTER_SIZE; i++) {
          altitudesSorted[i] = altitudes[i];
        }
        break;
      default:
        j = 0;
        for (i = currentAltitudesInd + 1; i < FILTER_SIZE; i++) {
          altitudesSorted[j] = altitudes[i];
          j++;
        }
        h = 0;
        for (i = j; i < FILTER_SIZE; i++) {
          altitudesSorted[i] = altitudes[h];
          h++;
        }
    }

    for (i = 1; i < FILTER_SIZE; i++) {
      dA[i - 1] = altitudesSorted[i] - altitudesSorted[i - 1];
    }

    sUmEr = 0;
    for (i = 0; i < FILTER_SIZE; i++) {
      aSm = aSm + dA[i];
      sUmEr = sUmEr + altitudes[i];
    }

    mAA = aSm / FILTER_SIZE;

    sUmEr = sUmEr / FILTER_SIZE;

    if (sUmEr > sUmErMax) {
      sUmErMax = sUmEr;
    }

    currentAltitudesInd++;

    if ( currentAltitudesInd > FILTER_SIZE - 1) {
      currentAltitudesInd = 0;
    }

    switch (rocketMode) {
      case 1:
        if (beepStatus) {
          digitalWrite(PIN_LED, HIGH);
          tone(PIN_RF, 540);
        }
        else
        {
          digitalWrite(PIN_LED, LOW);
          tone(PIN_RF, 0);
        }

        if (myAltitude > cAltitude) {
          maxAltitude = 0;
          EEPROMWriteInt(0, 0);
          EEPROMWriteInt(2, 0);
          EEPROMWriteInt(4, 0);
          EEPROMWriteInt(6, 0);
          EEPROMWriteInt(8, 0);
          EEPROMWriteInt(10, 0);

          measureCurrent = FILTER_SIZE;

          flyTimeStart = millis();
          rocketMode = 2;

          for (i = 0; i < FILTER_SIZE; i++) {
            EEPROMWriteInt(startEEPPROMWriting + i + i, altitudesSorted[i]);
          }

          waiting2StageStart = millis() + DELAY_WAITING_2STAGE_START;
          digitalWrite(PIN_LED, LOW);
        }
        break;
      case 2:

        tone(PIN_RF, myAltitude);

        if (myAltitude > cS2Altitude && !ssr_line_3_init && line3Ready) {
          ssr_line_3_init = true;
          delay_timer_line_3 = millis() + KEY_LINE_3_PROC_DURATION;
          digitalWrite(PIN_SSR_LINE_3, HIGH);
        }

        if (ssr_line_3_init && delay_timer_line_3 < millis() && !ssr_line_3_worked) {
          digitalWrite(PIN_SSR_LINE_3, LOW);
          ssr_line_3_worked = true;
        }

        if ((mAA < 0) && !rocketFlyBack && (sUmEr < sUmErMax) && (myAltitude > cAltitude) && (waiting2StageStart < millis())) {
          rocketFlyBack = true;

          EEPROMWriteInt(MAX_ALTITUDE_EEPROM, maxAltitude);
          int timeToCheckAppogeyInMillis = millis() - flyTimeStart;
          EEPROMWriteInt(CHECK_APOGEY_EEPROM, timeToCheckAppogeyInMillis);
          EEPROMWriteInt(ALTITUDE_IND_EEPROM, measureCurrent);
          EEPROMWriteInt(MIDDLE_ALT_I_EEPROM, sUmEr);

          delay_timer_line_1 = millis() + DELAY_LINE_1;
          ssr_line_1_init = true;

          delay_timer_line_2 = millis() + DELAY_LINE_2;
          ssr_line_2_init = true;
        }

        if (ssr_line_1_init && !ssr_line_1_worked && delay_timer_line_1 < millis()) {
          ssr_line_1_worked = true;
          timer_line_1 = millis() + KEY_LINE_1_PROC_DURATION;
          digitalWrite(PIN_LED, HIGH);
          tone(PIN_RF, 1000);
          beeper();
          digitalWrite(PIN_SSR_LINE_1, HIGH);
        }

        if (ssr_line_2_init && !ssr_line_2_worked && delay_timer_line_2 < millis()) {
          ssr_line_2_worked = true;
          timer_line_2 = millis() + KEY_LINE_2_PROC_DURATION;
          digitalWrite(PIN_SSR_LINE_2, HIGH);
        }

        if (ssr_line_2_init && !ssr_line_2_worked && delay_timer_line_2 > millis() && ssr_line_1_down && myAltitude < 200) {
          ssr_line_2_worked = true;
          timer_line_2 = millis() + KEY_LINE_2_PROC_DURATION;
          digitalWrite(PIN_SSR_LINE_2, HIGH);
        }

        if ((timer_line_1 < millis()) && ssr_line_1_worked && !ssr_line_1_down) {
          digitalWrite(PIN_SSR_LINE_1, LOW);
          ssr_line_1_down = true;
        }

        if ((timer_line_2 < millis()) && ssr_line_2_worked && !ssr_line_2_down) {
          digitalWrite(PIN_SSR_LINE_2, LOW);
          ssr_line_2_down = true;
        }

        if (ssr_line_1_down && ssr_line_2_down) {
          turn3Mode = true;
        }

        if (!eepromWritingComplete) {
          EEPROMWriteInt(startEEPPROMWriting + measureCurrent + measureCurrent, myAltitude);
          measureCurrent++;
          if (measureCurrent > measureQuantity) {
            eepromWritingComplete = true;
            int recordsTime = (millis() - flyTimeStart) / 1000;
            EEPROMWriteInt(REC_DURATION_EEPROM, recordsTime);
            int speedOfRecordInSec = measureQuantity*10 / recordsTime;
            EEPROMWriteInt(RECORDS_RATE_EEPROM, speedOfRecordInSec);
          }
        }

        if (turn3Mode &&
            eepromWritingComplete) {
          rocketMode = 3;
        }

        break;
      case 3:
        //playExitFlyModeAction();
        sleepMode = true;
        break;
    }

    delay(200);
  }
}

void myWatchdogEnable(const byte interval)
{
  // sleep bit patterns:
  //  1 second:  0b000110
  //  2 seconds: 0b000111
  //  4 seconds: 0b100000
  //  8 seconds: 0b100001
  //0,25 seconds: 0b000100

  adc_disable();

  // clear various "reset" flags
  MCUSR = 0;
  // allow changes, disable reset
  WDTCSR = bit (WDCE) | bit (WDE);
  // set interrupt mode and an interval
  WDTCSR =  0b01000000 | interval;// set WDIE, and delay
  wdt_reset();  // pat the dog

  set_sleep_mode (SLEEP_MODE_PWR_DOWN);

  sleep_enable();

  // turn off brown-out enable in software
  MCUCR = bit (BODS) | bit (BODSE);
  MCUCR = bit (BODS);
  sleep_cpu ();

  // cancel sleep as a precaution
  sleep_disable();
}


ISR (WDT_vect)
{
  wdt_disable();  // disable watchdog
}



void playExitFlyModeAction() {
  tone(PIN_RF, 940);
  digitalWrite(PIN_LED, HIGH);
  delay(500);
  digitalWrite(PIN_LED, LOW);
  tone(PIN_RF, 840);
  delay(500);
  digitalWrite(PIN_LED, HIGH);
  tone(PIN_RF, 740);
  delay(500);
  digitalWrite(PIN_LED, LOW);
  tone(PIN_RF, 640);
  delay(500);
  digitalWrite(PIN_LED, HIGH);
  tone(PIN_RF, 540);
  delay(1000);
  digitalWrite(PIN_LED, LOW);
  noTone(PIN_RF);
  delay(2000);

  sendAltitude();
  delay(5000);

  sendAltitude();
  delay(5000);

  sendAltitude();
  delay(5000);

  sendAltitude();
  delay(5000);

  sendAltitude();
  delay(5000);
}

void proc0() {
  tone(PIN_RF, 450);
  delay(DURATION_0);
  noTone(PIN_RF);
}

void proc1() {
  tone(PIN_RF, 550);
  delay(DURATION_1);
  noTone(PIN_RF);
}

void checkSerial() {
  delay(3000);

  if (Serial.available()) {

    String myStr = Serial.readStringUntil('\n');
    if (myStr.compareTo("clear") == 0) {

      digitalWrite(PIN_BEEP, HIGH);
      delay(2000);

      for (int i = 0 ; i < EEPROM.length() ; i++) {
        EEPROM.write(i, 0);
      }

      digitalWrite(PIN_BEEP, LOW);
    }


    Serial.println();
    Serial.print("maxAltitude:    ");
    Serial.print(EEPROMReadInt(MAX_ALTITUDE_EEPROM));
    Serial.println(" m");
    Serial.println();

    Serial.print("Altitude Index Pyro Initiated:    ");
    Serial.print(EEPROMReadInt(ALTITUDE_IND_EEPROM));
    Serial.println(" ");
    Serial.println();

    Serial.print("Middle Altitude Pyro Initiated:    ");
    Serial.print(EEPROMReadInt(MIDDLE_ALT_I_EEPROM));
    Serial.println(" m");
    Serial.println();

    Serial.print("timeToCheckAppogey:    ");
    Serial.print(EEPROMReadInt(CHECK_APOGEY_EEPROM));
    Serial.println(" millis");
    Serial.println();

    Serial.print("recordsTime:    ");
    Serial.print(EEPROMReadInt(REC_DURATION_EEPROM));
    Serial.println(" sec");
    Serial.println();

    Serial.print("recordsRate:    ");
    int val = EEPROMReadInt(RECORDS_RATE_EEPROM);
    float valf = val / 10.0;
    Serial.print( valf);
    Serial.println(" records/sec");
    Serial.println();


    Serial.println("log:   ");
    float j = 0;
    for (int i = startEEPPROMWriting; i < (measureQuantity + measureQuantity + 1); i += 2) {
      Serial.print(EEPROMReadInt(i));
      Serial.println();
      delay(50);
    }
  }
}


void EEPROMWriteInt (int p_address, int p_value)
{
  byte lowByte = EEPROM.read(p_address);
  byte highByte = EEPROM.read(p_address + 1);
  int val = ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
  if (val != p_value) {
    byte lowByte = ((p_value >> 0) & 0xFF);
    byte highByte = ((p_value >> 8) & 0xFF);
    EEPROM.write(p_address, lowByte);
    EEPROM.write(p_address + 1, highByte);
  }
}

int EEPROMReadInt(int p_address)
{
  byte lowByte = EEPROM.read(p_address);
  byte highByte = EEPROM.read(p_address + 1);
  return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
}

void sendAltitude() {
  String beaconData = String(maxAltitude);
  String oneStr = "";

  delay(1000);
  int d2RF;
  for (int i = 0; i < beaconData.length(); i++ ) {
    d2RF = 0;
    oneStr += beaconData.charAt(i);
    d2RF = oneStr.toInt();
    send_d2RF(d2RF);
    delay(1000);
    oneStr = "";
  }
}

void send_d2RF(int d2RF) {
  switch (d2RF) {
    case 0:
      proc0();
      break;
    case 1:
      proc1();
      break;
    case 2:
      proc1();
      delay(SPLITTER);
      proc0();
      break;
    case 3:
      proc1();
      delay(SPLITTER);
      proc1();
      break;
    case 4:
      proc1();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc0();
      break;
    case 5:
      proc1();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc1();
      break;
    case 6:
      proc1();
      delay(SPLITTER);
      proc1();
      delay(SPLITTER);
      proc0();
      break;
    case 7:
      proc1();
      delay(SPLITTER);
      proc1();
      delay(SPLITTER);
      proc1();
      break;
    case 8:
      proc1();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc0();
      break;
    case 9:
      proc1();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc0();
      delay(SPLITTER);
      proc1();
      break;
  }
}

void beeper() {
  digitalWrite(PIN_BEEP, HIGH);
  delay(200);
  digitalWrite(PIN_BEEP, LOW);

}