Qt и однослойная катушка индуктивности

Выполняя последний заказ — модернизация усилителя мощности — я столкнулся с необходимостью рассчитать и изготовить катушку индуктивности.

Ничего необычного в этой катушке нет. Обычная катушка, без сердечника, установлена на выходе усилителя. Индуктивность катушки — 5 мкГн. Собственно, задача уже выполнена. Всё посчитано, изготовлено, смонтировано. испытано. Всё работает отлично, вопросов нет.

Но вот, поскольку в настоящее время я человек безработный, то меня увлёк процесс создания программы для расчета катушки индуктивности. И я решил поделиться этими умениями с теми, кто читает мои записи.

По большому счёту ни в методике расчёта, ни в написании программы нет никакого ноу-хау. Всё давным давно известно. Поэтому тем людям, кто умеет и то, и другое, — им читать эту статью будет не интересно. А остальных я приглашаю под кат.

Давным-давно еще в начале 80-х я купил вот такую книженцию:

img_1298

Цена вопроса — 95 копеек. Это примерно 5 булок хлеба. В переводе на современные деньги это примерно 150 рублей. Да-да, всего каких-то 150 рублей за 215 страниц технического текста! Сравните с нынешними ценами на аналогичные книги по программированию и микроконтроллерам. Разительно, да? Но самое поразительное — тираж книжки! Ни много ни мало —150 тысяч экземпляров!

— Сто пятьдесят тысяч, Карл! Сто пятьдесят! Тысяч!!! (с)

Неплохая книжка. Написан простым понятным языком. Для людей, приступающим к изучению электроники, — самое то!

Нам же эта книжка понадобится чисто для получения изображения катушки индуктивности, которое мы встроим в нашу программу.

Итак, чтобы создать катушку индуктивности номиналом 5 мкГн для усилителя, нам нужно рассчитать её параметры. Поскольку катушка обладает не очень большой индуктивностью, то она будет выполнена как однослойная катушка. А это значит, что нам нужно найти её диаметр, длину намотки и количество витков.

Собственно, вот, формула для расчета:

img_1299Здесь

L — индуктивность катушки, мкГн,
D — диаметр намотки, см,
l  — длина намотки, см,
w — количество витков.

А вот изображение, которое нам понадобится для нашей супер-пупер программы:

img_1300

Как понимаете, весь расчет сводится к одной строке. Но я же не просто программист-электронщик. Я — безработный программист-электронщик! Поэтому акценты в «триумвирате» быстро-качественно-недорого будут смещены в сторону — долго-бесплатно. И да! Чуть не забыл! Прогу будем писать на Питоне. (Не, ну а на чём ещё!? 30 лет назад такие проги писали на BASIC-е. Сейчас вместо Васика в тренде Питон. А нам-то, быкам, какая разница?)

Итак. Открываем консольное окно, создаем директорий для разработки нашей программы, заходим в него и там вводим команду:

$ mkpy inductance

Эта команда (mkpy) была описана в блоге где-то ранее. Если у вас её нет, то найдите и установите её к себе в систему.

Отлично! После этих действий в директории появится файл inductance.py вот с таким содержимым:

#!/usr/bin/env python
#coding:utf-8

''' inductance.py'''

Теперь открывает текстовый редактор и добавляем в программу немного кода:

#!/usr/bin/env python
#coding:utf-8

''' inductance.py
  Расчет индуктивности у катушки
'''

 
def L(D, l, w):
  '''
  Расчет многослойной катушки индуктивности
  L  - индуктивность катушки, мкГн
  D  - диаметр намотки, см
  l  - длина намотки, см
  w  - количество витков
  '''
  return (0.01 * D * w * w) / ((l / D) + 0.44)


###########################################################################
if __name__ == "__main__":
  D = 2.0
  l = 4.0
  w = 50  
  print L(D, l, w)  # Должно получиться 20.5 мкГн

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

Относительно этого варианта программы, вам нужно подобрать параметры D, l и w, так чтобы в результате получилась индуктивность 5 мкГн. Мне это удалось сделать примерно за пять итераций, и я потратил на эти итерации не более двух минут. То есть применение Питона для таких вот расчётов получается весьма эффективным.

Но давайте пойдём дальше! Жизнь идёт не останавливаясь ни на минуту. Можно сидеть сложа руки, а можно что-то творить. Жизнь всё равно проходит. Но если никак не получается монетизировать свое время, тогда лучше тратить время на получение новые навыков и знаний.

На этот раз я предлагаю написать графическую версию проги. Эта еще не окончательная версия проги. Это, скорее, что-то типа пилотной или пробной версии. Нам сейчас важно понять — есть хоть какой-то смысл в графическом варианте или нет.

Итак, я ориентируюсь на использование графической системы Qt. Снова создаём директорий для проекта и точно так же, как в первом варианте, снова создаем шаблон (заготовку) для программы. Но на этот раз давайте в прогу добавим такой код:

#!/usr/bin/env python
#coding:utf-8

''' inductance.py '''

from PyQt4.QtGui import  QApplication, QWidget, QLabel, QLineEdit


