Освой Arduino играючи

Сайт Александра Климова

Шкодим

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

Управление выводами через потенциометр

01.Basics: AnalogReadSerial
Serial Plotter
01.Basics: ReadAnalogVoltage
Светодиод с плавной регулировкой
03.Analog: AnalogInput
03.Analog: AnalogInOutSerial
05.Control: IfStatementConditional

С помощью потенциометра мы можем менять напряжение и считывать данные с выводов.

Сначала чуть теории. На плате есть шесть выводов, которые подписаны от A0 до A5. Они работают с напряжением от 0 до 5V. Для чтения показания напряжения есть встроенный метод analogRead(), возвращающий значение от 0 до 1023. Значение 0 относится к 0V, а 1023 к 5V. Таким образом, если мы хотим конвертировать значение от 0 до 5, то нужно произвести деление 1023/5 = 204.6

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

И, наоборот, цифровые порты с символом тильды ~ (3, 5, 6, 9, 10, 11) могут работать как аналоговые выходы.

Изучим простой пример с одним проводом и аналоговым выводом. Соединим проводом порты A0 и 3.3V. Напишем скетч.


int analogPin = A0;

void setup() {
  Serial.begin(9600);
}

void loop() {
  int rawReading = analogRead(analogPin);
  float volts = rawReading / 204.6;
  Serial.println(volts);
  delay(1000);
}

Откройте окно Serial Monitor и наблюдайте за показаниями. Должны выводиться числа, близкие к значению 3.3: 3.1, 3.2, 3.3. Если, не закрывая программу, вытащить конец провода из порта 3.3V и вставить в порт 5V, то показания изменятся, а на экране появятся числа 5.0. Если перекинуть конец провода на GND, то увидим значения 0.

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

01.Basics | AnalogReadSerial (Чтение аналоговых выводов через потенциометр)

Продолжим изучение работы с аналоговыми выводами через пример AnalogReadSerial из меню File | Examples | 01.Basics. Для примера нам понадобится потенциометр. Цель урока - плавно изменять напряжение и подавать его на аналоговый вывод, чтобы получить с него текущее значение напряжения.

Нам понадобятся плата Arduino, потенциометр и несколько проводов (или перемычек). Соединяем парные ножки с выводами на плате 5V и GND. Среднюю ножку необходимо соединить с аналоговым выводом на плате, помеченную как A0.

Макет

Не важно, какая из крайних ножек потенциометра будет подключена к 5V, а какая к GND, поменяется только направление, в котором нужно крутить ручку для изменения напряжения. Сам сигнал считывается со средней ножки, которая связана с аналоговым портом. Для считывания аналогового сигнала, принимающего широкий спектр значений, а не просто 0 или 1, подходят только порты, помеченные на плате как ANALOG IN. Они все пронумерованы с префиксом A (A0-A5).

Схема готова. Вращая регулятором потенциометра, мы можем менять сопротивление от 5 Вольт до 0. Arduino позволяет считывать текущее напряжение, которое подаётся на среднюю ножку при помощи аналогового вывода. Результаты могут колебаться от 0 до 1023.

Код


void setup() {
  // инициализируем соединение на скорости 9600 бит в секунду:
  Serial.begin(9600);
}

void loop() {
  // Считываем данные с аналогового вывода A0
  int sensorValue = analogRead(A0);  // получаем текущее значение
  Serial.println(sensorValue); // выводим результат на монитор
  delay(1);        // небольшая задержка для стабильности вывода результатов
}

Код очень простой. При инициализации устанавливаем нужную скорость связи: Serial.begin(9600);. Далее в цикле мы постоянно считываем данные, поступающие с потенциометра при помощи метода analogRead(). Так как значения будут находиться в диапазоне от 0 до 1023, мы можем использовать тип int для переменной sensorValue.

Полученный результат будем выводить в окно последовательного монитора.

Проверка (Serial Monitor)

Запустите программу, а также откройте окно последовательного монитора. Вращая регулятором потенциометра, вы можете наблюдать, как в окне будут меняться значения от 0 до 1023.

