Кнопка
Кнопки очень часто используются в электронике. На первый взгляд, работа с ними не таит сюрпризов, но и тут есть «подводные камни».
Хотя у кнопки есть четыре ножки, фактически можно рассматривать их два участка цепи, который замыкается сверху. Следите за правильностью подключения, чтобы цепь была корректной.
Подключим кнопку без использования контроллера, пропустив ток из 5V. При нажатии кнопки цепь замкнётся и светодиод будет светиться. Ничего неожиданного.

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

int buttonPin = 12; int ledPin = 3; void setup() < pinMode(ledPin, OUTPUT); pinMode(buttonPin, INPUT); >void loop()
Код прекрасно работает при нажатии кнопки. А когда мы отпускаем кнопку и создаём разрыв в цепи, то возникает проблема. Вывод 12 становится свободным и висит в неопределённом состоянии в режиме INPUT (вспоминаем урок про цифровые выводы). В результате мы получаем случайные значения и светодиод то включается, то выключается от наводок.
Чтобы избежать этой проблемы, можно добавить резистор от 10 до 100 кОм и прижать кнопку к земле. В этом случае цепь будет замкнута даже при отпущенной кнопке. В этом случае резистор называют стягивающим (pull down). Это рабочая схема, которую можно использовать в учебной программе.
Несмотря на рабочую схему с стягивающим резистором, мы получаем проблему при работе со сложным проектом. Дело в том, что возможна ситуация, когда многие устройства в схеме используют разные значения питания. И тогда придётся к каждой кнопке устройства подавать свой отдельный стягивающий резистор. На практике принято подключаться не к питанию, а к земле, которая всегда одинакова и равно 0. В этом случае сам резистор следует подключить к питанию — подтянуть. Резистор в этом случае является подтягивающим (pull up). Правда, при этом возникает другая проблема — поведение светодиода изменилось противоположным образом — при нажатии светодиод выключается, а при отпускании — включается. Решается проблема просто — меняем одну строчку кода.
digitalWrite(ledPin, !val);
Мы просто меняем значение переменной на противоположное. Это стандартный подход при работе с кнопкой. Теперь вам будет легче разобраться с примерами из Arduino IDE.
Стоит отметить, что у платы Arduino у выводов уже есть встроенные подтягивающие резисторы (кроме вывода 13) и мы можем убрать внешний резистор. Но тогда надо также явно указать использование данного резистора через код с параметром INPUT_PULLUP.
int buttonPin = 12; int ledPin = 3; void setup() < pinMode(ledPin, OUTPUT); pinMode(buttonPin, INPUT_PULLUP); >void loop()
01.Basics: DigitalReadSerial (Чтение цифрового вывода)
Изучим пример DigitalReadSerial из File | Examples | 01.Basics.
Мы изучили, как правильно подключать кнопку и можем изучать встроенные примере. Будем считывать сигнал, идущий с цифрового вывода при нажатии кнопки.
Приблизительно собранная схема может выглядеть следующим образом:

