Мигание заданной цифры 4x7 сегментный дисплей и регистр сдвига 74HC595N

У меня есть проект, который является просто реле таймера. Код не завершен, поэтому вы увидите разделы "в процессе", не связанные с моим вопросом в моем коде.

Однако мой вопрос...

Я создаю таймер с 4 х 7 сегментным дисплеем с помощью поворотного кодера для установки времени. У меня есть 3 "режима", которые позволяют мне увеличить время на 1 секунду, 10 секунд и минут. Все это работает правильно, однако, когда я переключаю режимы, я хотел бы мигнуть соответствующей цифрой, чтобы дать своего рода визуальную обратную связь, показывающую, в каком режиме вы находитесь (первая цифра за секунды, вторая за 10 секунд и т. Д.). Я могу вручную заземлить соответствующий общий контакт, чтобы создать этот эффект вручную, однако у меня возникли проблемы с кодом.

Я попытался создать для циклов, которые digitalwrite() для конкретного компина, однако это просто выключает и включает весь дисплей. Раздел кода, на который я смотрю, находится примерно на полпути вниз.

Бонусный вопрос: Я хотел бы, чтобы Dp осветился между второй и третьей цифрами, чтобы показать "min:sec". Я предполагаю, что это должно быть связано с моей байтовой таблицей, однако все это ново для меня, и я не уверен, в каком направлении идти относительно изменений.

#include <MD_REncoder.h>

int LightClocksec = 0;
int LightClockmin = 0;

int LightClockAdd = 1;
int Mode = 0;
boolean LightSW = 5;

int EncoderSW = 4;
boolean EncoderSWstate = 0;
MD_REncoder R1 = MD_REncoder(2, 3);

int FocusSW = 13;
boolean FocusSWstate = 0;
boolean FocusSWstatePRE = 0;
int FocusSWCounter = 0;

int MainSW = 14;
boolean MainSWstate = 0;
boolean MainSWstatePRE = 0;

int RelayPIN = 15;
boolean Relaystate = LOW;

unsigned long millispre = 0;

int buttonPushCounter = 0; // счетчик количества нажатий кнопки
int lastButtonState = 0; // предыдущее состояние кнопки

int latchPin = 7;          // пин подключен к ST_CP из 74HC595(Pin12)
int clockPin = 8;          // пин подключен к SH_CP из 74HC595(Pin11)
int dataPin = 6;           // пин подключен к DS из 74HC595(Pin14)
int comPin[] = {12, 11, 10, 9};// общий контакт (анод) из 4-значный 7-сегментный 
дисплей


byte num[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 
0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};


void setup() {
  //  Serial.begin(9600);
  R1.begin();
  pinMode (LightSW, OUTPUT);
  pinMode (RelayPIN, OUTPUT);

  pinMode (EncoderSW, INPUT);
  pinMode (FocusSW, INPUT);

  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

for (int i = 0; i < 4; i++) {
  pinMode(comPin[i], OUTPUT);
  }

}

void loop() {

  ///установить время, кодировщик..

  EncoderSWstate = digitalRead(EncoderSW);

  uint8_t z = R1.read();
  if (z) {
    if (EncoderSWstate == 0) {
      if ((Mode == 2) )
      {
        z == DIR_CW ? LightClockmin ++  : LightClockmin --;
      }
      else if (Mode == 1) {
        z == DIR_CW ? LightClocksec = LightClocksec + 10  : LightClocksec = LightClocksec - 10 ;
        if (LightClocksec >= 60) {
          LightClocksec = (LightClocksec - 60);
          LightClockmin ++;
        }
        if ((LightClocksec < 0) && (LightClockmin >= 1 )) {
          LightClocksec = (60 - LightClockAdd) ;
          LightClockmin --;
        }
      }
      else if (Mode == 0) {
        z == DIR_CW ? LightClocksec ++  :  LightClocksec --;
        if (LightClocksec >= 60) {
          LightClocksec = (LightClocksec - 60);
          LightClockmin ++;
        }
        if ((LightClocksec < 0) && (LightClockmin >= 1 )) {
      LightClocksec = (60 - LightClockAdd) ;
      LightClockmin --;
    }
  }
  LightClocksec = constrain(LightClocksec, 0, 59);
  LightClockmin = constrain(LightClockmin, 0, 59);
}

if (EncoderSWstate == 1) {
  z == DIR_CW ? Mode -- : Mode ++ ;
  Mode = constrain(Mode, 0, 3);
  if (Mode == 0) {
    ////////STACK EXCHANGE?//// Мигание первой цифры включается и выключается 5 раз
  }

  if (Mode == 1) {
    ////////STACK EXCHANGE?//// Мигание второй цифры включается и выключается 5 раз
  }
  if (Mode == 2) {
   ////////STACK EXCHANGE?////  Мигание 3 й цифры Вкл и вкл 5 раз
  }
   }
 }

  ////switching

  FocusSWstate = digitalRead(FocusSW);
  MainSWstate = digitalRead(MainSW);

  if (FocusSWstate != FocusSWstatePRE ) {
    if (FocusSWstate == HIGH) {
      FocusSWCounter++;
    } else {}
  }

  FocusSWstatePRE  = FocusSWstate;
  if (FocusSWCounter % 2 == 0) {
    digitalWrite(RelayPIN, LOW);
  } else {
    digitalWrite(RelayPIN, HIGH);
  }


  if (MainSWstate != MainSWstatePRE ) {
    if (MainSWstate == HIGH) {
      digitalWrite(RelayPIN, HIGH);
      delay(((LightClockmin * 60) + (LightClocksec)) * 1000);
      digitalWrite(RelayPIN, LOW);
    }
    else {}
  }
  MainSWstatePRE  = MainSWstatePRE;

  //display

  byte bit[4];
  bit[0] = LightClocksec % 10;
  bit[1] = LightClocksec / 10 % 10;
  bit[2] = LightClockmin % 10;
  bit[3] = LightClockmin / 10 % 10;

  for (int i = 0; i < 4; i++) {
    chooseCommon(i);
    writeData(num[bit[3 - i]]);
    writeData(0xff);
  }
 }

