ARDUINO — Устройства ввода/вывода информации в 1 бит.

Из курса информатики известно — любое устройство, выдающее информацию для последующей ее обработки микропроцессором или микроконтроллером, является устройством ввода информации, а одно и более устройств, отображающих результат или отправляющих обработанные данные далее, называют устройствами вывода. У микроконтроллеров это несколько иначе — на одном и том же порту может быть и устройство ввода и устройство вывода и только сам МК формирует управляющую комбинацию для порта — ввод или вывод. Из этого следует, что МК отрабатывая программу и начальные установки (инициализацию), назначает направление движения данных. Портом в данном случае является один из выводов МК (в нашем случае — платы Ардуино Нано). Следует помнить, что в МК строгая система кратности информации.

Биты и байты.

Обычно в повседневной жизни информация в цифровой форме измеряется в байтах и производных от байта.

1Байт = 8 Бит, для измерения скоростей передачи информации => 1Байт/сек = 8Бит/сек

Для работы с микроконтроллерами применяются части Байта — полубайт

4бита = 1полубайт = 1тетрада

8бит = 2полубайта = 1 байт

Более мощные потоки и емкостя ОЗУ и ПЗУ измеряются также кратными величинами от Байта:

1 гигабит = 1024 мегабит = 1024 * 1024 килобит = 1024 * 1024 * 1024 бит и т.д.

1 Гигабайт = 1024 Мегабайт = 1024 * 1024 Килобайт = 1024 * 1024 * 1024 байт и т.д.

  Для оценки и примера — компьютер подключен к сети интернет через витую пару 100мБит — максимальная пропускная способность канала будет 100/8=12,5мБайт/сек. Но такой поток бывает очень редко. Предполагается, на компьютере установлена среда программирования Arduino IDE, имеется в наличии плата ARDUINO Nano. Принцип примеров в этом разделе — от простого к сложному с кратким описание схем и функций языка Си.

   Как указано выше — самый минимальны размер для информации — это 1бит (значение равное или 0 или 1). Сразу пару классических терминов в программировании (для тех кто знаком с ассемблером — не обращать внимания). Установить бит — записать в определенный разряд регистра единицу, сбросить бит — записать 0. Прочитать разряд (бит) — считать значение определенного разряда определенного регистра (значение может быть 0 или 1). Практически все узлы периферии МК изначально конфигурируются  (инициализируются) путем записи или сброса нужных битов в регистрах управления МК. Самая первая программа (на компьютере это равносильно написанию — «Hello, world!») —  мигание установленным прямо на плате светодиодом.


int TIMER = 500;  //переменная времени задержки 1000 = 1сек.
int OUTPIN = 13;  //номер вывода на плате с светодиодом

void setup() {
pinMode(OUTPIN, OUTPUT);
}

void loop() {
digitalWrite(OUTPIN, HIGH);
delay(TIMER);
digitalWrite(OUTPIN, LOW);
delay(TIMER);
}


   Копировать код необязательно — можно скачать отсюда. Запускается прошивка платы и через 4-5 сек светодиод начинает мигать. Как узнать, что это именно тот интервал который выставлен в программе??? Померить частоту переключения можно частотомером или осциллографом, если эти приборы под рукой, а если нет  — перезаписывается переменная TIMER = 150, перекомпиляция, прошивка — ???? Один из важнейших моментов — правильно выставленные параметры в разделе ИНСТРУМЕНТЫ — подраздел платы — должен соответствовать группе/типу — в данный момент ARDUINO — Nano, подраздел — ATMega328, подраздел порт — порт который светится в подменю и доступен для связи (от COM1 до COM 36). Если все работает правильно, то частота миганий в последнем случае будет около 6Гц. Если изменить TIMER = 50 — частота возрастет до 20Гц. Что может произойти, если переменной OUTPIN= 11 ??? Естественно — ничего, потому что функция digitalWrite  будет устанавливать и сбрасывать бит на 11 выводе платы, а ней не подключен светодиод. Если воспользоваться внешним светодиодом и резистором 1кОм по этой схеме подключения:

Arduino_ledout

То светодиод начнет мигать с частотой 20 Гц.

Теперь о функциях в программе:

int TIMER = 500;  — переменной TIMER присваивается значение 500 — задержка полсекунды
int OUTPIN = 13;  — переменной OUTPIN присваивается значение 13 — вывод с подключенным светодиодом

далее как указывалось ранее,  функция инициализации микроконтроллера — начальные установки:

void setup() {
pinMode(OUTPIN, OUTPUT);   — см. ниже
}

pinMode() -

Описание: Настраивает указанный вывод, чтобы вести себя как вход или выход. Подробные сведения о функциях контактов см. В описании цифровых контактов.Начиная с Arduino 1.0.1, можно включить внутренние подтягивающие резисторы с режимом INPUT_PULLUP. Кроме того, режим INPUT явно отключает внутренние подтягивания. Примечание: Аналоговые входные контакты могут использоваться в качестве цифровых воводов, называемых A0, A1 и т. Д.

Синтаксис: pinMode (вывод, режим)

Параметры: вывод —  номер контакта, режим — режим которого вы хотите установить: INPUT, OUTPUT или INPUT_PULLUP. (см. страницу цифровых контактов для более полного описания функций.)


Непрерывный цикл исполнения включает две функции —