Вкратце опишу на словах данную схему. Вставляем в центре макетной платы кнопку таким образом, чтобы между парными ножками проходил жёлоб макетной платы. Далее соединяем перемычками питание 5V и землю GND на Arduino с рельсами на макетной плате. Потом соединяем перемычкой цифровой вывод под номером 2 на Arduino с одной ножкой кнопки на макетной плате. Эту же ножку кнопки, но с другой стороны соединяем с резистором, который выполняет роль стягивающего резистора. После чего сам резистор соединяем с землёй. Третью ножку кнопки соединяем к положительной рельсе на макетной плате. Осталось только соединить между собой боковые рельсы на макетной плате, и мы готовы изучать новый пример.
Кнопка выполняет очень важную функцию — она замыкает цепь при нажатии. Когда кнопка не нажата, то ток не проходит между ножками кнопки, и не можем поймать сигнал с цифрового вывода под номером 2. Поэтому состояние вывода определяется системой как LOW или 0. При нажатии на кнопку его две ножки соединяются, позволяя току пройти от питания к цифровому выводу 2, а система считывает проходящий сигнал как HIGH или 1.
Разберём код по кусочкам
// Второй вывод связан с кнопкой int pushButton = 2; void setup() < Serial.begin(9600); pinMode(pushButton, INPUT); >void loop() < int buttonState = digitalRead(pushButton); Serial.println(buttonState); delay(1); // задержка для стабильности >
В функции setup() устанавливаем связь с портом для считывания данных на скорости 9600 бит в секунду с Arduino на ваш компьютер: Serial.begin(9600).
Вторая строчка нам уже знакома, но здесь теперь используется параметр INPUT — мы устанавливаем второй цифровой вывод на режим чтения данных, поступающих с кнопки: pinMode(pushButton, INPUT);
В цикле считываем поступающую информацию. Для начала нам понадобится новая переменная buttonState, которая будет содержать значения 0 или 1, поступающие от функции digitalRead().
Чтобы мы могли видеть поступающую информацию, нужно вывести получаемые результаты в окно Serial Monitor при помощи команды println().
Для большей стабильности при чтении данных установим минимальную задержку.
Если вы сейчас запустите программу и откроете также окно Serial Monitor (меню Tools | Serial Monitor), то на экране увидите бесконечные нули. Программа постоянно опрашивает состояние нашей конструкции и выводит результат — отсутствие тока. Если нажать на кнопку и удерживать её, то увидите, что цифры сменяются с 0 на 1. Значит в нашей цепи появился ток и информация изменилась.
02.Digital: Button
Работа с кнопкой рассматривается также в примере File | Examples | 02.Digital | Button. Кнопка соединяется с выводом 2, а светодиод с выводом 13. К кнопке также следует подвести питание и землю через резистор на 10K. Сам принцип работы остался без изменений. Только на этот раз мы не будем выводить информацию о состоянии кнопки на экран, а будем включать светодиод. Такой вариант более наглядный. При нажатии и отпускании кнопки встроенный светодиод должен загораться или гаснуть.

