image

Я в одной из предыдущих статей писал — я, фактически, безработный. Юридически — нет, во-первых я пенсионер, но вполне мог бы и работать. Во-вторых, вроде как и работаю в одной маленькой фирме из двух человек, но последний год у нас с контрактами напряженка. С голоду не умираем, пенсии вполне достаточно на жизнь, но ведь развлекаться как-то надо?
Время от времени от скуки публикую статьи-обзоры на сайте шопоголиков, администрация сайта даже денег довольно-таки регулярно за это дает. Очень хорошая отмазка для супруги — нет, я не шопоголик, это я, вроде как, при деле. И вот здесь взялся публиковать статейки — если на том сайте такие публиковать, только минусов нахватаешь — типа ты что, слишком умный, что ли? — а вот на тебе минус и не балуй. И в следующий раз пиши про какую-нибудь мыльницу.

В одной из предыдущих своих статей я рассказывал о дисплее на базе адресуемых светодиодов. Сейчас расскажу, как проектировались последние варианты плат для них.

Самих светодиодов было довольно-таки много — 1296 штук, плюс в плате должны быть вырезы. Дисплей, размещенный в окне, не должен полностью заслонять свет. А дисплей, предназначенный для замораживания, если его сделать сплошным, и порвать при заморозке может. Или компоненты оторвать. А может и еще что — специально обученный товарищ рассказывал, что случается при заморозке печатных плат во льду, но у меня в одно ухо влетело, во второе — вылетело.

Плата здесь приведена только для примера — реальная структура была чуть сложнее и были еще компоненты, которые надо было втолкать на эту же плату — но по сравнению с матрицей светодиодов это были совсем мелочи и окончательная разводка была сделана вручную.
Сразу предупреждаю, что я не большой специалист ни в Python, ни в KiCAD — для меня это лишь инструменты, которыми я пользуюсь время от времени. Наверное, я вообще во всем по жизни чайник — но зато медный и со свистком.

Первое дело — конечно, схема. Ее нужно нарисовать так, чтобы компоненты, расположенные рядом, имели и соответствующие номера.

image

image

image

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

Итак, создаем пустую плату и запускаем

вот этот скрипт:
panel_rows = 36
panel_lines = 36
deltaX = 10.0
deltaY = 10.0
holeX = 7.0
holeY = 7.0
hole_cut = 1.0
panel_gap = 2
origin=[0,0]

pcb_name = 'habr_dummy.kicad_pcb'
pcb_name2 = 'habr_edges.kicad_pcb'

def Create_edges():
    try:
        pcb_file = open(pcb_name, 'r')     
        #pcb_data = pcb_file.read()
        lineList = pcb_file.readlines()
        #pos = pcb_data.find(')')
        pcb_file.close()   
    except IOError:
        print("Cannot open file '%s'." % pcb_name)    
        return

    panel_size=[0,0]
    panel_size[0]= deltaX * panel_rows - panel_gap
    panel_size[1]= deltaY * panel_lines - panel_gap
    #print(panel_size)
    corners=[]
    corners.append([origin[0] - panel_size[0]/2, origin[1] - panel_size[1]/2])
    corners.append([origin[0] + panel_size[0]/2, origin[1] - panel_size[1]/2])
    corners.append([origin[0] + panel_size[0]/2, origin[1] + panel_size[1]/2])
    corners.append([origin[0] - panel_size[0]/2, origin[1] + panel_size[1]/2])
    #print(corners) 
    holes=[]
    for x in range(panel_rows-1):
        for y in range(panel_lines-1):  
            hole_orig =[0,0]
            hole_orig [0] = origin[0] - (deltaX * (panel_rows-1))/2 + x*deltaX + deltaX/2
            hole_orig [1] = origin[1] - (deltaY * (panel_lines-1))/2 + y*deltaY + deltaY/2
            hole_corners=[] 
            
            hole_corners.append([hole_orig[0] - holeX/2 + hole_cut, hole_orig[1] - holeY/2])     # left down
            hole_corners.append([hole_orig[0] + holeX/2 - hole_cut, hole_orig[1] - holeY/2 ])        
            hole_corners.append([hole_orig[0] + holeX/2, hole_orig[1] - holeY/2 + hole_cut])
            hole_corners.append([hole_orig[0] + holeX/2 , hole_orig[1] + holeY/2 - hole_cut])
            hole_corners.append([hole_orig[0] + holeX/2 - hole_cut, hole_orig[1] + holeY/2])
            
            hole_corners.append([hole_orig[0] - holeX/2 + hole_cut, hole_orig[1] + holeY/2])
            hole_corners.append([hole_orig[0] - holeX/2, hole_orig[1] + holeY/2 - hole_cut])
            hole_corners.append([hole_orig[0] - holeX/2, hole_orig[1] - holeY/2 + hole_cut])
            
            holes.append(hole_corners) 

    pos = len(lineList)-1

    # build board edge
    for i in range(len(corners)):
        k = i+1
        if k==len(corners):
            k=0;
        new_line = '  (gr_line (start '
        new_line += str(corners[i][0]) + ' '
        new_line += str(corners[i][1]) + ') (end '
        new_line += str(corners[k][0]) + ' '
        new_line += str(corners[k][1])
        new_line += ') (layer Edge.Cuts) (width 0.05))\n'
        #print(new_line)
        lineList.insert(pos, new_line) 
        pos += 1
    # build holes
    for hole in holes:
        for i in range(len(hole)):
            k = i+1
            if k==len(hole):
                k=0;
            new_line = '  (gr_line (start '
            new_line += str(hole[i][0]) + ' '
            new_line += str(hole[i][1]) + ') (end '
            new_line += str(hole[k][0]) + ' '
            new_line += str(hole[k][1])
            new_line += ') (layer Edge.Cuts) (width 0.05))\n'
            #print(new_line)
            lineList.insert(pos, new_line) 
            pos += 1

    lineList.insert(pos, '\n') 

    try:
        pcb_file = open(pcb_name2, 'w')        
        for line in lineList:
            #pcb_file.write(line.decode('utf-8'))
            pcb_file.write(line)    
        pcb_file.close()
    except IOError:
        print("Cannot write file '%s'." % pcb_name2)    
  
