/*
Релейная логическая схема Logic1 на основе релейных модулей 5V с оптической развязкой.
Перемычку на всех релейных модулях ставим между средним и левый контактом с надписью "H".
Входной разъем:
DC- подключаем к GND;
DC+ подключаем к +5V;
IN подключаем к PIN Arduino.
*/
//#define FuncTest // Тест на правильность функционирования логической схемы.
#define SpeedTest // Тест на скорость работы.
#ifdef FuncTest
#define logicDelay 300 // Время ожидания прохождения сигналов по всей релейной логической схеме.
#define cycleDelay 2000 // Задержка между шагами цикла.
#endif // FuncTest
#ifdef SpeedTest
#define plusDelta 1 // Значение на сколько миллисекунд нужно увеличивать currDelay.
#define minusDelta 10 // Значение на сколько миллисекунд нужно уменьшать currDelay.
#define startDelay 300 // Стартовое значение currDelay.
#define CycleMaxSpeedCountMax 100 // Максимальное количество циклов при максимальной скорости работы без ошибок.
bool errFound; // = False - ни одной ошибки с начала работы программы не было найдено; = True - ошибки были.
int currCycleMaxSpeedCountMax; // Текущее значение CycleMaxSpeedCountMax.
#endif // SpeedTest
int currDelay; // Текущее значение времени ожидания прохождения сигналов по всей релейной логической схеме.
int x0 = 2; // Пин 2.
int x1 = 3; // Пин 3.
int x2 = 4; // Пин 4.
int x3 = 5; // Пин 5.
int y3 = 6; // Пин 6.
byte xxxx; // x0, x1, x2, x3, представленные одним байтом, где x3 - младший бит 0, x0 - бит 3.
int currErrorsCount; // Счетчик количества ошибок в текущем цикле.
int totalErrorsCount; // Счетчик общего количества ошибок с начала запуска программы.
int currCycleCount; // Текущее значение цикла.
void setup() {
pinMode(x0, OUTPUT);
pinMode(x1, OUTPUT);
pinMode(x2, OUTPUT);
pinMode(x3, OUTPUT);
pinMode(y3, INPUT);
xxxx = 0;
totalErrorsCount = 0;
currCycleCount = 0;
#ifdef FuncTest
currDelay = logicDelay;
#endif // FuncTest
#ifdef SpeedTest
currDelay = startDelay;
errFound = false;
currCycleMaxSpeedCountMax = 0;
#endif // SpeedTest
Serial.begin(9600); // Для вывода результатов работы схемы.
Serial.println("Program Start");
}
void loop() {
if (xxxx == 0) {
#ifdef SpeedTest
if (currCycleMaxSpeedCountMax == 0) {
#endif // SpeedTest
Serial.println("");
Serial.print("Start Cycle N ");
Serial.print(currCycleCount, DEC);
Serial.print(". Current Delay ");
Serial.println(currDelay, DEC);
#ifdef SpeedTest
}
#endif // SpeedTest
currErrorsCount = 0;
}
#ifdef FuncTest
// Вывод текущего значения входных сигналов x0, x1, x2, x3.
Serial.print("xxxx = ");
Serial.print(xxxx, HEX);
Serial.print(" ");
#endif // FuncTest
setX0123(xxxx); // Установить новое значение входных сигналов релейной логической схемы.
delay(currDelay); // Время ожидания прохождения сигналов по всей релейной логической схеме.
switch (xxxx) {
case 0x0:
resultPrint(digitalRead(y3), HIGH);
break;
case 0x1:
resultPrint(digitalRead(y3), HIGH);
break;
case 0x2:
resultPrint(digitalRead(y3), HIGH);
break;
case 0x3:
resultPrint(digitalRead(y3), LOW);
break;
case 0x4:
resultPrint(digitalRead(y3), HIGH);
break;
case 0x5:
resultPrint(digitalRead(y3), HIGH);
break;
case 0x6:
resultPrint(digitalRead(y3), HIGH);
break;
case 0x7:
resultPrint(digitalRead(y3), LOW);
break;
case 0x8:
resultPrint(digitalRead(y3), HIGH);
break;
case 0x09:
resultPrint(digitalRead(y3), HIGH);
break;
case 0xa:
resultPrint(digitalRead(y3), HIGH);
break;
case 0xb:
resultPrint(digitalRead(y3), LOW);
break;
case 0xc:
resultPrint(digitalRead(y3), HIGH);
break;
case 0xd:
resultPrint(digitalRead(y3), LOW);
break;
case 0xe:
resultPrint(digitalRead(y3), HIGH);
break;
case 0xf:
resultPrint(digitalRead(y3), LOW);
break;
default:
break;
}
#ifdef FuncTest
delay(cycleDelay); // Задержка между шагами цикла.
#endif // FuncTest
// Инкремент входных сигналов x0, x1, x2, x3.
xxxx++;
if (xxxx > 0xf) {
xxxx = 0x0;
#ifdef SpeedTest
if (currCycleMaxSpeedCountMax == 0) {
#endif // SpeedTest
// Вывод количества обнаруженных ошибок.
Serial.print("Cycle Errors Count = ");
Serial.println(currErrorsCount, DEC);
Serial.print("Total Errors Count = ");
Serial.println(totalErrorsCount, DEC);
#ifdef SpeedTest
}
#endif // SpeedTest
#ifdef SpeedTest
if (errFound == true)
currCycleMaxSpeedCountMax++;
if (currCycleMaxSpeedCountMax >= CycleMaxSpeedCountMax) {
Serial.println("");
Serial.print("Delay ");
Serial.println(currDelay, DEC);
while (true) {};
}
if (errFound == false) {
if (currErrorsCount == 0) {
// Ускоряем работу логической схемы.
if (currDelay > 0) {
currDelay = currDelay - minusDelta;
}
}
}
if (currErrorsCount > 0) {
currCycleMaxSpeedCountMax = 0;
errFound = true;
// Замедляем работу логической схемы.
if (currDelay < startDelay) {
currDelay = currDelay + plusDelta ;
}
}
#endif // SpeedTest */
currErrorsCount = 0; // Обнуление количества ошибок цикла.
currCycleCount++; // Инкремент счетчика циклов.
}
}
// Функция вывода в терминал результата одной итерации.
// y3 - полученное из внешней схемы значение (HIGH или LOW).
// res - ожидаемое значение (HIGH или LOW).
void resultPrint(byte y3, byte res) {
if (y3 == res) {
#ifdef FuncTest
if (y3 == HIGH)
Serial.println("Ok: Y3 = 1");
else
Serial.println("Ok: Y3 = 0");
#endif // FuncTest
} else {
// Инкремент счетчиков ошибок.
currErrorsCount++;
totalErrorsCount++;
#ifdef FuncTest
if (y3 == HIGH)
Serial.println("Error: Y3 = 1");
else
Serial.println("Error: Y3 = 0");
#endif // FuncTest
}
}
// Функция вывода x0, x1, x2, x3 во внешнюю релейную логическую схему.
void setX0123(byte X0123) {
if ((X0123 & 0x1) == 0)
digitalWrite(x3, LOW);
else
digitalWrite(x3, HIGH);
if ((X0123 & 0x2) == 0)
digitalWrite(x2, LOW);
else
digitalWrite(x2, HIGH);
if ((X0123 & 0x4) == 0)
digitalWrite(x1, LOW);
else
digitalWrite(x1, HIGH);
if ((X0123 & 0x8) == 0)
digitalWrite(x0, LOW);
else
digitalWrite(x0, HIGH);
}