const int buttonPin = 2; // вывод для кнопки const int ledPin = 13; // вывод для светодиода int buttonState = 0; // статус кнопки - нажата или отпущена void setup() < // режим вывода для светодиода pinMode(ledPin, OUTPUT); // режим ввода для кнопки pinMode(buttonPin, INPUT); >void loop() < // считываем состояние кнопки buttonState = digitalRead(buttonPin); // если кнопка нажата, то её состояние HIGH: if (buttonState == HIGH) < // включаем светодиод digitalWrite(ledPin, HIGH); >else < // иначе выключаем светодиод digitalWrite(ledPin, LOW); >>
Допустим, мы хотим изменить поведение — если кнопка не нажата — светодиод горит, а при нажатии — светодиод не горит. Достаточно изменить одну строчку кода.
if (buttonState == LOW)
А теперь загадка! Вы загрузили первый вариант скетча на плату, и вдруг ваш компьютер сломался. Вы не можете отредактировать скетч, чтобы использовать второй вариант. Как можно выйти из положения?
Нужно поменять полярность цепи! Провод от резистора, который на землю, нужно воткнуть в 5V, а провод, который шёл из 5V к кнопке, перекинуть на землю. При включении ток пойдёт из питания на вывод 2 без всяких помех и будет получено значение HIGH. При нажатии кнопки получится другая цепь, и вывод 2 останется без питания.
02.Digital: StateChangeDetection
В примере File | Examples | 02.Digital | StateChangeDetection идёт подсчёт щелчков кнопки и состояние кнопки (включён или выключен). Схема осталась прежней. Кнопка соединяется с выводом 2, а светодиод с выводом 13 (можно использовать встроенный). К кнопке также следует подвести питание и стягивающий резистор к земле на 10K.
const int buttonPin = 2; // кнопка на выводе 2 const int ledPin = 13; // светодиод на выводе 13 int buttonPushCounter = 0; // счётчик нажатия кнопки int buttonState = 0; // текущее состояние кнопки int lastButtonState = 0; // предыдущее состояние кнопки void setup() < // устанавливаем режим ввода для кнопки pinMode(buttonPin, INPUT); // устанавливаем режим вывода для светодиода pinMode(ledPin, OUTPUT); // включаем последовательную передачу данных Serial.begin(9600); >void loop() < // считываем показания с вывода кнопки buttonState = digitalRead(buttonPin); // сравниваем состояние с предыдущим состоянием if (buttonState != lastButtonState) < // если состояние изменилось, увеличиваем счётчик if (buttonState == HIGH) < // если текущее состояние HIGH, значит кнопка включена buttonPushCounter++; Serial.println("on"); Serial.print("number of button pushes: "); Serial.println(buttonPushCounter); >else < // если текущее состояние LOW, значит кнопка выключена Serial.println("off"); >// небольшая задержка для устранения эффекта дребезга delay(50); > // сохраняем текущее состояние как последнее состояние для следующего раза lastButtonState = buttonState; // включаем светодиод при каждом четвёртом нажатии, проверяя деление по остатку счётчика нажатий if (buttonPushCounter % 4 == 0) < digitalWrite(ledPin, HIGH); >else < digitalWrite(ledPin, LOW); >>
02.Digital: Debounce (Дребезг)
У кнопок существует такой эффект, как «дребезг». При замыкании и размыкании между пластинами кнопки возникают микроискры, провоцирующие до десятка переключений за несколько миллисекунд. Явление называется дребезгом (англ. bounce). Это нужно учитывать, если необходимо фиксировать «клики». Поэтому первичным показаниям верить нельзя. По этой причине часто в скетчах делают небольшую задержку, а уже потом считывают показания. В обычном состоянии, когда мы не нажимаем кнопку или держим кнопку нажатой, эффекта дребезга не наблюдается. Иногда для этих целей в учебных примерах используют функцию delay(), но на практике следует использовать функцию millis(), как в примере File | Examples | 02.Digital | Debounce. Схема подключения остаётся без изменений.
const int buttonPin = 2; // кнопка на выводе 2 const int ledPin = 13; // светодиод на выводе 13 int ledState = HIGH; // текущее состояние светодиода int buttonState; // текущее состояние вывода для кнопки int lastButtonState = LOW; // предыдущее состояние вывода для кнопки // используем тип без знака, чтобы использовать большие числа unsigned long lastDebounceTime = 0; // последнее время unsigned long debounceDelay = 50; // задержка, увеличьте в случае необходимости void setup() < pinMode(buttonPin, INPUT); pinMode(ledPin, OUTPUT); digitalWrite(ledPin, ledState); >void loop() < // считываем состояние кнопки int reading = digitalRead(buttonPin); // если нажали кнопку, // то немного ожидаем, чтобы исключить дребезг // если состояние изменилось (дребезг или нажатие) if (reading != lastButtonState) < // сбрасываем таймер lastDebounceTime = millis(); >if ((millis() - lastDebounceTime) > debounceDelay) < // whatever the reading is at, it's been there for longer than the debounce // delay, so take it as the actual current state: // если состояние кнопки изменилось if (reading != buttonState) < buttonState = reading; // переключаем светодиод, если новое состояние кнопки стало HIGH if (buttonState == HIGH) < ledState = !ledState; >> > // устанавливаем светодиод digitalWrite(ledPin, ledState); // сохраняем состояние кнопки. В следующий раз в цикле это станет значением lastButtonState: lastButtonState = reading; >
02.Digital: DigitalInputPullup (Встроенный подтягивающий резистор)
У цифровых выводов уже есть резисторы на 20 кОм, которые можно использовать в качестве подтягивающих при работе с кнопками. Рассмотрим пример File | Examples | 02.Digital | DigitalInputPullup.
Схема подключения — соединим первый вывод кнопки с выводом 2 на плате, а второй вывод кнопки с выводом GND. Во время работы скетча будем считывать показания второго вывода.