Create_edges()


Сразу сделана хорошая часть работы:

image

image

Монтажных отверстий всего 6, но уж поставим их тоже сразу. Эти же отверстия будут служить и для подвода напряжения.

Код
import pcbnew

panel_rows = 36
panel_lines = 36
deltaX = 10.0
deltaY = 10.0

pcb_name2 = 'habr_edges.kicad_pcb'
                   
def MountHoles(pcb):
    libpath = "/usr/share/kicad/modules/MountingHole.pretty"  
    for i in range (2):
        x = panel_rows/4 * deltaX + deltaX/2 
        if i==0:
            x = -x   
        for j in range (3):
            y = panel_lines/3 * deltaY 
            if j==1:
                y = 0
            elif j==2:     
                y = -y
            print(x,y)
            footprint = pcbnew.FootprintLoad(libpath, "MountingHole_3.2mm_M3_DIN965_Pad")      

            pcb.Add(footprint)   
            footprint.SetPosition(pcbnew.wxPoint(pcbnew.Millimeter2iu(x),pcbnew.Millimeter2iu(y)))   
            footprint.Reference().SetVisible(False)    
    
def Convert():
    print("start")     
    pcb = pcbnew.LoadBoard(pcb_name2)
    MountHoles(pcb)
    pcb.Save(pcb_name2)
    print("created!")     
 
Convert()


image

image

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

image

Теперь на получившуюся плату загружаем список компонентов.

image

Мой компьютер после этого практически прекращает шевелиться — я его покупал несколько лет назад и основным критерием было отсутствие любых вентиляторов и шума соответственно. И должна быть возможность подключения двух, а лучше трех дисплеев. Цель была достигнута — и, кроме всего, системный блок потребляет всего 1 ампер от 12-Вольтового источника питания. Есть задачи, когда его быстродействия начинает не хватать, но их не так уж и много.

Размещаем светодиоды

Код
import pcbnew

panel_rows = 36
panel_lines = 36
deltaX = 10.0
deltaY = 10.0
holeX = 7.0
holeY = 7.0
hole_cut = 1.0
panel_gap = 2
origin=[0,0]

pcb_name = 'habr_populated.kicad_pcb'
pcb_name2 = 'habr_layout.kicad_pcb'
def LED_placement(pcb):
    led_position=[]
    for y in range (panel_lines):
        line_pos=[]  
        for x in range (panel_rows):
            diode_ref =  y*panel_rows + x +1
            # Find the component
            c = pcb.FindModuleByReference("D"+str(diode_ref))           
            # Place it somewhere
            pos = [0.0,0.0]
            rot =0;
            pos[1] = origin[1] + (deltaY * (panel_lines-1))/2 - y*deltaY
            if y%2==0:
                pos[0] = origin[0] - (deltaX * (panel_rows-1))/2 + x*deltaX
                #rot = (-45+180)*10
                rot = (270+180)*10
            else:
                pos[0] = origin[0] + (deltaX * (panel_rows-1))/2 - x*deltaX
                #rot = -45 *10
                rot = 270 *10
            line_pos.append(pos) 
            c.SetPosition(pcbnew.wxPointMM(pos[0], pos[1]))
            # Rotate it (angle in 1/10 degreee)
            c.SetOrientation(rot)
            c.Reference().SetVisible(False) 
        led_position.append(line_pos)
    return led_position    

