Arduino. Входы/выходы

Дата 24.03.2020 2:10:00 | Раздел: Arduino

Пришло время поработать с портами ввода вывода.

Напомню, в Arduino UNO 6 аналоговых входов, и 13 цифровых входов/выходов (6 из них могут управляться ШИМ сигналом).

Аналоговые входы
A0 - Аналоговый вход 0
A1 - Аналоговый вход 1
A2 - Аналоговый вход 2
A3 - Аналоговый вход 3
A4 - Аналоговый вход 4
A5 - Аналоговый вход 5

Цифровые входы/выходы (ШИМ)
0 - Цифровой вход/выход 0
1 - Цифровой вход/выход 1
2 - Цифровой вход/выход 2
3 - Цифровой вход/выход 3 (ШИМ)
4 - Цифровой вход/выход 4
5 - Цифровой вход/выход 5 (ШИМ)
6 - Цифровой вход/выход 6 (ШИМ)
7 - Цифровой вход/выход 7
8 - Цифровой вход/выход 8
9 - Цифровой вход/выход 9 (ШИМ)
10 - Цифровой вход/выход 10 (ШИМ)
11 - Цифровой вход/выход 11 (ШИМ)
12 - Цифровой вход/выход 12
13 - Цифровой вход/выход 13

Режим работы пина (вход или выход)

Начиная с Arduino 1.0.1, можно включить внутренние подтягивающие резисторы в режиме INPUT_PULLUP. Кроме того, режим INPUT явно отключает внутренние подтягивающие резисторы.

void setup() {
  pinMode(12, OUTPUT); // 12 пин выход
  pinMode(11, INPUT);  // 11 пин вход
  pinMode(7INPUT_PULLUP); // 7 пин вход с подтягивающим резистором
}


INPUT
Порты Arduino установленные в режим INPUT находятся в высокоимпедансном состоянии. Это означает то, что порт ввода дает слишком малую нагрузки на схему, в которую он включен. Эквивалентом внутреннему сопротивлению будет резистор 100 МОм подключенный к выводу микросхемы. Таким образом, для перевода порта ввода из одного состояния в другое требуется маленькое значение тока. Это позволяет применять выводы микросхемы для подключения различных датчиков, но не питания.

INPUT_PULLUP
Микроконтроллер ATmega на Arduino имеет внутренние подтягивающие резисторы (резисторы, которые подключаются к источнику питания внутри), к которым вы можете получить доступ. Если вы предпочитаете использовать их вместо внешних подтягивающих резисторов, вы можете использовать аргумент INPUT_PULLUP в pinMode ().

OUTPUT
Порт установленный в режим выхода — OUTPUT, находится в низкоимпедансном состояние. Он может пропускать через себя довольно большой ток, до 40 mA, достаточный для запитывание внешней цепи, например, светодиода. В этом состоянии порт может быть поврежден как замыкании на землю так и на питание 5В. Тока с порта микроконтроллера не достаточно для питания моторов и сервоприводов напрямую.

Функции digitalRead() и digitalWrite()
Функция digitalRead() считывает значение с заданного входа - 1 или 0.
Функция digitalWrite() при включении пина на выход, подает лог. 1 или 0 на указанный пин


int ledPin = 13;              // Светодиод подключенный к вход/выходу 13
int inPin = 7;                // кнопка на входе 7
int val = 0;                  // переменная для хранения значения
 
void setup()
{
  pinMode(ledPin, OUTPUT);    // устанавливает режим работы - выход для 13го вход/выхода (pin)
  pinMode(inPin, INPUT);      //  устанавливает режим работы - вход для 7го вход/выхода (pin)
}
 
void loop()
{
  val = digitalRead(inPin);      // считываем значение с входа
  digitalWrite(ledPin, val);     // устанавливаем значение на светодиоде равным значению входа кнопки
}


При включении пина на вход, то данная функция подключает и отключает подтягивающий резистор
pinMode(11, INPUT); // 11 пин вход

digitalWrite(11, HIGH); // подключить подтягивающий резистор
digitalWrite(11, LOW); // отключить подтягивающий резистор

Примечание:
Аналоговые входы (0-6) могут быть использованы как цифровые входы/выходы. Обращение идет по номерам 14-19

Функция analogRead()
Функция считывает значение с указанного аналогового входа. Большинство плат Arduino имеют 6 каналов (8 каналов у платы Mini и Nano, 16 — у Mega) c 10-битным аналого-цифровым преобразователем (АЦП). Напряжение, поданное на аналоговый вход (обычно от 0 до 5 вольт), будет преобразовано в значение от 0 до 1023 — это 1024 шага с разрешением 0,0049 вольт. Разброс напряжения и шаг может быть изменен функцией analogReference(). Считывание значения с аналогового входа занимает примерно 100 микросекунд (0,0001 сек), т. е. максимальная частота считывания приблизительно 10 000 раз в секунду.
Если аналоговый вход не подключен, то значения, возвращаемые функцией analogRead(), могут принимать случайные значения.

int analogPin = 3; // номер порта, к которому подключен потенциометр
int val = 0; // переменная для хранения считываемого значения

void setup()
{
Serial.begin(9600); // установка связи по serial
}