################################################################################
class InductorOne(QWidget):
  def __init__(self, parent=None):
    QWidget.__init__(self)
 
    self.leDiameter = QLineEdit(self)
    self.leDiameter.setGeometry(10, 20, 100, 24)
    self.leDiameter.textChanged.connect(self.onDiameter)

    self.leLength = QLineEdit(self)
    self.leLength.setGeometry(10, 60, 100, 24)
    self.leLength.textChanged.connect(self.onLength)

    self.leWind = QLineEdit(self)
    self.leWind.setGeometry(10, 100, 100, 24)
    self.leWind.textChanged.connect(self.onWind)

    self.lblL = QLabel(u"L = _______ мкГн", self)
    self.lblL.setGeometry(10, 140, 100, 16)

    self.resize(200, 200)
    
    
  def onDiameter(self, text):
    self.D = float(self.leDiameter.text())
    self.getInductance()

  def onLength(self, text):
    self.l = float(self.leLength.text())
    self.getInductance()

  def onWind(self, text):
    self.w = int(self.leWind.text())
    self.getInductance()

  def getInductance(self):
    try:
      L = (0.01 * self.D * self.w * self.w) / ((self.l / self.D) + 0.44)
      self.lblL.setText(u"<b>L = %6.2f мкГн</b>" % L)
    except e:
      pass

################################################################################
if __name__ == "__main__":
  import sys
  app = QApplication(sys.argv)
  
  wnd = InductorOne()
  wnd.show()
   
  sys.exit(app.exec_())

Прога выглядит ужасно неприлично:

onelaycoil-2

Не нужно обращать внимание на запредельный аскетизм проги, с ней нужно просто немного «поиграться». Попробуйте вводить в поля разные значения, попробуйте оценить на сколько это удобно или не удобно. Переход между полями удобнее осуществлять с помощью нажатия на клавишу Tab, а не с помощью мышкотыкания. Попробуйте! И вы поймёте прелесть этого метода.

Я сознательно не сделал наименования полей. Сейчас это не особо нужно. По тексту программы видно, что самое верхнее поле отвечает за диаметр намотки. Потом идет длина намотки. И последнее поле — это количество витков. Мы это знаем, и сейчас нам этого вполне достаточно.

Я провёл несколько минут, «играясь» с этим вариантом проги. Мне показалось, что — да, это удобно. Значит, нужно продолжать работу над прогой — приводить её в презентабельный вид.

Таким образом, мы незаметно подобрались с следующей версии проги. Что я сейчас намереваюсь сделать? Я планирую (и я об этом писал в самом начале статьи) взять изображение катушки и сверху на него программно положить виждеты.

Вот исходное фото из книги:

img_1300

С помощью Gimp я обрезал лишние вокруг изображения катушки.

l1

В местах, где указаны размеры D и l, мы разместим виждеты, которые будут отвечать за диаметр и длину намотки. Виджет для указания количества витков, я думаю, поместить в центр катушки. А для того, чтобы было понятно, что это витки, над виджетом помещу соответствующую надпись. Но тут есть небольшая неприятность.

Дело в том, что если помещать надпись на изображении, то она потеряется. Поэтому, с помощью того же Gimp-а я «расчистил» место для неё. Я тупо вырезал прямоугольную область над катушкой и скопировал её чуть выше центра катушки. Вот, что у меня получилось:

l2

Это изображение будет служить фоном для окна нашей программы.

Теперь текст нашей программы стал существенно сложнее:

#!/usr/bin/env python
#coding:utf-8

''' inductance.py '''

from PyQt4.QtGui import  QApplication, QPalette, QBrush, QPixmap, \
                         QWidget, QLabel, QLineEdit
# from PyQt4.QtCore import


################################################################################
class InductorOne(QWidget):
  def __init__(self, parent=None):
    QWidget.__init__(self)
    
    self.pal = QPalette(self);
    self.pal.setBrush(self.backgroundRole(), QBrush(QPixmap("L2.png")))
    self.setPalette(self.pal)
    
    self.setWindowTitle(u"Однослойная катушка индуктивности")
    self.resize(pixmap.size())
    
    self.leDiameter = QLineEdit(self)
    self.leDiameter.setGeometry(5, 135, 40, 24)
    self.leDiameter.textChanged.connect(self.onDiameter)
    self.lblDsm = QLabel(u"см", self)
    self.lblDsm.setGeometry(15, 157, 20, 16)

    self.leLength = QLineEdit(self)
    self.leLength.setGeometry(160, 238, 40, 24)
    self.leLength.textChanged.connect(self.onLength)
    self.lbllsm = QLabel(u"см", self)
    self.lbllsm.setGeometry(202, 243, 20, 16)

    self.lblWind = QLabel(u"<b>Витков</b>", self)
    self.lblWind.setGeometry(155, 125, 50, 16)
    self.leWind = QLineEdit(self)
    self.leWind.setGeometry(160, 144, 40, 24)
    self.leWind.textChanged.connect(self.onWind)

    self.lblL = QLabel(u"<b>L = _______ мкГн</b>", self)
    self.lblL.setGeometry(130, 30, 100, 16)
    
    
  def onDiameter(self, text):
    self.D = float(self.leDiameter.text())
    self.getInductance()

  def onLength(self, text):
    self.l = float(self.leLength.text())
    self.getInductance()

  def onWind(self, text):
    self.w = int(self.leWind.text())
    self.getInductance()

  def getInductance(self):
    try:
      L = (0.01 * self.D * self.w * self.w) / ((self.l / self.D) + 0.44)
      self.lblL.setText(u"<b>L = %6.2f мкГн</b>" % L)
    except e:
      pass