def Convert():   
    print("start")     
    pcb = pcbnew.LoadBoard(pcb_name)
    led_position = LED_placement(pcb)
    pcb.Save(pcb_name2)

    print("created!")     

 Convert()

image

image

теперь конденсаторы

Код
def Cap_placement(pcb):
    cap_position=[]
    for y in range (panel_lines-1):
        line_pos=[]  
        for x in range (panel_rows):
            cap_ref =  y*panel_rows + x +1
            # Find the component
            c = pcb.FindModuleByReference("C"+str(cap_ref))           
            # Place it somewhere
            pos = [0.0,0.0]
            rot =0;
            pos[1] = origin[1] + (deltaY * (panel_lines-1))/2 - y*deltaY - deltaY/2 
            if y%2==0:
                pos[0] = origin[0] - (deltaX * (panel_rows-1))/2 + x*deltaX  
                rot = (270+180)*10
            else:
                pos[0] = origin[0] + (deltaX * (panel_rows-1))/2 - x*deltaX
                rot = 270 *10
            line_pos.append(pos) 
            c.SetPosition(pcbnew.wxPointMM(pos[0], pos[1]))
            # Rotate it (angle in 1/10 degreee)
            c.SetOrientation(rot)
            c.Reference().SetVisible(False) 
        cap_position.append(line_pos)
    return cap_position


image

image

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

Код
def AddTrack(pcb, track, netCode, width, layer):
    for i in range (len(track)-1):
        t = pcbnew.TRACK(pcb)
        pcb.Add(t)
        t.SetStart(pcbnew.wxPoint(track[i][0], track[i][1]))
        t.SetEnd(pcbnew.wxPoint(track[i+1][0], track[i+1][1]))
        t.SetWidth(pcbnew.Millimeter2iu(width))
        t.SetNetCode(netCode)
        t.SetLayer(layer)
        
def AddVia(pcb, pos, netCode, dia, drill):
    v = pcbnew.VIA(pcb)
    pcb.Add(v)
    v.SetViaType(pcbnew.VIA_THROUGH)
    v.SetWidth(pcbnew.Millimeter2iu(dia))
    v.SetNetCode(netCode)
    v.SetPosition(pcbnew.wxPoint(pos[0],pos[1]))
    #v.SetLayerPair(0,31)
    v.SetDrill(pcbnew.Millimeter2iu(drill))

def LedGroundViaTrace(pcb, led_position, netCode):  
    #ground vias
    for y in range (panel_lines):
        for x in range (panel_rows):
            v = pcbnew.VIA(pcb)
            pcb.Add(v)
            v.SetViaType(pcbnew.VIA_THROUGH)
            v.SetWidth(pcbnew.Millimeter2iu(0.8))  # 1mm
            v.SetNetCode(netCode)
            pos = led_position[y][x]
            x0=pos[0]   
            if y%2==0:
                y0 = pos[1]-1.5-0.65                
            else:
                y0 = pos[1]+1.5+0.65                
            v.SetPosition(pcbnew.wxPointMM(x0,y0))
            v.SetLayerPair(0,31)
            v.SetDrill(pcbnew.Millimeter2iu(0.4))

    #line to via
    for y in range (panel_lines):
        for x in range (panel_rows):
            pos = led_position[y][x]
            if y%2==0:
                x0=pos[0]+1
                y0 = pos[1]-0.65  
                y1=y0-0.5
                x1=pos[0]
                y2=y1-1      
            else:
                x0=pos[0]-1
                y0 = pos[1]+0.65  
                y1=y0+0.5
                x1=pos[0]
                y2=y1+1                
                                   
            t = pcbnew.TRACK(pcb)
            pcb.Add(t)
            t.SetStart(pcbnew.wxPointMM(x0,y0))
            t.SetEnd(pcbnew.wxPointMM(x0, y1))
            t.SetWidth(pcbnew.Millimeter2iu(0.25))
            t.SetNetCode(netCode)
            
            t = pcbnew.TRACK(pcb)
            pcb.Add(t)
            t.SetStart(pcbnew.wxPointMM(x0,y1))
            t.SetEnd(pcbnew.wxPointMM(x1, y2))
            t.SetWidth(pcbnew.Millimeter2iu(0.25))
            t.SetNetCode(netCode)            


