/* Вариант проводного соединения блока управления с исполнительным устройством. Определение пинов вынесено в выдачу импульса. Запрещён вывод на экран ложных импульсов. Запрет снимается нажатием кнопки текущего канала. */ #include // библиотека для работы с дисплеем #include "Free_Fonts.h" // подключаемый файл #include // библиотека Arduino TFT_HX8357 tft = TFT_HX8357(); // вызов пользовательской библиотеки int trigPin = 11; // назначение вывода trig CKL int echoPinA = 14; // назначение вывода echoA L4 (3500 mV) int echoPinB = 15; // назначение вывода echoB L3 (2500 mV) int echoPinC = 16; // назначение вывода echoC L2 (1000 mV) int echoPinD = 17; // назначение вывода echoD L1 (200 mV) int ctrl0Pin = 54; // назначение вывода ctrl0Pin 4 импульса int ctrl1Pin = 55; // назначение вывода ctrl1Pin 8 импульсов int ctrl2Pin = 56; // назначение вывода ctrl2Pin 16 импульсов int ctrl3Pin = 57; // назначение вывода ctrl3Pin 0 - 12 В, 1 - 24 В int ctrl4Pin = 59; // назначение вывода ctrl4Pin коэф. усил х1 int ctrl5Pin = 60; // назначение вывода ctrl5Pin коэф. усил х6 int ctrl6Pin = 61; // назначение вывода ctrl6Pin коэф. усил х36 int ctrl7Pin = 62; // назначение вывода ctrl7Pin 0 - воздух, 1 - вода int ctrl8Pin = 63; // назначение вывода ctrl8Pin канал L4 int ctrl9Pin = 64; // назначение вывода ctrl9Pin канал L3 int ctrl10Pin = 65; // назначение вывода ctrl10Pin канал L2 int ctrl11Pin = 66; // назначение вывода ctrl11Pin канал L1 int ctrl12Pin = 67; // назначение вывода ctrl12Pin канал авто int analog1Pin = 68; // назначение вывода analogPin Uпит излучателя int analogPin = 69; // назначение вывода analogPin Uпит Ардуино int ind0Pin = 10; // назначение вывода ind0Pin 4 импульса int ind1Pin = 9; // назначение вывода ind1Pin 8 импульсов int ind2Pin = 8; // назначение вывода ind2Pin 16 импульсов int ind3Pin = 7; // назначение вывода ind3Pin коэф. усил х1 int ind4Pin = 6; // назначение вывода ind4Pin коэф. усил х6 int ind5Pin = 5; // назначение вывода ind5Pin коэф. усил х36 int ind6Pin = 4; // назначение вывода ind6Pin канал L4 int ind7Pin = 3; // назначение вывода ind7Pin канал L3 int ind8Pin = 2; // назначение вывода ind8Pin канал L2 int ind9Pin = 1; // назначение вывода ind9Pin канал L1 int ind10Pin = 0; // назначение вывода ind10Pin канал авто int indAPin = 13; // назначение вывода indA L4 (3500 mV) int indBPin = 12; // назначение вывода indB L3 (2500 mV) int indCPin = 18; // назначение вывода indC L2 (1000 mV) int indDPin = 19; // назначение вывода indD L1 (200 mV) int clockPin = 21; // назначение вывода clockPin int dataPin = 20; // назначение вывода dataPin int oscv; // указание верхней позиции y int oscn; // указание нижней позиции y int v(v=85); // указание счётчика строк v (начальное значение 85) float m; // указание переменной с плавающей точкой m int mn; // указание предельного расстояния mn float md; // указание переменной с плавающей точкой md int mnA; // указание предельного расстояния mnA int mnB; // указание предельного расстояния mnB int mnC; // указание предельного расстояния mnC int mnd; // указание предельного расстояния mnd int vmn; // указание предельного расстояния vmn int dispm; // указание количества точек dispm int disp; // указание количества точек disp int dispp; // указание количества точек dispp float cm; // объявление переменной cm (расстояние в см) uint16_t duration; // объявление переменной duration float voltage = 0.0; // объявление переменной voltage float analog = 0.0; // объявление переменной analog float voltage1 = 0.0; // объявление переменной voltage1 float analog1 = 0.0; // объявление переменной analog1 byte regkn1 = 0xFF; // регистр чтения кнопок управления исполнительным устройством byte regm1 = 0xC6; // регистр хранения режима управления исполнительным устройством byte regkn2 = 0xFF; // регистр чтения кнопок управления каналами byte regm2 = 0x3C; // регистр храннения режима управления каналами byte regkn = 0xFF; // рабочий регистр byte regout = 0x3A; // регистр выдачи на исполнительное устройство #define LOG_SIZE 20 // размер лога (20 ячеек) uint16_t us[LOG_SIZE]; // массив измерений. Для длительности отрезков между изменениями входа uint16_t durus[LOG_SIZE]; // массив измерений. Для текущего времени в момент изменения uint16_t errus[LOG_SIZE]; // массив измерений. Для текущего времени в момент изменения при ошибке uint32_t start; // Время старта uint32_t now; // Текущее машинное время в мкс uint32_t prevUs; // Предыдущее время изменения состояния пина int IN_PIN; // Пин входа текущего канала int IND_PIN; // Пин индикации текущего канала int count = 0; // Счётчик циклов измерения bool first,prevS,flag,flerr = 0; // Первое, предыдущее состояние пина, флаг не первого измерения, флаг ошибки bool flagn = 0; // Если 1, то пин в этом цикле прочитан bool airgnd; // 0 - пин на земле, 1 - висит в воздухе bool djmp; // бит переключателя bool oscknp, oscknt, osc = 0; // предыдущее, текущее состояние кнопки, флаг режима осциллографа int k = 0; // Указатель текущего канала для чтения void setup() { pinMode(trigPin, OUTPUT); // назначение вывода trig выходом pinMode(echoPinA, INPUT); // назначение вывода echoA входом pinMode(echoPinB, INPUT); // назначение вывода echoB входом pinMode(echoPinC, INPUT); // назначение вывода echoC входом pinMode(echoPinD, INPUT); // назначение вывода echoD входом pinMode(ctrl0Pin, INPUT_PULLUP); // назначение вывода ctrl0 входом pinMode(ctrl1Pin, INPUT_PULLUP); // назначение вывода ctrl1 входом pinMode(ctrl2Pin, INPUT_PULLUP); // назначение вывода ctrl2 входом pinMode(ctrl3Pin, INPUT_PULLUP); // назначение вывода ctrl3 входом pinMode(ctrl4Pin, INPUT_PULLUP); // назначение вывода ctrl4 входом pinMode(ctrl5Pin, INPUT_PULLUP); // назначение вывода ctrl5 входом pinMode(ctrl6Pin, INPUT_PULLUP); // назначение вывода ctrl6 входом pinMode(ctrl7Pin, INPUT_PULLUP); // назначение вывода ctrl7 входом pinMode(ctrl8Pin, INPUT_PULLUP); // назначение вывода ctrl8 входом pinMode(ctrl9Pin, INPUT_PULLUP); // назначение вывода ctrl9 входом pinMode(ctrl10Pin, INPUT_PULLUP); // назначение вывода ctrl10 входом pinMode(ctrl11Pin, INPUT_PULLUP); // назначение вывода ctrl11 входом pinMode(ctrl12Pin, INPUT_PULLUP); // назначение вывода ctrl12 входом pinMode(analog1Pin, INPUT); // назначение вывода analogPin входом pinMode(analogPin, INPUT); // назначение вывода analogPin входом pinMode(ind0Pin, OUTPUT); // назначение вывода ind0 выходом pinMode(ind1Pin, OUTPUT); // назначение вывода ind1 выходом pinMode(ind2Pin, OUTPUT); // назначение вывода ind2 выходом pinMode(ind3Pin, OUTPUT); // назначение вывода ind3 выходом pinMode(ind4Pin, OUTPUT); // назначение вывода ind4 выходом pinMode(ind5Pin, OUTPUT); // назначение вывода ind5 выходом pinMode(ind6Pin, OUTPUT); // назначение вывода ind6 выходом pinMode(ind7Pin, OUTPUT); // назначение вывода ind7 выходом pinMode(ind8Pin, OUTPUT); // назначение вывода ind8 выходом pinMode(ind9Pin, OUTPUT); // назначение вывода ind9 выходом pinMode(ind10Pin, OUTPUT); // назначение вывода ind10 выходом pinMode(indAPin, OUTPUT); // назначение вывода indAPin выходом pinMode(indBPin, OUTPUT); // назначение вывода indBPin выходом pinMode(indCPin, OUTPUT); // назначение вывода indCPin выходом pinMode(indDPin, OUTPUT); // назначение вывода indDPin выходом pinMode(clockPin, OUTPUT); // назначение вывода clockPin выходом pinMode(dataPin, OUTPUT); // назначение вывода dataPin выходом // запись начального состояния digitalWrite(ind0Pin, LOW); // запись нуля в ind0 digitalWrite(ind1Pin, HIGH); // запись единицы в ind1 digitalWrite(ind2Pin, HIGH); // запись единицы в ind2 digitalWrite(ind3Pin, LOW); // запись нуля в ind3 digitalWrite(ind4Pin, HIGH); // запись единицы в ind4 digitalWrite(ind5Pin, HIGH); // запись единицы в ind5 digitalWrite(ind6Pin, LOW); // запись нуля в ind6 digitalWrite(ind7Pin, HIGH); // запись единицы в ind7 digitalWrite(ind8Pin, HIGH); // запись единицы в ind8 digitalWrite(ind9Pin, HIGH); // запись единицы в ind9 digitalWrite(ind10Pin, HIGH); // запись единицы в ind10 analogReference(INTERNAL2V56); tft.begin(); // инициализациz TFT-экрана tft.setRotation(3); // альбомное расположение экрана tft.fillScreen(TFT_BLACK); // очистка экрана, цвет чёрный tft.setTextColor(TFT_YELLOW,TFT_BLACK); // жёлтый шрифт на чёрном фоне tft.setFreeFont(FSB24); // выбор фонта "Serif Bold 24pt" impuls(); // Выдача запускающего импульса trig (CKL), запись машинного времени старта в start } void loop() { // Чтение данных от приёмника // читаем время и текущий пин из IN_PIN now = micros(); // Читаем текущее машинное время bool s = digitalRead(IN_PIN); // Читаем текущее состояние пина if (prevS != s) { // Состояние пина изменилось? prevS = s; // Если изменилось, запомнили текущее состояние if (!flag) { // Опрос флага (первое срабатывание?) flag = 1; // Если первое срабатывание, устанавливаем флаг в 1 digitalWrite(IND_PIN, LOW); // Включаем светодиод текущего канала us[count] = now - start; // время до первого импульса if (flerr == 1) { // если установлен флаг ошибки errus[count] = us[count]; // заносим время до первого импульса в errus[count] }else { durus[count] = us[count]; // заносим время до первого импульса в durus[count] duration = durus[count]; } // duration = время до фронта первого импульса prevUs = now; // заносим текущее машинное время в prevUs count++; // + 1 в счётчик циклов } else // Если не первое срабатывание { // Обрабатываем следующие импульсы us[count] = now - prevUs; // длительность импульса if (flerr == 1) { // если установлен флаг ошибки errus[count] = (errus[count - 1] + us[count]); // errus[count] = текущее время всех импульсов if (count == 2) { // если это начало второго импульса durus[0] = errus[count]; // durus[count] = текущее время всех импульсов duration = errus[count]; // duration = время до фронта первого импульса flerr = 0; // сброс флага ошибки count = 0; }} // установка счётчика в 1 else { // если флага ошибки нет, считаем как обычно durus[count] = (durus[count - 1] + us[count]); // durus[count] = текущее время всех импульсов duration = durus[count - 1];} // duration = время до фронта последнего импульса prevUs = now; // Запомнили машинное время count++; // + 1 в счётчик циклов if (count >= LOG_SIZE) logOut(); // Если буфер переполнен - вывод лога } // Если состояние пина не изменилось, идём дальше } // Завершение чтения пина if (now - start > 60000) // Если время измерения истекло { // Устанавливаем начальные значения if (flag == 0) { // если импульсов не было durus[0] = 0; // в durus[0] пишем 0 durus[1] = 0; // в durus[1] пишем 0 duration = 0; // duration = время до фронта последнего импульса count = 1;} // сброс счётчика logOut(); // Переходим на вывод лога } // Если время измерения не истекло if (flag && now - prevUs > 60000) logOut(); // таймаут 60 мс (сигнал пропал) - вывод лога } // Вывод лога void logOut() { analog = analogRead(analogPin); voltage = (analog*6.2) / 400; analog1 = analogRead(analog1Pin); voltage1 = (analog1*6.2) / 400; airgnd = digitalRead(ctrl7Pin); // Чтение переключателя воздух / вода if (airgnd == 0){ // Если 0, то воздух cm = duration / 58; // Вычисление расстояния до объекта в воздухе в см и запись его в регистр if (cm <= 100) {(mn = 1); (vmn = 18);} // если расстояние меньше или равно 100, записываем 1 в mn else if (cm > 100 && cm <= 200) {(mn = 2); (vmn = 37);} // если расстояние больше 100, но меньше или равно 200, записываем 2 в mn else if (cm > 200 && cm <= 400) {(mn = 4); (vmn = 73);} // если расстояние больше 200, но меньше или равно 400, записываем 4 в mn else if (cm > 400 && cm <= 800) {(mn = 8); (vmn = 146);} // если расстояние больше 400, но меньше или равно 800, записываем 8 в mn else if (cm > 800 && cm <= 2000) {(mn = 20); (vmn = 370);} // если расстояние больше 800, но меньше или равно 2000, записываем 20 в mn m=(float)cm/100.0; // Запись в регистр m расстояния, делённого на 100 (перевод в метры) } else { // Если не 0, то вода cm = duration / 13; // Вычисление расстояния до объекта в воде и запись его в регистр if (cm <= 500) {(mn = 5); (vmn = 21);} // если расстояние меньше или равно 500, записываем 5 в mn else if (cm > 500 && cm <= 1000) {(mn = 10); (vmn = 42);} // если расстояние больше 500, но меньше или равно 1000, записываем 10 в mn else if (cm > 1000 && cm <= 2000) {(mn = 20); (vmn = 83);} // если расстояние больше 1000, но меньше или равно 2000, записываем 20 в mn else if (cm > 2000 && cm <= 4000) {(mn = 40); (vmn = 167);} // если расстояние больше 2000, но меньше или равно 4000, записываем 40 в mn else if (cm > 4000 && cm <= 8000) {(mn = 80); (vmn = 333);} // если расстояние больше 4000, но меньше или равно 8000, записываем 40 в mn m=(float)cm/100.0; // запись в регистр m расстояния, делённого на 100 (перевод в метры) } if (bitRead(regm2, 5) == 1) { // проверяем пятый бит если 1 - SEPAR md = m; // указание переменной с плавающей точкой md mnd = mn; } // указание предельного расстояния mnd else if (IN_PIN == echoPinA ) { mnA = mn; } // указание предельного расстояния mnA else if (IN_PIN == echoPinB ) { mnB = mn; } // указание предельного расстояния mnB else if (IN_PIN == echoPinC ) { mnC = mn; } // указание предельного расстояния mnC else if (IN_PIN == echoPinD ) { md = m; // указание переменной с плавающей точкой md mnd = mn; } // указание предельного расстояния mnd // Вывод на дисплей tft.setTextColor(TFT_YELLOW,TFT_BLACK); // жёлтый шрифт на чёрном фоне tft.fillRect(0,0,82,60,TFT_BLACK); // запись на экран чёрного квадрата tft.setCursor(0,40); // установка курсора на указанные позиции {tft.print(md); } // вывод на экран содержимого регистра (m) tft.fillRect(0,260,82,60,TFT_BLACK); // запись на экран чёрного квадрата tft.setCursor(16,304); // установка курсора на указанные позиции {tft.print(mnd); } // вывод на экран содержимого регистра (mn) tft.drawLine(0,160,84,160,TFT_YELLOW ); // вывод на экран средней линии tft.drawLine(84, 0, 84,320,TFT_YELLOW); // вывод на экран вертикальной линии) tft.fillRect(0,100,82,50,TFT_BLACK); // запись на экран чёрного квадрата tft.setCursor(0,140); // установка курсора на указанные позиции if (voltage >= 7){ // если напряжение больше или равно 7 В tft.setTextColor(TFT_GREEN,TFT_BLACK); // зелёный шрифт на чёрном фоне tft.println(voltage,1); // вывод на экран напряжения зелёным цветом }else { // иначе - выводим красным цветом tft.setTextColor(TFT_RED,TFT_BLACK); // красный шрифт на чёрном фоне tft.println(voltage,1);} // вывод на экран напряжения красным цветом tft.fillRect(0,170,82,50,TFT_BLACK); // запись на экран чёрного квадрата tft.setCursor(0,210); // установка курсора на указанные позиции if (voltage1 >= 10.5){ // если напряжение больше или равно 10.5 В tft.setTextColor(TFT_GREEN,TFT_BLACK); // зелёный шрифт на чёрном фоне tft.println(voltage1,1); // вывод на экран напряжения зелёным цветом }else { // иначе - выводим красным цветом tft.setTextColor(TFT_RED,TFT_BLACK); // красный шрифт на чёрном фоне tft.println(voltage1,1); } // вывод на экран напряжения красным цветом if (osc == 1){ // если включён осциллограф tft.drawLine(85,240,460,240,TFT_YELLOW ); // вывод на экран нижней линии if (bitRead(regm2, 5) == 1) { // проверяем пятый бит 0 - AUTO, 1 - SEPAR tft.fillRect(85,242,460,78,TFT_BLACK); } // запись на экран чёрного квадрата vmn = vmn*1.3; } // укорачиваем вертикальную выдачу в1,3 раза for (int j = 0; j < count;) { if (j == 0){ disp = durus[j]/vmn; dispp = durus[j+1]/vmn; if (bitRead(regm2, 5) == 0) { // проверяем пятый бит если 0 - AUTO if (IN_PIN == echoPinA ) { disp = disp*mnA/mnd; dispp = dispp*mnA/mnd; } else if (IN_PIN == echoPinB ) { disp = disp*mnB/mnd; dispp = dispp*mnB/mnd; } else if (IN_PIN == echoPinC ) { disp = disp*mnC/mnd; dispp = dispp*mnC/mnd; } } tft.drawLine(v,disp, v,0,TFT_LIGHTGREY); // вывод на экран графика содержимого регистра (disp) tft.drawLine(v,dispp, v,disp,TFT_MAGENTA); // вывод на экран графика содержимого регистра (dispp) if (osc == 1){ // если включён осциллограф disp = disp*1.5 + 85; dispp = dispp*1.5 + 85; oscv = 243; // указание верхней позиции y oscn = 317; // указание нижней позиции y if (IN_PIN == echoPinA ) { if (bitRead(regm2, 5) == 0) { // проверяем пятый бит 0 - AUTO, 1 - SEPAR oscv = 243; // указание верхней позиции y oscn = 260; // указание нижней позиции y tft.fillRect(85,241,460,22,TFT_BLACK); } // запись на экран чёрного квадрата tft.drawLine(disp,oscn,85,oscn,TFT_RED); // вывод на экран нуля первого импульса tft.drawLine(disp,oscv,disp,oscn,TFT_RED); // вывод на экран фронта первого импульса tft.drawLine(dispp,oscv,disp,oscv,TFT_RED); // вывод на экран полочки первого импульса tft.drawLine(dispp,oscv,dispp,oscn,TFT_RED); // вывод на экран спада первого импульса if (count == 2) { // если счётчик равен 2 tft.drawLine(460,oscn,dispp,oscn,TFT_RED); } // вывод на экран нулевой линии до конца } else if (IN_PIN == echoPinB ) { oscv = 263; // указание верхней позиции y if (bitRead(regm2, 5) == 0) { // проверяем пятый бит 0 - AUTO, 1 - SEPAR oscv = 263; // указание верхней позиции y oscn = 280; // указание нижней позиции y tft.fillRect(85,oscv,460,20,TFT_BLACK); } // запись на экран чёрного квадрата tft.drawLine(disp,oscn,85,oscn,TFT_YELLOW); // вывод на экран нуля первого импульса tft.drawLine(disp,oscv,disp,oscn,TFT_YELLOW); // вывод на экран фронта первого импульса tft.drawLine(dispp,oscv,disp,oscv,TFT_YELLOW); // вывод на экран полочки первого импульса tft.drawLine(dispp,oscv,dispp,oscn,TFT_YELLOW); // вывод на экран спада первого импульса if (count == 2) { // если счётчик равен 2 tft.drawLine(460,oscn,dispp,oscn,TFT_YELLOW); } // вывод на экран нулевой линии до конца } else if (IN_PIN == echoPinC ) { oscv = 283; // указание верхней позиции y if (bitRead(regm2, 5) == 0) { // проверяем пятый бит 0 - AUTO, 1 - SEPAR oscv = 283; // указание верхней позиции y oscn = 300; // указание нижней позиции y tft.fillRect(85,oscv,460,20,TFT_BLACK); } // запись на экран чёрного квадрата tft.drawLine(disp,oscn,85,oscn,TFT_GREEN); // вывод на экран нуля первого импульса tft.drawLine(disp,oscv,disp,oscn,TFT_GREEN); // вывод на экран фронта первого импульса tft.drawLine(dispp,oscv,disp,oscv,TFT_GREEN); // вывод на экран полочки первого импульса tft.drawLine(dispp,oscv,dispp,oscn,TFT_GREEN); // вывод на экран спада первого импульса if (count == 2) { // если счётчик равен 2 tft.drawLine(460,oscn,dispp,oscn,TFT_GREEN); } // вывод на экран нулевой линии до конца } else if (IN_PIN == echoPinD ) { oscv = 298; // указание верхней позиции y if (bitRead(regm2, 5) == 0) { // проверяем пятый бит 0 - AUTO, 1 - SEPAR oscv = 303; // указание верхней позиции y oscn = 317; // указание нижней позиции y tft.fillRect(85,oscv,460,20,TFT_BLACK); } // запись на экран чёрного квадрата tft.drawLine(disp,oscn,85,oscn,TFT_BLUE); // вывод на экран нуля первого импульса tft.drawLine(disp,oscv,disp,oscn,TFT_BLUE); // вывод на экран фронта первого импульса tft.drawLine(dispp,oscv,disp,oscv,TFT_BLUE); // вывод на экран полочки первого импульса tft.drawLine(dispp,oscv,dispp,oscn,TFT_BLUE); // вывод на экран спада первого импульса if (count == 2) { // если счётчик равен 2 tft.drawLine(460,oscn,dispp,oscn,TFT_BLUE); } // вывод на экран нулевой линии до конца } } j = j+2; } else { dispm = durus[j-1] / vmn; disp = durus[j] / vmn; dispp = durus[j+1] / vmn; tft.drawLine(v,disp, v,dispm,TFT_BLACK); // вывод на экран графика содержимого регистра (disp) if (IN_PIN == echoPinA ) { if (bitRead(regm2, 5) == 0) { // проверяем пятый бит если 0 - AUTO dispm = dispm*mnA/mnd; disp = disp*mnA/mnd; dispp = dispp*mnA/mnd; } tft.drawLine(v,disp, v,dispm,TFT_BLACK); // вывод на экран графика содержимого регистра (disp) tft.drawLine(v,dispp, v,disp,TFT_RED); } else if (IN_PIN == echoPinB ) { if (bitRead(regm2, 5) == 0) { // проверяем пятый бит если 0 - AUTO dispm = dispm*mnB/mnd; disp = disp*mnB/mnd; dispp = dispp*mnB/mnd; } tft.drawLine(v,disp, v,dispm,TFT_BLACK); // вывод на экран графика содержимого регистра (disp) tft.drawLine(v,dispp, v,disp,TFT_YELLOW); } else if (IN_PIN == echoPinC ) { if (bitRead(regm2, 5) == 0) { // проверяем пятый бит если 0 - AUTO dispm = dispm*mnC/mnd; disp = disp*mnC/mnd; dispp = dispp*mnC/mnd; } tft.drawLine(v,disp, v,dispm,TFT_BLACK); // вывод на экран графика содержимого регистра (disp) tft.drawLine(v,dispp, v,disp,TFT_GREEN); } else if (IN_PIN == echoPinD ) { tft.drawLine(v,disp, v,dispm,TFT_BLACK); // вывод на экран графика содержимого регистра (disp) tft.drawLine(v,dispp, v,disp,TFT_BLUE); } if (osc == 1){ // если включён осциллограф dispm = dispm*1.5 + 85; disp = disp*1.5 + 85; dispp = dispp*1.5 + 85; if (IN_PIN == echoPinA ){ tft.drawLine(disp,oscn,dispm,oscn,TFT_RED); // вывод на экран нуля текущего импульса tft.drawLine(disp,oscv,disp,oscn,TFT_RED); // вывод на экран фронта первого импульса tft.drawLine(dispp,oscv,disp,oscv,TFT_RED); // вывод на экран полочки первого импульса tft.drawLine(dispp,oscv,dispp,oscn,TFT_RED); // вывод на экран спада первого импульса if (j == count - 2) { // если последнее измерение tft.drawLine(460,oscn,dispp,oscn,TFT_RED); } // вывод на экран нулевой линии до конца } else if (IN_PIN == echoPinB ){ tft.drawLine(disp,oscn,dispm,oscn,TFT_YELLOW); // вывод на экран нуля текущего импульса tft.drawLine(disp,oscv,disp,oscn,TFT_YELLOW); // вывод на экран фронта первого импульса tft.drawLine(dispp,oscv,disp,oscv,TFT_YELLOW); // вывод на экран полочки первого импульса tft.drawLine(dispp,oscv,dispp,oscn,TFT_YELLOW); // вывод на экран спада первого импульса if (j == count - 2 ) { // если последнее измерение tft.drawLine(460,oscn,dispp,oscn,TFT_YELLOW); } // вывод на экран нулевой линии до конца } else if (IN_PIN == echoPinC ){ tft.drawLine(disp,oscn,dispm,oscn,TFT_GREEN); // вывод на экран нуля текущего импульса tft.drawLine(disp,oscv,disp,oscn,TFT_GREEN); // вывод на экран фронта первого импульса tft.drawLine(dispp,oscv,disp,oscv,TFT_GREEN); // вывод на экран полочки первого импульса tft.drawLine(dispp,oscv,dispp,oscn,TFT_GREEN); // вывод на экран спада первого импульса if (j == count - 2 ) { // если последнее измерение tft.drawLine(460,oscn,dispp,oscn,TFT_GREEN); } // вывод на экран нулевой линии до конца } else if (IN_PIN == echoPinD ) { tft.drawLine(disp,oscn,dispm,oscn,TFT_BLUE); // вывод на экран нуля текущего импульса tft.drawLine(disp,oscv,disp,oscn,TFT_BLUE); // вывод на экран фронта первого импульса tft.drawLine(dispp,oscv,disp,oscv,TFT_BLUE); // вывод на экран полочки первого импульса tft.drawLine(dispp,oscv,dispp,oscn,TFT_BLUE); // вывод на экран спада первого импульса if (j == count - 2 ) { // если последнее измерение tft.drawLine(460,oscn,dispp,oscn,TFT_BLUE); } // вывод на экран нулевой линии до конца } } j = j+2; } } v = v + 1; // переход графика на следующую позицию if (v==460){ (v = 85); tft.fillScreen(TFT_BLACK); // очистка экрана, цвет чёрный tft.setTextColor(TFT_YELLOW,TFT_BLACK); // жёлтый шрифт на чёрном фоне tft.setFreeFont(FSB24); // выбор фонта "Serif Bold 24pt" } impuls(); // Выдача запускающего импульса trig } void impuls() { // Выдача запускающего импульса trig // проверка кнопок 0 - 10 на нажатие regkn1 = PINF; // чтение кнопок управления исполнительным устройством regkn2 = PINK; // чтение кнопок управления каналами // проверка кнопок 0 - 5 на нажатие, формирование регистра regout regkn = regkn1 | 0b00011000; // маскировка ненужных битов regkn = ~regkn; // инвертируем if (regkn != 0) { // если есть нажатие кнопки if (bitRead(regkn, 0) == 1) { // проверяем нулевой бит - если есть нажатие кнопки 0 bitClear(regm1, 0); // запись нуля в ind0 bitSet(regm1, 1); // запись единицы в ind1 bitSet(regm1, 2); // запись единицы в ind2 bitSet(regout, 3); // запись единицы в A1T bitSet(regout, 5); } // запись единицы в A0T else // если нет нажатия кнопки 0 if (bitRead(regkn, 1) == 1) { // проверяем первый бит - если есть нажатие кнопки 1 bitSet(regm1, 0); // запись единицы в ind0 bitClear(regm1, 1); // запись нуля в ind1 bitSet(regm1, 2); // запись единицы в ind2 bitSet(regout, 3); // запись единицы в A1T bitClear(regout, 5); } // запись нуля в A0T else // если нет нажатия кнопки 1 if (bitRead(regkn, 2) == 1) { // проверяем второй бит - если есть нажатие кнопки 2 bitSet(regm1, 0); // запись единицы в ind0 bitSet(regm1, 1); // запись единицы в ind1 bitClear(regm1, 2); // запись нуля в ind2 bitClear(regout, 3); // запись нуля в A1T bitSet(regout, 5); } // запись единицы в A0T else // если нет нажатия кнопки 2 if (bitRead(regkn, 5) == 1) { // проверяем пятый бит - если есть нажатие кнопки 3 bitClear(regm1, 5); // запись нуля в ind3 bitSet(regm1, 6); // запись единицы в ind4 bitSet(regm1, 7); // запись единицы в ind5 bitSet(regout, 1); // запись единицы в A1R bitClear(regout, 2); } // запись нуля в A0R else // если нет нажатия кнопки 3 if (bitRead(regkn, 6) == 1) { // проверяем шестой бит - если есть нажатие кнопки 4 bitSet(regm1, 5); // запись единицы в ind3 bitClear(regm1, 6); // запись нуля в ind4 bitSet(regm1, 7); // запись единицы в ind5 bitClear(regout, 1); // запись нуля в A1R bitSet(regout, 2); } // запись единицы в A0R else // если нет нажатия кнопки 4 if (bitRead(regkn, 7) == 1) { // проверяем седьмой бит - если есть нажатие кнопки 5 bitSet(regm1, 5); // запись единицы в ind3 bitSet(regm1, 6); // запись единицы в ind4 bitClear(regm1, 7); // запись нуля в ind5 bitSet(regout, 1); // запись единицы в A1R bitSet(regout, 2); } // запись единицы в A0R // включение светодиодов индикации режима digitalWrite(ind0Pin, bitRead(regm1, 0)); // запись состояния в ind0 digitalWrite(ind1Pin, bitRead(regm1, 1)); // запись состояния в ind1 digitalWrite(ind2Pin, bitRead(regm1, 2)); // запись состояния в ind2 digitalWrite(ind3Pin, bitRead(regm1, 5)); // запись состояния в ind3 digitalWrite(ind4Pin, bitRead(regm1, 6)); // запись состояния в ind4 digitalWrite(ind5Pin, bitRead(regm1, 7)); // запись состояния в ind5 } // если нет нажатия кнопок 0 - 5, сразу идём сюда djmp = bitRead(regkn1, 3); // чтение переключателя DC bitWrite(regout, 4, !djmp); // запись состояния переключателя DC в DC // проверка кнопок 6 - 10 на нажатие regkn = regkn2 | 0b11000001; // маскировка ненужных битов regkn = ~regkn; // инвертируем if (regkn != 0) { // если есть нажатие кнопки regm2 = 0xFF; // устанавливаем все единицы в regm2 if (bitRead(regkn, 1) == 1) { // проверяем первый бит - если есть нажатие кнопки 6 bitClear(regm2, 1); } // запись нуля в ind6 else // если нет нажатия кнопки 6 if (bitRead(regkn, 2) == 1) { // проверяем второй бит - если есть нажатие кнопки 7 bitClear(regm2, 2); } // запись нуля в ind7 else // если нет нажатия кнопки 7 if (bitRead(regkn, 3) == 1) { // проверяем третий бит - если есть нажатие кнопки 8 bitClear(regm2, 3); } // запись нуля в ind8 else // если нет нажатия кнопки 8 if (bitRead(regkn, 4) == 1) { // проверяем четвёртый бит - если есть нажатие кнопки 9 bitClear(regm2, 4); } // запись нуля в ind9 else // если нет нажатия кнопки 10 if (bitRead(regkn, 5) == 1) { // проверяем пятый бит - если есть нажатие кнопки 10 bitClear(regm2, 5); } // запись нуля в ind10 // включение светодиодов индикации режима digitalWrite(ind6Pin, bitRead(regm2, 1)); // запись состояния в ind6 digitalWrite(ind7Pin, bitRead(regm2, 2)); // запись состояния в ind7 digitalWrite(ind8Pin, bitRead(regm2, 3)); // запись состояния в ind8 digitalWrite(ind9Pin, bitRead(regm2, 4)); // запись состояния в ind9 digitalWrite(ind10Pin, bitRead(regm2, 5)); // запись состояния в ind10 } // если нет нажатия, сразу идём сюда // проверка кнопоки 11 на нажатие oscknt = digitalRead(ctrl12Pin); // Читаем текущее состояние пина if (oscknt == 0 ) { // Если 0, смотрим, первое чтение, или нет if (oscknp == 1 ) { // Если 1, первое чтение, osc = !osc; // инвертируем флаг if (osc == 0 ) { // Если выключение осциллографа, tft.drawLine(85,240,460,240,TFT_BLACK); // стирание на экране нижней линии tft.fillRect(85,242,460,78,TFT_BLACK); }}} // запись на экран чёрного квадрата oscknp = oscknt; // записываем текущее состояние кнопки в предыдущее // гашение светодиодов L1 - L4 digitalWrite(indAPin, HIGH); // запись единицы в indAPin digitalWrite(indBPin, HIGH); // запись единицы в indBPin digitalWrite(indCPin, HIGH); // запись единицы в indCPin digitalWrite(indDPin, HIGH); // запись единицы в indDPin // Выясняем, какой пин текущий и заносим его в IN_PIN flerr = 0; // очистка флага ошибки if (bitRead(regm2, 5) == 0) // проверяем пятый бит 0 - AUTO, 1 - SEPAR { // Если 0 - AUTO, читаем все пины if (flagn == 0 ) { // Если 0, идём читать пин, иначе - уходим if (k == 0) // Если k = 0, - PinD {IN_PIN = echoPinD; // Читаем PinD IND_PIN = indDPin; // Устанавливаем пин индикации канала D errD(); // Вызываем подпрограмму коррекции D flagn = 1; // Устанавливаем flagn = 1. Пин определён k = 1; } // Устанавливаем следующий Pin else // Если k не 0, идём дальше if (k == 1) // Если k = 1, PinC {IN_PIN = echoPinC; // Читаем PinC IND_PIN = indCPin; // Устанавливаем пин индикации канала C errC(); // Вызываем подпрограмму коррекции C flagn = 1; // Устанавливаем flagn = 1. Пин прочитан k = 2; } // Устанавливаем следующий Pin else // Если k не 1, идём дальше if (k == 2) // Если k = 2, PinB {IN_PIN = echoPinB; // Читаем PinB IND_PIN = indBPin; // Устанавливаем пин индикации канала B errB(); // Вызываем подпрограмму коррекции B flagn = 1; // Устанавливаем flagn = 1. Пин прочитан k = 3; } // Устанавливаем следующий Pin else // Если k не 2, идём дальше if (k == 3) // Если k = 3, PinA {IN_PIN = echoPinA; // Читаем PinA IND_PIN = indAPin; // Устанавливаем пин индикации канала A errA(); // Вызываем подпрограмму коррекции A flagn = 1; // Устанавливаем flagn = 1. Пин прочитан k = 0;} // Устанавливаем PinD } // flagn =1. Пин уже прочитан, уходим }else { // Значит, пятый бит = 1 - SEPAR, идём читать if (bitRead(regm2, 1) == 0) // Если первый бит = 0 {IN_PIN = echoPinA; // Читаем PinA IND_PIN = indAPin; // Устанавливаем пин индикации канала A errA(); // Вызываем подпрограмму коррекции A }else // Если нет, идём дальше if (bitRead(regm2, 2) == 0) // Если второй бит = 0 {IN_PIN = echoPinB; // Читаем PinB IND_PIN = indBPin; // Устанавливаем пин индикации канала B errB(); // Вызываем подпрограмму коррекции B }else // Если нет, идём дальше if (bitRead(regm2, 3) == 0) // Если третий бит = 0 {IN_PIN = echoPinC; // Читаем PinC IND_PIN = indCPin; // Устанавливаем пин индикации канала C errC(); // Вызываем подпрограмму коррекции C }else // Если нет, идём дальше if (bitRead(regm2, 4) == 0) // Если четвёртый бит = 0 {IN_PIN = echoPinD; // Читаем PinD IND_PIN = indDPin; // Устанавливаем пин индикации канала D errD(); // Вызываем подпрограмму коррекции D } // С пинами разобрались. Идём дальше } // выдача сигналов управления на исполнительное устройство shiftOut(dataPin,clockPin,MSBFIRST,regout); // пересылка байта regout // Установка начальных значений count = 0; // count durus[0] = 0; // в durus[0] пишем 0 durus[1] = 0; // в durus[1] пишем 0 duration = 0; // duration = время до фронта последнего импульса flag = 0; // flag flagn = 0; // flagn first = prevS = digitalRead(IN_PIN); // Запомнили начальное состояние текущего пина digitalWrite(trigPin, LOW); // запись нуля в выходной вывод delayMicroseconds(2); // удержание нуля в течение 2 мксек digitalWrite(trigPin, HIGH); // запись единицы в выходной вывод delayMicroseconds(10); // удержание единицы в течение 10 мксек digitalWrite(trigPin, LOW); // запись нуля в выходной вывод start = micros(); } void errA() { // условие коррекции канала А if (digitalRead(ctrl8Pin) == 1) { // Если нет нажатия кнопки канала А if (digitalRead(ctrl3Pin) == 0) { // Если питание 12 В if (bitRead(regm1,7) == 0) { // Если Ку = 36 if (bitRead(regm1,1) == 0) { // Если 8 имп flerr = 1; } // Установка флага ошибки else { // если не этот режим if (bitRead(regm1,2) == 0) { // Если 16 имп flerr = 1; }}}} // Установка флага ошибки else { // если питание 24 В if (bitRead(regm1,7) == 0) { // Если Ку = 36 flerr = 1; }}} // Установка флага ошибки } void errB() { // условие коррекции канала B if (digitalRead(ctrl9Pin) == 1) { // Если нет нажатия кнопки канала B if (digitalRead(ctrl3Pin) == 0) { // Если питание 12 В if (bitRead(regm1,6) == 0) { // Если Ку = 6 if (bitRead(regm1,2) == 0) { // Если 16 имп flerr = 1; }} // Установка флага ошибки else { // если не этот режим if (bitRead(regm1,7) == 0) { // Если Ку = 36 flerr = 1; }}} // Установка флага ошибки else { // если питание 24 В if (bitRead(regm1,6) == 0) { // Если Ку = 6 if (bitRead(regm1,1) == 0) { // Если 8 имп flerr = 1; } // Установка флага ошибки else { // если не этот режим if (bitRead(regm1,2) == 0) { // Если 16 имп flerr = 1; }}} // Установка флага ошибки else { // если не этот режим if (bitRead(regm1,7) == 0) { // Если Ку = 36 flerr = 1; }}}} // Установка флага ошибки } void errC() { // условие коррекции канала C if (digitalRead(ctrl10Pin) == 1) { // Если нет нажатия кнопки канала C if (digitalRead(ctrl3Pin) == 0) { // Если питание 12 В if (bitRead(regm1,6) == 0) { // Если Ку = 6 if (bitRead(regm1,1) == 0) { // Если 8 имп flerr = 1; } // Установка флага ошибки else { // если не этот режим if (bitRead(regm1,2) == 0) { // Если 16 имп flerr = 1; }}} // Установка флага ошибки else { // если не этот режим if (bitRead(regm1,7) == 0) { // Если Ку = 36 flerr = 1; }}} // Установка флага ошибки else { // если питание 24 В if (bitRead(regm1,6) == 0) { // Если Ку = 6 flerr = 1; } // Установка флага ошибки else { // если не этот режим if (bitRead(regm1,7) == 0) { // Если Ку = 36 flerr = 1; }}}} // Установка флага ошибки } void errD() { // условие коррекции канала D if (digitalRead(ctrl11Pin) == 1) { // Если нет нажатия кнопки канала D if (digitalRead(ctrl3Pin) == 0) { // Если питание 12 В if (bitRead(regm1,6) == 0) { // Если Ку = 6 flerr = 1; } // Установка флага ошибки else { // если не этот режим if (bitRead(regm1,7) == 0) { // Если Ку = 36 flerr = 1; }}} // Установка флага ошибки else { // если питание 24 В if (bitRead(regm1,5) == 0) { // Если Ку = 1 if (bitRead(regm1,2) == 0) { // Если 16 имп flerr = 1; }} // Установка флага ошибки else { // если не этот режим if (bitRead(regm1,6) == 0) { // Если Ку = 6 flerr = 1; } // Установка флага ошибки else { // если не этот режим if (bitRead(regm1,7) == 0) { // Если Ку = 36 flerr = 1; }}}}} // Установка флага ошибки }