/* Вариант беспроводного соединения блока управления с исполнительным устройством. За основу взят последний проводной вариант Exolot_Var_2_2_3. Ардуино занимается только выводом информации на экран. Вся обработка импульсов производится WeMos, связанной с Исполнительным Устройством (ISP). Результаты измерения передаются по протоколу ESP-NOW на WeMos, связанную с Ардуино и далее по шине I2C на Ардуино. При наладке раскомментировать команды вывода на последовательный порт Serial для наблюдения процесса на экране монитора. Доработка схемы: 1. Для возможности вывода информации в последовательный порт пришлось освободить выводы 0 и 1 последовательного порта Ардуино, для чего контакты этих выводов с платы управления были обрезаны. В свободные разъёмы контактов 14 и 15 Ардуино вставлены два угловых контакта и проводами установлены связи: Контакт 0 платы управления - контакт 15 платы Ардуино и контакт 1 платы управления - контакт 14 платы Ардуино. 2. В связи с тем, чо в свЯзи с WeMos по протоколу I2C на сегодня Ардуино может быть только ведомым (slave) из - за отсутствия вменяемой библиотеки, пришлось отдельным проводом соединить свободный контакт 16 Ардуино с выводом D6 WeMos через делитель - преобразователь уровня 2,4 кОм / 4,7 кОм. По этому проводу Ардуино передаёт WeMos сигнал готовности, по которому WeMos Запрашивает У Ардуино и получает данные для передачи на ISP. */ #include // библиотека для работы с дисплеем #include "Free_Fonts.h" // подключаемый файл #include // библиотека Arduino #include // библиотека #include TFT_HX8357 tft = TFT_HX8357(); // вызов пользовательской библиотеки 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 ctrl13Pin = 68; // назначение вывода ctrl13Pin экран 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 = 14; // назначение вывода ind9Pin канал L1 int ind10Pin = 15; // назначение вывода ind10Pin канал авто int Requout = 16; // назначение вывода запрос выход 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 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; // регистр выдачи на исполнительное устройство byte reg_IN = 0x02; // регистр пина индикации #define LOG_SIZE 12 // размер лога (LOG_SIZE ячеек) uint16_t durus[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; // предыдущее, текущее состояние кнопки, флаг режима осциллографа volatile bool flagrec = 0; // флаг подтверждения приёма данных volatile bool flagsend = 0; // флаг подтверждения отправки данных int k = 0; // Указатель текущего канала для чтения void setup() { 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(ctrl13Pin, INPUT_PULLUP); // назначение вывода ctrl13 входом 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(Requout, OUTPUT); // назначение вывода Reqout выходом pinMode(indAPin, OUTPUT); // назначение вывода indAPin выходом pinMode(indBPin, OUTPUT); // назначение вывода indBPin выходом pinMode(indCPin, OUTPUT); // назначение вывода indCPin выходом pinMode(indDPin, OUTPUT); // назначение вывода indDPin выходом // запись начального состояния 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 reg_IN = 0xFD; // устанавливаем регистр пина индикации digitalWrite(Requout, HIGH); // запись единицы в Requout analogReference(INTERNAL2V56); Wire.begin(8); // задаем на шине i2c 8 адрес Wire.onReceive(receiveEvent); // регистрируем полученное событие Wire.onRequest(requestEvent); // регистрируем запрошенное событие // Serial.begin(115200); // открываем серийный порт для дебаггинга 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) } void loop() { digitalWrite(Requout, HIGH); // запись единицы в Requout if(flagsend == 1){ // если есть подтверждение отправки digitalWrite(Requout, LOW); // запись нуля в Requout // printSendDate(); flagsend = 0; // сброс флага отправки данных от Ардуино } if(flagrec == 1){ // ожидание приёма от WeMosArd // printIncomingReadings(); flagrec = 0; // сброс флага приёма данных от ISP logOut(); // вывод на дисплей } } // Функция для извлечения любых принимаемых данных от мастера на шину void receiveEvent (int howMany) { if (howMany >= (sizeof count) + (sizeof voltage1) + (sizeof duration) + (sizeof durus[LOG_SIZE])) { count = Wire.read(); I2C_readAnything (voltage1); I2C_readAnything (duration); for (int i = 0; i < LOG_SIZE; i++) { I2C_readAnything(durus[i]); // принимаем каждый из 20 элементов массива } flagrec = 1; // установка флага приёма данных от ISP } } // Функция для извлечения любых отправляемых данных от мастера на шину void requestEvent() { Wire.write(regkn2); Wire.write(regm1); Wire.write(regm2); Wire.write(reg_IN); Wire.write(regout); flagsend = 1; // установка флага отправки данных от Ардуино } /* void printSendDate(){ // Отображаем показания в мониторе порта Serial.println("SendDate "); Serial.println(regkn2); Serial.println(regm1); Serial.println(regm2); Serial.println(reg_IN); Serial.println(regout); } void printIncomingReadings(){ Serial.println("ПРИЁМ_ОТ_ISP "); Serial.print("count: "); Serial.println(count); Serial.print("voltage1: "); Serial.println(voltage1); Serial.print("duration: "); Serial.println(duration); Serial.println("durus"); for (int i = 0; i < LOG_SIZE; i++) { Serial.println(durus[i]); } } */ // Вывод лога void logOut() { if (duration != 0) { // если установлен флаг ошибки digitalWrite(IND_PIN, LOW); // Включаем светодиод текущего канала } analog = analogRead(analogPin); voltage = (analog*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 (bitRead(reg_IN,1) == 0){ // если текущий канал A mnA = mn; } // указание предельного расстояния mnA else if (bitRead(reg_IN,2) == 0){ // если текущий канал B mnB = mn; } // указание предельного расстояния mnB else if (bitRead(reg_IN,3) == 0){ // если текущий канал C mnC = mn; } // указание предельного расстояния mnC else if (bitRead(reg_IN,4) == 0){ // если текущий канал D 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 (bitRead(reg_IN,1) == 0){ // если текущий канал A disp = disp*mnA/mnd; dispp = dispp*mnA/mnd; } else if (bitRead(reg_IN,2) == 0){ // если текущий канал B disp = disp*mnB/mnd; dispp = dispp*mnB/mnd; } else if (bitRead(reg_IN,3) == 0){ // если текущий канал C 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 (bitRead(reg_IN,1) == 0){ // если текущий канал A 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 (bitRead(reg_IN,2) == 0){ // если текущий канал B 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 (bitRead(reg_IN,3) == 0){ // если текущий канал C 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 (bitRead(reg_IN,4) == 0){ // если текущий канал D 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 (bitRead(reg_IN,1) == 0){ // если текущий канал A 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 (bitRead(reg_IN,2) == 0){ // если текущий канал B 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 (bitRead(reg_IN,3) == 0){ // если текущий канал C 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 (bitRead(reg_IN,4) == 0){ // если текущий канал D 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 (bitRead(reg_IN,1) == 0){ // если текущий канал A 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 (bitRead(reg_IN,2) == 0){ // если текущий канал B 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 (bitRead(reg_IN,3) == 0){ // если текущий канал C 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 (bitRead(reg_IN,4) == 0){ // если текущий канал D 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(); // Выдача запускающего импульса } 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 bitWrite(regm1,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(ctrl13Pin); // Читаем текущее состояние пина 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 if (bitRead(regm2, 5) == 0) // проверяем пятый бит 0 - AUTO, 1 - SEPAR { // Если 0 - AUTO, читаем все пины if (flagn == 0 ) { // Если 0, идём читать пин, иначе - уходим if (k == 0) { // Если k = 0, - PinD reg_IN = 0xEF; // устанавливаем регистр пина индикации IND_PIN = indDPin; // Устанавливаем пин индикации канала D flagn = 1; // Устанавливаем flagn = 1. Пин определён k = 1; } // Устанавливаем следующий Pin else // Если k не 0, идём дальше if (k == 1) { // Если k = 1, PinC reg_IN = 0xF7; // устанавливаем регистр пина индикации IND_PIN = indCPin; // Устанавливаем пин индикации канала C flagn = 1; // Устанавливаем flagn = 1. Пин прочитан k = 2; } // Устанавливаем следующий Pin else // Если k не 1, идём дальше if (k == 2) { // Если k = 2, PinB reg_IN = 0xFB; // устанавливаем регистр пина индикации IND_PIN = indBPin; // Устанавливаем пин индикации канала B flagn = 1; // Устанавливаем flagn = 1. Пин прочитан k = 3; } // Устанавливаем следующий Pin else // Если k не 2, идём дальше if (k == 3) { // Если k = 3, PinA reg_IN = 0xFD; // устанавливаем регистр пина индикации IND_PIN = indAPin; // Устанавливаем пин индикации канала A flagn = 1; // Устанавливаем flagn = 1. Пин прочитан k = 0;} // Устанавливаем PinD } // flagn =1. Пин уже прочитан, уходим } else // Значит, пятый бит = 1 - SEPAR, идём читать if (bitRead(regm2, 1) == 0) { // Если первый бит = 0 reg_IN = 0xFD; // устанавливаем регистр пина индикации IND_PIN = indAPin; // Устанавливаем пин индикации канала A } else // Если нет, идём дальше if (bitRead(regm2, 2) == 0) { // Если второй бит = 0 reg_IN = 0xFB; // устанавливаем регистр пина индикации IND_PIN = indBPin; // Устанавливаем пин индикации канала B }else // Если нет, идём дальше if (bitRead(regm2, 3) == 0) { // Если третий бит = 0 reg_IN = 0xF7; // устанавливаем регистр пина индикации IND_PIN = indCPin; // Устанавливаем пин индикации канала C }else // Если нет, идём дальше if (bitRead(regm2, 4) == 0) { // Если четвёртый бит = 0 reg_IN = 0xEF; // устанавливаем регистр пина индикации IND_PIN = indDPin; // Устанавливаем пин индикации канала D } // С пинами разобрались. Идём дальше // Установка начальных значений count = 0; // count durus[0] = 0; // в durus[0] пишем 0 durus[1] = 0; // в durus[1] пишем 0 duration = 0; // duration = время до фронта последнего импульса flagn = 0; // flagn } /* 7 6 5 4 3 2 1 0 regm1 X36 X6 X1 12/24V - 16 имп 8 имп 4 имп regm2 - - АВТО D C B A - reg_IN - - - D C B A - regkn2 ЭКРАН - АВТО D C B A СРЕДА - - - - L1 L2 L3 L4 - - - - - КАН 4 КАН 3 КАН 2 КАН 1 - regout - - A0T DC A1T A0R A1R - DF EF F7 FB FD */