Arduino условные переходы


• О проекте
• Обратная связь
• Полезные ссылки
• Полезные программы
• Друзья сайта


Последние комментарии

Алексей: Генератор кода библиотеки axlib
Ну, а в чем пробл...

Андрей: 3D Модели для DipTrace
ОК, понял. За PB...




           

Библиотека для AVR





AXLIB Генератор





Помощь сайту


   
				

Arduino условные переходы

	
	
	

Дата: 13 Марта 2015. Автор: Алексей

	
	
Продолжаем изучать Arduino. В предыдущей статье мы узнали о таких вещах как переменные и написали первую программу в которой помигали светодиодом. Программа была предельно проста и линейна, но не всегда такое такое подходит при решении какой-либо задачи. Иногда необходимо выполнить какую-нибудь проверку. Например проанализировать цифровой вход и в зависимости от состояния выполнить определенный кусок кода. Для этих целей существуют условные переходы. Условные это потому что нужно какое-либо условие для перехода к одному или другому куску кода. Самый простой условный переход это if. Давайте посмотрим пример полного кода этого условия.

    if(условие) 
     {
        код 1
     }
    else  
     {
        код 2
     }

Давайте разберем все по порядку. if(условие) "if" по русски "если", далее идет открывающееся скобка. За ней условие и закрывающееся скобка. Вроде все понятно, но есть одно но. Условие в С может быть только двух видов, а именно либо true(истина), либо false(ложь). Вспоминая предыдущую статью можно сказать, что условия должны быть булевыми. Да это так, но можно например написать так.

    int i = 0;

    if(!i) i = 5;

    if(i) i = 0;

Пока не вдавайтесь в подробности, а просто посмотрите. Я в качестве условия передал 16-ти битную переменную со значением 0. В С в условиях если стоит 0, то это означает false(ложь). То есть 0 всегда ложь. Что будет в условии если переменная равна 5? А будет истина. В С любое число отличное от нуля есть истина. Этот момент нужно просто запомнить. Если 0, то ложь, а если не 0, то истина. И даже -48 будет тоже истина. Поэтому смотрите как сработает код выше. Сначала переменная i = 0. Попадая в условие мы поставили перед ней знак восклицания. Этот знак означает отрицание. То есть (не i). Так как i = 0, то соответственно это ложь, а если не ложь, то это истина. Значит условие выполнится и i станет 5. Далее 5 это истина и снова условие выполнится и i станет 0. И так по кругу. Заморочено, я понимаю, но это нужно понять, а иначе дальше идти будет сложно. Давайте еще раз повторим. Условие может быть либо ИСТИНА( любое число кроме 0), либо ЛОЖЬ( только 0). Также знак ! является отрицанием текущего значения. !ИСТИНА = ЛОЖЬ, а !ЛОЖЬ = ИСТИНА. Возвращаемся к синтаксису языка. Если вы заметили, то я писал условие без фигурных скобок. Такой вариант приемлем если следующий оператор один. Если нужно выполнить группу операторов, то эту группу обрамляют фигурными скобками. Выполнятся он будет так. Сначала выполнится условие в скобках, затем проверится на истину и если условие истинно, то выполнится следующий за if() код. А именно i = 5;. Если же условие было бы ложным, то следующий после if() код не выполнится, а программа перескочит через него и продолжит выполняться дальше. То есть если условие истинно, то выполняем следующий оператор, а если ложно, то пропускаем следующий оператор. Это так сказать короткая запись. А вот если нам нужно выполнить код при истине один, а при ложи другой, то тут нужно добавить слово else(иначе). Взгляните на начало статьи, на самый первый код.

    if(условие) если условие истинно, выполнить код 1
     {
        код 1
     }
    else  иначе (если ложь) выполнить код 2
     {
        код 2
     }

Но на этом не заканчивается. Есть еще один оператор условия который предназначен для группового выполнения. Например нам нужно проверить какое-нибудь число, которое передали микроконтроллеру и на основании этого числа выполнить тот или иной код. Для этого пишем.

    switch(значение для сранения)
    {
        case значение:
        {
            оператор 1;
            оператор 2;
            оператор n;
            break;
        }
    }

Как это работает. Сначала мы передаем некое значение оператору switch. Далее оператор начинает сравнивать данное значение с вариантами записанными после слова case. Если зачения совпадают, выполняются операторы в фигурных скобках после case. Последний оператор break; принудительно прекращает работу оператора switch и выходит из него. Это сделано для того чтобы после найденного верного case дальше switch не проверял остальные, так как вариант совпадения может быть только один. Пример, мы передадим переменную со значением 0 или 1 или 2, а условие switch выполнит то условие с которым совпал case.

    switch(i)
    {
        case 0:
        { 
            i++;
            break;
        }
        case 1:
        { 
            i++;
            break;
        }
        case 2:
        { 
            i = 0;
            break;
        }
    }

