Последовательный порт. Урок 5. Ардуино

Последовательный порт
Вывод нажатия кнопки в последовательный порт
Вывод нажатия кнопки в последовательный порт

Привет! Мы уже начали писать довольно объемные программы на ардуино. А когда программа сложнее чем «hello world» в ней могут появляться ошибки. И, наверняка, вы уже думали, что было бы неплохо следить за состоянием переменных, счетчиков и массивов в процессе выполнения программы. В этом нам поможет запись данных в последовательный порт.

В прошлый раз мы говорили про широтно-импульсную модуляцию или шим. Это довольно важная тема для ардуино. Поэтому, если вы уже забыли или пропустили предыдущий урок, пожалуйста, посмотрите его.

ШИМ. Урок 4. Ардуино

Во всех программах, которые мы уже написали, мы использовали массивы и переменные, которые изменяли свои значения в ходе выполнения программы. В процессе отладки такой программы очень важно иметь возможность проверить состояние переменных, счетчиков или значений элементов массива.

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

Для того, чтобы выполнить этот урок нам понадобиться.

  • Ардуино UNO
  • Макетная плата
  • Перемычки
  • 4 Резистора номиналом 220 Ом
  • 4 Светодиода 5 мм
  • Резистор номиналом 10 кОм
  • Кнопка
  • Кабель USB

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

Функции. Урок 3. Ардуино

Соберем схему еще раз и откроем скетч с программой.

Принципиальная схема подключения светодиодов и кнопки
Принципиальная схема подключения светодиодов и кнопки

Serial.begin и Serial.print()

Функция serial.begin() открывает последовательное соединение и принимает на вход скорость передачи данных в бит/c (бод). Чтобы использовать последовательный порт, добавим эту функцию в блок setup()

void setup(){
  Serial.begin(9600);
  
  pinMode (buttonPin , INPUT);  
  pinMode(leds[0], OUTPUT);
  pinMode(leds[1], OUTPUT);
  pinMode(leds[2], OUTPUT);
  pinMode(leds[3], OUTPUT);
}

Теперь мы сможем вывести необходимую информацию в последовательный порт с помощью команды serial.print() или serial.println()

Добавим вывод счетчика i в нашей функции LedON(). Это значит, что при нажатии на кнопку мы будем видеть значение переменной i.

boolean ledON(){
  for( int j=0; j <= 5; j++){
      digitalWrite(leds[j], LOW);
  }
  if( i == 5 ){i = 0;}

  Serial.println(i);

  if(i != 4){
      digitalWrite(leds[i], HIGH);
  }
  i++;

}

Загрузим программу в ардуино, откроем монитор последовательного порта и попробуем нажимать на кнопку. Открыть монитор можно кликом по его иконке в правом верхнем углу или комбинацией клавиш Ctrl+Shift+M.

Вывод в последовательный порт
Вывод в последовательный порт

Мы видим, что при каждом нажатии, переменная i увеличивается и выводится в монитор порта. Когда i равно 4, все светодиоды выключены, а когда 5, счетчик сбрасывается на 0.

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

Это было довольно просто, правда? Давайте немного изменим программу и рассмотрим еще одну полезную управляющую конструкцию.

Switch Case

Эта конструкция похожа на if else. Но, использовать ее намного удобнее, когда у вас есть много вариантов выполнения программы. Работает это так. Переменная, которая приходит на вход switch() сравнивается с вариантами в case и выполняется тот кусок кода, который отвечает условию.

switch (x) {
    case 1:
      //выполняется, когда x = 1
      break;
    case 2:
      //выполняется когда x = 2
      break;
    default:
      // выполняется, когда ни один вариант не подходит
      // default необязателен
  }

Заменим условные операторы в нашей функции на switch case таким образом.

boolean ledON(){
  
  for( int j=0; j <= 5; j++){
      digitalWrite(leds[j], LOW);
  }
  
  switch (i) {
      case 0:
        digitalWrite(leds[i], HIGH);   
        break;
      case 1:
        for(int n=0; n<=i; n++){
          digitalWrite(leds[n], HIGH);
        }
        break;
      case 2:
        for(int n=0; n<=i; n++){
          digitalWrite(leds[n], HIGH);
        }
        break;
      case 3:
        for(int n=0; n<=i; n++){
          digitalWrite(leds[n], HIGH);
        }
        break;
      case 4:
        break;        
      default:
        i = 0;
        digitalWrite(leds[i], HIGH);
    }
  Serial.println(i);
  
  i++;

}

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

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

Программа нажатия на кнопку switch case
Программа нажатия на кнопку switch case

Полный текст программы

const int buttonPin=2;

boolean lastButtonState = LOW;
boolean buttonState = LOW;

int leds[] = {5, 7, 9, 11, 13};
int i = 0;

void setup(){
  Serial.begin(9600);
  pinMode (buttonPin , INPUT);
  
  pinMode(leds[0], OUTPUT);
  pinMode(leds[1], OUTPUT);
  pinMode(leds[2], OUTPUT);
  pinMode(leds[3], OUTPUT);  
  
}

boolean ledON(){
  
  for( int j=0; j <= 5; j++){
      digitalWrite(leds[j], LOW);
  }
  
  switch (i) {
      case 0:
        digitalWrite(leds[i], HIGH);   
        break;
      case 1:
        for(int n=0; n<=i; n++){
          digitalWrite(leds[n], HIGH);
        }
        break;
      case 2:
        for(int n=0; n<=i; n++){
          digitalWrite(leds[n], HIGH);
        }
        break;
      case 3:
        for(int n=0; n<=i; n++){
          digitalWrite(leds[n], HIGH);
        }
        break;
      case 4:
        break;        
      default:
        i = 0;
        digitalWrite(leds[i], HIGH);
    }
  Serial.println(i);
  
  i++;

}

boolean debounce(boolean last){
  
  boolean current = digitalRead(buttonPin );
  
  if (last != current){
        delay(5);
        current = digitalRead(buttonPin );
        return current;
  }
}

void loop(){
  buttonState = debounce(lastButtonState);
    if (lastButtonState == LOW && buttonState == HIGH){
        
        ledON();
    }
  lastButtonState = buttonState;
}

Заключение

В этом уроке мы рассмотрели как мы можем использовать последовательный порт для вывода отладочной информации нашей программы. И познакомились с новой управляющей конструкцией switch case. Теперь мы готовы писать по-настоящему сложные программы и создавать настоящие проекты на ардуино. В следующий раз поговорим про получение данных с внешних датчиков на ардуино.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *