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

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

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

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

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

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

2) любой серводвигатель для Arduino (у меня Tower Pro 9g SG90)

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

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

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

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

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

Далее вставляем Yun Schield  в Arduino и подключаем серводвигатель: черный (коричневый) провод - GND, средний (обычно красного цвета) - 5V и самый светлый - pin 2.

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

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

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

//объявляем переменную servo типа Servo
Servo servo;

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

void setup() {
  //запуск моста
  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('/');

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

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

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

  //если за pin следует '/'
  if (client.read() == '/') {
    //считываем значение и выполняем команду
    value = client.parseInt();
    servo.attach(pin);
    servo.write(value);

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

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

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

1) Поворот вала серводвигателя на заранее выставленные значения углов с помощью кнопок Button

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

class Example(Frame):

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

    def initUI(self):
        #создание корневого окна; виджет Frame занимает все клиентское пространство корневого окна
        self.master.title("Servo Motor")
        self.pack(fill=BOTH, expand=True)
        #стиль текста font = (DejavuSansLight, Arial, TimesNewRoman, ComicSans, FreeSerif, LatoThin)
        #по нажатию кнопки вызов функции b30
        Button30 = Button(self, text="30", font="Arial", command=self.b30)
        #содание сетки; координаты кнопки в сетке (0, 0); padx (pady) - отступы по оси х (у)
        Button30.grid(row=0, column=0, padx=5, pady=5)
        #по нажатию кнопки вызов функции b60
        Button60 = Button(self, text="60", font="Arial", command=self.b60)
        #координаты кнопки в сетке (1, 0)
        Button60.grid(row=1, column=0, padx=5, pady=5)
        #по нажатию кнопки вызов функции b90
        Button90 = Button(self, text="90", font="Arial", command=self.b90)
        #координаты кнопки в сетке (2, 0)
        Button90.grid(row=2, column=0, padx=5, pady=5)

    def b30(self):
        #посылаем запрос
        requests.get('http://192.168.1.85/arduino/servo/2/30')

    def b60(self):
        requests.get('http://192.168.1.85/arduino/servo/2/60')

    def b90(self):
        requests.get('http://192.168.1.85/arduino/servo/2/90')

def main():
    root = Tk()
    ex = Example()
    root.geometry("50x150+300+300")
    root.mainloop()

if __name__ == '__main__':
    main()

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

2) Поворот вала серводвигателя посредством перетаскивания ползунка Scale

import requests
from tkinter import Tk, BOTH, IntVar, LEFT
from tkinter.ttk import Frame, Label, Scale, Style

class Example(Frame):

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

    def initUI(self):
        self.master.title("Servo Motor")
        self.style = Style()
        #доступные стили: alt, classic, clam, default
        self.style.theme_use("classic")

        self.pack(fill=BOTH, expand=1)

        #при движении ползунка вызывается метод onScale()
        scale = Scale(self, from_=0, to=180, command=self.onScale)
        scale.pack(side=LEFT, padx=15)

        self.var = IntVar()
        self.label = Label(self, text=0, textvariable=self.var)
        self.label.pack(side=LEFT)

    def onScale(self, val):
        v = int(float(val))
        #посылаем запрос
        requests.get('http://192.168.1.85/arduino/servo/2/' + str(v))
        self.var.set(v)

def main():
    root = Tk()
    ex = Example()
    root.geometry("250x100+300+300")
    root.mainloop()

if __name__ == '__main__':
    main()

Управление ползунком является несколько заторможенным. Удобство пользования будет зависеть от скорости Вашей сети.

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

Скетч, зашитый в ардуино, отправляет на 2 пин сигнал поворота на угол 30 градусов по запросу http://192.168.1.85/arduino/servo/2/30. Если, допустим, Вы хотите отправить сигнал поворота на 45 градусов на 3 пин - следует ввести адрес http://192.168.1.85/arduino/servo/3/45. Естественно, цифры 192.168.1.85 в запросе -  IP-адрес моей платы (его следует заменить на IP-адрес Вашей платы).

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