void setup() < Serial.begin(9600); // настроим вывод 2 на режим ввода и включим встроенный подтягивающий резистор pinMode(2, INPUT_PULLUP); pinMode(13, OUTPUT); // светодиод >void loop() < // снимаем показания кнопки int sensorVal = digitalRead(2); // выводим в Serial Monitor Serial.println(sensorVal); // Помните, что при использовании подтягивающего к питанию резистора, состояние кнопки инвертировано // В не нажатом состоянии кнопка имеет значение HIGH, и LOW при нажатии. // При нажатии на кнопку включим светодиод, при отпускании - выключим if (sensorVal == HIGH) < digitalWrite(13, LOW); >else < digitalWrite(13, HIGH); >>
Если запустить скетч, то увидим, что на монитор выводятся числа 1 (HIGH). При нажатии на кнопку значения поменяются на 0 (LOW).
Python & Arduino. Просто, быстро и красиво
Очень часто, у начинающих и не только разработчиков возникают вопросы. Как управлять с Arduino с компьютера? А если компьютер — не Raspberry Pi, а обычный домашний компьютер? А если не хочется мучится с ESP8266 и управлять через веб интерфейс? Неужели надо каждый раз открывать Arduino IDE и отправлять команды через Монитор порта? Именно о том, как создать своё собственное приложение с графическим интерфейсом для управления Arduino я сейчас и расскажу.
Оборудование
Недавно я заполучил очень интересную плату: Arduino SS Micro. Эта плата, внешне напоминающая Digispark Attiny 85, тем не менее является китайской версией Arduino Micro, с выведенным выходом USB.

Подробно рассказывать о ней я не буду, ведь это уже сделал пользователь YouTube с ником iomoio, и его обзор можно посмотреть здесь.
Как мне кажется — это довольно крутое и удобное устройство для небольших домашних проектов, ведь у проводов есть супер-свойство: теряться в самый неподходящий момент.
В качестве управляющего компьютера был использован MacBook Pro с операционной системой macOS Mojave, но не надо закрывать статью, если вы используете Windows или Linux — всё описанное в статье будет работать без изменений на любой операционной системе.
Скетч для Arduino
В качестве примера будет использоваться скетч, включающий и выключающий светодиод, по команде из Serial-порта.
Светодиод в Arduino SS Micro висит на порте SS, и поэтому он автоматически выключается. Не смотря на это, стандартный пример Blink — мигающий светодиод работает.
char inChar; #define LED_PIN SS void setup() < pinMode(LED_PIN, OUTPUT); // Инициализация светодиода Serial.begin(115200); // Инициализация Serial - порта >void loop() < if (Serial.available() >0) < inChar = Serial.read(); if (inChar=='e') // e - Enable - включить < digitalWrite(LED_PIN,HIGH); >> else if (inChar=='d') // d - Disable - выключить < digitalWrite(LED_PIN,LOW); >else if (inChar=='b') // b - Blink - выключить режим мигания < while (true)< digitalWrite(LED_PIN,HIGH); delay(1000); digitalWrite(LED_PIN,LOW); delay(1000); >> >
Если вы будете использовать другую Arduino — не забудьте сменить пин светодиода.
Код для компьютера
Одним из достоинств Python, кроме его кроссплатформенности — наличие гигантского числа библиотек. Нам понадобятся:
- PySerial — библиотека для работы с Serial-портом
- PyQT5 — библиотека для создания графического интерфейса
Установка
Для установки, воспользуемся встроенным менеджером пакетов — pip.
pip install pyserial pyqt5
Для удобства создания GUI можно установить программу QTDesigner.
Интерфейс
Поскольку данная программа предназначена скорее, для демонстрации возможностей, пользователь может выбрать порт из предложенных, а так же скорость, с которой будет происходить общение.