def CapGroundViaTrace(pcb, cap_position, netCode):  
    #ground vias
    for y in range (panel_lines-1):
        for x in range (panel_rows):
            v = pcbnew.VIA(pcb)
            pcb.Add(v)
            v.SetViaType(pcbnew.VIA_THROUGH)
            v.SetWidth(pcbnew.Millimeter2iu(0.8))  # 1mm
            v.SetNetCode(netCode)
            pos = cap_position[y][x]
            x0=pos[0];
            if y%2==0:
                y0 = pos[1]-1.5
            else:
                y0 = pos[1]+1.5
            v.SetPosition(pcbnew.wxPointMM(x0,y0))
            v.SetLayerPair(0,31)
            v.SetDrill(pcbnew.Millimeter2iu(0.4))

    #line to via
    for y in range (panel_lines-1):
        for x in range (panel_rows):
            t = pcbnew.TRACK(pcb)
            pcb.Add(t)
            pos = cap_position[y][x]
            if y%2==0:
                y0 = pos[1]-0.485
                y1 = pos[1]-1.5
            else:
                y0 = pos[1]+0.485
                y1 = pos[1]+1.5
            t.SetStart(pcbnew.wxPointMM(pos[0],y0))
            t.SetEnd(pcbnew.wxPointMM(pos[0], y1))
            t.SetWidth(pcbnew.Millimeter2iu(0.25))
            t.SetNetCode(netCode)


image

image

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

Код
def DataLines(pcb):
    for y in range (panel_lines):
        for x in range (panel_rows-1):
            diode_ref = "D"+str(y*panel_rows+x+1)
            diode = pcb.FindModuleByReference(diode_ref)    
            for pad in diode.Pads():
                if pad.GetPadName()=='1':
                    #PIN1 DOUT
                    netCode = pad.GetNet().GetNet()    
                    x0 = pad.GetPosition().x
                    y0 = pad.GetPosition().y    
                    if y%2==0:
                        x1 = x0 + pcbnew.Millimeter2iu(0.8)   
                        x2 = x1 + pcbnew.Millimeter2iu(0.65)  
                        y1 = y0 - pcbnew.Millimeter2iu(0.65) 
                        x3 = x2 + pcbnew.Millimeter2iu(5.1) 
                        x4 = x3 + pcbnew.Millimeter2iu(0.65) 
                        y2 = y1 - pcbnew.Millimeter2iu(0.65)
                        x5 = x4 + pcbnew.Millimeter2iu(0.8)  
                    else:
                        x1 = x0 - pcbnew.Millimeter2iu(0.8)
                        x2 = x1 - pcbnew.Millimeter2iu(0.65)
                        y1 = y0 + pcbnew.Millimeter2iu(0.65) 
                        x3 = x2 - pcbnew.Millimeter2iu(5.1) 
                        x4 = x3 - pcbnew.Millimeter2iu(0.65) 
                        y2 = y1 + pcbnew.Millimeter2iu(0.65)
                        x5 = x4 - pcbnew.Millimeter2iu(0.8)                              
                    # top 
                    track=[]
                    track.append([x0, y0])
                    track.append([x1, y0])
                    track.append([x2, y1])               
                    AddTrack(pcb, track, netCode, 0.25, 0)
                    AddVia(pcb, [x2, y1], netCode, 0.8, 0.4)
                    #bottom                    
                    track=[]
                    track.append([x2, y1]) 
                    track.append([x3, y1]) 
                    AddTrack(pcb, track, netCode, 0.25, 31)
                    AddVia(pcb, [x3, y1], netCode, 0.8, 0.4)                        
                    # top 
                    track=[]
                    track.append([x3, y1]) 
                    track.append([x4, y2]) 
                    track.append([x5, y2]) 
                    AddTrack(pcb, track, netCode, 0.25, 0)               
                             
