Использовать 7-сегментный дисплей для отсчета 0/9 с помощью потенциометра.

я пытаюсь переключить номер на дисплее с помощью потенциометр, он просто отсчитывает от 0/9. Вся помощь очень ценится!

int SegmentA = 6;
int SegmentB = 7;
int SegmentC = 8;
int SegmentD = 9;
int SegmentE = 10;
int SegmentF = 11;
int SegmentG = 12;


const int PP = A0;


void setup()
{
  pinMode (SegmentA, OUTPUT);
  pinMode (SegmentB, OUTPUT);
  pinMode (SegmentC, OUTPUT);
  pinMode (SegmentD, OUTPUT);
  pinMode (SegmentE, OUTPUT);
  pinMode (SegmentF, OUTPUT);
  pinMode (SegmentG, OUTPUT);


}

void loop() {

  int POD = analogRead(PP);
  int SM = map(POD, 0, 1023, 0 , 8);
  switch (SM) {


    case 0:
      digitalWrite (SegmentA, HIGH);
      digitalWrite (SegmentB, HIGH);
      digitalWrite (SegmentC, HIGH);
      digitalWrite (SegmentD, HIGH);
      digitalWrite (SegmentE, HIGH);   //0
      digitalWrite (SegmentF, HIGH);
      digitalWrite (SegmentG, LOW);

      delay(1000);

    case 1:
      digitalWrite (SegmentA, LOW);
      digitalWrite (SegmentB, HIGH);
      digitalWrite (SegmentC, HIGH);
      digitalWrite (SegmentD, LOW);
      digitalWrite (SegmentE, LOW);   //1
      digitalWrite (SegmentF, LOW);
      digitalWrite (SegmentG, LOW);

      delay(1000);

    case 2:
      digitalWrite (SegmentA, HIGH);
      digitalWrite (SegmentB, HIGH);
      digitalWrite (SegmentC, LOW);
      digitalWrite (SegmentD, HIGH);
      digitalWrite (SegmentE, HIGH);   //2
      digitalWrite (SegmentF, LOW);
      digitalWrite (SegmentG, HIGH);

      delay(1000);

    case 3:
      digitalWrite (SegmentA, HIGH);
      digitalWrite (SegmentB, HIGH);
      digitalWrite (SegmentC, HIGH);
      digitalWrite (SegmentD, HIGH);
      digitalWrite (SegmentE, LOW);   //3
      digitalWrite (SegmentF, LOW);
      digitalWrite (SegmentG, HIGH);

      delay(1000);

    case 4:
      digitalWrite (SegmentA, LOW);
      digitalWrite (SegmentB, HIGH);
      digitalWrite (SegmentC, HIGH);
      digitalWrite (SegmentD, LOW);
      digitalWrite (SegmentE, LOW);   //4
      digitalWrite (SegmentF, HIGH);
      digitalWrite (SegmentG, HIGH);

      delay(1000);

    case 5:
      digitalWrite (SegmentA, HIGH);
      digitalWrite (SegmentB, LOW);
      digitalWrite (SegmentC, HIGH);
      digitalWrite (SegmentD, HIGH);
      digitalWrite (SegmentE, LOW);   //5
      digitalWrite (SegmentF, HIGH);
      digitalWrite (SegmentG, HIGH);

      delay(1000);

    case 6:
      digitalWrite (SegmentA, HIGH);
      digitalWrite (SegmentB, LOW);
      digitalWrite (SegmentC, HIGH);
      digitalWrite (SegmentD, HIGH);
      digitalWrite (SegmentE, HIGH);   //6
      digitalWrite (SegmentF, HIGH);
      digitalWrite (SegmentG, HIGH);

      delay(1000);

    case 7:
      digitalWrite (SegmentA, HIGH);
      digitalWrite (SegmentB, HIGH);
      digitalWrite (SegmentC, HIGH);
      digitalWrite (SegmentD, LOW);
      digitalWrite (SegmentE, LOW);   //7
      digitalWrite (SegmentF, LOW);
      digitalWrite (SegmentG, LOW);

      delay(1000);

    case 8:
      digitalWrite (SegmentA, HIGH);
      digitalWrite (SegmentB, HIGH);
      digitalWrite (SegmentC, HIGH);
      digitalWrite (SegmentD, HIGH);
      digitalWrite (SegmentE, HIGH);   //8
      digitalWrite (SegmentF, HIGH);
      digitalWrite (SegmentG, HIGH);

  }

}

, 👍2

Обсуждение

