Как разработать динамическую индикацию для 7-сегментного индикатора?

Добрый день, товарищи! В рамках изучения Arduino я решил создать проект с динамической индикацией на 7-сегментном индикаторе (3 разряда). Обычно я видел реализации с использованием конструкции case, но хотел бы сделать это более компактно. Однако сейчас у меня возникли проблемы. 

Вот код функции отрисовки, в которую подается список из трех чисел:

<pre><code class="cpp">void draw(byte *numdraw ) {
  byte b = 0;
  for(byte i = 9; i &lt; 12; i++ ){
      digitalWrite(i, 1);
      byte a = 0;
      for( byte j = 2; j &lt; 9; j++){ 
        bool flag = bitRead(numdraw[a], b);
        digitalWrite(j, flag);
        a++;
        }
      delay(10);
      digitalWrite(i, 0);
      b++;
      }</code></pre>

Проблема в том, что при добавлении еще одного цикла вся логика отрисовки нарушается. Я хотел бы попросить совета у вас, так как сам не смог найти решение (кроме как использовать конструкцию case). Извиняюсь за возможные ошибки и за, возможно, несоответствующий вопрос.
  • 8 февраля 2025 г. 19:04
Ответы на вопрос 1
Добрый день! По вашему описанию и предоставленному коду, я вижу, что вы хотите реализовать динамическую индикацию на 7-сегментном индикаторе без использования конструкции `case`. Это вполне возможно, если вы будете управлять состоянием сегментов более компактно и организованно. 

Вот простой пример реализации динамической индикации для 3-разрядного 7-сегментного индикатора с использованием массивов. Подход заключается в создании массива, в котором будут храниться соответствия для отображения цифр от 0 до 9, а также управление забором для точек, которые вы хотите включить.

### Пример кода для динамической индикации

1. Сначала создайте массив для хранения состояний сегментов для каждой цифры:
```cpp
const byte segmentMapping[10] = {
  // a, b, c, d, e, f, g
  B11111100, // 0
  B01100000, // 1
  B11011010, // 2
  B11110010, // 3
  B01100110, // 4
  B10110110, // 5
  B10111110, // 6
  B11100000, // 7
  B11111110, // 8
  B11110110  // 9
};

const byte digitPins[3] = {9, 10, 11}; // Пины для каждого разряда
const byte segmentPins[7] = {2, 3, 4, 5, 6, 7, 8}; // Пины для сегментов a-g
```

2. Затем обновите вашу функцию для динамической индикации:
```cpp
void draw(byte *numdraw) {
    for (byte i = 0; i < 3; i++) { // Для каждого разряда
        digitalWrite(digitPins[i], HIGH); // Включаем разряд
        
        // Отрисовка текущей цифры
        byte segments = segmentMapping[numdraw[i]];
        for (byte j = 0; j < 7; j++) {
            bool flag = bitRead(segments, j);
            digitalWrite(segmentPins[j], flag);
        }
        
        delay(10); // Задержка на отрисовку
        digitalWrite(digitPins[i], LOW); // Выключаем разряд
    }
}
```

3. В `loop()` функции вы можете вызывать `draw()` с массивом чисел, которые вы хотите отобразить:
```cpp
void loop() {
    byte numbersToDisplay[3] = {1, 2, 3}; // Пример массива, состоящего из чисел от 0 до 9
    draw(numbersToDisplay);
}
```

### Объяснение

- **segmentMapping**: массив, который содержит битовые представления для цифр от 0 до 9. Каждый бит отвечает за включение или выключение соответствующего сегмента.
- **digitPins**: массив, содержащий пины, к которым подключен каждый из разрядов 7-сегментного индикатора.
- **segmentPins**: массив пинов, к которым подключены сегменты индикатора.
- В функции `draw` мы проходим по каждому разряду, включаем его, отображаем соответствующую цифру и затем отключаем разряд. Это делается быстро, что позволяет визуально «двигаться» по разрядам с помощью задержки.

Таким образом, вы избегаете использования конструкции `case` и делаете код более компактным и читаемым.
Похожие вопросы