Пример интересен своей универсальностью. Потенциометр является ручным делителем напряжения. Существуют другие детали, которые выполняют такую же работу. Например, фоторезистор меняет напряжение в зависимости от освещённости. Также напряжение может меняться от нажатия, от температуры и т.д. При этом нам не нужно менять программу, просто одну деталь меняем на другую и код будет выполняться. Единственное различие будет в выводимых результатах - каждый делитель напряжения имеет свои характеристики и, соответственно, будет давать свои показания.

Проверка (Serial Plotter)

Начиная с версии Arduino IDE 1.6.6, в настройках появился новый инструмент Plotter (Tools | Serial Plotter), позволяющий выводить простенький график. Обратите внимание, что он не может работать одновременно с последовательным монитором, который следует закрыть.

Вращая ручку потенциометра, можем наблюдать изменение графика.

Serial Plotter

01.Basics | ReadAnalogVoltage (Напряжение аналоговых выводов через потенциометр)

Рассмотрим урок ReadAnalogVoltage из меню File | Examples | 01.Basics. Он практически идентичен примеру AnalogReadSerial, только мы будем конвертировать значения от аналогового вывода (0...1023) в значения напряжения (0...5). Для примера нам понадобится потенциометр. Цель урока - плавно изменять напряжение и подавать его на аналоговый вывод, чтобы получить текущее значение напряжения.

Схема прежняя, ничего не меняем. Соединяем парные ножки с выводами на плате 5V и GND. Среднюю ножку необходимо соединить с аналоговым выводом на плате, помеченную как A0.

Макет

Схема готова. Вращая регулятором потенциометра, мы можем менять сопротивление от 5 Вольт до 0. Arduino позволяет считывать текущее напряжение, которое подаётся на среднюю ножку при помощи аналогового вывода. Результаты могут колебаться от 0 до 1023.

Код


void setup() {
  Serial.begin(9600);
}

void loop() {
  // читаем данные с вывода A0:
  int sensorValue = analogRead(A0);
  // Конвертируем данные от 0 до 1023) в значения напряжения (0 - 5V):
  float voltage = sensorValue * (5.0 / 1023.0);
  // Выводим результат
  Serial.println(voltage);
}

Если сравнить два примера, то разница в одной строке float voltage = sensorValue * (5.0 / 1023.0);. В цикле считываем данные, поступающие с потенциометра при помощи метода analogRead(). Так как значения будут находиться в диапазоне от 0 до 1023, мы можем использовать тип int для переменной sensorValue. Используем элементарную математику и делим результат на коэффициент.

Полученный результат будем выводить в окно последовательного монитора.

Запустите программу, а также откройте окно последовательного монитора. Вращая регулятором потенциометра, вы можете наблюдать, как в окне будут меняться значения от 0.00 до 5.00.

Светодиод с плавной регулировкой

Усложним конструкцию, добавив светодиод. Первую часть схему можно было не трогать. Но для экономии в предыдущем примере я соединил ножку потенциометра сразу с портом GND. На этот раз сделаем соединение из двух проводов. Это необходимо, чтобы светодиод тоже мог соединиться с заземлением. Поэтому финальный макет будет следующим.

Макет

Принципиальная схема.

Принципиальная схема

Напишем код.


int potPin = A0;
int ledPin = 9;

void setup() {
  // порт для светодиода на выход
  pinMode(ledPin, OUTPUT);
 
  // пин с потенциометром - вход
  // мы хотим считывать напряжение,
  // выдаваемое им
  pinMode(potPin, INPUT);
  Serial.begin(9600);
}

void loop() {
  // значение напряжения с потенциометра
  int rotation;
  // значение яркости
  int brightness;  
 
  // считываем напряжение с потенциометра от 0 до 1023
  // пропорциональное углу поворота ручки
  rotation = analogRead(potPin);
 
  // в brightness записываем полученное ранее значение rotation
  // делённое на 4. Дробная часть от деления будет отброшена.
  // В итоге мы получим целое число от 0 до 255
  brightness = rotation / 4;
 
  // выдаём результат на светодиод
  analogWrite(ledPin, brightness);

  // выводим результат в Serial Monitor
  Serial.println(brightness);
  delay(1); // задержка для стабильности
}