Я бы сократил задержку (1000), чтобы она была намного меньше - иначе вы поворачиваете банк, ничего не происходит, вы поворачиваете его немного и, наконец, что-то происходит, но теперь вы промахнулись, чего хотели, и переусердствуете в другую сторону, пытаясь получить туда, куда вы хотели. Попробуйте задержку от 50 до 100, чтобы она более реагировала на поворот ручки. Затем вы можете перейти к использованию поворотного декодера с фиксаторами: один щелчок для смены одного числа. Вот плохо освещенный пример с 2 цифрами и поворотным энкодером. В этом случае для управления каждым дисплеем использовался сдвиговый регистр (в отличие от мультиплексирования)., @CrossRoads

https://www.youtube.com/watch?v=f51eSlcZt-g Ссылка., @CrossRoads


2 ответа


Лучший ответ:

9

Вы пропустили оператор прерывания в конце каждого случая. например:

  digitalWrite (SegmentF, LOW);
  digitalWrite (SegmentG, HIGH);

  delay(1000);

  break;

case 4:

Это приводит к выполнению каждого дела и переходу к следующему делу. Однако, поскольку задержка составляет 1 секунду, похоже, она имеет значение.

На самом деле, я ожидаю, что он будет рассчитываться от определенного значения в зависимости от счетчика потенциометра до 7, поскольку цифра 9 не реализована, а также отсутствует задержка для цифры 8.

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

Также вы можете создать функцию void showDigit с параметром для каждого из возможных состояний сегмента и заменить весь (почти) дублированный код этим вызовом функции или отправить цифру и использовать showDigit для внутренней установки состояний каждого сегмента ( используя логический массив[nr_of_digits][nr_of_segments], примерно так, как предлагает Ник Хартли ниже.

,

Я бы добавил, что вам даже не нужен этот переключатель - вы можете легко использовать const bool digits[7 * 10], затем передать digits[7 * digit] и в функции извлечь из param[0], param[1] и т. д., @Fund Monica's Lawsuit

@NicHartley Спасибо ... Я думаю, что двумерный массив даже лучше, но в целом использование массива лучше., @Michel Keijzers

@Michel Keijzers Я не мог вспомнить синтаксис двумерного массива, поэтому я просто выбрал 1D, но вы правы - подойдет любой вариант. 2D, наверное, было бы красивее., @Fund Monica's Lawsuit

На самом деле, строго говоря, вы также можете выполнить const uint8_t digits[10];, а затем получить доступ к отдельным сегментам с помощью digits[n] & (1 << сегмент), если вы хотите, чтобы это было _наименее_ читаемым из возможных. код. Однако я бы не рекомендовал использовать такой подход с использованием массива (вероятно, двумерного массива), если только у вас нет _чрезвычайно_ жестких требований к памяти., @Fund Monica's Lawsuit

@NicHartley, поскольку у Arduino всего 2 КБ, это может быть полезно, но только при необходимости. Я всегда предпочитаю читабельность сокращению памяти., @Michel Keijzers

@MichelKeijzers Я предлагал это только в тех очень редких случаях, когда вы исчерпали все 2 КБ и вам нужно еще больше сжать данные. Я согласен, это определенно нехорошо начинать с этого., @Fund Monica's Lawsuit

@NicHartley У меня сразу заканчиваются 2 КБ (вот почему я хочу выполнить свой «основной» проект с STM, который имеет 192 КБ (но, возможно, мне следовало использовать Raspberry)., @Michel Keijzers

@MichelKeijzers Ха. У меня никогда не было с этим проблем. Однако я «вырос» в очень ограниченной среде, так что, возможно, у меня другой стиль. В любом случае, это все вышло несколько не по теме, хаха., @Fund Monica's Lawsuit

Давайте [продолжим обсуждение в чате](https://chat.stackexchange.com/rooms/85768/discussion-between-michel-keijzers-and-nic-hartley)., @Michel Keijzers


3

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

Замените вызовы задержки в case операторами break;. В противном случае, какой бы регистр вы ни вызвали, он перейдет в регистр ниже него и так далее, отображая каждую цифру по очереди, а это не то, что вы хотели (и это то, что вы уже видите).

Измените вызов map() на map(POD, 0, 1024, 0, 10). В противном случае на потенциометре не будет полосы «9», а ширина полосы «8» будет только 1 значение (из 1023): ровно значение «1023». Вам бы хотелось, чтобы полоса «9» была такой же широкой, как и все остальные. Возможно даже, что данный потенциометр не сможет приблизиться к нулевому сопротивлению, чтобы вы могли получить показание 1023.

,