Роторный компрессометр своими руками |
Здравствуйте, гость ( Вход | Регистрация )
Роторный компрессометр своими руками |
26.7.2013, 3:44
Сообщение
#1
|
|
GOLD Группа: Пользователи Сообщений: 1604 Регистрация: 9.1.2011 Из: vl Пользователь №: 4086 |
Для изготовления нам потребуется купить:
На первом пункте останавливаться не буду - нужен тот, у которого есть usb порт, а значит любой Датчик давления нужен с пределом измерения не ниже 10 кг^см2, но и не сильно большим, чтобы обеспечить приемлимую точность. Исполнение - трёх контактное, с питанием = 5вольт. Ардуина. Это плата для разработчиков на основе микроконтроллера atmega. Купить можно в ближайшем радио-магазине. Выбор моделей довольно огромен (http://arduino.cc/en/Main/Products) - подойдет любая 5-вольтовая. (есть 3.3 вольтовые исполнения - они нам не подходят) Железная часть: вкручиваем датчик давления в свечное отверстие (понадобится выточить переходник у любого токаря). Подключаем датчик давления к ардуине: питание датчика на контакт 5V, землю на GND, сигнальный выход на A0. Программная часть: Скачиваем три программы: Arduino IDE Processing Megalog Viewer Все три программы платформо-независимые, можно работать из под винды, мака, линукса. Если немножно исхитриться, то даже под андроидом замер компрессии не сложно организовать. Arduino IDE Процесс замера следующим сообщением... |
|
|
19.6.2014, 16:09
Сообщение
#2
|
|
Новичок (<30 постов) Группа: Пользователи Сообщений: 12 Регистрация: 27.1.2014 Пользователь №: 5724 |
Отловлено несколько багов, связанных с крайне низком объёмом памяти у АТМеги и большим разбросом параметров кнопок на LCD Keypad.
Версия 0.14. Главные изменения: - Между пином 3 и землёй повешена кнопка калибровки. - С пина 2 убрана кнопка выбора типа датчика - теперь тип переключается по нажатию "вверх-вниз" до замера - При первом включении после заливки скетча обязательна калибровка кнопок LCD keypad, также калибровку можно выполнить, зажав кнопку калибровки при подаче питания на компрессометр. - Мерить можно только одну секцию за один раз. датчик на аналоговом входе 1, можно менять. - Замер останавливается через заданный таймаут (по умолчанию 30 секунд), а не по нажатию кнопки. Просьба оттестировать и сообщить, если будут баги. Модеров прошу потереть старый пост, чтоб не было проблем с использованием старого скетча.. Код // Компрессометр by PCDeath
char ver[6] = "v0.14"; /* Версия 0.14 Для Arduino Uno R3 с LCD keypad shield. На других платформах не проверялось. Мерит обычные поршневые двигатели 4Т/2Т или РПД. В связи с большим разбросом значений кнопок у разных производителей LCD keypad Shield добавлена возможность калибровки кнопок. Для калибровки необходимо прицепить тактовую кнопку между цифр.пином 3 и массой. Датчик давления 5В, при атм.давлении возвращают 0,5В (102), при макс.давлении - 4,5В (922), погрешность не более +/-10% Верхний предел давления регулируемый, можно использовать 2 различных типа датчиков, в моём варианте 10,5 кгс/см2 и 14 кгс/см2. Установлены 2 порога давления - 20% и 30% от показаний датчика, для чёткого разделения по секциям Датчик подключается к аналоговому входу Arduino, по умолчанию 1, можно менять. Рекомендуется питать компрессометр от отдельного батарейного источника питания +8...+12В, во избежание помех и ошибок из-за просадки напряжения при прокрутке двигателя стартером. Управление: Калибровка кнопок: Если при включении нажата кнопка на цифр.пине 3, или ПО только что залито в контроллер, компрессометр переходит в режим калибровки. При калибровке требуется нажать кнопку, которая запрошена на экране, затем нажать кнопку калибровки. После записи значений на экране появится приглашение отпустить кнопку калибровки. Отпускаем сначала кнопку калибровки, затем - кнопку на keypad shield, которую откалибровали, и переходим к калибровке следующей кнопки. По окончании калибровки требуется перезагрузить компрессометр До замера: "ВВЕРХ" переходит к типу датчика 2 "ВНИЗ" переходит к типу датчика 1 "ВПРАВО" переводит к следующему типу измерения "ВЛЕВО" переводит к предыдущему типу измерения По нажатию кнопки "SELECT" стартует процесс измерения, останавливается через заданное время. При старте происходит десятикратный опрос датчиков с интервалом в 50 мс. Если показания на входе имеют погрешность более 10% от заявленного значения, (датчик отсутствует или замкнут), на экран выводится предупреждение с указанием, в какую сторону погрешность Во время роторного замера на экране сырые значения на аналоговом входе для всех камер. Во время поршневого замера на экране сырые значения. После роторного замера: "ВВЕРХ" показывает скорректированные значения "ВНИЗ" возвращается к истинным значениям Если хотя бы у одной из камер давление ниже порога или обороты двигателя слишком низкие - выдаётся предупреждение о низких оборотах или вылете секции. После поршневого замера на кнопки не реагирует. Если во время замера было достигнуто предельное давление, на которое рассчитан датчик, то при отображении результатов поршневого или роторного замера без коррекции информация об этом выводится на экран. При отображении результатов роторного замера с коррекцией полученные значения приводятся к эталонным оборотам Приятного использования. PCDeath P.S. Если захотите поблагодарить создателя, это можно сделать: 1. Добрым словом где-нибудь на форумах 2. Запчастями от РПД ВАЗа и RX-7 3. Деньгами на QIWI-кошелёк +79053834132 Коммерческое распространение кода без согласования с автором запрещено */ /********************************************************************** Четыре параметра ниже требуется поправить под используемые Вами датчики ***********************************************************************/ int MAX_SENS1 = 105; // Макс.показания датчика 1 типа в кгс/см2 * 10 int MAX_SENS2 = 140; // Макс.показания датчика 2 типа в кгс/см2 * 10 byte TRESHOLD1 = 20; // Порог 1 в процентах от диапазона датчика. Рекомендуется не менее 2 атм. // При падении давления ниже порога 1 компрессометр считает замер камеры завершённым. byte TRESHOLD2 = 30; // Порог 2 в процентах от диапазона датчика. Рекомендуется не менее 1,5 от порога 1. // При возрастании давления выше порога 2 компрессометр начнёт замер следующей камеры. /********************************************************************* Всё, что дальше, менять не стоит, если Вы не знаете точно, что делаете **********************************************************************/ int MINS = 102; // Показания датчика на аналоговом входе при атмосферном (нулевом) давлении int MAXS = 922; // Показания датчика на аналоговом входе при макс.давлении byte MODE = 0; // Режим работы. 0 - роторный, 1 - поршневой 4Т, 2 - поршневой 2Т int CORRPM = 250; // Обороты, к которым приводится компрессия при коррекции int MINRPM = 170; // Мин.допустимые для измерения обороты, не менее 2/3 от CORRPM byte Z_FIRST = 6; // Оборот, с которого начинается подсчёт RPM byte Z_LAST = 9; // Оборот, на котором заканчивается подсчёт RPM, не менее Z_FIRST + 3, не более Z_FIRST + 15 byte TIMER = 2; // Периодичность замера в миллисекундах, не более 30. byte TIMEOUT = 30; // Время, отведённое на замер после нажатия SELECT #define SENSPIN 1 // Аналоговый пин, на котором висит датчик #define btnCAL 3 // Цифровой пин, на котором висит кнопка калибровки /******************************** БОЛЬШЕ НАСТРАИВАТЬ НИЧЕГО НЕ НАДО ********************************/ /******************************* ОБЪЯВЛЯЕМ ПЕРЕМЕННЫЕ *******************************/ int CALIBRE, // Для калибровки "нуля" датчика и установки порогов измерения TRESHLOW, TRESHHIGH, // Для вычисления пороговых значений KGSCOMPR[3], // Итоговые значения компрессии, приведённые к кгс/см2 * 10 RPM, // Частота вращения вала. CORRVAL, // Значение множителя коррекции bUP, bDN, bLT, bRT, bSL; // Переменные для значений кнопок byte i, // Счётчики для калибровки датчиков ERRORCODE, // Коды ошибок BTN[6]; // Массив для калибровки кнопок boolean START, CORR, RPMCOUNT, // Флаги старта, коррекции, подсчёта оборотов ERR, OUT, // Флаг ошибки датчика, флаг вывода на экран MAX[3]; // Массив флагов информирования о достижении предельного давления volatile int DIGCOMPR[3], // Максимальные значения компрессии, сырые CURRCNT, Z_TMP, CNT[16];// Счётчик "тиков" таймера и массив для расчёта оборотов volatile byte CH, Z; // Номер камеры для расчётов, номер оборота volatile boolean STOP, UP; // Флаги остановки и движения к ВМТ int MAX_SENS = MAX_SENS1; // Устанавливаем начальное значение в тип 1 unsigned int T_OUT = TIMEOUT / TIMER * 1000; // Счётчик "тиков" для таймаута замера unsigned int FREQ = 2000 * TIMER; // Предельное значение для таймера. 1 мсек = 2000 тактов при делителе /8 unsigned int MAXCNT = 60000 / TIMER / MINRPM; // Максимальное зачение счётчика для мин.оборотов long DIVRPM = 60000 / TIMER * (Z_LAST - Z_FIRST); // Делитель для подсчёта RPM. /******************************************** ЦКПЛЯЕМ БИБЛИОТЕКИ И УЧИМ РАБОТАТЬ С КНОПКАМИ ********************************************/ #include <EEPROM.h> // Прицепляем EEPROM для калибровки кнопок #include <LiquidCrystal.h> // Прицепляем LCD LiquidCrystal lcd(8, 9, 4, 5, 6, 7); byte lcd_key = 0; int adc_key_in = 0; #define btnNONE 0 #define btnSELECT 1 #define btnLEFT 2 #define btnUP 3 #define btnDOWN 4 #define btnRIGHT 5 // Обработка кнопок int read_LCD_buttons() { adc_key_in = analogRead(0); // Читаем значение нопок. if (adc_key_in > bSL +10 ) return btnNONE; if (adc_key_in < bRT) return btnRIGHT; if (adc_key_in < bUP) return btnUP; if (adc_key_in < bDN) return btnDOWN; if (adc_key_in < bLT) return btnLEFT; if (adc_key_in < bSL) return btnSELECT; return btnNONE; // Если "всё не так" - считаем. что никакая кнопка не нажата. } void setup() { lcd.begin(16, 2); // Запускаем библиотеку LCD ERR = 1; // Ставим датчику признак высокого уровня на входе /****************************************** РИСУЕМ СПЛЕШ-СКРИН С ВЫВОДОМ ВЕРСИИ ******************************************/ lcd.setCursor(0,0); lcd.print(" ROTARY C-METER "); lcd.setCursor(0,1); lcd.print(" BY PCDeath"); lcd.setCursor(0,1); lcd.print(ver); delay (3000); /***************************************** НАСТРАИВАЕМ ТАЙМЕР НА НАЧАЛЬНЫЕ ЗНАЧЕНИЯ *****************************************/ TCCR1A = 0; TIMSK1 = 0; // Сбрасываем на всякий эти регистры TCCR1B = 0; // Мало ли что arduino IDE туда записало TCNT1 = 0; // Сбрасываем счетный регистр таймера 1 OCR1A = 0; // Отключаем таймер TCCR1B |= ((1 << CS11) | (1 << WGM12)); // Настраиваем таймер на делитель /8, режим CTC /***************************************** ОБРАБАТЫВАЕМ КАЛИБРОВОЧНУЮ КНОПКУ *****************************************/ pinMode(btnCAL, INPUT); // Назначаем цифр.пину 3 режим входа digitalWrite(btnCAL, HIGH); // Устанавливаем высокий уровень сигнала по умолчанию if (digitalRead(btnCAL) == 0) // Если нажата кнопка калибровок EEPROM.write(0, 0); // Снимаем флаг выполнения калибровки BTN[0] = EEPROM.read(0); // Читаем значение флага калибровки if (BTN[0] != 1) { // Если необходима калибровка, ERRORCODE = 5; // Выносим в обработку ошибки OUT = 1; // Настраиваем флаг записи CURRCNT = analogRead(0); // Калибруем отсутствие нажатия } else { bSL = int(EEPROM.read(1) * 4); // Читаем значение для кнопки "SELECT" bLT = int(EEPROM.read(2) * 4); // Читаем значение для кнопки "ВЛЕВО" bUP = int(EEPROM.read(3) * 4); // Читаем значение для кнопки "ВВЕРХ" bDN = int(EEPROM.read(4) * 4); // Читаем значение для кнопки "ВНИЗ" bRT = int(EEPROM.read(5) * 4); // Читаем значение для кнопки "ВПРАВО" } } void loop() { /*************************************** ОБРАБОТКА ОШИБОК ***************************************/ if (ERRORCODE > 0){ TIMSK1 &= (0 << OCIE1A); // Запрещаем генерацию прерывания таймера 1 OCR1A = 0; // И останавливаем таймер if (ERRORCODE == 5) CALIBER(); // Если требуется калибровка, входим в режим калибровки кнопок /************************************ ОШИБКА НИЗКИХ ОБОРОТОВ ИЛИ ВЫЛЕТА ************************************/ if (ERRORCODE == 3) { lcd.setCursor(0,0); lcd.print("LOW RPM!"); // Выводим на экран ошибку lcd.setCursor(0,1); lcd.print("OR CHAMBER DOWN"); ERRORCODE ++; } /******************************************** ОШИБКА ОТСУТСТВИЯ ИЛИ НЕИСПРАВНОСТИ ДАТЧИКА ********************************************/ if (ERRORCODE == 1){ lcd.setCursor(0,0); lcd.print(" SENSOR ERROR! "); // Выводим на экран ошибку lcd.setCursor(0,1); if (ERR == 0) // Если собранные значения ниже заявленных более чем на 10% lcd.print(" VALUE TOO LOW "); // Информируем о слишком низком значении else lcd.print(" VALUE TOO HIGH "); // Иначе информируем о слишком высоком значении ERRORCODE ++; } return; } /*************************************************************** ЕСЛИ НЕ ПРОИЗВОДИТСЯ ЗАМЕР КОМПРЕССИИ, ОБРАБАТЫВАЕМ КНОПКИ ***************************************************************/ if (START - STOP == 0 ) { lcd_key = read_LCD_buttons(); // Обрабатываем нажатие кнопки на LCD Shield if (lcd_key > 0) BUTTON(); // Если что-то нажато, идём в функцию обработки кнопок } /*************************************************** ВЫВОД НА ЭКРАН ДО ЗАМЕРА ***************************************************/ if (START == 0 && OUT == 0) { // Если замер не выполнялся и сброшен флаг вывода lcd.setCursor(0,0); lcd.print("MAX = ATMs"); // Отображаем верхний предел выбранного типа датчиков lcd.setCursor(6,0); lcd.print((float)MAX_SENS / 10.0); if (MODE == 0) { lcd.setCursor(0,1); lcd.print("ROTARY "); // Отображаем тип замера: роторный } else { lcd.setCursor(0,1); // Или поршневой lcd.print("PISTON T"); lcd.setCursor(14,1); if (MODE == 1) lcd.print("4"); // Четырёхтактный else lcd.print("2"); // Или двухтактный } OUT = 1; // Ставим флаг вывода, чтоб не мерцал экран return; } /************************* ВО ВРЕМЯ ЗАМЕРА *************************/ if (START == 1 && STOP == 0) { // Если выполняется замер lcd.begin(16,2); lcd.print("WAIT SECONDS"); // Выводим на экран обратный отсчёт lcd.setCursor(5,0); lcd.print((T_OUT - CURRCNT) / (1000 / TIMER)); lcd.setCursor(0,1); // и текущие сырые значения компрессии lcd.print(DIGCOMPR[0]); if (MODE == 0) { // Если режим роторный lcd.setCursor(6,1); // Выводим текущие сырые значения по камерам 2 и 3 lcd.print(DIGCOMPR[1]); lcd.setCursor(12,1); lcd.print(DIGCOMPR[2]); } delay(1000); return; } /**************************************************** ПОСЛЕ ЗАМЕРА ****************************************************/ if (STOP == 1 && OUT == 0) { // Если сброшен флаг вывода lcd.begin(16,2); // Очищаем экран. begin поставлен, т.к.иногда во время замера вывод на экран из-за прерывания ломается /**************************************************** ОРГАНИЗУЕМ ПОДСЧЁТ ОБОРОТОВ ****************************************************/ if (RPMCOUNT == 0) { // Если подсчёт не выполнялся for (Z_TMP = 0; Z_TMP <= Z_LAST - Z_FIRST; Z_TMP ++) { // Проверяем на низкие обороты и вылет секции if (CNT[Z_TMP+1] - CNT[Z_TMP] > MAXCNT && MODE == 0) // Если частота обновления ниже минимального порога и режим замера - роторный ERRORCODE = 3; // Ставим флаг низких оборотов } RPM = DIVRPM / (CNT[Z_LAST - Z_FIRST] - CNT[0]); // Считаем обороты в минуту if (MODE == 1) RPM *= 2; // Если тип замера поршневой 4-тактный, умножаем обороты на 2 RPMCOUNT = 1; // Ставим флаг выполнения подсчёта } /************************************************ ПОКАЗЫВАЕМ ОБОРОТЫ ИЛИ ИНФО О КОРРЕКЦИИ ************************************************/ if (MODE == 0 && CORR == 1) { // Если мерился роторный двигатель и установлен флаг коррекции CORRVAL = 1000 + (CORRPM - RPM) * 3; // рассчитываем значение для множителя х 1000 lcd.setCursor(9,0); // Информируем о коррекции lcd.print("CORR"); lcd.setCursor(13,0); lcd.print(CORRPM); } else { CORRVAL = 1000; // Иначе ставим множитель в единицу х 1000 lcd.setCursor(9,0); // И выводим обороты, при которых производился замер lcd.print("RPM= "); lcd.setCursor(13,0); lcd.print(RPM); } /****************************************************** ПЕРЕВОДИМ КОМПРЕССИЮ ИЗ ПОПУГАЕВ В КГС/СМ2 ******************************************************/ for (CH = 0; CH <= 2; CH ++) { // Для каждой камеры if (DIGCOMPR[CH] > MAXS + 3) // Если превышены макс.показания + погрешность MAX[CH] = 1; // Ставим флаг достижения максимального порога давления KGSCOMPR[CH] = // Мапим показания датчика из сырых в кгс/см2 х 10 // map((long)DIGCOMPR[CH] * CORRVAL / 1000, MINS, MAXS, 0, MAX_SENS); // без учёта начальной калибровки map((long)DIGCOMPR[CH] * CORRVAL / 1000, CALIBRE, MAXS, 0, MAX_SENS); // с учётом начальной калибровки } /***************************************************** ПОКАЗЫВАЕМ НА ЭКРАН, ЧЕГО ТАМ НАМЕРИЛИ *****************************************************/ if (MODE == 0){ // Если режим роторный lcd.setCursor(0,0); lcd.print("ROTARY"); // Выводим на экран тип замера for (CH = 0; CH <= 2; CH ++){ // И итоговые значения компрессии по камерам lcd.setCursor(CH * 6,1); if (MAX[CH] == 1 && CORR == 0) // Если нет флага коррекции и достигнут макс.порог измерения - информируем об этом lcd.print("MAX!"); else lcd.print((float)KGSCOMPR[CH] / 10.0); } } else { // Если режим поршневой lcd.setCursor(0,0); lcd.print("PISTON"); // Выводим на экран инфо о поршневом замере lcd.setCursor(0,1); // И итоговые значения компрессии if (MAX[0] == 1) { // Если достигнут макс.порог измерения - информируем об этом lcd.print("MAX! >"); lcd.print((float)KGSCOMPR[0] / 10.0); } else lcd.print((float)KGSCOMPR[0] / 10.0); } OUT = 1; } } /****************************************************** ФУНКЦИЯ ОБРАОТКИ НАЖАТИЯ ******************************************************/ void BUTTON(){ switch (lcd_key) // Производим действие, в зависимости от нажатой кнопки { case btnRIGHT: // Кнопка "ВПРАВО" { OUT = 0; // Сбрасываем флаг вывода для обновления экрана if (START == 0) {MODE ++; // Если замер не выполнялся, переключаем режим MODE = min(MODE, 2); // Ограничиваем номер режима } break; } case btnLEFT: // Кнопка "ВЛЕВО" { OUT = 0; // Сбрасываем флаг вывода для обновления экрана if (START == 0) {MODE --; // Если замер не выполнялся, переключаем режим if (MODE != 1) MODE = 0; // Ограничиваем номер режима } break; } case btnUP: // Кнопка "ВВЕРХ" { OUT = 0; // Сбрасываем флаг вывода для обновления экрана if (START == 0) MAX_SENS = MAX_SENS2; // Переключаем на тип датчика 2 if (STOP == 1 && MODE == 0) CORR = 1; // Если роторный замер завершён, ставим флаг коррекции break; } case btnDOWN: // Кнопка "ВНИЗ" { OUT = 0; // Сбрасываем флаг вывода для обновления экрана if (START == 0) MAX_SENS = MAX_SENS1; // Переключаем на тип датчика 1 if (STOP == 1 && MODE == 0) CORR = 0; // Если роторный замер завершён, убираем флаг коррекции break; } case btnSELECT: // Кнопка "SELECT" { if (START == 0){ // Если замер остановлен START = 1; // Ставим флаг запуска OUT = 0; // Сбрасываем флаг вывода для обновления экрана lcd.clear(); // Очищаем экран for (i=0; i < 10; i++) { // Проверяем датчики на отсутствие/замыкание/большую погрешность CALIBRE += analogRead(SENSPIN); // С интервалом 50 мс 10 раз читаем показания delay(50); } if (CALIBRE > 11 * MINS || CALIBRE < 9 * MINS) { // Если отсутствует/неисправен датчик (погрешность более 10% от заявленной) ERRORCODE = 1; // Ставим флаги ошибок if (CALIBRE < 9 * MINS) // Если показания ниже заявленных ERR = 0; // Ставим указатель на низкое значение } } if (ERRORCODE == 0) { // Если датчики опрошены успешно CALIBRE = analogRead(SENSPIN); // Калибруем датчики - выставляем "0" TRESHLOW = (long)CALIBRE * (100 + TRESHOLD1) / 100; // Ставим порог падения давления TRESHHIGH = (long)CALIBRE * (100 + TRESHOLD2) / 100; // Ставим порог роста давления delay(500); // Ждём 0,5 сек, чтоб точно отпустить кнопку OCR1A = FREQ; // И настраиваем таймер: TIMSK1 |= (1 << OCIE1A); // Разрешаем генерацию прерывания таймера 1 по совпадению с регистром OCR1A } break; } } delay(500); } /****************************************************** ФУНКЦИЯ КАЛИБРОВКИ КНОПОК ******************************************************/ void CALIBER(){ while (1 == 1){ // Входим в бесконечный цикл if (digitalRead(btnCAL) == 0) { // Если нажата кнопка калибровки lcd.setCursor(0,0); lcd.print("RELEASE CALIBER"); // Выводим на экран приглашение отпустить кнопку калибровки lcd.setCursor(0,1); lcd.print(" BUTTON "); if (i <= 4 && OUT == 0) { // Если значение калибровки ещё не снято i++; // Увеличиваем счётчик кнопки на единицу BTN[i] = analogRead(0) / 4 + 5; // Пишем в переменную значение кнопки / 4, чтоб влезло в тип byte OUT = 1; // Ставим флаг записи значения кнопки } if (i > 4 && BTN[0] != 1) { // Если все кнопки откалиброваны и значения ещё не записаны в EEPROM BTN[0] = 1; // Ставим флаг завершения калибровки for (CH = 0; CH <= 5; CH ++) // Повторяем 6 раз EEPROM.write(CH, BTN[CH]); // Пишем в EEPROM значения из массива } } else { // Если кнопка калибровки не нажата delay(100); // Задержка для исключения дребезга кнопки if (i > 4) { // Если калибровка завершена lcd.setCursor(0,0); lcd.print(" REBOOT THE "); // Выводим на экран приглашение к перезагрузке lcd.setCursor(0,1); lcd.print(" DEVICE "); } else { // Если калибровка ещё не завершена lcd.setCursor(0,0); lcd.print(" PRESS "); // Выводим на экран приглашение к нажатию кнопки на KEYPAD lcd.setCursor(0,1); lcd.print(" ");// Выводим на экран приглашение к нажатию кнопки на KEYPAD lcd.setCursor(8,0); if (i == 0) lcd.print("SELECT"); // Для каждой кнопки своя строка if (i == 1) lcd.print("LEFT"); if (i == 2) lcd.print("UP"); if (i == 3) lcd.print("DOWN"); if (i == 4) lcd.print("RIGHT"); if (analogRead(0) < CURRCNT - 10 || analogRead(0) > CURRCNT + 10) { // Если нажата кнопка на Keypad lcd.setCursor(0,1); lcd.print(" PRESS CALIBER "); // Выводим приглашение к нажатию кнопки калибровки } OUT = 0; } } delay(500); } } /************************************************* А ВОТ ЗДЕСЬ ТВОРИТСЯ ВСЁ САМОЕ ИНТЕРЕСНОЕ *************************************************/ ISR(TIMER1_COMPA_vect) { // Обрабатываем прерывание по таймеру CURRCNT ++; // Увеличиваем значение текущего счётчика "тиков" /************************ ДЛЯ РАСЧЁТА ОБОРОТОВ ************************/ if (Z >= Z_FIRST && Z <= Z_LAST + 1){ if(CNT[Z - Z_FIRST] == 0) { // Если счётчик оборотов в пределах измерений и измерение ещё не записано CNT[Z - Z_FIRST] = CURRCNT; // Присваиваем значение счётчика элементу массива } } /*************************** ДЛЯ РАСЧЁТА КОМПРЕССИИ ***************************/ int TMP = analogRead(SENSPIN); // Читаем показания датчика // и пишем во временную переменную if (UP == 1) { // Если установлен флаг движения к ВМТ if (TMP >= TRESHLOW) { // Если временное значение больше нижнего порога (окончания замера) if (TMP > DIGCOMPR[CH]) // Если временное значение больше итогового DIGCOMPR[CH] = TMP; // Пишем временное значение в итоговое } else UP = 0; // Иначе снимаем флаг движения к ВМТ } else { // Если флаг движения к ВМТ не установлен if (TMP >= TRESHHIGH) { // Если текущее значение больше верхнего порога (начала замера следующей камеры) UP = 1; // Ставим флаг движения к ВМТ Z ++; // Прибавляем счётчик оборотов if (MODE == 0) CH ++; // Если режим роторный, переходим к следующей камере if (CH > 2) CH = 0; // Ходим по кругу камер } } /***************************************** ДЕЛАЕМ ВЫХОД ИЗ ЗАМЕРА ПО ТАЙМАУТУ *****************************************/ if (CURRCNT > T_OUT) { // Если вышло время замера TIMSK1 &= (0 << OCIE1A); // Запрещаем генерацию прерывания таймера 1 OCR1A = 0; // Останавливаем таймер STOP = 1; // Ставим флаг остановки } } Сообщение отредактировал pcdeath - 24.6.2014, 17:14 |
|
|
Текстовая версия | Сейчас: 11.11.2024, 8:03 |