некорректно выполняется программа

Савелий
Offline
Зарегистрирован: 26.10.2019

Здравствуйте столкнулся с тем что программа стала выполнятся некорректно, помогите пожалуйста найти и исправить ошибку.(Некорректно в смысле steup выполняется несколько раз, а если и идет дальше steup, то на дисплей ничего не выводится, хотя должно)

Вот сам код

 

 Часть кода закомментирована, если его раскомментировать, то дальше steup не пойдет, а так проходит дальше, но на дисплей все равно ничего не выводится.

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>                          
#include <iarduino_RTC.h>                                               // Подключаем библиотеку iarduino_RTC для работы с модулями реального времени.
//  iarduino_RTC time(RTC_DS1302, 2, 3, 4);                             // Объявляем объект time для работы с RTC модулем на базе чипа DS1302, указывая выводы Arduino подключённые к выводам модуля RST, CLK, DAT.
uint8_t D, M, Y, h, m, s, W;
iarduino_RTC time(RTC_DS1307);
#define OLED_MOSI   9
#define OLED_CLK   10
#define OLED_DC    11
#define OLED_CS    12
#define OLED_RESET 13
int tim = 0;
Adafruit_SSD1306 display (128, 64, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

#define amperkot_logo_width 23
#define amperkot_logo_height 23
int se = 0;
int sek = 0;
int flag = 0;
int mi = 0;
int flager = 0;

int val1;
// используемые пины
const int ledPin = 6; // анод инфракрасного светодиода
const int sensorPin = 7; // выход датчика
const int beepPin = 3; // анод бипера со встроенным генератором

// размер буфера для вычисления порога
const int bufSize = 16;
// буфер для вычисления порога
int buf[bufSize];
// текущая позиция в буфере
int bufPos = 0;
// сумма значений в буфере
long int bufSum = 0;
// порог, вычисляемый, как среднее арифметическое
// значений в буфере
int  threshold = 0;
// расстояние до верхнего и нижнего порогов
// больше значение - меньше ложных срабатываний
// и меньше чувствительности
const int hyst = 1;

// пропуск некоторого количества замеров
// после пересечения порога
int skipDetect = 2; // количество замеров,
// которые необходимо пропустить
const int crossSkip = 4; // пишется в skipDetect
// после каждого пересечения порога

// напряжение на датчике при включенном светодиоде
int sensorValueLedOn;
// при выключенном светодиоде
// фоновая засветка
int sensorValueLedOff;
// значение на датчике с компенсацией фонового освещения
// по формуле sensorValueLedOff - sensorValueLedOn
int sensorValue;

// начало и конец текущего периода
// время записывается при детектировании
// пересечения порогового уровня сверху вниз
unsigned long prevTime, timer;

// находилось ли значение предыдущего отсчёта выше порога
boolean above;

// мгновенное значение пульса
// количество ударов в минуту
int pulse;
// медианное значение пульса
int pulseMed;
// среднее значение пульса
int pulseAvg;

// медианный фильтр
int medFilt(int value) {
  const int bufSize = 7; // количество элементов
  // должно быть нечётным
  static int buf[bufSize]; // массив нескольких
  // последних элементов
  static int sortBuf[bufSize]; // массив элементов
  // который сортируется
  static int pos = 0; // текущая позиция в массиве

  buf[pos] = value; // запись нового значения в массив

  // вычисление позиции следующего элемента
  pos++;
  if (pos == bufSize) pos = 0;

  // копирование первого массива во второй
  for (int i = 0; i < bufSize; i++) {
    sortBuf[i] = buf[i];
  }

  // сортировка второго массива
  for (int i = 0; i < bufSize; i++) {
    for (int j = i; j < bufSize; j++) {
      if (sortBuf[i] < sortBuf[j]) {
        int k = sortBuf[i];
        sortBuf[i] = sortBuf[j];
        sortBuf[j] = k;
      }
    }
  }

  // возвращается средний элемент
  // из отсортированного массива
  return sortBuf[(bufSize / 2)];
}

// вычисление среднего значения
int avg(int value) {
  const int bufSize = 16; // количество значений
  static int buf[bufSize]; // массив из последних значений
  static int pos; // текущая позиция
  static long int sum = 0; // сумма всех значений
  int avg; // среднее значение

  buf[pos] = value; // добавление нового значения
  sum += value; // его добавление в сумму
  avg = sum / bufSize; // вычисление среднего значения
  // компенсация погрешности целочисленного деления
  if ((sum % bufSize) >= (bufSize / 2)) avg++;

  // вычисление позиции следующего элемента
  pos++;
  if (pos == bufSize) pos = 0;

  sum -= buf[pos]; // элемент, который будет перезаписан
  // в следующий раз заранее вычитается
  // из суммы
  return avg;
}
int zxc = 0;
int p;
int aht = 0;
int xyw = 0;
static const unsigned char PROGMEM  ves [] {
  0x00, 0x00, 0x00,
  0x00, 0xFF, 0x01,
  0xC0, 0x00, 0x06,
  0x60, 0x00, 0x0C,
  0x30, 0x00, 0x18,
  0x18, 0x00, 0x30,
  0x88, 0x81, 0x21,
  0x44, 0x43, 0x43,
  0xC4, 0xC3, 0x43,
  0x84, 0x81, 0x41,
  0x04, 0x00, 0x40,
  0x04, 0x00, 0x40,
  0x04, 0x00, 0x40,
  0x04, 0x00, 0x40,
  0x44, 0x00, 0x44,
  0x84, 0x00, 0x42,
  0x08, 0x01, 0x21,
  0x18, 0xFE, 0x30,
  0x30, 0x00, 0x18,
  0x60, 0x00, 0x0C,
  0xC0, 0x00, 0x06,
  0x00, 0xFF, 0x01,
  0x00, 0x00, 0x00
};
static const unsigned char PROGMEM  x_x[] {
  0x00, 0x00, 0x00,
  0x0C, 0x00, 0x60,
  0x18, 0x00, 0x30,
  0x30, 0x00, 0x18,
  0x60, 0x00, 0x0C,
  0xC0, 0x00, 0x06,
  0x80, 0x01, 0x03,
  0x00, 0x83, 0x01,
  0x00, 0xC6, 0x00,
  0x00, 0x7C, 0x00,
  0x00, 0x7C, 0x00,
  0x00, 0x7C, 0x00,
  0x00, 0x7C, 0x00,
  0x00, 0xC6, 0x00,
  0x00, 0x83, 0x01,
  0x80, 0x01, 0x03,
  0xC0, 0x00, 0x06,
  0x60, 0x00, 0x0C,
  0x30, 0x00, 0x18,
  0x18, 0x00, 0x30,
  0x0C, 0x00, 0x60,
  0x04, 0x00, 0x40,
  0x00, 0x00, 0x00
}
;
static const unsigned char PROGMEM  ser[] {
  0x00, 0x00, 0x00,
  0x00, 0xFF, 0x01,
  0xC0, 0x00, 0x06,
  0x60, 0x00, 0x0C,
  0x30, 0x00, 0x18,
  0x18, 0x00, 0x30,
  0x88, 0x81, 0x21,
  0xC4, 0xC3, 0x43,
  0xC4, 0xC2, 0x42,
  0x84, 0x81, 0x41,
  0x04, 0x00, 0x40,
  0x04, 0x00, 0x40,
  0x04, 0x00, 0x40,
  0x04, 0x00, 0x40,
  0x04, 0x00, 0x40,
  0x04, 0x00, 0x40,
  0x08, 0xFF, 0x21,
  0x18, 0x00, 0x30,
  0x30, 0x00, 0x18,
  0x60, 0x00, 0x0C,
  0xC0, 0x00, 0x06,
  0x00, 0xFF, 0x01,
  0x00, 0x00, 0x00

}
;
static const unsigned char PROGMEM  grs[] {
  0x00, 0x00, 0x00,
  0x00, 0xFF, 0x01,
  0xC0, 0x00, 0x06,
  0x60, 0x00, 0x0C,
  0x30, 0x00, 0x18,
  0x18, 0x00, 0x30,
  0x88, 0x81, 0x21,
  0xC4, 0xC3, 0x43,
  0xC4, 0xC2, 0x42,
  0x84, 0x81, 0x41,
  0x04, 0x00, 0x40,
  0x04, 0x00, 0x40,
  0x04, 0x00, 0x40,
  0x04, 0x00, 0x40,
  0x04, 0xFE, 0x40,
  0x04, 0x01, 0x41,
  0x88, 0x00, 0x22,
  0x18, 0x00, 0x30,
  0x30, 0x00, 0x18,
  0x60, 0x00, 0x0C,
  0xC0, 0x00, 0x06,
  0x00, 0xFF, 0x01,
  0x00, 0x00, 0x00

};

void setup() {
  delay(300);   // Ждем готовности модуля отвечать на запросы
  pinMode(ledPin, OUTPUT);
  pinMode(beepPin, OUTPUT);
  pinMode (A2, OUTPUT);
  pinMode (A3, OUTPUT);
  pinMode (A0, INPUT);
  pinMode (A1, INPUT_PULLUP);  
  digitalWrite(beepPin, LOW);
  Serial.begin(9600);                                                 // Инициируем передачу данных в монитор последовательного порта на скорости 9600 бод.
  Serial.println (pin_SW_SDA);
  time.begin();
  display.begin (SSD1306_SWITCHCAPVCC);         //пример картинки )
  display.display();
  delay (2000);
  display.clearDisplay();
  display.setTextSize(2);        // Normal 1:1 pixel scale
 // display.setTextColor(SSD1306_WHITE);        // Draw white text  
 // display.drawXBitmap(128 - (23), 23, ves, 23, 23, 1);
 // display.display(); //Конец
  Serial.println ("установка2");
// delay (1000);
  Serial.println ("установка3");
}

void loop() {
  delay (1);
  Serial.println ("1");
  while (aht==0) {
    Serial.println ("установка41");
    if (flag == 0) {
      Serial.println ("установка42");
      p = val1;
      flag = 1;
      Serial.println ("установка");
    }
    digitalWrite (A3, 1);
    display.setCursor (0, 0);
    display.println ("Vosrast?");
    int val = analogRead (A0);
    int val1 = map (val, 0, 1023, 0, 99);
    display.setCursor (0, 40);
    display.print (val1);
    display.display ();
    int q = !digitalRead (A1);
    if (q == 1) {
      delay (1000);
      display.clearDisplay();
      zxc = 1;
      break;
    }

    if (p == val1) {

    } else {
      display.clearDisplay ();
      flag = 0;
      Serial.println ("очистка");
    }
    delay (1);
  }
  while (aht == 0) {
    aht = !digitalRead (A1);
    digitalWrite (A2, 1);
    digitalWrite (A3, 0);
    ystanovka ();
    if (flag == 0) {
      mi = m;
      flag = 1;
      Serial.println ("установка");
    }
    int has = h;
    data ();
    minute ();
    ned ();
    aht = !digitalRead (A1);
    if (aht == 1) {
      delay (1000);
      display.clearDisplay ();
      aht = 1;
      Serial.println ("Выход");
      break;
    }
    if (mi == m) {

    } else {
      display.clearDisplay ();
      flag = 0;
      Serial.println ("очистка");
    }
    delay (1);
  }
  while (xyw == 0) {

    if (xyw == 1) {
      delay (500);
      display.clearDisplay ();
      xyw = 1;
      aht = 0;
      delay (500);
      break;
    }
  }
  while (val1 < 1) {

  }
  while (val1 >  0 && val1 < 3) {

  }
  while (val1 >  2 && val1 < 6) {

  }
  while (val1 > 5  && val1 < 7) {

  }
  while (val1 > 6  && val1 < 9) {

  }
  while (val1 > 8  && val1 < 11) {

  }
  while (val1 > 10  && val1 < 15) {

  }
  while (val1 > 14  && val1 < 50) {

  }
  while (val1 > 49  && val1 < 70) {

  }
  while (val1 > 69) {

  }
}
void ystanovka () {
  time.gettime();                                                   // Считываем текущее время из модуля.

  D = time.day;                       // Получаем текущий день месяца 1-31.
  M = time.month;                     // Получаем текущий месяц       1-12.
  Y = time.year;                     // Получаем текущий год         0-99.
  h = time.Hours;                   // Получаем текущие часы        0-23.
  m = time.minutes;               // Получаем текущие минуты      0-59.
  s = time.seconds;              // Получаем текущие секунды     0-59.
  W = time.weekday;             // Получаем текущий день недели 0-6.
  delay (1);
}
void data () {
  display.setTextSize(2);
  tim = millis + 1000;
  display.setCursor (((128 - 60) / 2), 0);
  display.print (D);
  display.print ("/");
  display.print (M);
  display.display();

}
void minute () {

  display.setTextSize(3);
  ystanovka ();
  display.setTextColor(SSD1306_WHITE);
  display.setCursor (14, 20) ;
  display.print (h);
  display.print (":");
  if (m < 10) {
    display.print ("0");
  }
  display.println (m);
  display.display();
}
void ned () {
  ystanovka ();
  time.gettime("D");
  display.setCursor (45, 50) ;
  display.setTextSize(2);
  display.println (time.gettime("D"));
  display.display ();
}

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

а автор кода чо говорит?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

В коде полно ляпов и работать нормально он не может по определению.

Вот, например ляп (один из стапятисот имеющихся) :
в строке №351 бесконечный цикл по условию val1 < 1. Внимание, вопрос: где, когда и при каких обстоятельствах эта самая val1 получает хоть какое-нибудь значение? По мне, так нигде и никогда – она как получила значение 0 при описании в строке №25, так  всю жизнь нулём и остаётся.

 

Савелий
Offline
Зарегистрирован: 26.10.2019

val1 Принимает значение потенциометра в начале

Савелий
Offline
Зарегистрирован: 26.10.2019

БОльшую часть кода писал я (%70)

nik182
Offline
Зарегистрирован: 04.05.2015

От же. 

SLKH
Offline
Зарегистрирован: 17.08.2015

ЕвгенийП пишет:

В коде полно ляпов и работать нормально он не может по определению.

Вот, например ляп (один из стапятисот имеющихся) :
в строке №351 бесконечный цикл по условию val1 < 1. Внимание, вопрос: где, когда и при каких обстоятельствах эта самая val1 получает хоть какое-нибудь значение? По мне, так нигде и никогда – она как получила значение 0 при описании в строке №25, так  всю жизнь нулём и остаётся.

 

Там вроде бы возраст вводится с какого-то потенциометра (в 287-288). Но при любых значениях val1 где-то в стр. 351 - 380 программа всё равно зациклится.

Савелий
Offline
Зарегистрирован: 26.10.2019

Там вводится возраст, далее с помощью далее при нажатии на кнопку выводится время на дисплей потом при нажатии на кнопку еще раз замеряется пульс с помощью датчика и сравнивается с нормами по возрасту, пульс и сравнение с нормами не доделал т.к. программа не работает корректно (кстати, скетч занимает 66% памяти)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Савелий пишет:

val1 Принимает значение потенциометра в начале

Савелий, Вы невнимательны. Я Вам сказал, что объявленная в строке №25 (и используемая в строках №№351-378) переменная val1 нигде и никогда не получает никакого значения. Вы с этим не согласны? Тогда скажите в каком именно начале она получает значение - у этого начала номер строки есть?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

SLKH пишет:

Там вроде бы возраст вводится с какого-то потенциометра (в 287-288). 

Насчёт возраста не знаю, а вот val1 не получает никакого значения нигде  - это сто пудов. 

SLKH пишет:

программа всё равно зациклится.

Так я и писал, что это лишь один из 100500 ляпов.

Савелий
Offline
Зарегистрирован: 26.10.2019

288

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

В строке №288 описана другая переменная val1, не имеющая никакого (от слова "совсем") отношения к переменной val1, описанной в строке 25. Читайте про "экранирование переменных" вот здесь.

val1 описанная в строке 288 используется в строках №№288-307. Во всех остальных местах (включая строки с условиями, о которых я писал), используется val1, описанная в строке №25. А вот она-то не получает никакого значения нигде и никогда.

Савелий
Offline
Зарегистрирован: 26.10.2019

Спасибо! Можете, пожалуйста, описать остальные ошибки

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Не сейчас, но там их слишком много (начиная с решения использовать глючную до последнего безобразия библиотеку iarduino_RTC.h).

Может, позже.

А для чего Вам эти бесконечные циклы? Типа "на вырост"? Но в них-то точно всё зависнет. стоит туда попасть.

Савелий
Offline
Зарегистрирован: 26.10.2019

Я вроде писалБ в них будет сравниваться значение пульса с нормой и вывод пульса и  смайлика на дисплей (в зависимости от пульса)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, может будет, но сейчас, если Вы запуститесь, то в них всё намертво повиснет. Вы это понимаете?

Савелий
Offline
Зарегистрирован: 26.10.2019

Тогда мне удалить их?И заменить на if?

b707
Offline
Зарегистрирован: 26.05.2017

ЕвгенийП пишет:

Ну, может будет, но сейчас, если Вы запуститесь, то в них всё намертво повиснет. Вы это понимаете?

судя по описанию автора - и в будущем мало что изменится. Программа будет намертво виснуть в этих циклах - ведь val1 это возраст, а возраст при измерении пульса менять не предполагается. Значит попав в любой из циклов программа останется там навечно.

b707
Offline
Зарегистрирован: 26.05.2017

Савелий пишет:

Спасибо! Можете, пожалуйста, описать остальные ошибки

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

хотите еще ошибок - держите

- цикл while в строке 340 точно такая же "ловушка" для программы, как и циклы, указанные Евгением. так как переменная xyw, управляющая циклом - всегда равна нулю и в цикле не меняется

- переменная pos так же как val1 - описана в нескольких местах программы и явно будет работать совсем не так, как вы предполагаете

В общем. советую вам проштудировать тему "область видимости переменных в языке С/С++" (прямо так и ищите в яндексе). А также разобраться, как работают циклы while - у вас их несоразмерно много в коде. вы явно не очень хорошо понимаете, как оно работает

 

Савелий
Offline
Зарегистрирован: 26.10.2019

Спасибо!

Савелий
Offline
Зарегистрирован: 26.10.2019

Удалил значимую часть кода, и программа стала весить 18000 байт (с копейками), и все работает. Ощущение что зависит от занимаемого объема памяти. Притом не работает (при более 18000) только дисплей, а менее 18000 дисплей работает

Савелий
Offline
Зарегистрирован: 26.10.2019

Можно попросить помощи? Читайте выше

b707
Offline
Зарегистрирован: 26.05.2017

Савелий пишет:

Можно попросить помощи? Читайте выше

можно, хотя непонятно, что за помощь вам нужна.

Про 18000 байт, думаю. вы ошибаетесь. Размер прошивки (пока он не превышает размер флешпамяти в плате) - значения не имеет, можно занять его хоть до последнего байта - все должно работать.

Куда важнее размер оперативной памяти, который ИДЕ вам пишет во второй строке. Тут уже при 70% использования могут начаться глюки.