void loop() {
digitalWrite(OUTPIN, HIGH);   // включаем светодиод (записываем в порт значение 1)
delay(TIMER);                 // ждем указанную в мсек паузу
digitalWrite(OUTPIN, LOW);    // выключаем светодиод (записываем в порт значение 0)
delay(TIMER);                 // ждем указанную в мсек паузу
}

digitalWrite() -

Описание: устанавливает значение HIGH или LOW для цифрового вывода. Если вывод сконфигурирован как OUTPUT с pinMode (), его напряжение будет установлено на соответствующее значение: 5 В (или 3,3 В на платах 3,3 В) для HIGH, 0 В (земля) для LOW. Если вывод сконфигурирован как INPUT, digitalWrite () включит (HIGH) или отключит (LOW) внутреннюю подтяжку на входном выводе. Рекомендуется установить pinMode () в INPUT_PULLUP, чтобы включить внутренний подтягивающий резистор. Дополнительную информацию см. В руководстве по цифровым контактам. ПРИМЕЧАНИЕ. Если вы не установите pinMode () в OUTPUT и подключите светодиод к выходу, при вызове digitalWrite (HIGH) светодиод может выглядеть тусклым. Без явной установки pinMode (), digitalWrite () будет включать внутренний нагрузочный резистор, который действует как большой токоограничивающий резистор.

Синтаксис: digitalWrite (вывод, значение)

Параметры: вывод — номер штыря, значение — HIGH или LOW


   Из выше приведенного четко видно, что классический светодиод, подключенный к порту, есть не что иное как 1-битное устройство вывода. Естественно, что самым простым 1-битным устройством ввода является обыкновенная тактовая кнопка с нормально разомкнутыми контактами. Но и здесь присутствуют «подводные камни» — так называемый дребезг контактов. Дребезг контактов — явление, происходящее в электромеханических коммутационных устройствах и аппаратах (кнопках, реле, герконах, переключателях, контакторах, магнитных пускателях и др.), длящееся некоторое время после замыкания электрических контактов. После замыкания происходят многократные неконтролируемые замыкания и размыкания контактов за счет упругости материалов и деталей контактной системы — некоторое время контакты отскакивают друг от друга при соударениях, размыкая и замыкая электрическую цепь. В зависимости от размеров, массы, материала и конструкции контактной системы время дребезга (время от первого соприкосновения контактов до затухания механических колебаний и установления стабильного контактирования) составляет 0,5—2 мс у миниатюрных герконов и до сотен миллисекунд у мощных контакторов. При размыкании электромеханических контактов дребезг не наблюдается. Исключать это явление необходимо именно в цифровой технике, потому что, для правильного считывания состояния с клавиатуры (кнопки), требуется стабильность значения от момента замыкания и на все время считывания.

  Следующий пример программы позволяет управлять кнопкой для включения и выключения светодиода. Код программы имеет следующий вид:


const int buttonPin = 2; //номер вывода для подключения кнопки
const int ledPin =  13;     //номер вывода для подключения светодиода
int buttonState = 0;        //переменная для хранениясостояния кнопки

void setup() {
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT);
}

void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) { digitalWrite(ledPin, HIGH); }
else { digitalWrite(ledPin, LOW); }
}


digitalRead ()-

Описание:
Считывает значение с указанного цифрового вывода, либо HIGH, либо LOW.

Синтаксис:
digitalRead(pin) ;

Параметры:
pin: номер цифрового вывода, который считывается (int)

Возвращает результат:
HIGH или LOW


if (true or false) {1-я группа операторов;} else {1-я группа операторов;}

Описание:

Оператор ветвления — выполнение по условию, применяется вместе с операторами сравнения: (равно ==), (не равно ! =), (меньше <), (больше >). В случае когда указанное условие принимает значение истина=TRUE, выполняется 1-я группа операторов, при значении условия ложно = FALSE — выполняется 2-я группа операторов.

Синтаксис:

if (x > 50) { a = 100; b=200} else {a = 0; b = 0;}

if (x <100) h = 200;

второй вариант приведен для односложного условия.


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


const int buttonPin = 2;    //номер вывода для подключения кнопки
const int ledPin = 13;          //номер вывода для подключения светодиода

int ledState = HIGH;                   // текущее состояние входного вывода
int buttonState;                             // текущее считывание с входного вывода
int lastButtonState = LOW;     // предыдущее чтение с входного вывода

unsigned long lastDebounceTime = 0;  // последнее время, когда выходной вывод был переключен
unsigned long debounceDelay = 50;       // время дребезга, увеличивается, если контакт дребезжит

void setup() {
pinMode(buttonPin, INPUT);
pinMode(ledPin, OUTPUT);

digitalWrite(ledPin, ledState);
}

void loop() {
int reading = digitalRead(buttonPin);

if (reading != lastButtonState) {  //сбрасываем счетчик времени дребезга
  lastDebounceTime = millis();
  }

if ((millis() — lastDebounceTime) > debounceDelay) {
  if (reading != buttonState) {
    buttonState = reading;
    if (buttonState == HIGH) {  //меняем статус светодиода если состояние кнопки изменилось
    ledState = !ledState;
    }
  }
}
digitalWrite(ledPin, ledState);  //записываем в вывод статус светодиода

lastButtonState = reading;   //записываем установившееся состояние кнопки
}


Поскольку речь идет об информационных сигналах (слаботочных и малого напряжения), более упрощенный вариант антидребезга — это сделать паузу в 50-150мс и еще раз проверить состояние кнопки. Код выглядит вот так:

» …

void loop() {
int reading = digitalRead(buttonPin);
delay (100);

…»

К оглавлению