Исходный код
Вся работа с устройством происходит благодаря библиотеке PySerial. Но есть несколько нюансов. Например, как узнать, в какой из портов подключено устройство?
На всем прекрасно известном сайте stackoverflow, пользователь с ником Thomas предложил уже готовое решение, которое я и использовал.
def serial_ports(): """ Lists serial port names :raises EnvironmentError: On unsupported or unknown platforms :returns: A list of the serial ports available on the system """ if sys.platform.startswith('win'): ports = ['COM%s' % (i + 1) for i in range(256)] elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'): # this excludes your current terminal "/dev/tty" ports = glob.glob('/dev/tty[A-Za-z]*') elif sys.platform.startswith('darwin'): ports = glob.glob('/dev/tty.*') else: raise EnvironmentError('Unsupported platform') result = [] for port in ports: try: s = serial.Serial(port) s.close() result.append(port) except (OSError, serial.SerialException): pass return result
Кроме этого необходимо хранить список доступных скоростей:
speeds = ['1200','2400', '4800', '9600', '19200', '38400', '57600', '115200']
А теперь соберём вместе дизайн(созданный в QtDesigner и сконвертированный с помощью утилиты pyuic5 в .py файл), функции для сканирования портов и основной код программы.
Основной класс, содержащий в себе всю логику программы
class LedApp(QtWidgets.QMainWindow, design.Ui_Form): def __init__(self): super().__init__() self.setupUi(self) self.Port.addItems(serial_ports()) self.Speed.addItems(speeds) self.realport = None self.ConnectButton.clicked.connect(self.connect) self.EnableBtn.clicked.connect(self.send) def connect(self): try: self.realport = serial.Serial(self.Port.currentText(),int(self.Speed.currentText())) self.ConnectButton.setStyleSheet("background-color: green") self.ConnectButton.setText('Подключено') except Exception as e: print(e) def send(self): if self.realport: self.realport.write(b'b')
Переменные self.Port и self.Speed — это выпадающие списки, содержащие в себе значения доступных портов и скоростей.
При нажатии на кнопку self.ConnectButton вызывается функция connect, в которой производится попытка подключения к заданному порту с заданной скоростью. Если подключение успешно, то кнопка окрашивается в зелёный цвет, и меняется надпись.

Функция send отправляет в наш порт байтовую строку — заставляющую включить режим мигания.
Таким образом можно управлять различными устройствами, подключёнными к USB.
Данная статья является вводной и обзорной, более полную информацию можно найти например тут:
- PySerial
- PyQT
- Serial в Arduino
Arduino для начинающих. Урок 8. Подключение датчика движения (PIR). Отправка E-mail


Продолжаем серию уроков “Arduino для начинающих”. Сегодня мы разберем проект подключение PIR-датчика (движения) к Arduino и организуем автоматическую отправку e-mail при срабатывании датчика. Arduino является сердцем этого проекта — считывает показания ИК-датчика, и при обнаружении движения отдает компьютеру через порт USB команду отправить письмо. Обработку сигнала, поступающего на компьютер реализуем с помощью программы Python.
Список деталей для сборки модели
Для сборки проекта, описанного в этом уроке, понадобятся следующие детали:
- Arduino UNO или аналог (подробнее, о том как выбрать Arduino здесь);
- PIR-датчик (подойдет такой за $ 2);
- бредбоард (можно купить за $2,4);
- провода папа-папа (можно купить такую связку с большим запасом).




Также потребуется компьютер с подключением к Интернету, через него будем отправлять электронную почту! Роль компьютера в этом уроке может выполнять Raspberry Pi.
Схема подключения PIR-датчика к Arduino
К Arduino в этом проекте требуется подключить только PIR-датчик, поэтому провода от датчика можно подключить непосредственно к Arduino. Но т.к. в таком случае провода держаться немного не плотно удобнее использовать схему c бредбоард:

