Как использовать 4 входа на Arduino в качестве двоичного декодера?

Как использовать 4 входные линии в качестве двоичного декодера? Я хотел бы прочитать 4 входа (16 вариантов) и на основе этого выбрать одно из 16 выходных поведений?

Мне нужно иметь возможность настроить мой проект схемы «Индикатор десяти фаз Луны» (MPI ECP) на фазу Луны, видимую на небе в этот день, или на определенное время, указанное в одном из многочисленных приложений, доступных в Интернете. В настоящее время MPI ECP сбрасывается на начало цикла полнолуния, так как это единственный доступный цикл. (этот код работает) ПРИМЕЧАНИЕ: из-за энергопотребления схемы и процессора Arduino для этого приложения потребуется вечное питание.

Чтобы решить эту проблему, я намерен использовать четыре из 14 доступных входов/выходов на Arduino Uno в качестве ВХОДОВ, используя четыре тумблера с защитой от дребезга (с подтягивающими резисторами): (0) Выкл., (1) как Вкл. Остальные десять доступных входов/выходов будут использоваться для десяти светодиодов ВЫХОДА дисплея Moon или для управления десятью реле.

Чего я хочу от программы Sketch:

  1. digitalRead контакты 0, 1, 12, 13
  2. В зависимости от 1 из 16 возможных комбинаций включения/выключения, запустите определенный цикл.

