Arduino Yun + Python: Мигание светодиодом (http-запрос)
×

Arduino Yun + Python: Мигание светодиодом (http-запрос)

Смотреть видео в Дзен

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

Нам понадобятся:

1) Arduino Yun или Arduino (UnoNano или Mega) + Yun Shield (у меня в наличии бутерброд из Arduino Uno и Yun Shield).

Для программирования:

1) Среда разработки Python (у меня PyCharm);

2) Среда разработки Arduino IDE.

Цель - управление светодиодом посредством нажатия кнопок On / Off. Дополнительный светодиод как на картинке вовсе не обязателен, т. к. от пина 13 также питается светодиод, встроенный в плату Arduino.

Далее, введем свой IP (у меня 192.168.1.85) в адресную строку и зайдем в настройки платы Arduino Yun в раздел SYSTEM и откроем к ней доступ (см. рис. ниже). После выбора OPEN жмем CONFIGURE & RESTART.

Подготовка закончена!

Посредством программы Arduino IDE загружаем скетч по Wi-Fi:

#include <Bridge.h>
#include <BridgeServer.h>
#include <BridgeClient.h> 

//подключение, веб-сервер Yun перенаправляет http-запросы в порт 5555
BridgeServer server;

void setup() {
  //pin 13 (встроенный светодиод на Ардуино) инициализируем в качестве выхода
  int pin = 13;
  pinMode(pin, OUTPUT);
  digitalWrite(pin, LOW); //убираем напряжение с 13 пина (гасим светодиод)
  
  //запуск моста
  Bridge.begin();

  //принимаем сигналы по локальной сети (из внешней доступ закрыт)
  server.listenOnLocalhost();
  server.begin();
}

void loop() {
  //принимаем клиентов с сервера
  BridgeClient client = server.accept();
  
  //если есть новый клиент
  if (client) {
    process(client); //обрабатываем запрос
    client.stop();   //закрываем соединение и освобождаем ресурсы
  }
  
  delay(50); //обновление каждые 50 мс
}

void process(BridgeClient client) {
  //чтение команды
  String command = client.readStringUntil('/');

  //если команда "digital" - вызываем функцию digitalCommand
  if (command == "digital") {
    digitalCommand(client);
  }
}

void digitalCommand(BridgeClient client) {
  int pin, value;

  //считываем pin из адресной строки
  pin = client.parseInt();

  //если за pin следует '/'
  if (client.read() == '/') {
    //подаем на пин сигнал (0 - LOW, 1 - HIGH)
    value = client.parseInt();
    digitalWrite(pin, value);
  }

  //отправляем уведомление на страницу запроса
  client.print(F("Pin D"));
  client.print(pin);
  client.print(F(" set to "));
  client.println(value);

  //запись (обновление) информации (ключ/значение) в процессор Linux
  String key = "D";
  key += pin;
  Bridge.put(key, String(value));
}

Для python предлагаю два кода:

1) Управление горением светодиода с помощью конопок "On" и "Off" посредством библиотеки Tkinter

import requests
from tkinter import Tk, BOTH, Frame, Button
import time

class Example(Frame):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        #создание корневого окна; виджет Frame занимает все клиентское пространство корневого окна
        self.master.title("Мигание светодиодом")
        self.pack(fill=BOTH, expand=True)
        #стиль текста font = (DejavuSansLight, Arial, TimesNewRoman, ComicSans, FreeSerif, LatoThin)
        #по нажатию кнопки вызов функции led_on
        onButton = Button(self, text="On", font="Arial", command=self.led_on)
        #содание сетки; координаты кнопки в сетке (0, 0); padx (pady) - отступы по оси х (у)
        onButton.grid(row=0, column=0, padx=5, pady=5)
        #по нажатию кнопки вызов функции led_off
        offButton = Button(self, text="Off", font="Arial", command=self.led_off)
        #координаты кнопки в сетке (0, 1)
        offButton.grid(row=0, column=1, padx=5, pady=5)

    def led_on(self):
        #отправляем запрос
        requests.get('http://192.168.1.85/arduino/digital/13/1')
        #ждем 1 секунду для стабильности
        time.sleep(1)

    def led_off(self):
        requests.get('http://192.168.1.85/arduino/digital/13/0')
        time.sleep(1)

def main():
    root = Tk()
    root.geometry("300x200+300+300")
    app = Example()
    root.mainloop()

if __name__ == '__main__':
    main()

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

2) Управление горением светодиода с помощью одной кнопки-переключателя

import requests
from tkinter import Tk, BOTH, Frame, Button
import time

class Example(Frame):

    def __init__(self):
        super().__init__()
        #создаем переменную flash логического типа
        self.flash = False
        self.initUI()

    def initUI(self):
        self.master.title("Мигание светодиодом")
        self.pack(fill=BOTH, expand=True)
        ledButton = Button(self, text="Led", command=self.led)
        ledButton.pack(pady = 30)

    def led(self):
        if self.flash == False:
            requests.get('http://192.168.1.85/arduino/digital/13/1')
        else:
            requests.get('http://192.168.1.85/arduino/digital/13/0')
        self.flash = not self.flash
        time.sleep(1)

def main():
    root = Tk()
    root.geometry("300x200+300+300")
    app = Example()
    root.mainloop()

if __name__ == '__main__':
    main()

Как это работает?

Скетч, зашитый в ардуино, включает светодиод по запросу http://192.168.1.85/arduino/digital/13/1 и выключает по запросу http://192.168.1.85/arduino/digital/13/0 (убедитесь сами). Естественно, цифры 192.168.1.85 в запросе -  IP-адрес моей платы (его следует заменить на IP-адрес Вашей платы).

Код на python создает графическое окно, при нажатии кнопок которого функция get библиотеки requests отправляет http-запрос в локальную сеть, который ловит Arduino.

Как зажечь светодиод на другом пине?

В скетче следует заменить pin = 13 (например на pin = 7):

//pin 7 инициализируем в качестве выхода
  int pin = 7;
  pinMode(pin, OUTPUT);
  digitalWrite(pin, LOW); //убираем напряжение с 7 пина (гасим светодиод)

А в коде python заменим число 13 на цифру 7:

def led_on(self):
        #отправляем запрос
        requests.get('http://192.168.1.85/arduino/digital/7/1')
        #ждем 1 секунду для стабильности
        time.sleep(1)

    def led_off(self):
        requests.get('http://192.168.1.85/arduino/digital/7/0')
        time.sleep(1)

Подключаем светодиод и наслаждаемся проделанной работой!