Схема подключения PIR-датчика к бредбоард
Arduino скетч
Arduino будет послать сообщение по USB Serial связи при обнаружении движения. Но если посылать e-mail при каждом срабатывании датчика, то можно получить огромное количество писем. Поэтому если прошло еще слишком мало времени от прошлого сигнала — будем посылать другое сообщение.
int pirPin = 7;
int minSecsBetweenEmails = 60; // 1 min
long lastSend = -minSecsBetweenEmails * 1000;
void setup()
pinMode(pirPin, INPUT);
Serial.begin(9600);
>
void loop()
long now = millis();
if (digitalRead(pirPin) == HIGH)
if (now > (lastSend + minSecsBetweenEmails * 1000))
Serial.println(«MOVEMENT»); lastSend = now;
>
else
Serial.println(«Too soon»); >
>
delay(500);
>
Переменная «minSecsBetweenEmails» может быть изменена на другое разумное значение. В примере она установлена на 60 секунд, и письма не будут отправлены чаще одной минуты. Чтобы отслеживать, когда последний раз была отдана команда слать e-mail используется переменная «lastSend». Ее инициализируем отрицательным числом, равным числу миллисекунд, указанных в переменной «minSecsBetweenEmails». Это гарантирует нам обработку срабатывания PIR-датчика сразу как только скетч Arduino запущен. В цикле используется функция Millis () чтобы получить число миллисекунд с Arduino и сравнить со временем от прошлого срабатывания датчика и соответствующей отправке сообщения «MOVEMENT» (движение). Если сравнение показывает, что прошло слишком мало времени от прошлого срабатывания датчика, то несмотря на то, что движение было обнаружено, посылаем сообщение «Too soon» (Слишком рано). Перед тем как писать программу на Python для обработки сигнала, поступающего с Arduino на компьютер или Raspberry Pi по USB, можно проверить работу программы на Arduino, просто открыв Serial Monitor на Arduino IDE.

Serial Monitor Arduino IDE
Установка Python и PySerial
Если в проекте используется компьютер с операционной системой Linux, например, Raspberry Pi, Python уже установлен. Если используется компьтер с операционной системой Windows, то Python требуется установить. В любом случае, потребуется установить библиотеку PySerial чтобы обеспечить связь с Arduino.
Установка Python на Windows

Чтобы установить Python на Windows, скачайте установщик с https://www.python.org/downloads/. Были сообщения о проблемах с PySerial на Windows при использовании Python 3, поэтому используем Python 2. После установки Python, в меню Пуск появится соответствующая группа. Но для установки PySerial нужно будет использовать Python из командной строки, поэтому добавим к переменной PATH среды Windows соответствующий каталог. Чтобы сделать это, нужно зайти в Панель управления Windows, найти System Properties (Свойства системы). Затем нажать на кнопку с надписью Environment Variabes («Переменные среды») и в появившемся окне выбрать «Path» в нижней части System variables (Системные переменные). Нажать кнопку Edit («Изменить»), а затем в конце «Значение переменной», не удаляя имеющийся текст, добавить «; C: \ Python27». Не забывать «;» после каждой указанной папки. Чтобы проверить, что переменную PATH изменили корректно, в командной строке введем команду «“python». Должна появляться подобная картина:
Установка PySerial
Независимо от используемой операционной системы, скачиваем .tar.gz установочный пакет для PySerial 2.6 с https://pypi.python.org/pypi/pyserial Получаем файл с именем pyserial-2.6.tar.gz При использовании Windows нужно распаковать файл в папку. К сожалению, это не обычный файл ZIP, так что, возможно, потребуется скачать, например, 7-zip (http://www.7-zip.org/). При использовании компьютера с операционной системой Linux, например, при использовании в этом проекте Raspberry Pi, нужно открыть терминальную сессию, выполнить команду «CD» с указанием папки куда скачана pyserial-2.6.tar.gz, а затем выполнить следующую команду, чтобы распаковать установщик:
$ tar -xzf pyserial-2.6.tar.gz
Далее независимо от используемой операционной системы в командной строке выполняем команду “CD” c указанием папки pyserial-2.6 и выполняем команду:
sudo python setup.py install
Код на Python

