"Вы читаете о роботах и программировании и думаете: «Было бы здорово сделать что-то подобное самому!» Теми, кем эта идея овладевает чуть больше просто мыслей смотрят кто и как делал своего робота. Читают статьи, смотрят видео. На картинках все понятно. В видеороликах тоже обычно показываются уже готовые продукты, а также сжато показываются технологии их изготовления. И вроде бы то же всё понятно: отпилил, прикрутил, припаял, соединил, запрограммировал вон на той программе вот этим кодом."

воскресенье, 9 декабря 2018 г.

Программа управления светодиодом


Программа должна при каждом нажатии кнопки менять состояние светодиода, т.е. включать и выключать его. В этой программе надо:
  • считать состояние кнопки;
  • сравнить его с предыдущим состоянием;
  • если предыдущее состояние было отжата, а текущее состояние нажата – инвертировать состояние светодиода.
Т.е. программа должна отлавливать фронт кнопки или перепад состояния сигнала. Есть два фронта сигнала:
  • с высокого состояния в низкое ( --_ );
  • с низкого состояния в высокое (_--).
Нажатие кнопки будет соответствовать перепаду сигнала из высокого в низкое. Это событие мы и должны выделить.
/*  Программа sketch_6_1 урока 6 
 *  На каждое нажатие кнопки инвертирует состояние светодиода
 *  Работает неправильно из-за дребезга контактов */ 
   
#define LED_PIN 13     // номер вывода светодиода равен 13
#define BUTTON_PIN 12  // номер вывода кнопки равен 12
boolean buttonState;      // состояние кнопки 
boolean buttonPrevState;  // предыдущее состояние кнопки 
boolean ledState;         // состояние светодиода
void setup() {
  pinMode(LED_PIN, OUTPUT);        // определяем вывод 13 (светодиод) как выход
  pinMode(BUTTON_PIN, INPUT_PULLUP);  // определяем вывод 12 (кнопка) как вход
}
void loop() {
  buttonState= digitalRead(BUTTON_PIN); // записываем состояние кнопки в переменную buttonState
  
  if ( (buttonPrevState == HIGH) && (buttonState == LOW) ) {
    
    // предыдущее состояние кнопки - отжата, а текущее - нажата
    ledState= ! ledState;             // инверсия состояния светодиода
    digitalWrite(LED_PIN, ledState);  // запись состояния светодиода из переменной нв выход    
  }
  
  buttonPrevState= buttonState;         // предыдущее состояние кнопки = текущему
}
Выделение события происходит в конструкции
if ( (buttonPrevState == HIGH) && (buttonState == LOW) )
&& это логическое И, производимое над условными выражениями. В результате его применения будет выработано условие истинно, если оба выражения истинны. В данном случае блок оператора if будет выполнен, если одновременно предыдущее состояние кнопки = HIGH и текущее состояние кнопки = LOW. Т.е. если кнопка была отжата в предыдущей проверке, а  сейчас нажата.
По этому условию инвертируется состояние светодиода.
В принципе, несложная программа. Но загрузите ее в плату Ардуино и проверьте, как она работает.
Неправильно она работает. Иногда, на нажатие кнопки, она инвертирует состояние светодиода, иногда нет. Часто светодиод мерцает в момент нажатия. Происходит это потому, что сигнал с кнопки совсем не такой, как мы его представляем.
по материалам  http://mypractic.ru/urok-6-obrabotka-drebezga-kontaktov-knopki-interfejs-svyazi-mezhdu-programmnymi-blokami.html
Проанализируем в ИС ДРАКОН предложенный вариант (функцию void loop()) так как предложенный выше вариант рассчитан скорее на работу программы с компьютером, чем с контроллером. 
 альтернативный вариант предусматривает защиту от долгого нажатия кнопки, которое может перевести к миганию светодиода. Кроме того экономиться оперативная память, что для контроллера очень значимо.
программный  код представлен ниже

    // ИС Дракон. Маршрутный транслятор.
    // Y:\home\deniska\Документы\др длкр\Новый_17.drt
    // 33. Схема - Гном, Изменение 09.12.2018 13:41:08
    // 37. Модуль, Начало

void setup()
{

pinMode(13, OUTPUT);        // определяем вывод 13 (светодиод) как выход
pinMode(12, INPUT);  // определяем вывод 12 (кнопка) как вход

pinMode(13, INPUT);  // определяем вывод 13 (светодиод) как вход
}
    // Y:\home\deniska\Документы\др длкр\Новый_17.drt
    // 4. Схема - процедура, Изменение 09.12.2018 14:52:18, Начало

void loop()
{

    // ==================== Шампур
    // 5. Заголовок / альтернатива
    // 38. Вопрос / digitalRead(12) == HIGH == Да

    // -19. Левый комментарий / предыдущее состояние кнопки - отжата, а       текущее - нажата
if (digitalRead(12) == HIGH) goto L42; 
    // 6. Конец / Конец
goto L_end4; 
    // ==================== Шампур
L42: ;
    // 42. Вопрос / digitalRead(13)== LOW == Да
if (digitalRead(13)== LOW &&  digitalRead(12) == HIGH) goto L20; 
    // 21. Полка / запись состояния светодиода на выход / digitalWrite(13, LOW);
digitalWrite(13, LOW);
L40: ;

    // 40. Вопрос / digitalRead(12) == HIGH == Да
    // -24. Левый комментарий / пока конопка нажата

if (digitalRead(12) == HIGH) goto L_end4;
goto L_end4; 

    // ==================== Шампур
L20: ;
    // 20. Полка / запись состояния светодиода на выход / digitalWrite(13, HIGH);
digitalWrite(13, HIGH);
goto L40; 

    // 4. Схема, Конец
L_end4: ;
//
}
    // 37. Модуль, Конец
//

тоже самое в скретче виртуальной лаборотории
void setup()
{
  pinMode(12, INPUT);
  pinMode(13, INPUT);
  pinMode(13, OUTPUT);
}

void loop()
{
  if (digitalRead(12) == HIGH) {
    if (digitalRead(13) == LOW) {
      digitalWrite(13, HIGH);
    } else {
      digitalWrite(13, LOW);
    }
    while (digitalRead(12) == HIGH) {
    }
  }
  
}