Я рассчитываю, что Вы уже разобрались с подключением своей платы к локальной сети и умеете загружать на нее скечи. Также надеюсь, что с подключением сервопривода к обычной Arduino уже знакомы. Поэтому сразу к делу.
Нам понадобятся:
1) Arduino Yun или Arduino (Uno, Nano или 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.