некорректно выполняется программа
- Войдите на сайт для отправки комментариев
Втр, 29/10/2019 - 13:29
Здравствуйте столкнулся с тем что программа стала выполнятся некорректно, помогите пожалуйста найти и исправить ошибку.(Некорректно в смысле 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 (); }
а автор кода чо говорит?
В коде полно ляпов и работать нормально он не может по определению.
Вот, например ляп (один из стапятисот имеющихся) :
в строке №351 бесконечный цикл по условию val1 < 1. Внимание, вопрос: где, когда и при каких обстоятельствах эта самая val1 получает хоть какое-нибудь значение? По мне, так нигде и никогда – она как получила значение 0 при описании в строке №25, так всю жизнь нулём и остаётся.
val1 Принимает значение потенциометра в начале
БОльшую часть кода писал я (%70)
От же.
В коде полно ляпов и работать нормально он не может по определению.
Вот, например ляп (один из стапятисот имеющихся) :
в строке №351 бесконечный цикл по условию val1 < 1. Внимание, вопрос: где, когда и при каких обстоятельствах эта самая val1 получает хоть какое-нибудь значение? По мне, так нигде и никогда – она как получила значение 0 при описании в строке №25, так всю жизнь нулём и остаётся.
Там вроде бы возраст вводится с какого-то потенциометра (в 287-288). Но при любых значениях val1 где-то в стр. 351 - 380 программа всё равно зациклится.
Там вводится возраст, далее с помощью далее при нажатии на кнопку выводится время на дисплей потом при нажатии на кнопку еще раз замеряется пульс с помощью датчика и сравнивается с нормами по возрасту, пульс и сравнение с нормами не доделал т.к. программа не работает корректно (кстати, скетч занимает 66% памяти)
val1 Принимает значение потенциометра в начале
Савелий, Вы невнимательны. Я Вам сказал, что объявленная в строке №25 (и используемая в строках №№351-378) переменная val1 нигде и никогда не получает никакого значения. Вы с этим не согласны? Тогда скажите в каком именно начале она получает значение - у этого начала номер строки есть?
Там вроде бы возраст вводится с какого-то потенциометра (в 287-288).
Насчёт возраста не знаю, а вот val1 не получает никакого значения нигде - это сто пудов.
программа всё равно зациклится.
Так я и писал, что это лишь один из 100500 ляпов.
288
В строке №288 описана другая переменная val1, не имеющая никакого (от слова "совсем") отношения к переменной val1, описанной в строке 25. Читайте про "экранирование переменных" вот здесь.
val1 описанная в строке 288 используется в строках №№288-307. Во всех остальных местах (включая строки с условиями, о которых я писал), используется val1, описанная в строке №25. А вот она-то не получает никакого значения нигде и никогда.
Спасибо! Можете, пожалуйста, описать остальные ошибки
Не сейчас, но там их слишком много (начиная с решения использовать глючную до последнего безобразия библиотеку iarduino_RTC.h).
Может, позже.
А для чего Вам эти бесконечные циклы? Типа "на вырост"? Но в них-то точно всё зависнет. стоит туда попасть.
Я вроде писалБ в них будет сравниваться значение пульса с нормой и вывод пульса и смайлика на дисплей (в зависимости от пульса)
Ну, может будет, но сейчас, если Вы запуститесь, то в них всё намертво повиснет. Вы это понимаете?
Тогда мне удалить их?И заменить на if?
Ну, может будет, но сейчас, если Вы запуститесь, то в них всё намертво повиснет. Вы это понимаете?
судя по описанию автора - и в будущем мало что изменится. Программа будет намертво виснуть в этих циклах - ведь val1 это возраст, а возраст при измерении пульса менять не предполагается. Значит попав в любой из циклов программа останется там навечно.
Спасибо! Можете, пожалуйста, описать остальные ошибки
Савелий, цикл отладки программы обычно нужно строить так - нашел ошибку - исправил - ищем следующую. так что сначала исправте те ошибки, на которые вам указали - потом снова проверяйте, как будет работать новая версия кода. И страйтесь находить ошибки сами.
хотите еще ошибок - держите
- цикл while в строке 340 точно такая же "ловушка" для программы, как и циклы, указанные Евгением. так как переменная xyw, управляющая циклом - всегда равна нулю и в цикле не меняется
- переменная pos так же как val1 - описана в нескольких местах программы и явно будет работать совсем не так, как вы предполагаете
В общем. советую вам проштудировать тему "область видимости переменных в языке С/С++" (прямо так и ищите в яндексе). А также разобраться, как работают циклы while - у вас их несоразмерно много в коде. вы явно не очень хорошо понимаете, как оно работает
Спасибо!
Удалил значимую часть кода, и программа стала весить 18000 байт (с копейками), и все работает. Ощущение что зависит от занимаемого объема памяти. Притом не работает (при более 18000) только дисплей, а менее 18000 дисплей работает
Можно попросить помощи? Читайте выше
Можно попросить помощи? Читайте выше
можно, хотя непонятно, что за помощь вам нужна.
Про 18000 байт, думаю. вы ошибаетесь. Размер прошивки (пока он не превышает размер флешпамяти в плате) - значения не имеет, можно занять его хоть до последнего байта - все должно работать.
Куда важнее размер оперативной памяти, который ИДЕ вам пишет во второй строке. Тут уже при 70% использования могут начаться глюки.