Как это работает. Сначала мы передали switch переменную i. Если в ней 0 то выполнится первый case в котором i увеличится на единицу. При следующем круге в переданной переменной i уже лежит единица и поэтому выполнится case с условием 1 где i снова увеличится на единицу. И наконец при третьем заходе получив двойку выполнится последний case и обнулит переменную. И все по новой. Для закрепления материала, давайте ка помучаем энкодер. Для того чтобы не распинаться повторно о том что это за штука и как работает, идем сюда. Вот весь код программы.

unsigned char input =0;
unsigned char buf = 0;
unsigned char data = 0;
unsigned char data_old = 0;

void setup() 
{  
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  
  Serial.begin(9600);
}

void loop() 
{
  input = ((digitalRead(3)<<1) | digitalRead(2));
  
  if(buf != input)
  {
    switch(buf)
    {
      case 1:
      {
        if((input == 0) & (data < 9)) data++;
        if((input == 3) & (data != 0)) data--;
        break;
      }
      case 0:
      {
        if((input == 2) & (data < 9)) data++;
        if((input == 1) & (data != 0)) data--;
        break;
      }
      case 2:
      {
        if((input == 3) & (data < 9)) data++;
        if((input == 0) & (data != 0)) data--;
        break;
      }
      case 3:
      {
        if((input == 1) & (data < 9)) data++;
        if((input == 2) & (data != 0)) data--;
        break;
      }
    }
    buf = input;
    if(data_old != data) Serial.write(data+0x30);
    data_old = data;
  }
}

Как этот код работает. Сначала мы создаем переменные input, buf и data. data_old нужно лишь для удержания границ вывода. Далее в функции void setup() мы инициализируем два пина 2 и 3 как вход. Причем пишем не просто INPUT, а INPUT_PULLUP. Добавка PULLUP подключает, встроенный в микроконтроллер, подтягивающий резистор к плюсу. Это нужно чтобы выходные ножки энклдера не висели в воздухе, а выводили единицу. Serial.begin(9600); это настройка порта UART. С ним пока разбиратся рано, поэтому просто перепишите и все. Что творится в функции void loop(). В переменную input мы записываем следующую абракадабру. В скобках слева на право. Читаем состояние пина 3 сдвигаем его на один бит влево. Далее читаем состояние пина 2 и логически прибавляем его. Далее все это заносим в переменную. (Если непонятно, то ничего страшного. Я отдельно напишу статью для работы с логическими операторами и станет все понятно. пока просто примите как есть.) Далее идет наш оператор if которому мы передаем условие. Если предыдущее значение экодера не равно (помним знак !) текущему, то выполняем группу операторов, иначе возвращаемся к чтению пинов. Если данные разнились, input отличается от buf, значит энкодер повернули. Отлично, берем текущее значение и передаем его в switch. Тот в свое время начинает искать варианты, а у нас их всего четыре, либо 1, либо 0, либо 2, либо 3. Найдя нужный вариант смотрим куда повернули энкодер и в зависимости от направления либо увеличим переменную data, либо уменьшим. После выходим из switch и сохранем в buf значения input. И в конце выводим значение data в порт. Прибавление 0x30 нужно для перевода числа в ASCII код. data_old = data; нужно сугубо для удержания от дублирования одинаковых крайних чисел в терминале. При обработке переменной data без терминала, data_old = data; можно выкинуть. Для проверки работы кода, после загрузки запускаете терминал с тем же портом что и при прошивке, а скорость выбираете 9600.

Для самых ленивых готовый Скетч.

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


                                  Читать предыдущий урок           Читать следущий урок



Николай    30.09.16 08:48

после "лож" всё ж таки поставьте мягкий знак, а то читать грустно ... вдобавок к тому, что распознавать русские буквы в UTF-8 и так невесело ...

Алексей    30.09.16 09:22

Бывает) С utf-8 переходить не буду так как win1251 еще грустнее так как он отмирает.

Николай    03.10.16 06:55

Это я как раз поэтому if'ами интересуюсь ) И как раз про логические операторы хочется почитать. Первый опыт выложил тут (русифицированная бегущая строка).
ссылка

Алексей    03.10.16 07:30

ЕвгенийП верно подметил, Вам нужно сначала изучить азы С, а потом пытаться что-то сделать. А то получается Вы пытаетесь вникнуть в элементарную алгебру при этом не вникая в арифметику. Вы не первый кто спотыкается об эти кочки. Я в ближайшее время начну записывать видео на тему азов С. И как раз я там буду уперать на самые элементарные вещи.

Николай    04.10.16 00:47

Там (по ссылке) в 42-м посте уже готовый результат. Всё работает, кочки перепрыгнуты ) А с азами - да, логика развращает ) Ну и изучать лучше на практике, чем просто зубрить. Сейчас вот стало интересно, сколько логических условий можно впихнуть в оператор if.




Чтобы вставить ссылку используйте форму вида[url]http://www.адрес.ru[/url][text]текст ссылки[/text]
Чтобы вставить код используйте форму вида[code]код[/code]

Имя:   





  








Вверх


Рейтинг@Mail.ru Яндекс.Метрика