Теперь создаем программу на Python. Для этого копируем данный код в файл с именем «movement.py». На Linux можно использовать «нано» редактор, на Windows, вероятно, самый простой способ сделать файл с помощью редактора Python ‘IDLE » (доступен из группы программ Python в меню Пуск).
import time
import serial
import smtplib
TO = ‘putyour@email.here’
GMAIL_USER = ‘putyour@email.here’
GMAIL_PASS = ‘putyourpasswordhere’
SUBJECT = ‘Intrusion!!’
TEXT = ‘Your PIR sensor detected movement’
ser = serial.Serial(‘COM4’, 9600)
def send_email():
print(«Sending Email»)
smtpserver = smtplib.SMTP(«smtp.gmail.com»,587)
smtpserver.ehlo() smtpserver.starttls()
smtpserver.ehlo smtpserver.login(GMAIL_USER, GMAIL_PASS)
header = ‘To:’ + TO + ‘\n’ + ‘From: ‘ + GMAIL_USER
header = header + ‘\n’ + ‘Subject:’ + SUBJECT + ‘\n’
print header
msg = header + ‘\n’ + TEXT + ‘ \n\n’
smtpserver.sendmail(GMAIL_USER, TO, msg)
smtpserver.close()
while True:
message = ser.readline()
print(message)
if message[0] == ‘M’ :
send_email()
time.sleep(0.5)
Перед тем как запустить программу Python вносим некоторые изменения (все они в верхней части программы). Программа предполагает, что электронные письма создаются из аккаунта Gmail. Если его нет регистрируем (даже если это только для этого проекта). Изменяем значение переменной «TO» на адрес электронной почты, куда будут отправляться уведомления. Изменяем значение «GMAIL_USER» на адрес электронной почты Gmail и соответственно пароль в следующей строке (GMAIL_PASS). Также можно изменить тему и текст сообщения для отправки («SUBJECT» и «TEXT»). Необходимо установить последовательный порт, к которому подключена Arduino в строке ser = serial.Serial(‘COM4’, 9600) Для Windows, это будет что-то навроде «COM4» для Linux — что-то навроде «/dev/tty.usbmodem621». К какому порту компьютера подключена плата смотрим в Arduino IDE в правом нижнем углу. После этих изменений, запускаем программу из командной строки / терминала: python movement.py Готово! Когда PIR-датчик срабатывает вскоре приходит сообщение на указанный e-mail.
Что еще можно сделать с использованием PIR-датчика
Теперь, освоив средства отправки электронной почты с Arduino, можно приступить к расширению возможностей проекта. Можно добавить другие датчики, и, например, отправлять себе по электронной почте почасовые отчеты о температуре. Безусловно, PIR-датчик быть использован непосредственно с Arduino без соединения с компьютером. В этом случае при срабатывании датчика можно включать предупреждающий звуковой сигнал, мигать светодиодом, или включать освещение в помещении (через высоковольтное реле).
Смотрите также:
Посты по урокам:
- Первый урок: Светодиод
- Второй урок: Кнопка
- Третий урок: Потенциометр
- Четвертый урок: Сервопривод
- Пятый урок: Трехцветный светодиод
- Шестой урок: Пьезоэлемент
- Седьмой урок: Фоторезистор
- Восьмой урок: Датчика движения (PIR) и E-mail
- Девятый урок: Подключение датчика температуры и влажности DHT11 или DHT22
Все посты сайта “Занимательная робототехника” по тегу Arduino .
Наш YouTube канал , где публикуются видео-уроки.
Не знаете, где купить Arduino ? Все используемые в уроке комплектующие входят в большинство готовых комплектов Arduino, их также можно приобрести по отдельности. Подробная инструкция по выбору здесь . Низкие цены, спецпредложения и бесплатная доставка на сайтах AliExpress и DealExtreme . Если нет времени ждать посылку из Китая — рекомендуем интернет-магазины Амперка и DESSY . Низкие цены и быструю доставку предлагает интернет-магазин ROBstore.
Автор Александр Гагарин. В статье использованы материалы learn.adafruit.com.
Arduino, DigiSpark, ATTiny85, IR, пульт ДУ
От какой-то фоторамки у меня остался пульт и ИК приёмник. Они долго лежали у меня «на всякий случай» и такой случай настал. У меня нет телевизора и его роль выполняет старый ноутбук, на котором я смотрю ютуб. Я решил, что стоит сделать удалённое управление с пульта ноутбуком, для удобного просмотра https://youtube.com/tv не вставая с кресла.
Сразу отмечу, что всё, что описано ниже, это результат моих опытов и моих выводов. Всё может работать совершенно не так, а я идиот. У меня была цель сделать, чтобы заработало конкретно у меня, так что вот.
В качестве микроконтроллера я использую DigiSpark, она же ATTiny85 с USB в комплекте. Он может эмулировать клавиатуру, что мне как раз понадобится. Гребёнки на плате уже были припаяны, так что я просто соединил проводами приёмник и плату. Думаю, что по фото понятна распиновка приёмника и как он подключен к плате.
Существуют готовые библиотеки для работы с ИК приёмником. В ATTiny всего 6кб под программу (2кб загрузчик), так что не все они подойдут. Я же решил написать свой велосипед под свой конкретный случай. Разумеется, я подсматривал в готовые библиотеки, чтобы понять общий принцип работы. Просто было интересно разобраться в работе ИК пультов.
Если в двух словах, то принцип работы следующий. Когда вы нажимаете кнопку на пульте, ИК передатчик включается на длинный период и гаснет. Это означает начало передачи. Затем вспышками разной длинны времени передаются данные. Короткая вспышка (500-600) кодирует ноль, а длинная (1600-1700) кодирует единицу. В других пультах и приёмниках возможно всё иначе. Все эти данные были получены экспериментально.
Сначала я проводил эксперименты на Arduino UNO и написал простой код:
int irPin = 2; void setup() < Serial.begin(9600); while (!Serial) <>pinMode(irPin, INPUT); Serial.println(F("Program started!")); > void loop() < int s = pulseIn(irPin, HIGH); if(s) < Serial.println(s); >>
Функция pulseIn(pin, value) считает длину сигнала на заданном пине в микросекундах. В данном случае, она считает сколько времени на пине, к которому был подключен ИК приёмник, держится высокий уровень. Если сигнал так и не пришёл, то возвращается 0. С помощью этого нехитрого скетча, мне удалось выяснить длительность стартового сигнала и количество передаваемых бит.
Далее, нужно было принять всю посылку и преобразовать её в число. Я делал это в цикле. Оказалось, что первые биты во всех посылках одинаковые и их можно не трогать. В моём случае, принимались 20 бит, но переводились в код только последние 8 (с 12, по 20).
void loop() < int i, data[20]; int s = pulseIn(irPin, HIGH); if(s >4000) < for(i = 0; i < 20; i++) data[i] = pulseIn(irPin, HIGH); int result = 0; for(i = 12; i < 20; i++) if(data[i] >1000) result |= (1 >
Код должен быть понятен. Получаем длительность сигнала. Если она больше заданного значения (в данном случае 4000), значит за этим сигналом будут следовать данные. В цикле записываем длительности сигналов в массив. Затем берём последние 8 элементов из массива и переводим их в целое число по правилам описанным выше. На этом, мы разобрались, как работать с пультом и приёмником.
Теперь, при нажатии на соответствующую кнопку на пульте и принятии её приёмником, мы должны передавать это нажатие на компьютер, эмулируя нажатие кнопок на клавиатуре. Для этого есть файл DigiKeyboard.h. К сожалению, в нём почему-то отсутствуют коды всех стрелочек, кроме левой. Пришлось гуглить и вставлять недостающие коды. Весь окончательный скетч есть на GitHub.
После загрузки кода, подключаем DigiSpark к компьютеру по USB и видим, что нажатые кнопки на пульте транслируются в нажатия кнопок клавиатуры.
