I can totally share it - not proprietary at all......
You can modify it to suit.
Some of the pieces and parts were patched together from other shared ULP's
This one pulls my internal part number from the attributes of the parts. This is what allows my PnP machine to recognize and connect the part to its own database. All of my parts have an attribute 'SCI_PN' that holds this data.
#usage "ver 2.10 Create CSV data for SCI Quad 4000C assembly"
string Version = "2.10"; // Dec 10, 2019
string fileMessage;
// Calculate angle of component
string rotation(real Angle)
{
string s;
sprintf(s, "%.1f", Angle);
int pos = strchr(s, '.');
if (pos >= 0) if (s[pos + 1] == '0') s[pos] = 0;
return s;
}
// Determine side of PCB the component is on
string side(int Mirror)
{
string side;
if (Mirror){
side = "BOT";
}
else {
side = "TOP";
}
return side;
}
// Get the filename from user
string usrFilename;
board(B){
usrFilename = dlgFileSave("Pick a location and prefix name", B.name, "");
}
// Display error dialog if NOT in board view
if (!board) {
dlgMessageBox("<hr><b>ERROR: This ULP will only operate in the board layout view.</b></hr><p>Switch to the board layout editor and re-run.");
exit(1);
}
// Main output for Quad Machine
if (board) board(B) {
output(usrFilename + "_TOP.cad") {
// File comments
printf("[COMMENT]\n");
printf("Solid Camera TOP SMD component position file.\n");
printf("Created by IVC_TOP_Program Out D-v3.ulp %s.\n\n", Version);
printf("Centroid Data for pc board: \"%s\" as of: %s\n", filename(B.name), t2string(time()));
printf("Measurements are in mils. Comma delimited\n");
printf("Only surface mount components included\n\n");
printf("%s,%s,%s,%s,%s,\n", "SCI PN", " RefDes", " LocationX", " LocationY", " Rotation");
printf("[PLACEMENT]\n");
B.elements(E) {
int isSmd;
int isDnp = 1;
// string partNumber = E.attribute["SCI_PN"];
isSmd = 0;
E.package.contacts(C) { if (C.smd && !E.mirror) isSmd = 1; }
if (E.attribute["DNP"] == "1") isDnp = 0;
if (isSmd && isDnp) printf("%s,%s,%6.4f,%6.4f,%s\n", E.attribute["SCI_PN"], E.name, u2inch(E.x), u2inch(E.y), rotation(E.angle));
}
}
}
// Courtesy CSV output for quick checking in Excel
if (board) board(B) {
output(usrFilename + "_TOP.csv") {
// File comments
printf("[COMMENT]\n");
printf("Solid Camera TOP SMD component position file.\n");
printf("Created by IVC_TOP_Program Out D-v3.ulp %s.\n\n", Version);
printf("Centroid Data for pc board: \"%s\" as of: %s\n", filename(B.name), t2string(time()));
printf("Measurements are in mils. Comma delimited\n");
printf("Only surface mount components included\n\n");
printf("%s,%s,%s,%s,%s,\n", "SCI PN", " RefDes", " LocationX", " LocationY", " Rotation");
printf("[PLACEMENT]\n");
B.elements(E) {
int isSmd;
int isDnp = 1;
// string partNumber = E.attribute["SCI_PN"];
isSmd = 0;
E.package.contacts(C) { if (C.smd && !E.mirror) isSmd = 1; }
if (E.attribute["DNP"] == "1") isDnp = 0;
if (isSmd && isDnp) printf("%s,%s,%6.4f,%6.4f,%s\n", E.attribute["SCI_PN"], E.name, u2inch(E.x), u2inch(E.y), rotation(E.angle));
}
}
fileMessage = "<hr><b>Success! TOP LAYER CAD Data file for Quad 4000C PCB assembly.</b></hr><p>For import as CSV into PPM software:<P>" + filesetext(B.name, "_TOP.cad\n");
dlgMessageBox(fileMessage);
}
Sample output.....
[COMMENT]
Solid Camera TOP SMD component position file.
Created by IVC_TOP_Program Out D-v3.ulp 2.10.
Centroid Data for pc board: "E20-400-0100 Vac Sense Upper D-v7.brd" as of: 12/10/2019 12:00 PM
Measurements are in mils. Comma delimited
Only surface mount components included
SCI PN, RefDes, LocationX, LocationY, Rotation,
[PLACEMENT]
E03-080-1230,C1,1.0700,0.6500,180
E03-040-0990,C2,1.2820,0.4960,180
E03-040-0990,C3,0.6880,2.0090,0
E03-040-0990,C5,1.0950,0.5450,180
E03-040-0750,C6,1.0950,0.5850,180
E03-040-0990,C15,0.1600,1.0233,90
E03-040-0990,C16,0.2200,0.8267,270
E03-040-0990,C22,1.8010,1.5570,270
E03-040-1110,C23,1.5760,1.6420,180
E03-040-1110,C24,1.4910,1.6420,0
E03-040-1110,C25,1.6750,1.6500,270
E03-040-0990,C26,1.7470,1.6250,180
E03-120-1493,C27,0.5850,1.3340,90
E03-120-1493,C28,0.6990,1.3350,90
E03-121-1505,C29,0.7320,1.5660,270
E03-121-1505,C30,0.5950,1.5650,270
E08-065-0050,D1,1.8880,0.5690,90
E08-065-0050,D2,1.7110,0.3720,90
E08-065-0050,D3,1.4860,0.2320,90
E08-065-0050,D4,1.2320,0.1590,90
E08-065-0050,D5,0.9680,0.1590,90
E08-065-0050,D6,0.7140,0.2320,90
E08-065-0050,D7,0.4890,0.3720,90
E08-065-0050,D8,0.3120,0.5690,90
E10-160-0110,D12,1.0530,1.4800,270
E50-120-0160,F2,1.2730,1.5750,180
E99-100-0100,FID1,1.3990,2.0080,0
E99-100-0100,FID2,0.2100,0.6650,0
E99-100-0100,FID3,2.0150,0.7400,0
E02-040-0730,R2,0.3350,0.4800,0
E02-040-0730,R3,0.3950,0.5600,90
E02-040-0730,R6,0.5100,0.2850,0
E02-040-0730,R7,0.5600,0.3700,90
E02-040-0730,R8,0.7350,0.1450,0
Carlos Acosta
Factory400 - YouTube|Instagram