原理图的转换也做好了 代码太长 就不贴了。。。实际上都有修改 代码也都长了 只能提醒还是从GitHub获取最新版。。。如果每次修正都放在这里 这帖子至少得长两页
基本能考虑的都考虑了 包括文字大小 线型 旋转 电源符号的转换 一般不带子框图的基本都没问题了
当然还是需要手工校正一些的
增加了对线型等支持 修改了一些bug 目前还在继续改进 打算之后还是增加原理图也迁移
因为老在修改完善 程序也越来越长 我已经上传ghub 大家还是从XXXXXXXXXXXXXXXXXX/m24h/lcEDA2KiCAD 下载吧
.........................................
最近使用了立创的EDA 发现它的元件符号库太全了 尤其是国内常用产品 KiCAD远远不如 那么 有没有可能转它的符号库给KiCAD用
经研究 发现立创EDA使用SQLite3数据库存储其数据 比如个人建立一个元件库 然后从各处找到感兴趣的元件符号 就可以拷贝到自己的库 也就出现在本地存放的.elib数据库中 在表Components的dataStr字段里 格式大致如下
其实也可以在元件编辑器的菜单"文件"->"查看源码"里面得到
或者在自己工程的备份压缩文件里 各元件符号以.esym后缀的文件独立存放
批量导出数据库字段变成文件并不难 我也不多说 也暂时不需要 只是想把工程中遇到的元件加入KiCad的元件库中 因为我大概是购买了 以后也会用的 所以做了一个脚本 用来转换.esym文件为KiCad的.kicad_sym文件 处理文本 当然是perl最擅长 所以用perl
use JSON; my %pintypes=('IN' => 'input', 'OUT' => 'output'); die "Usage: perl $0 <.esym file name> <output filename or - (STDOUT) or empty (use symbol name)>\n" if $#ARGV<0; die "File '$ARGV[0]' is not found\n" unless open F, "<$ARGV[0]"; $symb=from_json('['.join(',', <F>).']'); close F; #get all parts my @parts; foreach (@$symb) { push @parts, [] if $_->[0] eq 'PART'; push @{$parts[-1]}, $_ if $#parts>=0; } #["FONTSTYLE","st4",null,null,"Times new roman",15,0,0,0,null,1,0] my %fonts=map {$_->[1] => $_->[5] && '(font (size '.($_->[5]*0.254).' '.($_->[5]*0.254).'))' || ''} grep {$_->[0] eq 'FONTSTYLE'} @$symb; #["LINESTYLE","st19",null,3,"#330033",null] my %linestyles=map {$_->[1] => '(stroke (width '. ($_->[5]*0.254 || 0).') (type '.($_->[3] && qw(solid dash dot dash_dot)[$_->[3]] || 'default').')' .($_->[2]=~/#([0-9A-F][0-9A-F])([0-9A-F][0-9A-F])([0-9A-F][0-9A-F])/i && " (color ${\hex($1)} ${\hex($2)} ${\hex($3)} 1)" || '').')' .($_->[4]=~/#([0-9A-F][0-9A-F])([0-9A-F][0-9A-F])([0-9A-F][0-9A-F])/ && " (fill (type color) (color ${\hex($1)} ${\hex($2)} ${\hex($3)} 1))" || ' (fill (type none))')} grep {$_->[0] eq 'LINESTYLE'} @$symb; #get symbol name (but there's only part name in file, so the first part name is adopted) my $name=$parts[0]->[0]->[1]=~s/[\-#\$_\.:,]\d*$//r; unless ($#ARGV>0 && $ARGV[0] eq '-') { $#ARGV>0 && (open STDOUT,">$ARGV[1]" or die "Failed to open '$ARGV[1]' for writing\n") or open STDOUT, ">$name.kicad_sym" or open STDOUT, '>'.($ARGV[0]=~s/\.[^\.]*$//r).'.kicad_sym' or die "Failed to open '".($ARGV[0]=~s/\.[^\.]*$//r).".kicad_sym' for writing\n"; } #start to write header print <<"EOF"; (kicad_symbol_lib (version 20220914) (generator esym2kicad_pl) (symbol "$name" (in_bom yes) (on_board yes) (property "Reference" "${\map {split /\?$/, $_->[4]} grep {$_->[0] eq 'ATTR' && $_->[3] eq 'Designator' } @$symb}" (at -5.08 6.35 0) (effects (justify left)) ) (property "Value" "${\map {$_->[4]} grep {$_->[0] eq 'ATTR' && $_->[3] eq 'Symbol' } @$symb}" (at -5.08 8.89 0) (effects (justify left)) ) (property "Footprint" "${\map {$_->[4]} grep {$_->[0] eq 'ATTR' && $_->[3] eq 'Footprint' } @$symb}" (at 0 0 0) (effects hide) ) (property "Datasheet" "${\map {$_->[4]} grep {$_->[0] eq 'ATTR' && $_->[3] eq 'link' } @$symb}" (at 0 0 0) (effects hide) ) EOF #do every parts my $part_suffix=1; foreach my $part(@parts) { print <<"EOF"; # there seems to be a rule about symbol's name, which is not compatible with LcEDA (symbol "${name}_${\$part_suffix++}_1" EOF #["RECT","e3",-60,-55,60,55,0,0,0,"st1",0] foreach (grep {$_->[0] eq 'RECT'} @$part) { print <<"EOF"; (rectangle (start ${\($_->[2]*0.254)} ${\($_->[3]*0.254)}) (end ${\($_->[4]*0.254)} ${\($_->[5]*0.254)}) $linestyles{$_->[9]} ) EOF } #["ARC","e14",4.44,-6.9,1.66049,0.08325,4.53,7.03,"st1",0] foreach (grep {$_->[0] eq 'ARC'} @$part) { eval { # will fail if 3 points is in a line # can't believe that kiCAD does not support arcs with angles >180 degree, so hard to fix it my ($x1,$y1,$x2,$y2,$x3,$y3)=($_->[2]*0.254,$_->[3]*0.254,$_->[4]*0.254,$_->[5]*0.254,$_->[6]*0.254,$_->[7]*0.254); my ($x21,$x32,$x13,$y21,$y32,$y13)=($x2-$x1,$x3-$x2,$x1-$x3,$y2-$y1,$y3-$y2,$y1-$y3); my ($a,$b)=($x21*$y32-$y21*$x32, $x21*$y13-$y21*$x13); # 0 means 3 points is in a line my ($c,$d)=($x1*$x1+$y1*$y1-$x2*$x2-$y2*$y2, $x1*$x1+$y1*$y1-$x3*$x3-$y3*$y3); my ($x0,$y0)=(-($y13*$c+$y21*$d)/$b/2, ($x21*$d+$x13*$c)/$b/2); my ($s1,$s3,$pi2)=(atan2($y1-$y0,$x1-$x0), atan2($y3-$y0,$x3-$x0), 4*atan2(1,0)); my $ang=$a>0?($s3-$s1):($s1-$s3); $ang+=$pi2 if ($ang<0); #CCW running angle if ($ang>3.14) { # have to split it my $r=sqrt(($x1-$x0)*($x1-$x0)+($y1-$y0)*($y1-$y0)); my ($x4,$y4)=($x0+$r*cos($s1+$ang/2), $y0+$r*sin($s1+$ang/2)); my ($x5,$y5)=($x0+$r*cos($s1+$ang/4), $y0+$r*sin($s1+$ang/4)); my ($x6,$y6)=($x0+$r*cos($s3-$ang/4), $y0+$r*sin($s3-$ang/4)); print <<"EOF"; (arc (start $x1 $y1) (mid $x5 $y5) (end $x4 $y4) $linestyles{$_->[8]} ) (arc (start $x4 $y4) (mid $x6 $y6) (end $x3 $y3) $linestyles{$_->[8]} ) EOF } else { print <<"EOF"; (arc (start $x1 $y1) (mid $x2 $y2) (end $x3 $y3) $linestyles{$_->[8]} ) EOF } }; } #["POLY","e11",[-2,8,-2,-8],0,"st1",0] foreach (grep {$_->[0] eq 'POLY'} @$part) { print <<"EOF"; (polyline (pts EOF my $pts=$_->[2]; for (my $i=0; $i<$#$pts; $i+=2) { print <<"EOF"; (xy ${\($pts->[$i]*0.254)} ${\($pts->[$i+1]*0.254)}) EOF } print <<"EOF"; ) $linestyles{$_->[4]} ) EOF } #["BEZIER","e211",[-140,-20,-120,0,-90,0,-80,-10],"st1",0], not supported, just take a pose foreach (grep {$_->[0] eq 'BEZIER'} @$part) { print <<"EOF"; (polyline (pts EOF my $pts=$_->[2]; for (my $i=0; $i<$#$pts; $i+=2) { print <<"EOF"; (xy ${\($pts->[$i]*0.254)} ${\($pts->[$i+1]*0.254)}) EOF } print <<"EOF"; ) $linestyles{$_->[3]} ) EOF } #["CIRCLE","e4",-55,50,1.5,"st1",0] foreach (grep {$_->[0] eq 'CIRCLE'} @$part) { print <<"EOF"; (circle (center ${\($_->[2]*0.254)} ${\($_->[3]*0.254)}) (radius ${\($_->[4]*0.254)}) $linestyles{$_->[5]} ) EOF } #["ELLIPSE","e206",-100,20,10,20,0,"st1",0], not supported, just take a pose foreach (grep {$_->[0] eq 'ELLIPSE'} @$part) { print <<"EOF"; (circle (center ${\($_->[2]*0.254)} ${\($_->[3]*0.254)}) (radius ${\(($_->[4]+$_->[5])*0.127)}) $linestyles{$_->[7]} ) EOF } #["PIN","e5",1,1,-70,45,10,0,null,0,0,1] #["ATTR","e6","e5","NAME","VSS",false,true,-56.3,39.08502,0,"st4",0] #["ATTR","e7","e5","NUMBER","1",false,true,-60.5,44.08502,0,"st5",0] #["ATTR","e8","e5","Pin Type","IN",false,false,-70,45,0,"st2",0] foreach (grep {$_->[0] eq 'PIN'} @$part) { my $id=$_->[1]; print <<"EOF"; (pin ${\($pintypes{(map {$_->[4]} grep {$_->[0] eq 'ATTR' && $_->[2] eq $id && $_->[3] eq 'Pin Type'} @$part)[0]} || 'passive')} line (at ${\($_->[4]*0.254)} ${\($_->[5]*0.254)} $_->[7]) (length ${\($_->[6]*0.254)}) (name "${\map {$_->[4]} grep {$_->[0] eq 'ATTR' && $_->[2] eq $id && $_->[3] eq 'NAME' } @$part}") (number "${\map {$_->[4]} grep {$_->[0] eq 'ATTR' && $_->[2] eq $id && $_->[3] eq 'NUMBER' } @$part}"\) ) EOF } #["TEXT","e313",908,160,0,"yyy","st4",0] foreach (grep {$_->[0] eq 'TEXT'} @$part) { my $id=$_->[1]; my $style=$_->[6]; print <<"EOF"; (text "$_->[5]" (at ${\($_->[2]*0.254)} ${\($_->[3]*0.254)} ${\($_->[4]*10)}) (effects $fonts{$_->[6]}) ) EOF } print <<"EOF"; ) EOF } print <<"EOF"; ) ) EOF close STDOUT;
目前支持引脚 文字 方框 圆 弧 折线 基本够用了 目前测试下来 基本都没有问题
当然 这需要一个个元件加入KiCad 正好顺便检查 批量导入其实大概也有方法的 .kicad_sym文件其实也是库文件 只需要在顶层的kicad_symbol_lib级别下放多个symbol就是了 元件文件就只放一个 至于修改脚本还是后期用copy合并后去掉重复的kicad_symbol_lib头 都不难 但我就不做了
............................... 10.8 .....
更新了脚本 增加了对多单元器件的支持 (比如双运放之类)
顺便 也把从.elib eprj导出所有元件的脚本做了
use DBI; die "Usage: perl $0 <.elib .eprj file name> \n\tIt will extract all symbols and save them to this directory." if $#ARGV<0; die "Unable to find '$ARGV[0]'\n" unless -e $ARGV[0]; $dbh=DBI->connect("DBI:SQLite:dbname=$ARGV[0]", '', '', {PrintError=>0}) or die "Unable to connect file '$ARGV[0]': ".DBI::errstr."\n"; $sth=$dbh->prepare("SELECT title,dataStr from components where docType=2 and title is not null and title!=''") and $sth->execute()>=0 or die "Failed to extract symbol data from file '$ARGV[0]': ".DBI::errstr."\n"; while(my @row = $sth->fetchrow_array()) { $row[0]=~tr/\*\|\"\?\/\\\&;\<\> /_/; $row[1]=~s/\r*(?=\n)//gm;; next unless $row[0] && $row[1]; next unless open F, ">$row[0].esym"; print F $row[1]; close F; } $sth->finish(); $dbh->disconnect();
还包括把多个.kicad_sym文件合并成一个库的脚本 (这样 导出 for %f in (*.esym) do .... 然后再合并 库迁移就OK了)
die "Usage: perl $0 <.output file name or '-' (STDOUT)>\n\t\All .kicad_sym file (which should be created by esym2kicad.pl) will be packed to a signle lib file\n" if $#ARGV<0; die "Unable to open '$ARGV[0]'\n" unless $ARGV[0] eq '-' || open STDOUT,">$ARGV[0]"; undef $/; print <<"EOF"; (kicad_symbol_lib (version 20220914) (generator makekicadlib_pl) EOF foreach (grep {!-d $_ && -e $_ && !/^\./ } <'*.kicad_sym'>) { print STDERR "processing $_\n"; next unless open T, "<$_"; $_=<T>; close T; print " $1\n" if /(\(\s*symbol\s(.|\n)*?)(\s|\n)*\)[^\)]*$/i; } print <<"EOF"; ) EOF close STDOUT;
[修改于 1年1个月前 - 2023/10/10 20:18:37]
原理图的转换也做好了 代码太长 就不贴了。。。实际上都有修改 代码也都长了 只能提醒还是从GitHub获取最新版。。。如果每次修正都放在这里 这帖子至少得长两页
基本能考虑的都考虑了 包括文字大小 线型 旋转 电源符号的转换 一般不带子框图的基本都没问题了
当然还是需要手工校正一些的
立创EDA就是经常要提示更新还要登账号这一点很反人类,还是AD没这个问题,没有收录到库里边的的符号和...
毕竟人家是云开发 而且它问题也不少 关键是方便啊 开发到下单速度超快 专业版有完全离线
不过最头疼的是 共享很难做到 而且我看文件数据库 因为考虑团队协作开发 里面有加入参与者的账号信息的可能 虽然我目前个人开发 账号信息是一个公开共用的立创账号 但是也有泄漏什么的可能
而且sch转到kicad也不完美 因为各家都是根据坐标位置重合 来判断连接性的 一种用英式(反而是立创用英式) 一种用国际单位 转换之后因为精度问题 有些时候就对不上
时段 | 个数 |
---|---|
{{f.startingTime}}点 - {{f.endTime}}点 | {{f.fileCount}} |
200字以内,仅用于支线交流,主线讨论请采用回复功能。