7-сегментный многоэкранный дисплей, отображает только 1 цифру

Я пытаюсь создать отображение так, чтобы при нажатии кнопки счетчик увеличивался на единицу. Проблема в том, что загорается только один из них, и он не показывает правильный результат, он показывает комбинацию обеих цифр (например, 01 показывает 0, 02 показывает 8). Вот мой полный код.

const int a = 8;  //Для отображения сегмента "а"
const int b = 9;  //Для отображения сегмента "b"
const int c = 4;  //Для отображения сегмента "c"
const int d = 5;  //Для отображения сегмента "d"
const int e = 6;  //Для отображения сегмента "e"
const int f = 2;  //Для отображения сегмента "f"
const int g = 3;  //Для отображения сегмента "g"
const int D1 = 7;
const int D2 = 13;

bool bPress = false;
const int IncbuttonPin = 10;

// Переменные изменятся:
int buttonPushCounter = 0;   // счетчик количества нажатий кнопок
int buttonPushCounterD1 = 0;
int buttonPushCounterD2 = 0;

int IncbuttonState = 0;         
int lastIncbuttonState = 0;     

void setup() {
  // поместите сюда свой код установки для однократного запуска:
  pinMode(a, OUTPUT);  //А
  pinMode(b, OUTPUT);  //Б
  pinMode(c, OUTPUT);  //С
  pinMode(d, OUTPUT);  //Д
  pinMode(e, OUTPUT);  //Э
  pinMode(f, OUTPUT);  //Ф
  pinMode(g, OUTPUT);  //Г
  pinMode(D1, OUTPUT);
  pinMode(D2, OUTPUT);

  pinMode( IncbuttonPin , INPUT_PULLUP );
  Serial.begin(9600);

}

void loop() {

   IncbuttonState = digitalRead(IncbuttonPin);

   checkIncButtonPress();


  if( bPress ){
    bPress = false;
     turnOff();
     lightDigit1(buttonPushCounterD1);
     delay(5);
     lightDigit2(buttonPushCounterD2);
     delay(5);
  }
}

void checkIncButtonPress()
{
   // сравниваем IncbuttonState с его предыдущим состоянием
  if (IncbuttonState != lastIncbuttonState) {
    // если состояние изменилось, увеличиваем счетчик
    if (IncbuttonState == LOW) {
      // если текущее состояние ВЫСОКОЕ, то кнопка переключилась из выключенного состояния во включенное:
      bPress = true;
      buttonPushCounter++;
      buttonPushCounterD1 = buttonPushCounter / 10;
      buttonPushCounterD2 = buttonPushCounter % 10; 
      Serial.println("on");
      Serial.println(buttonPushCounterD1);
      Serial.println(buttonPushCounterD2);

    } else {
      // если текущее состояние НИЗКОЕ, то кнопка переключилась из включенного состояния в выключенное:
      Serial.println("off");
    }
    // Небольшая задержка, чтобы избежать подпрыгивания
    delay(50);
  }
  // сохраняем текущее состояние как последнее для следующего прохода цикла
  lastIncbuttonState = IncbuttonState;

}

void lightDigit1(byte digit) {
  digitalWrite(D1, LOW);
  digitalWrite(D2, HIGH);
  displayDigit1(digit);
}

void lightDigit2(byte digit) {
  digitalWrite(D1, HIGH);
  digitalWrite(D2, LOW);
  displayDigit2(digit);
}

void displayDigit1(byte digit)
{
 //Условия отображения сегмента a
 if(digit!=1 && digit != 4)
 digitalWrite(a,HIGH);

 //Условия отображения сегмента b
 if(digit != 5 && digit != 6)
 digitalWrite(b,HIGH);

 //Условия отображения сегмента c
 if(digit !=2)
 digitalWrite(c,HIGH);

 //Условия отображения сегмента d
 if(digit != 1 && digit !=4 && digit !=7)
 digitalWrite(d,HIGH);

 //Условия отображения сегмента e
 if(digit == 2 || digit ==6 || digit == 8 || digit==0)
 digitalWrite(e,HIGH);

 //Условия отображения сегмента f
 if(digit != 1 && digit !=2 && digit!=3 && digit !=7)
 digitalWrite(f,HIGH);
 if (digit!=0 && digit!=1 && digit !=7)
 digitalWrite(g,HIGH);
}


void displayDigit2(byte digit)
{
// digitalWrite(D1, HIGH);
// digitalWrite(D2, LOW);
 //Условия отображения сегмента a
 if(digit!=1 && digit != 4)
 digitalWrite(a,HIGH);

 //Условия отображения сегмента b
 if(digit != 5 && digit != 6)
 digitalWrite(b,HIGH);

 //Условия отображения сегмента c
 if(digit !=2)
 digitalWrite(c,HIGH);

 //Условия отображения сегмента d
 if(digit != 1 && digit !=4 && digit !=7)
 digitalWrite(d,HIGH);

 //Условия отображения сегмента e
 if(digit == 2 || digit ==6 || digit == 8 || digit==0)
 digitalWrite(e,HIGH);

 //Условия отображения сегмента f
 if(digit != 1 && digit !=2 && digit!=3 && digit !=7)
 digitalWrite(f,HIGH);
 if (digit!=0 && digit!=1 && digit !=7)
 digitalWrite(g,HIGH);
}


void turnOff()
{
  digitalWrite(a,LOW);
  digitalWrite(b,LOW);
  digitalWrite(c,LOW);
  digitalWrite(d,LOW);
  digitalWrite(e,LOW);
  digitalWrite(f,LOW);
  digitalWrite(g,LOW);
}

когда я удаляю код

     lightDigit1(buttonPushCounterD1);
     delay(5);

Он показывает правильный вывод, но только для 1 цифры. Кто-нибудь может мне помочь в этом? Спасибо.

, 👍1


1 ответ


1

Вы неправильно мультиплексируете дисплеи.

В данный момент вы делаете:

  1. Ничего не делайте, пока кнопка не будет нажата
  2. Включить дисплей 1
  3. Включить сегменты для цифры 1.
  4. Подождите 5 мс.
  5. Выключить дисплей 1
  6. Включить дисплей 2
  7. Включить сегменты для цифры 2.
  8. Подождите 5 мс.
  9. Перейти к 1

Приблизительно в течение 5 мс одна цифра будет кратковременно мигать, но поскольку вы не выключаете сегменты, включенные для этой цифры, они просто добавляются к второй цифре, которую вы отображаете в течение длительного периода времени.

Для правильного мультиплексирования необходимо:

  • Отключить сегменты, которые больше не используются для текущего отображения (лучше всего отключить их все)
  • Неоднократно отображать обе цифры все время.

В идеале ваш метод должен быть следующим:

  1. Отключить все сегменты
  2. Включить сегменты для цифры 1.
  3. Включить цифру 1.
  4. Задержка 5 мс
  5. Отключить цифру 1
  6. Отключить все сегменты
  7. Включить сегменты для цифры 2.
  8. Включить цифру 2
  9. Задержка 5 мс
  10. Отключить цифру 2
  11. Перейдите к 1 (обычно это делает loop()).

И отдельно от того, что вы обрабатываете нажатие кнопки и меняете отображаемое значение.

Также обратите внимание на отключение цифры перед расстановкой сегментов для следующей цифры. Это предотвращает двоение, когда вы получаете слабое впечатление от предыдущей цифры, наложенной на текущую.

,