################################################################################
if __name__ == "__main__":
  import sys
  app = QApplication(sys.argv)
  
  wnd = InductorOne()
  wnd.show()
   
  sys.exit(app.exec_())

Но зато сама программа стала выглядеть куда более симпатично:

onelaycoil

В принципе, прогой уже сейчас приятно пользоваться. Но тем, кто только разогрелся и жаждет «продолжения банкета», могу подсказать что ещё можно относительно легко добавить.

Ну, например, дописать текстовые подсказки, которые появляются при наведении курсора мышки на виждеты:

onelaycoil-3

Это делается чрезвычайно просто — добавкой к каждому виджету строки типа вот такой:

    self.leDiameter.setToolTip(u"Диаметр в сантиметрах")

Что ещё? Ещё было бы недурственно запретить изменять размеры окна. Для этого нужно чуть-чуть изменить конструктор класса:

...
    QWidget.__init__(self)
    
    pixmap = QPixmap("L2.png")
    
    self.pal = QPalette(self);
    self.pal.setBrush(self.backgroundRole(), QBrush(pixmap))
    self.setPalette(self.pal)
    self.setFixedSize(pixmap.size());
    
    self.setWindowTitle(u"Однослойная катушка индуктивности")
    self.resize(pixmap.size())
...

Кроме того, желательно к программе «прикрутить» какую-нибудь красивую иконку. Для простоты можно выбрать какую-нибудь иконку из пула стандартных иконок:

    self.setWindowIcon(self.style().standardIcon(QStyle.SP_TitleBarMenuButton))

Так же нужно подумать на тему как обрабатывать нештатные ситуации при вводе (или отсутствии ввода). Но здесь я пока не готов предложить вариант кода для решения.

Следует отметить один из приятных моментов — размер программы. У меня питоновский файл получился чуть больше двух с половиной килобайт. Совершенно невообразимый крошечный размер.

Но не обошлось и без ложки дёгтя. Для работы нашей проги требуется два файла — сам текст проги и файл изображения. А если вы будете использовать свою иконку, то появиться третий файл.

Наша программа не большая, состоит всего из пары-тройки файлов. Но вполне может оказаться так, что когда-нибудь вы напишите увесистую прогу с большим функционалом и множеством дополнительных файлов. Мне кажется, что работать с набором из нескольких файлов несколько сложнее, чем иметь один файл. Особой проблемы нет, есть только какой-то лёгкий дискомфорт от осознания того факта, что файлов как, на грязной кухне, — много, и так или иначе их нужно контролировать, следить, чтобы случайно не стёрлись или не потерялись при копировании. Это всего лишь мои личные предрассудки и страхи. Не принимайте их всерьез!

Самое главное, не относитесь к этой проге как к чему-то серьёзному. Рассматривайте её лишь учебный материал, ну или как игрушку человека, которому нечем заняться.

Всем хорошего дня!

4 responses to “Qt и однослойная катушка индуктивности

  1. Например есть созданное мной устройство с которым по rs232 должен общаться ПК а лучше планшет и просто менять несколько переменных. Я хотел бы научиться такое ПО создавать, можно ли как-то связаться с вами получить пример, разумеется за деньги заказчика…

    • Теоретически возможно. Нужно обсудить детали — объём работ, сроки, размер вознаграждения. Это не публичные дела, поэтому пишите на почту zhevak@mail.ru.

  2. Кажется, единица измерения генри обозначается Гн.

    • Ох, да!
      Спасибо, officemacro! Вы абсолютно правы.

      Видимо мозги были чем-то другим заняты, и я не заметил разницу между иностранным и русским обозначениями «uH» и «мкГн». Что называется, не приходя в сознание, что пишу по русски, а не по английски, тупо вписал и даже не подумал, что в русском варианте должно быть две буквы, а не одна.

      Возможно ещё сработала старая школа. Когда я был молод, единицы физических величин имели несколько другое сокращение. Потом, где-то на рубеже 70-80 годов произошло изменение. Но что впервые вписалось в мозг, то и истина. Мозг ещё та сволочь! И что бы ты не делал, стоит только отпустить внимание, как он, собака, тут же сыграет свою игру.

      У меня со школьных времён есть справочник по физике.

      h1

      Книжка довольно-таки толстая

      h2

      Так вот, там есть таблица физических величин

      h3

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

      Ещё раз спасибо за ценное замечание. Пойду править.

Ответить на zhevak Отменить ответ