Вот что у меня получилось: (обратите внимание, код не компилируется, я новичок)

 void setup()  {
 pinMode(2, OUTPUT);   // Новое воскование:
 pinMode(3, OUTPUT);   // Молодой Растущий:
 pinMode(4,OUTPUT);   // Растущая луна:
 pinMode(5, OUTPUT);   // Четверть роста:
 pinMode(6, OUTPUT);   // Растущая луна:
 pinMode(7,OUTPUT);   // Полная луна:
 pinMode(8, OUTPUT);   // Убывающая выпуклость:
 pinMode(9, OUTPUT);   // Квартальное понижение:
 pinMode(10, OUTPUT);  // Полумесяц Ваннинг:
 pinMode(11, OUTPUT);  // Старое Wanning:
 pinMode(13, INPUT);  // Переключатель 4
 pinMode(12,INPUT);     // Переключатель 3
 pinMode(1, INPUT);     // Переключатель 2
 pinMode(0,INPUT);      // Переключатель 1

 } void loop() {
 int Reading = digitalRead;
Reading = digitalRead (12); Reading = digitalRead (13);
Reading = digitalRead (1);   Reading = digitalRead (0); 

 if  (digitalRead(0) == HIGH; digitalRead (1)==
   HIGH; digitalRead(12) == HIGH; (digitalRead(13) == HIGH);  { } else 
    {   // цикл Полнолуние Запуск digitalWrite(7, HIGH); // ПОЛНОЛУНИЕ ВКЛЮЧЕНЫ
  delay(5000); 
  digitalWrite(7, LOW);    // ПОЛНАЯ ЛУНА ВЫКЛ
        delay(10);
   digitalWrite(8,HIGH);   // БЛЕДНАЯ ГЛУБОКАЯ ЛУНА НА
        delay(5000);  
 digitalWrite(8, LOW);    // БЛЕДНАЯ ГЛУБОКАЯ ЛУНА ВЫКЛЮЧЕНА
          delay(10); 
  digitalWrite(9, HIGH);   // ЛУНА В 3-Й ЧЕТВЕРТИ ВКЛЮЧЕНА
          delay(5000);
   digitalWrite(9, LOW);     // ЛУНА В 3-ЕЙ ЧЕТВЕРТИ ВЫКЛ
          delay(10); 
  digitalWrite(10, HIGH);    // БЛЕДНАЯ ПОЛУМЕСЯЧНАЯ ЛУНА ВКЛЮЧЕНА
         delay(5000); 
  digitalWrite(10, LOW);     // БЛЕДНАЯ ПОЛУМЕСЯЧНАЯ ЛУНА ВЫКЛ
          delay(10); 
  digitalWrite(11, HIGH);     // СТАРАЯ ЛУНА ВКЛЮЧЕНА
         delay(5000);  
 digitalWrite(11, LOW);      // СТАРАЯ ЛУНА ВЫКЛЮЧЕНА
          delay(5000); 
   digitalWrite(2, HIGH);  // НОВОЛУНИЕ ВКЛЮЧЕНЫ
          delay(5000); 
  digitalWrite(2, LOW);   // НОВОЛУНИЕ ВЫКЛ
          delay(10);  
 digitalWrite(3, HIGH);  // МОЛОДАЯ ЛУНА ВКЛЮЧЕНА
          delay(5000);
   digitalWrite(3, LOW);  // МОЛОДАЯ ЛУНА ВЫКЛ
          delay(100); 
 digitalWrite(4, HIGH);   // ВОСКОВАЯ ЛУНА ВКЛЮЧЕНА
         delay(5000);
   digitalWrite(4, LOW);    // ВОСКОВАЯ ЛУНА ВЫКЛ
          delay(10); 
  digitalWrite(5, HIGH);   // ПЕРВАЯ ЧЕТВЕРТЬ ВКЛ
          delay(5000);
   digitalWrite(5, LOW);     // ПЕРВЫЙ ПОЛУМЕСЯЦ ВЫКЛ
          delay(10);  
 digitalWrite(6, HIGH);   // ВОСКОВАЯ ГИББУСНАЯ НА
         delay(5000); 
  digitalWrite(6, LOW);    // ВОСКОВАЯ ГИББУС ВЫКЛ
          delay(10);

// цикл для сброса новолуния if (digitalRead(0) == LOW;digitalRead (1)==LOW; digitalRead(12) == LOW;(digitalRead(13) ==
    LOW);  
  { } else   // цикл Новолуние Начало
 digitalWrite(2, HIGH);  // НОВОЛУНИЕ ВКЛЮЧЕНЫ
          delay(5000);
   digitalWrite(2, LOW);   // НОВОЛУНИЕ ВЫКЛ
          delay(10);
   digitalWrite(3, HIGH);  // МОЛОДАЯ ЛУНА ВКЛЮЧЕНА
          delay(5000);
   digitalWrite(3, LOW);    // МОЛОДАЯ ЛУНА ВЫКЛ
          delay(100);
   digitalWrite(4, HIGH);   // ВОСКОВАЯ ЛУНА ВКЛЮЧЕНА
         delay(5000);
   digitalWrite(4, LOW);    // ВОСКОВАЯ ЛУНА ВЫКЛ
          delay(10);
   digitalWrite(5, HIGH);   // ПЕРВАЯ ЧЕТВЕРТЬ ВКЛ
          delay(5000); 
  digitalWrite(5, LOW);     // ПЕРВЫЙ ПОЛУМЕСЯЦ ВЫКЛ
          delay(10); 
  digitalWrite(6, HIGH);   // ВОСКОВАЯ ГИББУСНАЯ НА
         delay(5000);
   digitalWrite(6, LOW);    // ВОСКОВАЯ ГИББУС ВЫКЛ
          delay(10);
  digitalWrite(7, HIGH);  // ПОЛНАЯ ЛУНА ВКЛЮЧЕНА
        delay(5000);
   digitalWrite(7, LOW);    // ПОЛНАЯ ЛУНА ВЫКЛ
        delay(10); 
   digitalWrite(8,HIGH);   // БЛЕДНАЯ ГЛУБОКАЯ ЛУНА НА
        delay(5000);
   digitalWrite(8, LOW);    // БЛЕДНАЯ ГЛУБОКАЯ ЛУНА ВЫКЛЮЧЕНА
          delay(10);
   digitalWrite(9, HIGH);   // ЛУНА В 3-Й ЧЕТВЕРТИ ВКЛЮЧЕНА
          delay(5000);
   digitalWrite(9, LOW);     // ЛУНА В 3-ЕЙ ЧЕТВЕРТИ ВЫКЛ
          delay(10); 
  digitalWrite(10, HIGH);    // БЛЕДНАЯ ПОЛУМЕСЯЧНАЯ ЛУНА ВКЛЮЧЕНА
         delay(5000);
   digitalWrite(10, LOW);     // БЛЕДНАЯ ПОЛУМЕСЯЧНАЯ ЛУНА ВЫКЛ
          delay(10); 
  digitalWrite(11, HIGH);     // СТАРАЯ ЛУНА ВКЛЮЧЕНА
         delay(5000);
   digitalWrite(11, LOW);      // СТАРАЯ ЛУНА ВЫКЛЮЧЕНА
          delay(5000); 
 { } else  { // Молодая луна Сброс Начать
 if  (digitalRead(0) == LOW; digitalRead (1)==LOW; digitalRead(12) ==
    LOW;(digitalRead(13) == HIGH;
 )
   { } else  // цикл Новолуние Начало
         digitalWrite(3, HIGH);
  // МОЛОДАЯ ЛУНА НА
          delay(5000);
   digitalWrite(3, LOW);    // МОЛОДАЯ ЛУНА ВЫКЛ
          delay(100); 
  digitalWrite(4, HIGH);   // ВОСКОВАЯ ЛУНА ВКЛЮЧЕНА
         delay(5000); 
  digitalWrite(4, LOW);    // ВОСКОВАЯ ЛУНА ВЫКЛ
          delay(10);
   digitalWrite(5, HIGH);   // ПЕРВАЯ ЧЕТВЕРТЬ ВКЛ
          delay(5000); 
  digitalWrite(5, LOW);     // ПЕРВЫЙ ПОЛУМЕСЯЦ ВЫКЛ
          delay(10); 
  digitalWrite(6, HIGH);   // ВОСКОВАЯ ГИББУСНАЯ НА
         delay(5000); 
  digitalWrite(6, LOW);    // ВОСКОВАЯ ГИББУС ВЫКЛ
          delay(10); 
 digitalWrite(7, HIGH);    // ПОЛНАЯ ЛУНА ВКЛЮЧЕНА
        delay(5000);
   digitalWrite(7, LOW);    // ПОЛНАЯ ЛУНА ВЫКЛ
        delay(10); 
   digitalWrite(8,HIGH);   // БЛЕДНАЯ ГЛУБОКАЯ ЛУНА НА
        delay(5000); 
  digitalWrite(8, LOW);    // БЛЕДНАЯ ГЛУБОКАЯ ЛУНА ВЫКЛЮЧЕНА
          delay(10); 
  digitalWrite(9, HIGH);   // ЛУНА В 3-Й ЧЕТВЕРТИ ВКЛЮЧЕНА
          delay(5000);  
 digitalWrite(9, LOW);     // ЛУНА В 3-ЕЙ ЧЕТВЕРТИ ВЫКЛ
          delay(10); 
  digitalWrite(10, HIGH);    // БЛЕДНАЯ ПОЛУМЕСЯЧНАЯ ЛУНА ВКЛЮЧЕНА
         delay(5000);
   digitalWrite(10, LOW);     // БЛЕДНАЯ ПОЛУМЕСЯЧНАЯ ЛУНА ВЫКЛ
          delay(10); 
  digitalWrite(11, HIGH);     // СТАРАЯ ЛУНА ВКЛЮЧЕНА
         delay(5000); 
  digitalWrite(11, LOW);      // СТАРАЯ ЛУНА ВЫКЛЮЧЕНА
          delay(5000); 
         digitalWrite(2, HIGH);   // НОВОЛУНИЕ ВКЛЮЧЕНЫ
          delay(5000);
   digitalWrite(2, LOW);       // НОВОЛУНИЕ ВЫКЛ
          delay(10);
  } 
 // Растущий полумесяц Сброс Начать if (digitalRead(0) == LOW; digitalRead (1)== LOW; digitalRead(12) ==
    HIGH; digitalRead(13) == HIGH;)    { } else  // Растущая Луна
    reset Start
  digitalWrite(4, HIGH);   // ВОСКОВАЯ ЛУНА ВКЛЮЧЕНА
         delay(5000);
   digitalWrite(4, LOW);    // ВОСКОВАЯ ЛУНА ВЫКЛ
          delay(10); 
 digitalWrite(5, HIGH);   // ПЕРВАЯ ЧЕТВЕРТЬ ВКЛ
          delay(5000);
   digitalWrite(5, LOW);     // ПЕРВЫЙ ПОЛУМЕСЯЦ ВЫКЛ
          delay(10);
   digitalWrite(6, HIGH);   // ВОСКОВАЯ ГИББУСНАЯ НА
         delay(5000); 
  digitalWrite(6, LOW);    // ВОСКОВАЯ ГИББУС ВЫКЛ
          delay(10);
  digitalWrite(7, HIGH);    // ПОЛНАЯ ЛУНА ВКЛЮЧЕНА
        delay(5000);
   digitalWrite(7, LOW);    // ПОЛНАЯ ЛУНА ВЫКЛ
        delay(10);  
  digitalWrite(8,HIGH);   // БЛЕДНАЯ ГЛУБОКАЯ ЛУНА НА
        delay(5000);
   digitalWrite(8, LOW);    // БЛЕДНАЯ ГЛУБОКАЯ ЛУНА ВЫКЛЮЧЕНА
          delay(10); 
  digitalWrite(9, HIGH);   // ЛУНА В 3-Й ЧЕТВЕРТИ ВКЛЮЧЕНА
          delay(5000);
   digitalWrite(9, LOW);     // ЛУНА В 3-ЕЙ ЧЕТВЕРТИ ВЫКЛ
          delay(10);  
 digitalWrite(10, HIGH);    // БЛЕДНАЯ ПОЛУМЕСЯЧНАЯ ЛУНА ВКЛЮЧЕНА
         delay(5000);
   digitalWrite(10, LOW);     // БЛЕДНАЯ ПОЛУМЕСЯЧНАЯ ЛУНА ВЫКЛ
          delay(10); 
  digitalWrite(11, HIGH);     // СТАРАЯ ЛУНА ВКЛЮЧЕНА
         delay(5000);   digitalWrite(11, LOW);      // СТАРАЯ ЛУНА ВЫКЛЮЧЕНА
         delay(5000);
   digitalWrite(2, HIGH);   // НОВОЛУНИЕ ВКЛЮЧЕНЫ
          delay(5000);
   digitalWrite(2, LOW);      // НОВОЛУНИЕ ВЫКЛ
          delay(10);
   digitalWrite(3, HIGH);  // МОЛОДАЯ ЛУНА ВКЛЮЧЕНА
          delay(5000);
   digitalWrite(3, LOW);       // МОЛОДАЯ ЛУНА ВЫКЛ
          delay(100);
  } 
  // Сброс первой четверти Луны if (digitalRead(0) == LOW; digitalRead(1) == HIGH; digitalRead(12) ==
    HIGH; digitalRead(13) == HIGH;)   { else  {
  //ПЕРВАЯ ЧЕТВЕРТЬ Луны
    reset Start
digitalWrite(5, HIGH);   // ПЕРВАЯ ЧЕТВЕРТЬ ВКЛ
          delay(5000);
   digitalWrite(5, LOW);     // ПЕРВЫЙ ПОЛУМЕСЯЦ ВЫКЛ
          delay(10);
   digitalWrite(6, HIGH);   // ВОСКОВАЯ ГИББУСНАЯ НА
         delay(5000); 
  digitalWrite(6, LOW);    // ВОСКОВАЯ ГИББУС ВЫКЛ
          delay(10);
  digitalWrite(7, HIGH);  // ПОЛНАЯ ЛУНА ВКЛЮЧЕНА
        delay(5000);
   digitalWrite(7, LOW);    // ПОЛНАЯ ЛУНА ВЫКЛ
        delay(10); 
   digitalWrite(8,HIGH);   // БЛЕДНАЯ ГЛУБОКАЯ ЛУНА НА
        delay(5000); 
  digitalWrite(8, LOW);    // БЛЕДНАЯ ГЛУБОКАЯ ЛУНА ВЫКЛЮЧЕНА
          delay(10); 
  digitalWrite(9, HIGH);   // ЛУНА В 3-Й ЧЕТВЕРТИ ВКЛЮЧЕНА
          delay(5000);
   digitalWrite(9, LOW);     // ЛУНА В 3-ЕЙ ЧЕТВЕРТИ ВЫКЛ
          delay(10); 
  digitalWrite(10, HIGH);    // БЛЕДНАЯ ПОЛУМЕСЯЧНАЯ ЛУНА ВКЛЮЧЕНА
         delay(5000);
   digitalWrite(10, LOW);     // БЛЕДНАЯ ПОЛУМЕСЯЧНАЯ ЛУНА ВЫКЛ
          delay(10); 
  digitalWrite(11, HIGH);     // СТАРАЯ ЛУНА ВКЛЮЧЕНА
         delay(5000); 
  digitalWrite(11, LOW);      // СТАРАЯ ЛУНА ВЫКЛЮЧЕНА
          delay(5000); 
  digitalWrite(2, HIGH);   // НОВОЛУНИЕ ВКЛЮЧЕНЫ
          delay(5000); 
  digitalWrite(2, LOW);    // НОВОЛУНИЕ ВЫКЛ
          delay(10);
   digitalWrite(3, HIGH);  // МОЛОДАЯ ЛУНА ВКЛЮЧЕНА
          delay(5000);
   digitalWrite(3, LOW);    // МОЛОДАЯ ЛУНА ВЫКЛ
          delay(100);
   digitalWrite(4, HIGH);   // ВОСКОВАЯ ЛУНА ВКЛЮЧЕНА
         delay(5000); 
  digitalWrite(4, LOW);        // ВОСКОВАЯ ЛУНА ВЫКЛ
          delay(10); 
 } 
// код будет продолжаться с другими циклами. Спасибо за внимание к моей проблеме 16 RESET, напишите мне на почту. Буду признателен за любые предложения

, 👍-1


3 ответа


0

Обратите внимание, что A0–A5 доступны также для digitalRead(). Обычно я инициализирую их как

byte pin14 = 14; // сделайте так, чтобы имя что-то значило для вас

pinMode (pin14, INPUT_PULLUP);

Then you can read it as

if (digitalRead(pin14) == LOW){

// контакт подключен к Gnd

}

Или, если вы используете D14-17 для своих 4 входов, вы можете прочитать все 4 с помощью чтения PORT и действовать в соответствии с этим (вы по-прежнему используете pinMode() для их инициализации):

byte addressByte = PORTC & 0x0F; // результат от 0 до 15 в зависимости от состояния 4 контактов

(Я думаю, что PORTC — это A0–A5, стоит это проверить)

затем прочитайте их и действуйте соответственно. Гораздо чище, чем while куча digitalRead() и if() операторов.

switch(addressByte){

case 0:

// что бы ни случилось

:

:

case 15:

// что бы ни случилось
}
,

1

скелетное решение:

int in[] = {0,1,12,13};
int out[] = {2,3,4,5,6,7,8,9,10,11};
...
void setup()
{
    for(int i=0; i < 4; i++)
        pinMode(in[i], INPUT)

    for(int i=0; i < 10; i++)
        pinMode(out[i], OUTPUT)
}
...
void do0 {...};
void do1 {...};
void do2 {...};
void do3 {...};
void do4 {...};
void do5 {...};
void do6 {...};
void do7 {...};
void do8 {...};
void do9 {...};
void do10 {...};
void do11 {...};
void do12 {...};
void do13 {...};
void do14 {...};
void do15 {...};
...
void loop()
{
    int addr = 0;
    for(int i=0; i<4; i++)
       addr |= digitalRead(in[i]) << i;

    switch(addr)
    {
    case 0:
       do0();
       break;
    case 1:
       do1();
       break;
    case 2:
       do2();
       break;
    case 3:
       do3();
       break;
    case 4:
       do4();
       break;
    case 5:
       do5();
       break;
    case 6:
       do6();
       break;
    case 7:
       do7();
       break;
    case 8:
       do8();
       break;
    case 9:
       do9();
       break;
    case 10:
       do10();
       break;
    case 11:
       do11();
       break;
    case 12:
       do12();
       break;
    case 13:
       do13();
       break;
    case 14:
       do14();
       break;
    case 15:
       do15();
       break;
    }
}
,

1

Это может быть слишком продвинуто для OP, но... чтение esoterik's ответ, я не мог удержаться от желания превратить этот большой выключатель/корпус в поиск массива. Конечно, синтаксис объявления массива Указатели на функции — это немного эзотерично. ;-)

void loop()
{
    // Список реализованных поведений.
    static void (* const behaviors[])() = {
        do0, do1, do2,  do3,  do4,  do5,  do6,  do7,
        do8, do9, do10, do11, do12, do13, do14, do15
    };

    // Создаем индекс запрошенного поведения.
    int addr = 0;
    for (int i = 0; i < 4; i++)
       addr |= digitalRead(in[i]) << i;

    // Теперь сделай это.
    behaviors[addr]();
}

Редактировать: Чтобы решить проблему OP. Я мог что-то упустить, но это Мне кажется, что все случаи делают одно и то же: перебирают выходы, включите каждый, подождите 5 секунд, затем выключите. Единственный Разница между случаями — это индекс вывода, который включается на первом. В этом случае весь этот повторяющийся код можно разложить на одиночный цикл следующим образом:

// Включаем и выключаем все выходы по очереди,
// начиная с указанного индекса.
void loop_outputs(int start_index)
{
    int index = start_index;
    for (int count = 0; count < 10; count++) {

        // Зажгите светодиод на 5 секунд.
        digitalWrite(out[index], HIGH);
        delay(5000);
        digitalWrite(out[index], LOW);
        delay(10);

        // Переходим к следующему, перенося индекс 10 -> 0.
        if (++index == 10) index = 0;
    }
}
,