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-порта.

    WARNING

    Светодиод в 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.

    Данная статья является вводной и обзорной, более полную информацию можно найти например тут:


    Полный исходный код, как скетча для Arduino, так и программы размещён на GitHub.

    Only registered users can participate in poll. Log in, please.

    Была бы интересна более подробная статья про управление RGB-светодиодами?

    • +20
    • 14.3k
    • 6
    Share post

    Similar posts

    Comments 6

      0

      https://github.com/firmata/arduino
      Я почему-то ожидал увидеть это


      Работающее с этим:
      https://pypi.org/project/pyFirmata/

      –1
      При наличии в зависимостях PyQt монстра, ожидаешь увидеть более внушительный интерфейс, а не два комбобокса с вырвиглазной статус-кнопкой.
      Например, как узнать, в какой из портов подключено устройство?

      Ага, не плохо бы знать что это именно ардуина, а какое либо другое устройство какой-нить usbtouart, но в целом да… не нужно.
      Заголовок спойлера
      статьи которые мы заслужили(
        0
        Обязательно добавлю в следующей статье
        0
        весит на порте SS…
          0
          Исправил, спасибо

        Only users with full accounts can post comments. Log in, please.