void chooseCommon(byte com) {
  // Close all single 7-segment display
  for (int i = 0; i < 4; i++) {
    digitalWrite(comPin[i], LOW);
  }
  // Open the selected single 7-segment display
  digitalWrite(comPin[com], HIGH);
}

void writeData(int evalue) {
  // Make latchPin output low level
  digitalWrite(latchPin, LOW);
  // Отправить последовательные данные на 74HC595
  shiftOut(dataPin, clockPin, LSBFIRST, evalue);
  // Make latchPin output high level, затем 74HC595 обновит данные для параллельного вывода
  digitalWrite(latchPin, HIGH);
}

, 👍0

Обсуждение

Ты вроде как уже знаешь ответ. Чтобы включить определенный сегмент, вы вручную подключили его к **земле**. Но в вашем коде вы устанавливаете сегмент, который вы хотите **ВЫСОКИЙ**, и все сегменты, которые вы не хотите опускать (то есть землю). Измените HIGH на LOW и LOW на HIGH в вашей функции chooseCommon., @Gerben

У меня возникли проблемы с определением конкретного общего, я думаю, что в этом и заключается проблема. Я попробовал следующий код, но он просто выключает весь дисплей, а не только comPin[0], как я думал. Я не могу выложить все это здесь из-за длины, так что вставлю в другой комментарий., @Ashley Reid

if (Mode == 0) { байтовый бит[4]; бит[0] = LightClocksec % 10; бит[1] = LightClocksec / 10 % 10; бит[2] = LightClockmin % 10; бит[3] = LightClockmin / 10 % 10; chooseCommonblink(0); writeData(num[bit[0]]); writeData(0xff); } а затем после моего пустого цикла(): void chooseCommonblink(байт com) { digitalWrite(comPin[com], LOW); задержка(50); digitalWrite(comPin[com], HIGH); задержка(50); digitalWrite(comPin[com], LOW); задержка(50); digitalWrite(comPin[com], HIGH); }, @Ashley Reid

Кажется, у вас есть общий катод, но код для общего анода. Или у вас есть какие-то транзисторы на этих контактах?, @Gerben

хорошо, я просто посмотрел код с моего дисплея и справа от вас, у меня есть общий катод, который я купил как неопределенную замену старого, который был включен в комплект, который теперь живет в другом проекте, у которого был общий анод. Ну, дисплей работает так, как я думаю, правильно освещается и т. Д. теперь я не совсем понимаю, как это возможно?, @Ashley Reid


1 ответ


1

При отображении цифр вам необходимо сравнить текущий номер цифры (i) с номером цифры, который вы хотите отобразить. Если это совпадение, то либо отобразите номер, либо не отображайте номер. Как вы принимаете это решение, нужно изучить millis().

Взгляните на пример BlinkWithoutDelay в среде IDE, чтобы узнать, как заставить что-то мигать без использования функции delay (), и примените эти знания к миганию цифры.

,

Я использовал 'millis()' / 'BlinkWithoutDelay' в других проектах, чтобы понять этот процесс. То, что я вижу, - это просто создание прерывания с 5 миганиями при изменении режима, поэтому обычные задержки для меня не являются проблемой. Проблема, с которой я сталкиваюсь, заключается в "сравнении текущего цифрового числа", как вы говорите, или в выделении правильного компина для последовательности digitalWrite LOW/HIGH. Извините, если моя терминология немного не в порядке, я надеюсь, вы понимаете, к чему я клоню., @Ashley Reid

Эта строка: writeData(num[бит[3 - i]]); - сравните "i" с выбранной цифрой, и если она совпадает, либо запустите эту строку, либо не зависите от переменной "мигает", управляемой millis ()., @Majenko