def CrossLines(pcb):
    for y in range (panel_lines-1):  #panel_rows
        diode_ref = "D"+str((y+1)*panel_rows )
        diode = pcb.FindModuleByReference(diode_ref)    
        for pad in diode.Pads():
            if pad.GetPadName()=='1':
                #PIN1 DOUT
                netCode = pad.GetNet().GetNet()    
                x0 = pad.GetPosition().x
                y0 = pad.GetPosition().y    
                    
                if y%2==0:
                    x1 = x0 + pcbnew.Millimeter2iu(0.8)   
                    x2 = x1 + pcbnew.Millimeter2iu(0.65)  
                    y1 = y0 - pcbnew.Millimeter2iu(0.65) 
                    y2 = y1 - pcbnew.Millimeter2iu(deltaY - 1.3) 
                    y3 = y2 - pcbnew.Millimeter2iu(0.65) 
                else:
                    x1 = x0 - pcbnew.Millimeter2iu(0.8)
                    x2 = x1 - pcbnew.Millimeter2iu(0.65)
                    y1 = y0 - pcbnew.Millimeter2iu(0.65) 
                    y2 = y1 - pcbnew.Millimeter2iu(deltaY - 1.3) 
                    y3 = y2 - pcbnew.Millimeter2iu(0.65)                            
                # top 
                track=[]
                track.append([x0, y0])
                track.append([x1, y0])
                track.append([x2, y1])       
                track.append([x2, y2])    
                track.append([x1, y3])           
                track.append([x0, y3]) 
                AddTrack(pcb, track, netCode, 0.25, 0)



image

image

Полигоны, конечно, и ручкам сделать несложно, да уж ладно, раз взялись писать подпрограммы, то доделаем и это

Код
def DrawPolygons(pcb):
    # grownd plane DrawPolygons(pcb)
    plane_size=[0,0]
    plane_size[0]= deltaX * panel_rows/2 -  panel_gap/2 - 0.5 
    plane_size[1]= deltaY * panel_lines/2 - panel_gap/2 - 0.5
    
    Contour=[]
    Contour.append( [pcbnew.Millimeter2iu(plane_size[0]),   pcbnew.Millimeter2iu(plane_size[1]) ])
    Contour.append( [pcbnew.Millimeter2iu(plane_size[0]),  -pcbnew.Millimeter2iu(plane_size[1]) ])
    Contour.append( [-pcbnew.Millimeter2iu(plane_size[0]), -pcbnew.Millimeter2iu(plane_size[1]) ])
    Contour.append( [-pcbnew.Millimeter2iu(plane_size[0]),  pcbnew.Millimeter2iu(plane_size[1]) ])  
    
    nets = pcb.GetNetsByName()
    net = nets.find("GND").value()[1]
    netCode = net.GetNet()
    
    newarea = pcb.InsertArea(netCode, pcbnew.B_Cu, pcbnew.B_Cu, Contour[0][0], Contour[0][1], pcbnew.ZONE_CONTAINER.DIAGONAL_EDGE)    
    newoutline = newarea.Outline()
    for i in range (1,4):
        newoutline.Append(Contour[i][0],Contour[i][1]);
    
    poly_set = pcbnew.SHAPE_POLY_SET()
    poly_set.NewOutline()
    for i in range (0,4):
        poly_set.Append(Contour[i][0],Contour[i][1])    
    newarea.SetFilledPolysList(poly_set)    
    
    nets = pcb.GetNetsByName()
    net = nets.find("+5V").value()[1]
    netCode = net.GetNet()
    
    newarea = pcb.InsertArea(netCode, pcbnew.F_Cu, pcbnew.F_Cu, Contour[0][0], Contour[0][1], pcbnew.ZONE_CONTAINER.DIAGONAL_EDGE)    
    newoutline = newarea.Outline()
    for i in range (1,4):
        newoutline.Append(Contour[i][0],Contour[i][1]);
    
    poly_set = pcbnew.SHAPE_POLY_SET()
    poly_set.NewOutline()
    for i in range (0,4):
        poly_set.Append(Contour[i][0],Contour[i][1])    
    newarea.SetFilledPolysList(poly_set)  


image

image

image

И суммарная процедура теперь выглядит так

Код
def Convert():
    
    print("start")     
    pcb = pcbnew.LoadBoard(pcb_name)
    led_position = LED_placement(pcb)
    cap_position = Cap_placement(pcb)
    nets = pcb.GetNetsByName()
    net = nets.find("GND").value()[1]
    netCode = net.GetNet()    
    CapGroundViaTrace(pcb, cap_position, netCode)
    LedGroundViaTrace(pcb, led_position, netCode)
    DataLines(pcb)
    CrossLines(pcb)
    DrawPolygons(pcb)
    pcb.Save(pcb_name2)
    print("created!")     
 