Практически все инструкции вам знакомы. Тут нужно уяснить момент, что яркость светодиода управляется нашим кодом, а не подачей напряжения через потенциометр. Мы считываем показания потенциометра, как в первом варианте и переводим получаемые значения в диапазон от 0 до 255. Затем воспроизводим старый пример с плавной регулировкой светодиода и подаём ему нужные значения. Теперь при вращении ручки потенциометра мы одновременно управляем степенью накала светодиода. Напомню, что светодиод следует подключить к портам с тильдой, например, ~9

03.Analog: AnalogInput

Небольшая модификация примера с миганием светодиода. Частота мигания будет зависеть от показаний потенциометра. Можно использовать встроенный светодиод или установить свой. Общая схема остаётся как у первого примера.


int sensorPin = A0;    // аналоговый вывод A0 для потенциометра
int ledPin = 13;      // вывод для светодиода
int sensorValue = 0;  // значение, поступаемое от потенциометра

void setup() {
  // устанавливаем режим для светодиода
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // считываем показание с потенциометра
  sensorValue = analogRead(sensorPin);
  // включаем светодиод
  digitalWrite(ledPin, HIGH);
  // делаем задержку на значение от потенциометра в мсек
  delay(sensorValue);
  // выключаем светодиод
  digitalWrite(ledPin, LOW);
  // делаем задержку на значение от потенциометра в мсек
  delay(sensorValue);
}

Получая показания от потенциометра в интервале 0-1023 мы регулируем задержку между миганием светодиода в интервале от 0 до 1.023 секунд.

03.Analog: AnalogInOutSerial

Считываем данные с потенциометра и распределяем их в интервале от 0 до 255 с помощью функции map(). Данный интервал удобно использовать для выводов с PWM (ШИМ). Применим получаемые значения для управления яркостью светодиода, а также будем выводить информацию в Serial Monitor.

Analog


const int analogInPin = A0;  // потенциометр к A0
const int analogOutPin = 9; // светодиод на выводе 9

int sensorValue = 0;        // значения от потенциометра
int outputValue = 0;        // значения для PWM

void setup() {
  Serial.begin(9600);
}

void loop() {
  // считываем данные из потенциометра
  sensorValue = analogRead(analogInPin);
  // распределяем данные из интервала 0-1023 в интервал 0-255
  outputValue = map(sensorValue, 0, 1023, 0, 255);
  // подаём сигнал на светодиод:
  analogWrite(analogOutPin, outputValue);

  // печатаем результаты в Serial Monitor
  Serial.print("sensor = ");
  Serial.print(sensorValue);
  Serial.print("\t output = ");
  Serial.println(outputValue);

  // ждём 2 миллисекунды
  delay(2);
}

Запускаем скетч, крутим ручку потенциометр, наблюдаем за показаниями на экране и следим за яркостью светодиода.

Analog

05.Control: IfStatementConditional

В примере File | Examples | 05.Control | IfStatementConditional рассматривается случай, когда показания достигают определённой величины. При достижении заданного порога включается светодиод. Урок знакомит новичка с оператором условия if (Если).

Схема без изменений (см. рисунки выше). Среднюю ножку потенциометра соединяем с аналоговым выводом A0, остальные две ножки соединяем с питанием 5В и землёй. При желании установите внешний светодиод на цифровой вывод 13 (можно обойтись встроенным светодиодом).


const int analogPin = A0;    // аналоговый вывод для потенциометра
const int ledPin = 13;       // цифровой вывод для светодиода
const int threshold = 400;   // произвольный порог для показаний потенциометра

void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  // считываем данные с потенциометра
  int analogValue = analogRead(analogPin);

  // Если показания выше чем заданный порог, то включаем светодиод
  if (analogValue > threshold) {
    digitalWrite(ledPin, HIGH);
  } else {
    digitalWrite(ledPin, LOW); // иначе держим светодиод выключенным
  }

  // выводим показания на Serial monitor
  Serial.println(analogValue);
  delay(1);        // задержка для стабильности
}

Другие примеры

07.Display: barGraph (Световая шкала и потенциометр)

04.Communication: Graph (Рисуем график в Processing)

Реклама