void loop()
{
val = analogRead(analogPin); // считываем значение
Serial.println(val); // выводим полученное значение
}


Функция analogWrite()
Выдает аналоговую величину (ШИМ) на порт входа/выхода. Функция может быть полезна для управления яркостью подключенного светодиода или скоростью вращения электродвигателя. После вызова analogWrite() на выходе будет генерироваться постоянная прямоугольная волна с заданной шириной импульса до следующего вызова analogWrite (или вызова digitalWrite или digitalRead на том же порту входа/выхода). Частота ШИМ-сигнала приблизительно 490 Гц.

На большинстве плат Arduino (на базе микроконтроллера ATmega168 или ATmega328) ШИМ поддерживают порты 3, 5, 6, 9, 10 и 11, на плате Arduino Mega — порты с 2 по 13. На более ранних версиях плат Arduino analogWrite() ра- ботал только на портах 9, 10 и 11.

Для вызова analogWrite() нет необходимости устанавливать тип входа/выхода функцией pinMode(). Функция analogWrite() никак не связана с аналоговыми входами и с функцией analogRead().

Функция analogWrite
 


int ledPin = 9; // Светодиод подключен к выходу 9
int analogPin = 3; // потенциометр подключен к выходу 3
int val = 0; // переменная для хранения значения

void setup()
{
pinMode(ledPin, OUTPUT); // установка порта на выход
}

void loop()
{
val = analogRead(analogPin); // считываем значение с порта,
// подключенного к потенциометру
analogWrite(ledPin, val / 4); // analogRead возвращает значения от 0
// до 1023, analogWrite должно быть
// в диапазоне от 0 до 255
}


RGB лента от Arduino

Задался целью преобразовать некое напряжение в цветовую гамму. Низкое напряжение - синий цвет, среднее значение зеленый, и высокое значение - красный. К примеру, датчик температуры, подключенный на аналоговый вход.

Вот примерная зависимость света от напряжения.
Рис. 2

И схема
Рис. 3

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

Скетч:

// Плавное изменение цвета RGB ленты в зависимосчти от некоего датчика,
// подключенного к аналоговому входу 3
// Цвет переходит с синего к красному, через зеленый цвет,
// Промежуточные цвета смешиваются.
// В зависимости от датчика, начальное и конечное напряжение,
// а точнее, цифровой код напряжения можно указать в переменных

int Pin9 = 9; // красный
int Pin10 = 10; // синий
int Pin11 = 11; // зеленый
int Pin3 = 3; // потенциометр подключен к входу 3
int val = 0; // переменная для хранения значения
int valbeg = 200; // начальное значение параметра (0-1023) обычно ближе к нулю
int valend = 800; // конечное значение параметра (0-1023)ближе к краю
// valbeg должен быть заведомо меньше valend
int pwm = 0; // переменная для хранения значения шим
float konst = (valend - valbeg) / 256.0; // Подсчитываем коэффициент
// Данный коэффициент нужен для того, чтоб вписать диапазон в 0-255 для ШИМ

void setup()
{
  pinMode(Pin9, OUTPUT); // установка порта на выход
  pinMode(Pin10, OUTPUT); // установка порта на выход
  pinMode(Pin11, OUTPUT); // установка порта на выход
  Serial.begin(9600); // открыть последовательный порт
}

void loop()
{
  val = analogRead(Pin3); // считываем значение с порта 3,
  pwm = (val - valbeg) / konst; // Полученные данные должны вписаться в 0-255 для вывода

  if (pwm < 0) { pwm = 0; }; // если данные меньше, то 0
  if (pwm > 255) { pwm = 255; }; // если данные больше, то 255
  // Даже если параметры вышли за пределы, они обрежутся, и будет один из крайних цветов

  if (pwm < 128)
   {
    analogWrite(Pin10, 255 - pwm * 2); //Выводим синий цвет
    analogWrite(Pin11, pwm * 2); //Выводим зеленый цвет
    analogWrite(Pin9, 0); // меньше середины красный не выводим
   }
  else
   {
    analogWrite(Pin9, pwm * 2 - 255); //Выводим красный цвет
    analogWrite(Pin11, 510 - pwm*2 ); //Выводим зеленый цвет
    analogWrite(Pin10, 0); // дальше середины синий не выводим
  }
 ;


  Serial.print(val);
  Serial.print(" - ");
  Serial.print(pwm);
  Serial.print(" - ");
  Serial.print(konst);
  Serial.println();
  delay(100);
}



У меня выставлено valbeg = 200 и valend = 800, что означает, что напряжение замеряется примерно от 1В до 3.9В. Это означает, что до 1В лента светит только синим, и после 3.9В лента светит только красным.
Если выставить valbeg = 0 и valend = 1023, то лента будет плавно изменять цвет от 0 до 5В.
Чем меньше измеряемый диапазон, тем больше ступеньки переключения цвета. Оптимально, если разность начального и конечного значения больше 255 (если значения больше, они все равно приводятся к значению 255, так как ШИМ у Ардуины имеет 256 значений 0-255).
Синий Голубой Зеленый Желтый Красный






Эта статья взята с сайта Портал радиолюбителей
https://radio-hobby.org

Адрес этой статьи:
https://radio-hobby.org/modules/news/article.php?storyid=1558