Это старая версия документа!
Научившись подключать и управлять светодиодным индикатором попробуем использовать его для отображения данных. Сконструируем простейший секундомер, который отсчитывает и отображает секунды от 0 до 9.
Оставим схему, собранную на прошлом эксперименте.
Рисунок 1. Электрическая принципиальная схема эксперимента
Токоограничительные резисторы обязательны!
int segments[7] = {14, 13, 4, 5, 12, 16, 15}; // ABCDEFG int digits[10][7] = { {1, 1, 1, 1, 1, 1, 0}, // 0 {0, 1, 1, 0, 0, 0, 0}, // 1 {1, 1, 0, 1, 1, 0, 1}, // 2 {1, 1, 1, 1, 0, 0, 1}, // 3 {0, 1, 1, 0, 0, 1, 1}, // 4 {1, 0, 1, 1, 0, 1, 1}, // 5 {1, 0, 1, 1, 1, 1, 1}, // 6 {1, 1, 1, 0, 0, 0, 0}, // 7 {1, 1, 1, 1, 1, 1, 1}, // 8 {1, 1, 1, 1, 0, 1, 1}, // 9 }; void draw_time(int digit) { for (int i = 0; i < 7; i++) { } } void setup() { for (int i = 0; i < 7; i++){ } } void loop() { for (int i = 0; i < 7; i++) { draw_time(i); } }
В этой программе мы записали номера выводов микроконтроллера, к которым подключены сегменты индикатора, в массив segments
. Порядок перечисления сегментов указан в комментарии в этой строке.
Комментарии используются в программах, чтобы записать какие либо пояснения к коду, и предназначены только для человека, который читает код. Комментарии никак не влияют на выполнение программы. В языке Arduino комментарий начинается с символов . Также часто комментируют части кода, которые не должны исполняться, но удалять совсем их пока не нужно.
</WRAP>
В строке 3 объявляем массив, в котором описываем цифры от 0 до 9 и какие сегменты должны светиться на индикаторе, чтобы эту цифру отобразить, а какие должны быть потушены. Для описания этого мы использовали двумерный массив. Это массив, у которого каждый из элементов является тоже массивом. Посмотрим внимательнее: элементом под индексом 0 у массива
digits является массив
{1, 1, 1, 1, 1, 1, 0}. Это перечисление состояний сегментов для отображения цифры 0. Порядок перечисления соответствует порядку в массиве
segments. Это важно и потребуется нам для отображения цифр.
В основном цикле программы мы перебираем все элементы массива
digits с целью отображения на дисплее.
<code arduino [enable_line_numbers=«2», start_line_numbers_at=«29»]>
void loop() {
for (int i = 0; i < 7; i++) {
draw_time(i);
delay(1000);
}
}
</code>
Рассмотрим код функции
draw_time, которая предназначена для отображения цифры, передаваемой ей в качестве параметра. Начнем с того, что разберемся что именно передается функции в качестве входных данных. Ей передается один из элементов массива
digits, каждый элемент которого, как мы помним, сам является массивом, описывающим состояние сегментов.
<code arduino [enable_line_numbers=«2», start_line_numbers_at=«24»]>
void draw_time(int digit) {
for (int i = 0; i < 7; i++) {
if (digits[digit][i]) digitalWrite(segments[i], HIGH);
else digitalWrite(segments[i], LOW);
}
}
</code>
Получается, что функция получила данные о том какие сегменты ей нужно включить, а какие выключить. Соответственно она должна это исполнить. Для этого она проходит по всем элементам массива сегментов, как обычно, с помощью оператора
in, но в этот раз мы использовали еще оператор
enumerate. Обычно оператор
in перебирая элементы массива записывает в переменную содержимое элемента массива, его значение, а
enumerate(digit) создает последовательность кортежей, состоящих из индексов и значений. В кортеже
el в элементе 0 оказывается индекс, а в элементе 1 значение.
Номер индекса нам нужен, чтобы обратиться по нему к нужному сегменту, а его значение, чтобы знать что с ним делать- зажигать или тушить.
<code python [enable_line_numbers=«2», start_line_numbers_at=«26»]>
if (el[1]):
Pin(segments[el[0]]).on()
else:
Pin(segments[el[0]]).off()
</code>
Если сегмент должен быть включен (
el[1] истинно), то нужно его зажечь. Номер пина, который нужно включить записан в переменной
segments в элементе с индексом, который мы берем из
el[0]. Именно поэтому мы сделали так, что последовательность пинов в массиве
segments соответствует им в массиве
digits, чтобы у них были одинаковые индексы.
Не совсем обычным является и то, как мы зажигаем сегменты.
Pin(segments[el[0]]).on(). Обычно мы создавали объект
Pin'', записывали его в переменную и оперировали с ней. Сейчас мы сделали тоже самое, только не создавали отдельную переменную, а сделали все сразу. Просто нам не нужна эта переменная в будущем, поэтому мы ее не создавали и для краткости записи сделали так.
==== Дополнительные задания ====
Добавь к цифрам 0..9 еще буквы A, b, C d E F, чтобы секундомер переключал символы от 0 до F