Convert()


image

image

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

В заключение на жизнь пожаловаться, что ли. Хотя Остап Бендер советовал с этим обращаться во всемирную лигу сексуальных реформ (смех смехом, а она действительно существовала в то время).

Отвечайте нам, а то,
Если вы не отзовётесь,
мы напишем в «Спортлото» ©

В Финляндии вовсю кричат о нехватке рабочей силы, особенно квалифицированной в области IT. Но о чем крик — я не понимаю.

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

А тут-то мне равных немного — мало у кого дома есть столько оборудования, как у меня. И опыт работы в фирмах, круче которых, наверно, только яйца вкрутую, и то не факт.

И знакомых полно — руководителей среднего звена. Но они работают в крупных фирмах и кадровиков не могут убедить никак, всем нужны молодые работники на постоянную работу.
А пенсионера со странными требованиями (например, зарплата не должна быть больше определенного уровня), всерьез никто не воспринимает. Типа, иди, кури. А я ищу не денег, а просто применения сил — потому, наверно, и не хотят связываться.

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

В нашем переулке, в двух соседних от меня домах, живут инженеры по электронике, были далеко не последними специалистами. С коллапсом Nokia многие фирмы, которые работали с ней, тоже позакрывали свои подразделения. Много народа осталось без работы, и они тоже.
Ладно, один из них не молодой, а второй через какое-то время тяжело заболел. Но у меня есть и несколько знакомых инженеров, в самом расцвете сил — но перебиваются случайными заработками. Я с ними сталкивался как раз, когда у них была такая временная работа, большинство из них очень квалифицированные специалисты.

Комментарии (11)


  1. lukan
    11.12.2021 13:44
    +2

    спаасибо автору за статтю, очень понятно и доходчиво обяснено


  1. AVDerov
    11.12.2021 14:11

    Хорошая работа!


  1. slovak
    11.12.2021 20:57
    +1

    Статья на самом деле интересная, но для Kicad есть плагин replicate layout. Пользуюсь им для разводки многоканальных схем. Можно конечно и самому скриптить, но автор плагина и его пользователи уже прошли по большинству граблей.


  1. AlexanderS
    11.12.2021 21:27
    +3

    Похоже, пост оказался неинтересным.
    Извините.

    Прошлые ваши статьи набрали дикие плюсы из-за научно-популярного стиля изложения, охватив максимуму аудитории. Там не было перегрузки всяким матаном, спецификациями и прочей «техничкой». А эта статья — очень узконаправленная, специализированная, детализированная. Естественно, что у неё охват гораздо меньше -> оценивать её будет потребность у гораздо меньшего количества людей -> не будет рейтинга за сотню. Но это не значит, что статья неинтересна. Просто не всем подряд. Новичку в Kiсad — самое то будет. Так что не стоит извиняться и считать статью бесполезной — это не так. Вы просто кому-то в будущем, возможно, помогли в разбирательстве с скриптами. И для человека это будет весьма полезно. Спасибо вам кто-то скажет просто в воздух, а не плюсиком сейчас ;)


    1. DustyZebra Автор
      11.12.2021 21:49
      +1

      Спасибо, пусть живет, как есть :) А то я уже, после чьего-то минуса, чуть не снес ее совсем.


      1. monane
        11.12.2021 23:26
        +1

        Простите что влез, не надо сносить если выпустили редакторы пусть живет. Хабр давно не место где можно получить минус за профессионализм или его отсутвие, чаще тут минус просто так. Или стадность, к сожалению. Как правило если есть претензии к оформлению или что важнее к содержанию то от настоящих оппонентов вы увидите посты, что именно не нравится или неверно.


  1. belav
    11.12.2021 22:28

    Спасибо. Полезный скрипт. У меня так и не дошли руки, обычно разводил один модуль, потом редактировал net лист в notepad++, прописывал координаты элементов с помощью поиска и замены.


  1. engine9
    12.12.2021 11:18

    Друзья, буду признателен, если кто поделится русскоязычным руководством по кикаду. В общих чертах освоил, но как подключать сторонние ресурсы или создавать свои компоненты (или просто изменять существующие) до сих пор не осилил. Там так запутанно и не логично сделана система управления ресурсами, что мозг закипает...


    1. DustyZebra Автор
      12.12.2021 11:46
      +1

      1. engine9
        13.12.2021 12:11

        О! Класс, спасибо тебе, добрый человек!


  1. Max_Krasnov
    13.12.2021 09:35

    Отличная статья!