真不错
增加了对线型等支持 修改了一些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年2个月前 - 2023/10/10 20:18:37]
原理图的转换也做好了 代码太长 就不贴了。。。实际上都有修改 代码也都长了 只能提醒还是从GitHub获取最新版。。。如果每次修正都放在这里 这帖子至少得长两页
基本能考虑的都考虑了 包括文字大小 线型 旋转 电源符号的转换 一般不带子框图的基本都没问题了
当然还是需要手工校正一些的
立创EDA就是经常要提示更新还要登账号这一点很反人类,还是AD没这个问题,没有收录到库里边的的符号和封装我一般是直接画的,库文件找一个路径存在本机里就行,若要备份可以考虑用NAS存一份。
立创EDA就是经常要提示更新还要登账号这一点很反人类,还是AD没这个问题,没有收录到库里边的的符号和...
毕竟人家是云开发 而且它问题也不少 关键是方便啊 开发到下单速度超快 专业版有完全离线
不过最头疼的是 共享很难做到 而且我看文件数据库 因为考虑团队协作开发 里面有加入参与者的账号信息的可能 虽然我目前个人开发 账号信息是一个公开共用的立创账号 但是也有泄漏什么的可能
而且sch转到kicad也不完美 因为各家都是根据坐标位置重合 来判断连接性的 一种用英式(反而是立创用英式) 一种用国际单位 转换之后因为精度问题 有些时候就对不上
200字以内,仅用于支线交流,主线讨论请采用回复功能。