Использовать 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);
}
}
@user51180, 👍2
Обсуждение2 ответа
Лучший ответ:
Вы пропустили оператор прерывания в конце каждого случая. например:
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
Вам понадобится одна задержка (если она есть) в нижней части функции цикла(). Возможно, он вам не понадобится, поскольку он будет отображать текущую цифру, пока вы не переместите потенциометр. Исключение: если банк находится на границе между двумя цифрами, вы можете увидеть некоторое размывание.
Замените вызовы задержки в case
операторами break;
. В противном случае, какой бы регистр вы ни вызвали, он перейдет в регистр ниже него и так далее, отображая каждую цифру по очереди, а это не то, что вы хотели (и это то, что вы уже видите).
Измените вызов map() на map(POD, 0, 1024, 0, 10)
. В противном случае на потенциометре не будет полосы «9», а ширина полосы «8» будет только 1 значение (из 1023): ровно значение «1023». Вам бы хотелось, чтобы полоса «9» была такой же широкой, как и все остальные. Возможно даже, что данный потенциометр не сможет приблизиться к нулевому сопротивлению, чтобы вы могли получить показание 1023.
- Как использовать SPI на Arduino?
- Как решить проблему «avrdude: stk500_recv(): programmer is not responding»?
- Как создать несколько запущенных потоков?
- Как подключиться к Arduino с помощью WiFi?
- avrdude ser_open() can't set com-state
- Как узнать частоту дискретизации?
- Что такое Serial.begin(9600)?
- Я закирпичил свой Arduino Uno? Проблемы с загрузкой скетчей на плату
Я бы сократил задержку (1000), чтобы она была намного меньше - иначе вы поворачиваете банк, ничего не происходит, вы поворачиваете его немного и, наконец, что-то происходит, но теперь вы промахнулись, чего хотели, и переусердствуете в другую сторону, пытаясь получить туда, куда вы хотели. Попробуйте задержку от 50 до 100, чтобы она более реагировала на поворот ручки. Затем вы можете перейти к использованию поворотного декодера с фиксаторами: один щелчок для смены одного числа. Вот плохо освещенный пример с 2 цифрами и поворотным энкодером. В этом случае для управления каждым дисплеем использовался сдвиговый регистр (в отличие от мультиплексирования)., @CrossRoads
https://www.youtube.com/watch?v=f51eSlcZt-g Ссылка., @CrossRoads