diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..02c16a3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +__pycache__/ +*.py[cod] +.DS_Store +._* diff --git a/README.md b/README.md index 467db66..bcc0ce7 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,28 @@ joint the projects community [Discord Server](https://discord.gg/maRvMVpa2Q). 5. Upload firmware using VSCode with PlattformIO plugin 6. Calibrate axis -## ✨NEW: Open Micro-Manipulator GUI +Also check out the setup guide for new devices: [Setup Guide](documentation/setup_guide/setup_guide.md) + +## ✨NEW: Hardware Version 4.0 +A new version of the hardware has been released, fixing several issues with the previous design: + +- Self collision during homing fixed. +- Connection of ball joint block with screws only was not well constrained and could rotated a bit. +- No reliable way to ensure consistent linkage rod length +- Unnecessary ball joint friction +- Accurate ball position heavily dependet on print quality and corner rounding +- Rubber bands could not be changed or removed once glued in. + +A video about the improved ball joint and linkage manufactoring process can be found on YouTube: [Better Ball Joints for the Open Micro-Manipulator](https://www.youtube.com/watch?v=NM2KXvRGmpg) +Also the FreeCAD model was restructured and improved and now includes all pins and fasteners. It now provides a reference for all required mechanical parts. + +
+ Open Micro-Manipulator GUI +
+ +WARNING: BOM is not updated yet... + +## Open Micro-Manipulator GUI To make testing and using the Open-Micro Manipulator easy and convenient a python control program with a graphical user interface is provided here: [Open Micro-Manipulator GUI](https://github.com/0x23/OpenMicroManipulatorGUI). It has simple controlls to move the device around, while also displaying a live camera feed (e.g. from a microscope camera). Additional features, include a simple g-code runner and realtime mouse control (e.g. for Biology applications). @@ -78,6 +99,7 @@ get_workspace_transform() home(axis_list=None) calibrate_joint(joint_index, save_result) move_to(x, y, z, f, move_immediately, blocking, timeout) +set_tool_output(tool_idx, output_value, immediate) set_pose(x, y, z) dwell(time_s, blocking, timeout) enable_motors(enable) @@ -85,8 +107,27 @@ wait_for_stop(polling_interval_ms, disable_callbacks) set_max_acceleration(linear_accel, angular_accel) set_servo_parameter(pos_kp, pos_ki, vel_kp, vel_ki, vel_filter_tc) ``` +## ✨ Firmware v1.0.4 -## ✨ Firmware v1.0.1 +Firmware 1.0.4 comes with many smaller improvements and bugfixes and a great new feature as well: + + - **Tools**: Tool usage (for example for laser engraving) is now supported on the two GPIO pins of J5 on the pcb. + Tools are integrated into the planner and run fast and with correct timing when executing g-code. + The tools support PWM (using the PIO feature to squeeze out extra channels without relying on software PWM). + + Example usage: + ``` + M3 T0 S0.7 // set pwm output of tool 0 to 70% + G4 S0.001 // dwell command (or any other motion command) - necessary to apply the tools output + ``` + +- **Calibration**: Calibration has now some addition error checks to improve error reporting of potential problems like encoder alignment. +- **Kinematic Model Parameter**: Initialization code has been cleaned up and better comments where added to the parameters. Parameters are preset for HW v4.0 but you can toggle back to the old HW-v3.0 parameters if necessary. +- **Bugfixes**: smaller bugfixes + +IMPORTANT: If you have **Hardware Version v3.0** you need to switch back to the old kinematic parameters in the [kinematic_model_delta3d.cpp](firmware/MotionControllerRP/src/kinematic_models/kinematic_model_delta3d.cpp) file (there is an #define for that at the top). + +## Firmware v1.0.1 This update improves calibration, homing, logging, and adds several new G-Code commands. @@ -118,7 +159,7 @@ You can also 3D-Print the parts but have to live with thermal drift (carbon fill
The CAD files can be found here: [CAD Models](construction). -Please note that FreeCAD version **1.1.0dev** was used, and the files might not work with older versions. +Please note that FreeCAD version **1.2.0dev** was used, and the files might not work with older versions. STL files for printing can be found here: [STL Files](construction/STL_3D_Printing/) @@ -139,6 +180,8 @@ For usual winding resistance of your motors, the device should be powered by $${ Image 2 +The repository now also contains the fabrication files that can be directly uploaded to the PCB manufacturer. + ## ⚙ Firmware The firmware is written in C++ and takes some inspiration from the 'SimpleFOC' project. It aims to be streamlined and readable without any extra fuss, focusing on the hardware used in this project. @@ -170,6 +213,7 @@ The client must wait for an acknowledgment from the previous command before send | `G4 S/P` | Dwell/pause for a specified time.
• `S`: seconds
• `P`: milliseconds | | `G24 X Y Z A B C` | Directly set current pose for servo loops with optional rotation vector* `A`, `B`, `C`. | | `G28 A-F` | Home one or more joints.
• Optional joint selection `A`–`F`. | +| `M3` | Set Tool output.
• `T`: tool index
• `S`: output value (0.0..1.0)
Note: new values is only applied on the next motion or dwell command | | `M17` | Enable motors and read current pose as the start pose. | | `M18` | Disable motors. | | `M50` | Get current internal pose. (Encoders are not read here) | @@ -194,4 +238,6 @@ If you'd like to support this project, consider the following: - **Support the project on Ko-fi** – If you find this project valuable, you can support it financially via [Ko-fi](https://ko-fi.com/diffractionlimited) ☕. ## Youtube Video -[![Watch the video](images/thumbnail.jpg)](https://youtu.be/MgQbPdiuUTw) +[![Watch the video](images/video-thumbnails/01_MicroManipulator.jpg)](https://youtu.be/MgQbPdiuUTw) +[![Better Ball Joints for the Open Micro-Manipulator](images/video-thumbnails/02_BetterBallJoints.jpg)](https://youtu.be/MgQbPdiuUTw) + diff --git a/construction/micro_manipulator/Assembly_Actuator.FCStd b/construction/micro_manipulator/Assembly_Actuator.FCStd new file mode 100644 index 0000000..36f32ab Binary files /dev/null and b/construction/micro_manipulator/Assembly_Actuator.FCStd differ diff --git a/construction/micro_manipulator/Assembly_BallJointPlate.FCStd b/construction/micro_manipulator/Assembly_BallJointPlate.FCStd new file mode 100644 index 0000000..9b28632 Binary files /dev/null and b/construction/micro_manipulator/Assembly_BallJointPlate.FCStd differ diff --git a/construction/micro_manipulator/Assembly_EndEffector.FCStd b/construction/micro_manipulator/Assembly_EndEffector.FCStd new file mode 100644 index 0000000..4fbe479 Binary files /dev/null and b/construction/micro_manipulator/Assembly_EndEffector.FCStd differ diff --git a/construction/micro_manipulator/Assembly_LinkageUnit.FCStd b/construction/micro_manipulator/Assembly_LinkageUnit.FCStd new file mode 100644 index 0000000..08c6b74 Binary files /dev/null and b/construction/micro_manipulator/Assembly_LinkageUnit.FCStd differ diff --git a/construction/micro_manipulator/Assembly_MicroManipulator.FCStd b/construction/micro_manipulator/Assembly_MicroManipulator.FCStd new file mode 100644 index 0000000..589708b Binary files /dev/null and b/construction/micro_manipulator/Assembly_MicroManipulator.FCStd differ diff --git a/construction/micro_manipulator/BallJointPlate.FCStd b/construction/micro_manipulator/BallJointPlate.FCStd new file mode 100644 index 0000000..7207641 Binary files /dev/null and b/construction/micro_manipulator/BallJointPlate.FCStd differ diff --git a/construction/micro_manipulator/BaseBlock.FCStd b/construction/micro_manipulator/BaseBlock.FCStd new file mode 100644 index 0000000..189d0e9 Binary files /dev/null and b/construction/micro_manipulator/BaseBlock.FCStd differ diff --git a/construction/micro_manipulator/CrimpBead.FCStd b/construction/micro_manipulator/CrimpBead.FCStd new file mode 100644 index 0000000..98ca470 Binary files /dev/null and b/construction/micro_manipulator/CrimpBead.FCStd differ diff --git a/construction/v3/EncoderMagnet.FCStd b/construction/micro_manipulator/EncoderMagnet.FCStd similarity index 100% rename from construction/v3/EncoderMagnet.FCStd rename to construction/micro_manipulator/EncoderMagnet.FCStd diff --git a/construction/micro_manipulator/EncoderMagnetArray.FCStd b/construction/micro_manipulator/EncoderMagnetArray.FCStd new file mode 100644 index 0000000..eb1f6ff Binary files /dev/null and b/construction/micro_manipulator/EncoderMagnetArray.FCStd differ diff --git a/construction/micro_manipulator/EndEffector.FCStd b/construction/micro_manipulator/EndEffector.FCStd new file mode 100644 index 0000000..7dd66ea Binary files /dev/null and b/construction/micro_manipulator/EndEffector.FCStd differ diff --git a/construction/micro_manipulator/JointBall.FCStd b/construction/micro_manipulator/JointBall.FCStd new file mode 100644 index 0000000..a6c5ce6 Binary files /dev/null and b/construction/micro_manipulator/JointBall.FCStd differ diff --git a/construction/micro_manipulator/LinkageRod.FCStd b/construction/micro_manipulator/LinkageRod.FCStd new file mode 100644 index 0000000..1645b0d Binary files /dev/null and b/construction/micro_manipulator/LinkageRod.FCStd differ diff --git a/construction/micro_manipulator/MT6835.FCStd b/construction/micro_manipulator/MT6835.FCStd new file mode 100644 index 0000000..e6c2328 Binary files /dev/null and b/construction/micro_manipulator/MT6835.FCStd differ diff --git a/construction/micro_manipulator/MotorHorn.FCStd b/construction/micro_manipulator/MotorHorn.FCStd new file mode 100644 index 0000000..01ac53e Binary files /dev/null and b/construction/micro_manipulator/MotorHorn.FCStd differ diff --git a/construction/micro_manipulator/MotorMount.FCStd b/construction/micro_manipulator/MotorMount.FCStd new file mode 100644 index 0000000..4ece5eb Binary files /dev/null and b/construction/micro_manipulator/MotorMount.FCStd differ diff --git a/construction/micro_manipulator/RubberBand.FCStd b/construction/micro_manipulator/RubberBand.FCStd new file mode 100644 index 0000000..6d36e08 Binary files /dev/null and b/construction/micro_manipulator/RubberBand.FCStd differ diff --git a/construction/micro_manipulator/RubberBandCollet.FCStd b/construction/micro_manipulator/RubberBandCollet.FCStd new file mode 100644 index 0000000..492060b Binary files /dev/null and b/construction/micro_manipulator/RubberBandCollet.FCStd differ diff --git a/construction/micro_manipulator/StepperMotorNema17.FCStd b/construction/micro_manipulator/StepperMotorNema17.FCStd new file mode 100644 index 0000000..1d2594a Binary files /dev/null and b/construction/micro_manipulator/StepperMotorNema17.FCStd differ diff --git a/construction/micro_manipulator/balljoint_plate_pcb/BallJointPlate-Contour.dxf b/construction/micro_manipulator/balljoint_plate_pcb/BallJointPlate-Contour.dxf new file mode 100644 index 0000000..74fbf8b --- /dev/null +++ b/construction/micro_manipulator/balljoint_plate_pcb/BallJointPlate-Contour.dxf @@ -0,0 +1,1230 @@ +999 +FreeCAD v1.1 41365 (Git) + 0 +SECTION + 2 +HEADER + 9 +$ACADVER + 1 +AC1014 + 9 +$ACADMAINTVER + 70 + 9 + 9 +$DWGCODEPAGE + 3 +ANSI_1252 + 9 +$TEXTSTYLE + 7 +STANDARD + 9 +$DIMSTYLE + 2 +STANDARD + 9 +$DIMTXSTY + 7 +STANDARD + 9 +$CMLSTYLE + 2 +STANDARD + 9 +$LUNITS + 70 +2 + 9 +$INSUNITS + 70 +4 + 9 +$PEXTMAX + 10 +50 + 20 +50 + 30 +50 + 9 +$PEXTMIN + 10 +0 + 20 +0 + 30 +0 + 9 +$HANDSEED + 5 +FFFF + 0 +ENDSEC + 0 +SECTION + 2 +CLASSES + 0 +CLASS + 1 +ACDBDICTIONARYWDFLT + 2 +AcDbDictionaryWithDefault + 3 +ObjectDBX Classes + 90 + 0 +280 + 0 +281 + 0 + 0 +CLASS + 1 +XRECORD + 2 +AcDbXrecord + 3 +ObjectDBX Classes + 90 + 0 +280 + 0 +281 + 0 + 0 +CLASS + 1 +LWPOLYLINE + 2 +AcDbPolyline + 3 +ObjectDBX Classes + 90 + 0 +280 + 0 +281 + 1 + 0 +ENDSEC + 0 +SECTION + 2 +TABLES + 0 +TABLE + 2 +VPORT + 5 +20 +330 +0 +100 +AcDbSymbolTable + 70 + 1 + 0 +VPORT + 5 +21 +330 +20 +100 +AcDbSymbolTableRecord +100 +AcDbViewportTableRecord + 2 +*ACTIVE + 70 + 0 + 0 +ENDTAB + 0 +TABLE + 2 +LTYPE + 5 +22 +330 +0 +100 +AcDbSymbolTable + 70 + 1 + 0 +LTYPE + 5 +23 +330 +21 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +BYBLOCK + 70 + 0 + 3 + + 72 + 65 + 73 + 0 + 40 +0.0 + 0 +LTYPE + 5 +24 +330 +21 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +BYLAYER + 70 + 0 + 3 + + 72 + 65 + 73 + 0 + 40 +0.0 + 0 +LTYPE + 5 +25 +330 +21 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +CONTINUOUS + 70 + 0 + 3 +Solid line + 72 + 65 + 73 + 0 + 40 +0.0 + 0 +ENDTAB + 0 +TABLE + 2 +LAYER + 5 +A1E +330 +0 +100 +AcDbSymbolTable + 70 +3 + 0 +LAYER + 5 +A1F +330 +A1E +100 +AcDbSymbolTableRecord +100 +AcDbLayerTableRecord + 2 +0 + 70 + 0 + 62 + 7 + 6 +CONTINUOUS + 0 +LAYER + 5 +A20 +330 +A1E +100 +AcDbSymbolTableRecord +100 +AcDbLayerTableRecord + 2 +none + 70 + 0 + 62 + 7 + 6 +CONTINUOUS + 0 +LAYER + 5 +A21 +330 +A1E +100 +AcDbSymbolTableRecord +100 +AcDbLayerTableRecord + 2 +Shape2DView + 70 + 0 + 62 + 7 + 6 +CONTINUOUS + 0 +ENDTAB + 0 +TABLE + 2 +STYLE + 5 +70 +330 +0 +100 +AcDbSymbolTable + 70 + 2 + 0 +STYLE + 5 +71 +330 +70 +100 +AcDbSymbolTableRecord +100 +AcDbTextStyleTableRecord + 2 +STANDARD + 70 + 0 + 40 +0.0 + 41 +1.0 + 50 +0.0 + 71 + 0 + 42 +2.5 + 3 +arial.ttf + 4 + + 0 +STYLE + 5 +72 +330 +70 +100 +AcDbSymbolTableRecord +100 +AcDbTextStyleTableRecord + 2 +ANNOTATIVE + 70 + 0 + 40 +0.0 + 41 +1.0 + 50 +0.0 + 71 + 0 + 42 +2.5 + 3 +arial.ttf + 4 + + 0 +ENDTAB + 0 +TABLE + 2 +VIEW + 5 +73 +330 +0 +100 +AcDbSymbolTable + 70 + 0 + 0 +ENDTAB + 0 +TABLE + 2 +UCS + 5 +74 +330 +0 +100 +AcDbSymbolTable + 70 + 0 + 0 +ENDTAB + 0 +TABLE + 2 +APPID + 5 +75 +330 +0 +100 +AcDbSymbolTable + 70 + 2 + 0 +APPID + 5 +76 +330 +75 +100 +AcDbSymbolTableRecord +100 +AcDbRegAppTableRecord + 2 +ACAD + 70 + 0 + 0 +APPID + 5 +77 +330 +75 +100 +AcDbSymbolTableRecord +100 +AcDbRegAppTableRecord + 2 +ACADANNOTATIVE + 70 + 0 + 0 +ENDTAB + 0 +TABLE + 2 +DIMSTYLE + 5 +78 +330 +0 +100 +AcDbSymbolTable + 70 + 2 + 0 +DIMSTYLE +105 +79 +330 +78 +100 +AcDbSymbolTableRecord +100 +AcDbDimStyleTableRecord + 2 +STANDARD + 70 + 0 + 3 + + 4 + + 5 + + 6 + + 7 + + 40 +0.0 + 41 +2.5 + 42 +0.625 + 43 +3.75 + 44 +1.25 + 45 +0.0 + 46 +0.0 + 47 +0.0 + 48 +0.0 +140 +2.5 +141 +2.5 +142 +0.0 +143 +0.03937007874016 +144 +1.0 +145 +0.0 +146 +1.0 +147 +0.625 + 71 + 0 + 72 + 0 + 73 + 0 + 74 + 0 + 75 + 0 + 76 + 0 + 77 + 1 + 78 + 8 +170 + 0 +171 + 3 +172 + 1 +173 + 0 +174 + 0 +175 + 0 +176 + 0 +177 + 0 +178 + 0 +270 + 2 +271 + 2 +272 + 2 +273 + 2 +274 + 3 +340 +71 +275 + 0 +280 + 0 +281 + 0 +282 + 0 +283 + 0 +284 + 8 +285 + 0 +286 + 0 +287 + 3 +288 + 0 + 0 +ENDTAB + 0 +TABLE + 2 +BLOCK_RECORD + 5 +A01 +330 +0 +100 +AcDbSymbolTable + 70 +5 + 0 +BLOCK_RECORD + 5 +A02 +330 +A01 +100 +AcDbSymbolTableRecord +100 +AcDbBlockTableRecord + 2 +*MODEL_SPACE + 0 +BLOCK_RECORD + 5 +A03 +330 +A01 +100 +AcDbSymbolTableRecord +100 +AcDbBlockTableRecord + 2 +*PAPER_SPACE + 0 +ENDTAB + 0 +ENDSEC + 0 +SECTION + 2 +BLOCKS + 0 +BLOCK + 5 +A04 +330 +A02 +100 +AcDbEntity + 8 +0 +100 +AcDbBlockBegin + 2 +*MODEL_SPACE + 70 + 0 + 10 +0 + 20 +0 + 30 +0 + 3 +*MODEL_SPACE + 1 + + 0 +ENDBLK + 5 +A05 +330 +A02 +100 +AcDbEntity + 8 +0 +100 +AcDbBlockEnd + 0 +BLOCK + 5 +A06 +330 +A03 +100 +AcDbEntity + 67 +1 + 8 +0 +100 +AcDbBlockBegin + 2 +*PAPER_SPACE + 70 + 0 + 10 +0 + 20 +0 + 30 +0 + 3 +*PAPER_SPACE + 1 + + 0 +ENDBLK + 5 +A07 +330 +A03 +100 +AcDbEntity + 67 + 1 + 8 +0 +100 +AcDbBlockEnd + 0 +ENDSEC + 0 +SECTION + 2 +ENTITIES + 0 +LINE + 5 +A08 +330 +A02 +100 +AcDbEntity + 8 +Shape2DView +100 +AcDbLine + 10 +-7.085786438 + 20 +-5.000000000 + 30 +0.000000000 + 11 +7.085786438 + 21 +-5.000000000 + 31 +0.000000000 + 0 +ARC + 5 +A09 +330 +A02 +100 +AcDbEntity + 8 +Shape2DView +100 +AcDbCircle + 10 +7.085786438 + 20 +-4.000000000 + 30 +0.000000000 + 40 +1.000000000 +100 +AcDbArc + 50 +-90.000000000 + 51 +-45.000000000 + 0 +ARC + 5 +A0A +330 +A02 +100 +AcDbEntity + 8 +Shape2DView +100 +AcDbCircle + 10 +-7.085786438 + 20 +-4.000000000 + 30 +0.000000000 + 40 +1.000000000 +100 +AcDbArc + 50 +-135.000000000 + 51 +-90.000000000 + 0 +LINE + 5 +A0B +330 +A02 +100 +AcDbEntity + 8 +Shape2DView +100 +AcDbLine + 10 +-7.792893219 + 20 +-4.707106781 + 30 +0.000000000 + 11 +-9.707106781 + 21 +-2.792893219 + 31 +0.000000000 + 0 +ARC + 5 +A0C +330 +A02 +100 +AcDbEntity + 8 +Shape2DView +100 +AcDbCircle + 10 +-9.000000000 + 20 +-2.085786438 + 30 +0.000000000 + 40 +1.000000000 +100 +AcDbArc + 50 +180.000000000 + 51 +-135.000000000 + 0 +LINE + 5 +A0D +330 +A02 +100 +AcDbEntity + 8 +Shape2DView +100 +AcDbLine + 10 +-10.000000000 + 20 +2.000000000 + 30 +0.000000000 + 11 +-10.000000000 + 21 +-2.085786438 + 31 +0.000000000 + 0 +ARC + 5 +A0E +330 +A02 +100 +AcDbEntity + 8 +Shape2DView +100 +AcDbCircle + 10 +-9.000000000 + 20 +2.000000000 + 30 +0.000000000 + 40 +1.000000000 +100 +AcDbArc + 50 +90.000000000 + 51 +180.000000000 + 0 +LINE + 5 +A0F +330 +A02 +100 +AcDbEntity + 8 +Shape2DView +100 +AcDbLine + 10 +9.000000000 + 20 +3.000000000 + 30 +0.000000000 + 11 +-9.000000000 + 21 +3.000000000 + 31 +0.000000000 + 0 +ARC + 5 +A10 +330 +A02 +100 +AcDbEntity + 8 +Shape2DView +100 +AcDbCircle + 10 +9.000000000 + 20 +2.000000000 + 30 +0.000000000 + 40 +1.000000000 +100 +AcDbArc + 50 +-0.000000000 + 51 +90.000000000 + 0 +LINE + 5 +A11 +330 +A02 +100 +AcDbEntity + 8 +Shape2DView +100 +AcDbLine + 10 +10.000000000 + 20 +-2.085786438 + 30 +0.000000000 + 11 +10.000000000 + 21 +2.000000000 + 31 +0.000000000 + 0 +ARC + 5 +A12 +330 +A02 +100 +AcDbEntity + 8 +Shape2DView +100 +AcDbCircle + 10 +9.000000000 + 20 +-2.085786438 + 30 +0.000000000 + 40 +1.000000000 +100 +AcDbArc + 50 +-45.000000000 + 51 +-0.000000000 + 0 +LINE + 5 +A13 +330 +A02 +100 +AcDbEntity + 8 +Shape2DView +100 +AcDbLine + 10 +7.792893219 + 20 +-4.707106781 + 30 +0.000000000 + 11 +9.707106781 + 21 +-2.792893219 + 31 +0.000000000 + 0 +CIRCLE + 5 +A14 +330 +A02 +100 +AcDbEntity + 8 +Shape2DView +100 +AcDbCircle + 10 +-4.750000000 + 20 +-3.000000000 + 30 +0.000000000 + 40 +1.000000000 + 0 +CIRCLE + 5 +A15 +330 +A02 +100 +AcDbEntity + 8 +Shape2DView +100 +AcDbCircle + 10 +-8.500000000 + 20 +-1.750000000 + 30 +0.000000000 + 40 +0.600000000 + 0 +CIRCLE + 5 +A16 +330 +A02 +100 +AcDbEntity + 8 +Shape2DView +100 +AcDbCircle + 10 +4.750000000 + 20 +-3.000000000 + 30 +0.000000000 + 40 +1.000000000 + 0 +CIRCLE + 5 +A17 +330 +A02 +100 +AcDbEntity + 8 +Shape2DView +100 +AcDbCircle + 10 +8.500000000 + 20 +-1.750000000 + 30 +0.000000000 + 40 +0.600000000 + 0 +CIRCLE + 5 +A18 +330 +A02 +100 +AcDbEntity + 8 +Shape2DView +100 +AcDbCircle + 10 +-8.500000000 + 20 +-0.000000000 + 30 +0.000000000 + 40 +0.350000000 + 0 +CIRCLE + 5 +A19 +330 +A02 +100 +AcDbEntity + 8 +Shape2DView +100 +AcDbCircle + 10 +-4.750000000 + 20 +0.000000000 + 30 +0.000000000 + 40 +1.000000000 + 0 +CIRCLE + 5 +A1A +330 +A02 +100 +AcDbEntity + 8 +Shape2DView +100 +AcDbCircle + 10 +-8.500000000 + 20 +1.750000000 + 30 +0.000000000 + 40 +0.600000000 + 0 +CIRCLE + 5 +A1B +330 +A02 +100 +AcDbEntity + 8 +Shape2DView +100 +AcDbCircle + 10 +4.750000000 + 20 +-0.000000000 + 30 +0.000000000 + 40 +1.000000000 + 0 +CIRCLE + 5 +A1C +330 +A02 +100 +AcDbEntity + 8 +Shape2DView +100 +AcDbCircle + 10 +8.500000000 + 20 +-0.000000000 + 30 +0.000000000 + 40 +0.350000000 + 0 +CIRCLE + 5 +A1D +330 +A02 +100 +AcDbEntity + 8 +Shape2DView +100 +AcDbCircle + 10 +8.500000000 + 20 +1.750000000 + 30 +0.000000000 + 40 +0.600000000 + 0 +ENDSEC + 0 +SECTION + 2 +OBJECTS + 0 +DICTIONARY + 5 +F000 +330 +0 +100 +AcDbDictionary + 3 +ACAD_GROUP +350 +F001 + 0 +DICTIONARY + 5 +F001 +330 +F000 +100 +AcDbDictionary + 0 +ENDSEC + 0 +EOF \ No newline at end of file diff --git a/construction/micro_manipulator/balljoint_plate_pcb/balljoint_plate_pcb.kicad_pcb b/construction/micro_manipulator/balljoint_plate_pcb/balljoint_plate_pcb.kicad_pcb new file mode 100644 index 0000000..cda8e79 --- /dev/null +++ b/construction/micro_manipulator/balljoint_plate_pcb/balljoint_plate_pcb.kicad_pcb @@ -0,0 +1,1279 @@ +(kicad_pcb + (version 20241229) + (generator "pcbnew") + (generator_version "9.0") + (general + (thickness 1.6) + (legacy_teardrops no) + ) + (paper "A4") + (layers + (0 "F.Cu" signal) + (2 "B.Cu" signal) + (9 "F.Adhes" user "F.Adhesive") + (11 "B.Adhes" user "B.Adhesive") + (13 "F.Paste" user) + (15 "B.Paste" user) + (5 "F.SilkS" user "F.Silkscreen") + (7 "B.SilkS" user "B.Silkscreen") + (1 "F.Mask" user) + (3 "B.Mask" user) + (17 "Dwgs.User" user "User.Drawings") + (19 "Cmts.User" user "User.Comments") + (21 "Eco1.User" user "User.Eco1") + (23 "Eco2.User" user "User.Eco2") + (25 "Edge.Cuts" user) + (27 "Margin" user) + (31 "F.CrtYd" user "F.Courtyard") + (29 "B.CrtYd" user "B.Courtyard") + (35 "F.Fab" user) + (33 "B.Fab" user) + (39 "User.1" user) + (41 "User.2" user) + (43 "User.3" user) + (45 "User.4" user) + ) + (setup + (pad_to_mask_clearance 0) + (allow_soldermask_bridges_in_footprints no) + (tenting front back) + (grid_origin 150 80) + (pcbplotparams + (layerselection 0x00000000_00000000_55555555_5755f5ff) + (plot_on_all_layers_selection 0x00000000_00000000_00000000_00000000) + (disableapertmacros no) + (usegerberextensions no) + (usegerberattributes yes) + (usegerberadvancedattributes yes) + (creategerberjobfile yes) + (dashed_line_dash_ratio 12.000000) + (dashed_line_gap_ratio 3.000000) + (svgprecision 4) + (plotframeref no) + (mode 1) + (useauxorigin no) + (hpglpennumber 1) + (hpglpenspeed 20) + (hpglpendiameter 15.000000) + (pdf_front_fp_property_popups yes) + (pdf_back_fp_property_popups yes) + (pdf_metadata yes) + (pdf_single_document no) + (dxfpolygonmode yes) + (dxfimperialunits yes) + (dxfusepcbnewfont yes) + (psnegative no) + (psa4output no) + (plot_black_and_white yes) + (sketchpadsonfab no) + (plotpadnumbers no) + (hidednponfab no) + (sketchdnponfab yes) + (crossoutdnponfab yes) + (subtractmaskfromsilk no) + (outputformat 1) + (mirror no) + (drillshape 1) + (scaleselection 1) + (outputdirectory "") + ) + ) + (net 0 "") + (footprint "MountingHole:MountingHole_2mm" + (layer "F.Cu") + (uuid "0c148355-8937-4590-8faf-e4225d14dce0") + (at 158.5 81.75) + (descr "Mounting Hole 2mm, no annular, generated by kicad-footprint-generator mountinghole.py") + (tags "mountinghole") + (property "Reference" "H9" + (at 0 -2.95 0) + (layer "F.SilkS") + (hide yes) + (uuid "f918860a-c693-4c04-8f12-a7f530b9e6ac") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Value" "MountingHole" + (at 0 2.95 0) + (layer "F.Fab") + (hide yes) + (uuid "567764cd-dbc3-4047-97dd-57112b2891ad") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Datasheet" "" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "32ddd030-4c29-4eeb-b2d2-416788d37adb") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property "Description" "Mounting Hole without connection" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "0a51ab40-3ff8-475a-869a-20eada6731fb") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property ki_fp_filters "MountingHole*") + (path "/fe98a2dd-c6f8-4781-ad26-1f0d6d940384") + (sheetname "/") + (sheetfile "balljoint_plate_pcb.kicad_sch") + (attr exclude_from_pos_files exclude_from_bom) + (pad "" thru_hole circle + (at 0 0) + (size 2 2) + (drill 1) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (uuid "9da372fa-a7d6-4c89-9953-36e19c6d1bbc") + ) + (embedded_fonts no) + ) + (footprint "MountingHole:MountingHole_2mm" + (layer "F.Cu") + (uuid "1d682d90-d6c7-4342-a5a0-23e1a3bba53d") + (at 141.5 78.25) + (descr "Mounting Hole 2mm, no annular, generated by kicad-footprint-generator mountinghole.py") + (tags "mountinghole") + (property "Reference" "H10" + (at 0 -2.95 0) + (layer "F.SilkS") + (hide yes) + (uuid "7870a08b-63cb-4f2d-8505-0f8e8331d066") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Value" "MountingHole" + (at 0 2.95 0) + (layer "F.Fab") + (hide yes) + (uuid "72c238af-8515-4f6e-95d5-8e67c5f5e695") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Datasheet" "" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "223a8c0c-65ef-42a2-a119-dae3c79cdc48") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property "Description" "Mounting Hole without connection" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "85797136-278f-4488-bc87-f3ebd1cdebcb") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property ki_fp_filters "MountingHole*") + (path "/ef8cad87-32d9-4829-8ec4-9aba40945885") + (sheetname "/") + (sheetfile "balljoint_plate_pcb.kicad_sch") + (attr exclude_from_pos_files exclude_from_bom) + (pad "" thru_hole circle + (at 0 0) + (size 2 2) + (drill 1) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (uuid "16921fd4-90c8-4243-be1a-03cf5e52905f") + ) + (embedded_fonts no) + ) + (footprint "MountingHole:MountingHole_2mm" + (layer "F.Cu") + (uuid "30e3de66-6697-4e66-8a3f-3a424f95f2bc") + (at 145.25 83) + (descr "Mounting Hole 2mm, no annular, generated by kicad-footprint-generator mountinghole.py") + (tags "mountinghole") + (property "Reference" "H4" + (at 0 -2.95 0) + (layer "F.SilkS") + (hide yes) + (uuid "0c99f4e4-eedc-4d9d-a5b5-3de5b2f81306") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Value" "MountingHole" + (at 0 2.95 0) + (layer "F.Fab") + (uuid "93fc6c72-0fc2-4c88-816d-339a210b96d8") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Datasheet" "" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "db512bdc-14d8-4043-8609-bd7b25506559") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property "Description" "Mounting Hole without connection" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "f7ac65ae-281e-485f-9210-6359192e1793") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property ki_fp_filters "MountingHole*") + (path "/ea0c2fa5-13e6-496d-a0ba-a48b9d6ec936") + (sheetname "/") + (sheetfile "balljoint_plate_pcb.kicad_sch") + (attr exclude_from_pos_files exclude_from_bom) + (fp_text user "${REFERENCE}" + (at 0 0 0) + (layer "F.Fab") + (uuid "279975d2-d8d8-4ca0-990d-7f185468d5b9") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (pad "" np_thru_hole circle + (at 0 0) + (size 2 2) + (drill 2) + (layers "*.Cu" "*.Mask") + (uuid "7405c935-08ab-412e-8f4d-b59de7c3e248") + ) + (embedded_fonts no) + ) + (footprint "MountingHole:MountingHole_2mm" + (layer "F.Cu") + (uuid "5f2e8ec0-b9c0-478d-809e-715efb0e3a8d") + (at 158.5 78.25) + (descr "Mounting Hole 2mm, no annular, generated by kicad-footprint-generator mountinghole.py") + (tags "mountinghole") + (property "Reference" "H5" + (at 0 -2.95 0) + (layer "F.SilkS") + (hide yes) + (uuid "5643f0be-5bfa-4ca3-8d6b-2f0197dcfa25") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Value" "MountingHole" + (at 0 2.95 0) + (layer "F.Fab") + (hide yes) + (uuid "01d08d65-266c-442b-9568-11929b1b6eee") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Datasheet" "" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "65596d4a-83e8-49f9-b1ac-d822dc81ef78") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property "Description" "Mounting Hole without connection" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "169b3ca4-c375-4f06-a301-8dffc1d5bb26") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property ki_fp_filters "MountingHole*") + (path "/bf678316-db0e-4397-9446-1c043850ee54") + (sheetname "/") + (sheetfile "balljoint_plate_pcb.kicad_sch") + (attr exclude_from_pos_files exclude_from_bom) + (pad "" thru_hole circle + (at 0 0) + (size 2 2) + (drill 1) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (uuid "9dc7e8b2-403c-45ca-8199-29a760cf52bc") + ) + (embedded_fonts no) + ) + (footprint "MountingHole:MountingHole_2mm" + (layer "F.Cu") + (uuid "64ef2fe1-4fd0-4e11-b2b2-642cb78682a1") + (at 158.5 80) + (descr "Mounting Hole 2mm, no annular, generated by kicad-footprint-generator mountinghole.py") + (tags "mountinghole") + (property "Reference" "H7" + (at 0 -2.95 0) + (layer "F.SilkS") + (hide yes) + (uuid "204f8a73-6a67-43f0-b944-ab10b8892776") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Value" "MountingHole" + (at 0 2.95 0) + (layer "F.Fab") + (hide yes) + (uuid "e787af3d-8da8-44e8-a135-9abd114cce51") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Datasheet" "" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "492093b1-bc7c-4fa1-a469-615014575acb") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property "Description" "Mounting Hole without connection" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "e4ddaadb-e2fd-4aa1-bc15-487800d1efd9") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property ki_fp_filters "MountingHole*") + (path "/22cd77c6-6419-49c9-a315-e5470917281d") + (sheetname "/") + (sheetfile "balljoint_plate_pcb.kicad_sch") + (attr exclude_from_pos_files exclude_from_bom) + (pad "" np_thru_hole circle + (at 0 0) + (size 0.8 0.8) + (drill 0.8) + (layers "*.Cu" "*.Mask") + (uuid "44fe3548-dc5e-4d90-aeb4-f86df0d84b98") + ) + (embedded_fonts no) + ) + (footprint "MountingHole:MountingHole_2mm" + (layer "F.Cu") + (uuid "67bc8b48-5be7-4572-bfbb-72883188e43b") + (at 145.25 80) + (descr "Mounting Hole 2mm, no annular, generated by kicad-footprint-generator mountinghole.py") + (tags "mountinghole") + (property "Reference" "H3" + (at 0 -2.95 0) + (layer "F.SilkS") + (hide yes) + (uuid "a638f975-164c-4f9b-a292-5299530e4e8e") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Value" "MountingHole" + (at 0 2.95 0) + (layer "F.Fab") + (uuid "dcf7eb89-1747-401e-a5fb-45f5705c0564") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Datasheet" "" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "b96d887c-2013-49cb-a8d3-7ae569237d6f") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property "Description" "Mounting Hole without connection" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "7a433481-900f-4b9e-9411-7733be4aec61") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property ki_fp_filters "MountingHole*") + (path "/ce16cea6-101f-4ffc-a2f6-b65e2eb092ea") + (sheetname "/") + (sheetfile "balljoint_plate_pcb.kicad_sch") + (attr exclude_from_pos_files exclude_from_bom) + (fp_text user "${REFERENCE}" + (at 0 0 0) + (layer "F.Fab") + (uuid "323974f5-d5d1-48d4-9012-e212f9f34795") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (pad "" np_thru_hole circle + (at 0 0) + (size 2 2) + (drill 2) + (layers "*.Cu" "*.Mask") + (uuid "b0b70f22-2038-4cc6-ad9e-0b19a6bd01c3") + ) + (embedded_fonts no) + ) + (footprint "MountingHole:MountingHole_2mm" + (layer "F.Cu") + (uuid "ac391abc-0248-47d9-a461-94f403005c9e") + (at 141.5 80) + (descr "Mounting Hole 2mm, no annular, generated by kicad-footprint-generator mountinghole.py") + (tags "mountinghole") + (property "Reference" "H8" + (at 0 -2.95 0) + (layer "F.SilkS") + (hide yes) + (uuid "685ea87c-ef45-43c1-99e4-ffe921293c76") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Value" "MountingHole" + (at 0 2.95 0) + (layer "F.Fab") + (hide yes) + (uuid "e5a3f4af-c4fe-4ea6-af3c-284f8e938958") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Datasheet" "" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "a9e54724-3042-4578-a12a-51c208264387") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property "Description" "Mounting Hole without connection" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "9c128c6f-0902-4481-a377-ee72ca2a5da2") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property ki_fp_filters "MountingHole*") + (path "/e2172f75-ac85-4747-8e3f-8bd8f214554d") + (sheetname "/") + (sheetfile "balljoint_plate_pcb.kicad_sch") + (attr exclude_from_pos_files exclude_from_bom) + (pad "" np_thru_hole circle + (at 0 0) + (size 0.8 0.8) + (drill 0.8) + (layers "*.Cu" "*.Mask") + (uuid "7591ff1c-7e55-4691-bdda-2f621556f07a") + ) + (embedded_fonts no) + ) + (footprint "MountingHole:MountingHole_2mm" + (layer "F.Cu") + (uuid "d9259034-b892-4fbc-80d8-3dd07155ede9") + (at 154.75 80) + (descr "Mounting Hole 2mm, no annular, generated by kicad-footprint-generator mountinghole.py") + (tags "mountinghole") + (property "Reference" "H1" + (at 0 -2.95 0) + (layer "F.SilkS") + (hide yes) + (uuid "69c7ce72-112c-43cd-9023-e885b115d1a7") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Value" "MountingHole" + (at 0 2.95 0) + (layer "F.Fab") + (hide yes) + (uuid "036ca1e4-0d7b-41e4-b161-5297a46fcbf6") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Datasheet" "" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "6c0717f0-7fc2-498d-8e29-969a9647678a") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property "Description" "Mounting Hole without connection" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "91a92264-db0b-467d-a8c5-8741993c45ea") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property ki_fp_filters "MountingHole*") + (path "/35b726c5-8939-42dc-9c24-6937721b1381") + (sheetname "/") + (sheetfile "balljoint_plate_pcb.kicad_sch") + (attr exclude_from_pos_files exclude_from_bom) + (pad "" np_thru_hole circle + (at 0 0) + (size 2 2) + (drill 2) + (layers "*.Cu" "*.Mask") + (uuid "9259ec48-7fd6-499a-a49c-b5352e0e508e") + ) + (embedded_fonts no) + ) + (footprint "MountingHole:MountingHole_2mm" + (layer "F.Cu") + (uuid "e3f2f65f-55c0-4b12-92f6-db3dbd3f8ca2") + (at 141.5 81.75) + (descr "Mounting Hole 2mm, no annular, generated by kicad-footprint-generator mountinghole.py") + (tags "mountinghole") + (property "Reference" "H6" + (at 0 -2.95 0) + (layer "F.SilkS") + (hide yes) + (uuid "25011f75-7824-4b1b-a53d-b947258523ea") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Value" "MountingHole" + (at 0 2.95 0) + (layer "F.Fab") + (hide yes) + (uuid "13646420-13d5-43a1-a899-72c0fc944e00") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Datasheet" "" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "e609939b-7184-463f-b151-dbf4ac10c667") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property "Description" "Mounting Hole without connection" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "0e237a9b-7ab8-496e-b1e4-e2ce4918879c") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property ki_fp_filters "MountingHole*") + (path "/77599518-9e81-421c-a589-255563863e7d") + (sheetname "/") + (sheetfile "balljoint_plate_pcb.kicad_sch") + (attr exclude_from_pos_files exclude_from_bom) + (pad "" thru_hole circle + (at 0 0) + (size 2 2) + (drill 1) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (uuid "c79415a6-2ef5-4c29-af34-618beb7b7e08") + ) + (embedded_fonts no) + ) + (footprint "MountingHole:MountingHole_2mm" + (layer "F.Cu") + (uuid "e7f0314e-f532-4a27-a741-8443c74ab68b") + (at 154.75 83) + (descr "Mounting Hole 2mm, no annular, generated by kicad-footprint-generator mountinghole.py") + (tags "mountinghole") + (property "Reference" "H2" + (at 0 -2.95 0) + (layer "F.SilkS") + (hide yes) + (uuid "0fa082d9-cba6-47fb-bf28-aad4fb47b7bb") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Value" "MountingHole" + (at 0 2.95 0) + (layer "F.Fab") + (uuid "d2121ee4-382e-461a-ba7c-e2baebc664c9") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Datasheet" "" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "5f104ca9-2390-4c3c-aff1-7a9142b77064") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property "Description" "Mounting Hole without connection" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "37724620-4bdf-423d-89ad-25dd402642d1") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property ki_fp_filters "MountingHole*") + (path "/fb8c5c26-8db1-405b-b136-fb52772326a9") + (sheetname "/") + (sheetfile "balljoint_plate_pcb.kicad_sch") + (attr exclude_from_pos_files exclude_from_bom) + (fp_text user "${REFERENCE}" + (at 0 0 0) + (layer "F.Fab") + (uuid "13a434ea-f65d-4c95-a439-6fa812958912") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (pad "" np_thru_hole circle + (at 0 0) + (size 2 2) + (drill 2) + (layers "*.Cu" "*.Mask") + (uuid "c366281d-96eb-468c-a89c-fe1afd0bbf36") + ) + (embedded_fonts no) + ) + (gr_circle + (center 158.5 80) + (end 159.5 80) + (stroke + (width 0.5) + (type solid) + ) + (fill no) + (layer "F.Cu") + (uuid "1318d3c3-1a1d-492b-99c7-14442cc499a9") + ) + (gr_circle + (center 141.5 80) + (end 142.5 80) + (stroke + (width 0.5) + (type solid) + ) + (fill no) + (layer "F.Cu") + (uuid "57870389-142d-4e6d-9327-354cf040e612") + ) + (gr_circle + (center 141.5 80) + (end 142.25 80) + (stroke + (width 0.01) + (type solid) + ) + (fill yes) + (layer "F.Mask") + (uuid "3314a7ba-9c39-4fa8-86bc-31613ed7026c") + ) + (gr_circle + (center 158.5 80) + (end 159.25 80) + (stroke + (width 0.01) + (type solid) + ) + (fill yes) + (layer "F.Mask") + (uuid "e864d7ff-3cd5-4180-b444-26b97546088a") + ) + (gr_circle + (center 151.5 84) + (end 152 84) + (stroke + (width 0) + (type solid) + ) + (fill yes) + (layer "F.SilkS") + (uuid "08fcbaef-6a2c-422c-9f26-ef3f049c6594") + ) + (gr_circle + (center 148.5 81) + (end 149 81) + (stroke + (width 0) + (type solid) + ) + (fill yes) + (layer "F.SilkS") + (uuid "0b25bf7a-6376-4518-b557-3e4d39c01bcd") + ) + (gr_circle + (center 150 81) + (end 150.5 81) + (stroke + (width 0) + (type solid) + ) + (fill yes) + (layer "F.SilkS") + (uuid "207ecfde-071b-41f5-9e54-94564ca83a60") + ) + (gr_circle + (center 141.5 80) + (end 143.5 80) + (stroke + (width 2.5) + (type solid) + ) + (fill no) + (layer "F.SilkS") + (uuid "26a958ed-1f94-46a5-99bf-f7b3f56edaf7") + ) + (gr_circle + (center 148.5 82.5) + (end 149 82.5) + (stroke + (width 0) + (type solid) + ) + (fill yes) + (layer "F.SilkS") + (uuid "29a6d5af-8527-4483-ad1b-63021072495c") + ) + (gr_circle + (center 150 82.5) + (end 150.5 82.5) + (stroke + (width 0) + (type solid) + ) + (fill yes) + (layer "F.SilkS") + (uuid "351b7510-6fa5-4552-84a8-1321feeb6347") + ) + (gr_circle + (center 151.5 81) + (end 152 81) + (stroke + (width 0) + (type solid) + ) + (fill yes) + (layer "F.SilkS") + (uuid "372e0c51-50ef-41ac-b3ef-63a160b53933") + ) + (gr_circle + (center 151.5 78) + (end 152 78) + (stroke + (width 0) + (type solid) + ) + (fill yes) + (layer "F.SilkS") + (uuid "3fbf605d-f877-4344-be0f-493c6bc7fa1d") + ) + (gr_circle + (center 150 78) + (end 150.5 78) + (stroke + (width 0) + (type solid) + ) + (fill yes) + (layer "F.SilkS") + (uuid "53b00169-e0e4-4d71-a02a-d87b13893f68") + ) + (gr_circle + (center 150 79.5) + (end 150.5 79.5) + (stroke + (width 0) + (type solid) + ) + (fill yes) + (layer "F.SilkS") + (uuid "6d23a736-2d85-434d-bda5-2edc4c6873a7") + ) + (gr_circle + (center 150 84) + (end 150.5 84) + (stroke + (width 0) + (type solid) + ) + (fill yes) + (layer "F.SilkS") + (uuid "6d94f2da-f79a-4992-b402-5f33b17b310d") + ) + (gr_circle + (center 151.5 79.5) + (end 152 79.5) + (stroke + (width 0) + (type solid) + ) + (fill yes) + (layer "F.SilkS") + (uuid "6e0d4f73-9337-4aea-80a6-c220190d9329") + ) + (gr_circle + (center 148.5 78) + (end 149 78) + (stroke + (width 0) + (type solid) + ) + (fill yes) + (layer "F.SilkS") + (uuid "8eda3e65-9721-4392-ba1c-d2e289e4ab9a") + ) + (gr_circle + (center 151.5 82.5) + (end 152 82.5) + (stroke + (width 0) + (type solid) + ) + (fill yes) + (layer "F.SilkS") + (uuid "a31cdcd4-7b70-4c38-b789-90d743589d14") + ) + (gr_circle + (center 148.5 84) + (end 149 84) + (stroke + (width 0) + (type solid) + ) + (fill yes) + (layer "F.SilkS") + (uuid "a775878f-46f1-4a9f-8a52-ca8e4d892cff") + ) + (gr_circle + (center 148.5 79.5) + (end 149 79.5) + (stroke + (width 0) + (type solid) + ) + (fill yes) + (layer "F.SilkS") + (uuid "b41561b0-45a6-46cf-ae95-568124f2512f") + ) + (gr_circle + (center 158.5 80) + (end 160.5 80) + (stroke + (width 2.5) + (type solid) + ) + (fill no) + (layer "F.SilkS") + (uuid "b61ad354-d4f9-456d-a53b-e1e09a2e4e1a") + ) + (gr_arc + (start 157.792893 84.707107) + (mid 157.468469 84.923875) + (end 157.085786 85) + (stroke + (width 0.1) + (type default) + ) + (layer "Edge.Cuts") + (uuid "135acae0-2c15-4bcf-ad00-cb071b276e08") + ) + (gr_line + (start 142.207107 84.707107) + (end 140.292893 82.792893) + (stroke + (width 0.1) + (type default) + ) + (layer "Edge.Cuts") + (uuid "5fd5cc1c-be3a-47c7-a8b9-1c5c1121a433") + ) + (gr_arc + (start 140.292893 82.792893) + (mid 140.07612 82.46847) + (end 140 82.085786) + (stroke + (width 0.1) + (type default) + ) + (layer "Edge.Cuts") + (uuid "64ee3463-3a46-4d30-9f31-95be6e1df41c") + ) + (gr_arc + (start 140 78) + (mid 140.292893 77.292893) + (end 141 77) + (stroke + (width 0.1) + (type default) + ) + (layer "Edge.Cuts") + (uuid "6f8c62a7-4fdd-4165-8593-f5123ae8c185") + ) + (gr_arc + (start 142.914214 85) + (mid 142.53153 84.92388) + (end 142.207107 84.707107) + (stroke + (width 0.1) + (type default) + ) + (layer "Edge.Cuts") + (uuid "7e87d578-da4f-4a98-aab8-5d12e02d61ea") + ) + (gr_arc + (start 160 82.085786) + (mid 159.923884 82.468472) + (end 159.707107 82.792893) + (stroke + (width 0.1) + (type default) + ) + (layer "Edge.Cuts") + (uuid "827a80d5-4237-4a7a-91d2-03f1c22fe389") + ) + (gr_line + (start 157.792893 84.707107) + (end 159.707107 82.792893) + (stroke + (width 0.1) + (type default) + ) + (layer "Edge.Cuts") + (uuid "875299c7-8aa7-4881-bd85-65e21c9872ed") + ) + (gr_line + (start 142.914214 85) + (end 157.085786 85) + (stroke + (width 0.1) + (type default) + ) + (layer "Edge.Cuts") + (uuid "9616804d-ac4e-471a-954e-356988d34c0b") + ) + (gr_line + (start 140 78) + (end 140 82.085786) + (stroke + (width 0.1) + (type default) + ) + (layer "Edge.Cuts") + (uuid "bc641ccd-ebf8-46c4-8d46-84ec8b81c24e") + ) + (gr_line + (start 159 77) + (end 141 77) + (stroke + (width 0.1) + (type default) + ) + (layer "Edge.Cuts") + (uuid "bde7fbac-52be-494e-b172-cb2cb12af5c2") + ) + (gr_line + (start 160 82.085786) + (end 160 78) + (stroke + (width 0.1) + (type default) + ) + (layer "Edge.Cuts") + (uuid "cee9fd88-6f61-4da7-90af-63a03015800a") + ) + (gr_arc + (start 159 77) + (mid 159.707107 77.292893) + (end 160 78) + (stroke + (width 0.1) + (type default) + ) + (layer "Edge.Cuts") + (uuid "de616fc2-3a46-4e40-ab0e-af24fa514d96") + ) + (zone + (net 0) + (net_name "") + (layer "B.Mask") + (uuid "a72854d7-b5db-4a93-ab0b-dc38eb14f372") + (hatch edge 0.5) + (connect_pads + (clearance 0) + ) + (min_thickness 0.25) + (filled_areas_thickness no) + (fill yes + (thermal_gap 0.5) + (thermal_bridge_width 0.5) + ) + (polygon + (pts + (xy 139.5 76.5) (xy 160.5 76.5) (xy 160.5 85.75) (xy 139.5 85.75) + ) + ) + (filled_polygon + (layer "B.Mask") + (island) + (pts + (xy 159.001509 77.000037) (xy 159.087578 77.002145) (xy 159.108733 77.004491) (xy 159.279006 77.03836) + (xy 159.302268 77.045416) (xy 159.461254 77.111271) (xy 159.482692 77.12273) (xy 159.625775 77.218335) + (xy 159.644565 77.233756) (xy 159.766243 77.355434) (xy 159.781664 77.374224) (xy 159.877269 77.517307) + (xy 159.888728 77.538745) (xy 159.954583 77.697731) (xy 159.961639 77.720993) (xy 159.995508 77.891266) + (xy 159.997854 77.912419) (xy 159.999963 77.998488) (xy 160 78.001526) (xy 160 82.084384) (xy 159.999968 82.087197) + (xy 159.998015 82.173267) (xy 159.995664 82.194645) (xy 159.96181 82.364841) (xy 159.954753 82.388105) + (xy 159.888883 82.547119) (xy 159.877422 82.568559) (xy 159.781001 82.71285) (xy 159.767562 82.729612) + (xy 159.708069 82.791885) (xy 159.70609 82.793909) (xy 157.793957 84.706042) (xy 157.791812 84.708136) + (xy 157.729488 84.767517) (xy 157.712836 84.780848) (xy 157.568486 84.877287) (xy 157.547049 84.888745) + (xy 157.388062 84.95459) (xy 157.364802 84.961644) (xy 157.194518 84.99551) (xy 157.173367 84.997855) + (xy 157.087298 84.999963) (xy 157.084262 85) (xy 142.915624 85) (xy 142.912776 84.999967) (xy 142.826721 84.99799) + (xy 142.805379 84.995641) (xy 142.635159 84.961784) (xy 142.611898 84.954728) (xy 142.452885 84.888865) + (xy 142.431446 84.877406) (xy 142.287146 84.78099) (xy 142.270385 84.767552) (xy 142.208134 84.708088) + (xy 142.206104 84.706104) (xy 140.293904 82.793904) (xy 140.291928 82.791883) (xy 140.232443 82.729622) + (xy 140.218997 82.712851) (xy 140.122584 82.568555) (xy 140.111125 82.547117) (xy 140.045262 82.388104) + (xy 140.038206 82.364843) (xy 140.004351 82.194631) (xy 140.002001 82.173276) (xy 140.000032 82.087183) + (xy 140 82.084348) (xy 140 78.001526) (xy 140.000037 77.99849) (xy 140.002145 77.912421) (xy 140.004491 77.891266) + (xy 140.03836 77.720993) (xy 140.045416 77.697731) (xy 140.111271 77.538745) (xy 140.12273 77.517307) + (xy 140.218335 77.374224) (xy 140.233756 77.355434) (xy 140.355434 77.233756) (xy 140.374224 77.218335) + (xy 140.517307 77.12273) (xy 140.538745 77.111271) (xy 140.697731 77.045416) (xy 140.720993 77.03836) + (xy 140.891266 77.004491) (xy 140.912421 77.002145) (xy 140.998491 77.000037) (xy 141.001527 77) + (xy 158.998473 77) + ) + ) + ) + (zone + (net 0) + (net_name "") + (layer "F.SilkS") + (uuid "c2a2fc72-d02b-49db-917f-90f11c63cf3c") + (hatch edge 0.5) + (connect_pads + (clearance 0) + ) + (min_thickness 0.25) + (filled_areas_thickness no) + (fill yes + (thermal_gap 0.5) + (thermal_bridge_width 0.5) + ) + (polygon + (pts + (xy 153.5 77) (xy 152.75 78.25) (xy 152.75 83) (xy 153.75 85) (xy 160 85) (xy 160 81.75) (xy 157.25 81.75) + (xy 157.25 77) + ) + ) + (filled_polygon + (layer "F.SilkS") + (island) + (pts + (xy 157.193039 77.019685) (xy 157.238794 77.072489) (xy 157.25 77.124) (xy 157.25 81.75) (xy 159.876 81.75) + (xy 159.943039 81.769685) (xy 159.988794 81.822489) (xy 160 81.874) (xy 160 82.084384) (xy 159.999968 82.087197) + (xy 159.998015 82.173267) (xy 159.995664 82.194645) (xy 159.96181 82.364841) (xy 159.954753 82.388105) + (xy 159.888883 82.547119) (xy 159.877422 82.568559) (xy 159.781001 82.71285) (xy 159.767562 82.729612) + (xy 159.708069 82.791885) (xy 159.70609 82.793909) (xy 157.793957 84.706042) (xy 157.791812 84.708136) + (xy 157.729488 84.767517) (xy 157.712836 84.780848) (xy 157.568486 84.877287) (xy 157.547049 84.888745) + (xy 157.388062 84.95459) (xy 157.364802 84.961644) (xy 157.194518 84.99551) (xy 157.173367 84.997855) + (xy 157.087298 84.999963) (xy 157.084262 85) (xy 153.826636 85) (xy 153.759597 84.980315) (xy 153.715727 84.931454) + (xy 152.763091 83.026182) (xy 152.75 82.970728) (xy 152.75 78.284345) (xy 152.767671 78.220548) + (xy 153.463878 77.060203) (xy 153.515249 77.012844) (xy 153.570207 77) (xy 157.126 77) + ) + ) + ) + (zone + (net 0) + (net_name "") + (layer "F.SilkS") + (uuid "e85aa69f-a571-453f-92d0-52c2d8bdbb57") + (hatch edge 0.5) + (connect_pads + (clearance 0) + ) + (min_thickness 0.25) + (filled_areas_thickness no) + (fill yes + (thermal_gap 0.5) + (thermal_bridge_width 0.5) + ) + (polygon + (pts + (xy 146.5 77) (xy 147.25 78.25) (xy 147.25 83) (xy 146.25 85) (xy 140 85) (xy 140 81.75) (xy 142.75 81.75) + (xy 142.75 77) + ) + ) + (filled_polygon + (layer "F.SilkS") + (island) + (pts + (xy 146.496832 77.019685) (xy 146.536122 77.060203) (xy 147.232329 78.220548) (xy 147.25 78.284345) + (xy 147.25 82.970728) (xy 147.236909 83.026182) (xy 146.284273 84.931454) (xy 146.236686 84.982613) + (xy 146.173364 85) (xy 142.915624 85) (xy 142.912776 84.999967) (xy 142.826721 84.99799) (xy 142.805379 84.995641) + (xy 142.635159 84.961784) (xy 142.611898 84.954728) (xy 142.452885 84.888865) (xy 142.431446 84.877406) + (xy 142.287146 84.78099) (xy 142.270385 84.767552) (xy 142.208134 84.708088) (xy 142.206104 84.706104) + (xy 140.293904 82.793904) (xy 140.291928 82.791883) (xy 140.232443 82.729622) (xy 140.218997 82.712851) + (xy 140.122584 82.568555) (xy 140.111125 82.547117) (xy 140.045262 82.388104) (xy 140.038206 82.364843) + (xy 140.004351 82.194631) (xy 140.002001 82.173276) (xy 140.000032 82.087183) (xy 140 82.084348) + (xy 140 81.874) (xy 140.019685 81.806961) (xy 140.072489 81.761206) (xy 140.124 81.75) (xy 142.75 81.75) + (xy 142.75 77.124) (xy 142.769685 77.056961) (xy 142.822489 77.011206) (xy 142.874 77) (xy 146.429793 77) + ) + ) + ) + (embedded_fonts no) +) diff --git a/construction/micro_manipulator/balljoint_plate_pcb/balljoint_plate_pcb.kicad_pro b/construction/micro_manipulator/balljoint_plate_pcb/balljoint_plate_pcb.kicad_pro new file mode 100644 index 0000000..80bf51f --- /dev/null +++ b/construction/micro_manipulator/balljoint_plate_pcb/balljoint_plate_pcb.kicad_pro @@ -0,0 +1,618 @@ +{ + "board": { + "3dviewports": [], + "design_settings": { + "defaults": { + "apply_defaults_to_fp_fields": false, + "apply_defaults_to_fp_shapes": false, + "apply_defaults_to_fp_text": false, + "board_outline_line_width": 0.05, + "copper_line_width": 0.2, + "copper_text_italic": false, + "copper_text_size_h": 1.5, + "copper_text_size_v": 1.5, + "copper_text_thickness": 0.3, + "copper_text_upright": false, + "courtyard_line_width": 0.05, + "dimension_precision": 4, + "dimension_units": 3, + "dimensions": { + "arrow_length": 1270000, + "extension_offset": 500000, + "keep_text_aligned": true, + "suppress_zeroes": true, + "text_position": 0, + "units_format": 0 + }, + "fab_line_width": 0.1, + "fab_text_italic": false, + "fab_text_size_h": 1.0, + "fab_text_size_v": 1.0, + "fab_text_thickness": 0.15, + "fab_text_upright": false, + "other_line_width": 0.1, + "other_text_italic": false, + "other_text_size_h": 1.0, + "other_text_size_v": 1.0, + "other_text_thickness": 0.15, + "other_text_upright": false, + "pads": { + "drill": 0.8, + "height": 0.8, + "width": 0.8 + }, + "silk_line_width": 0.1, + "silk_text_italic": false, + "silk_text_size_h": 1.0, + "silk_text_size_v": 1.0, + "silk_text_thickness": 0.1, + "silk_text_upright": false, + "zones": { + "min_clearance": 0.0 + } + }, + "diff_pair_dimensions": [], + "drc_exclusions": [], + "meta": { + "version": 2 + }, + "rule_severities": { + "annular_width": "error", + "clearance": "error", + "connection_width": "warning", + "copper_edge_clearance": "error", + "copper_sliver": "warning", + "courtyards_overlap": "error", + "creepage": "error", + "diff_pair_gap_out_of_range": "error", + "diff_pair_uncoupled_length_too_long": "error", + "drill_out_of_range": "error", + "duplicate_footprints": "warning", + "extra_footprint": "warning", + "footprint": "error", + "footprint_filters_mismatch": "ignore", + "footprint_symbol_mismatch": "warning", + "footprint_type_mismatch": "ignore", + "hole_clearance": "error", + "hole_to_hole": "warning", + "holes_co_located": "warning", + "invalid_outline": "error", + "isolated_copper": "warning", + "item_on_disabled_layer": "error", + "items_not_allowed": "error", + "length_out_of_range": "error", + "lib_footprint_issues": "warning", + "lib_footprint_mismatch": "warning", + "malformed_courtyard": "error", + "microvia_drill_out_of_range": "error", + "mirrored_text_on_front_layer": "warning", + "missing_courtyard": "ignore", + "missing_footprint": "warning", + "net_conflict": "warning", + "nonmirrored_text_on_back_layer": "warning", + "npth_inside_courtyard": "ignore", + "padstack": "warning", + "pth_inside_courtyard": "ignore", + "shorting_items": "error", + "silk_edge_clearance": "warning", + "silk_over_copper": "warning", + "silk_overlap": "warning", + "skew_out_of_range": "error", + "solder_mask_bridge": "error", + "starved_thermal": "error", + "text_height": "warning", + "text_on_edge_cuts": "error", + "text_thickness": "warning", + "through_hole_pad_without_hole": "error", + "too_many_vias": "error", + "track_angle": "error", + "track_dangling": "warning", + "track_segment_length": "error", + "track_width": "error", + "tracks_crossing": "error", + "unconnected_items": "error", + "unresolved_variable": "error", + "via_dangling": "warning", + "zones_intersect": "error" + }, + "rules": { + "max_error": 0.005, + "min_clearance": 0.0, + "min_connection": 0.0, + "min_copper_edge_clearance": 0.5, + "min_groove_width": 0.0, + "min_hole_clearance": 0.25, + "min_hole_to_hole": 0.25, + "min_microvia_diameter": 0.2, + "min_microvia_drill": 0.1, + "min_resolved_spokes": 2, + "min_silk_clearance": 0.0, + "min_text_height": 0.8, + "min_text_thickness": 0.08, + "min_through_hole_diameter": 0.3, + "min_track_width": 0.0, + "min_via_annular_width": 0.1, + "min_via_diameter": 0.5, + "solder_mask_to_copper_clearance": 0.005, + "use_height_for_length_calcs": true + }, + "teardrop_options": [ + { + "td_onpthpad": true, + "td_onroundshapesonly": false, + "td_onsmdpad": true, + "td_ontrackend": false, + "td_onvia": true + } + ], + "teardrop_parameters": [ + { + "td_allow_use_two_tracks": true, + "td_curve_segcount": 0, + "td_height_ratio": 1.0, + "td_length_ratio": 0.5, + "td_maxheight": 2.0, + "td_maxlen": 1.0, + "td_on_pad_in_zone": false, + "td_target_name": "td_round_shape", + "td_width_to_size_filter_ratio": 0.9 + }, + { + "td_allow_use_two_tracks": true, + "td_curve_segcount": 0, + "td_height_ratio": 1.0, + "td_length_ratio": 0.5, + "td_maxheight": 2.0, + "td_maxlen": 1.0, + "td_on_pad_in_zone": false, + "td_target_name": "td_rect_shape", + "td_width_to_size_filter_ratio": 0.9 + }, + { + "td_allow_use_two_tracks": true, + "td_curve_segcount": 0, + "td_height_ratio": 1.0, + "td_length_ratio": 0.5, + "td_maxheight": 2.0, + "td_maxlen": 1.0, + "td_on_pad_in_zone": false, + "td_target_name": "td_track_end", + "td_width_to_size_filter_ratio": 0.9 + } + ], + "track_widths": [], + "tuning_pattern_settings": { + "diff_pair_defaults": { + "corner_radius_percentage": 80, + "corner_style": 1, + "max_amplitude": 1.0, + "min_amplitude": 0.2, + "single_sided": false, + "spacing": 1.0 + }, + "diff_pair_skew_defaults": { + "corner_radius_percentage": 80, + "corner_style": 1, + "max_amplitude": 1.0, + "min_amplitude": 0.2, + "single_sided": false, + "spacing": 0.6 + }, + "single_track_defaults": { + "corner_radius_percentage": 80, + "corner_style": 1, + "max_amplitude": 1.0, + "min_amplitude": 0.2, + "single_sided": false, + "spacing": 0.6 + } + }, + "via_dimensions": [], + "zones_allow_external_fillets": false + }, + "ipc2581": { + "dist": "", + "distpn": "", + "internal_id": "", + "mfg": "", + "mpn": "" + }, + "layer_pairs": [], + "layer_presets": [], + "viewports": [] + }, + "boards": [], + "cvpcb": { + "equivalence_files": [] + }, + "erc": { + "erc_exclusions": [], + "meta": { + "version": 0 + }, + "pin_map": [ + [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 2, + 0, + 1, + 0, + 0, + 1, + 0, + 2, + 2, + 2, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 2 + ], + [ + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 1, + 1, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2 + ], + [ + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 2 + ], + [ + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 2, + 1, + 2, + 0, + 0, + 1, + 0, + 2, + 2, + 2, + 2 + ], + [ + 0, + 2, + 0, + 1, + 0, + 0, + 1, + 0, + 2, + 0, + 0, + 2 + ], + [ + 0, + 2, + 1, + 1, + 0, + 0, + 1, + 0, + 2, + 0, + 0, + 2 + ], + [ + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2 + ] + ], + "rule_severities": { + "bus_definition_conflict": "error", + "bus_entry_needed": "error", + "bus_to_bus_conflict": "error", + "bus_to_net_conflict": "error", + "different_unit_footprint": "error", + "different_unit_net": "error", + "duplicate_reference": "error", + "duplicate_sheet_names": "error", + "endpoint_off_grid": "warning", + "extra_units": "error", + "footprint_filter": "ignore", + "footprint_link_issues": "warning", + "four_way_junction": "ignore", + "global_label_dangling": "warning", + "hier_label_mismatch": "error", + "label_dangling": "error", + "label_multiple_wires": "warning", + "lib_symbol_issues": "warning", + "lib_symbol_mismatch": "warning", + "missing_bidi_pin": "warning", + "missing_input_pin": "warning", + "missing_power_pin": "error", + "missing_unit": "warning", + "multiple_net_names": "warning", + "net_not_bus_member": "warning", + "no_connect_connected": "warning", + "no_connect_dangling": "warning", + "pin_not_connected": "error", + "pin_not_driven": "error", + "pin_to_pin": "warning", + "power_pin_not_driven": "error", + "same_local_global_label": "warning", + "similar_label_and_power": "warning", + "similar_labels": "warning", + "similar_power": "warning", + "simulation_model_issue": "ignore", + "single_global_label": "ignore", + "unannotated": "error", + "unconnected_wire_endpoint": "warning", + "unit_value_mismatch": "error", + "unresolved_variable": "error", + "wire_dangling": "error" + } + }, + "libraries": { + "pinned_footprint_libs": [], + "pinned_symbol_libs": [] + }, + "meta": { + "filename": "balljoint_plate_pcb.kicad_pro", + "version": 3 + }, + "net_settings": { + "classes": [ + { + "bus_width": 12, + "clearance": 0.2, + "diff_pair_gap": 0.25, + "diff_pair_via_gap": 0.25, + "diff_pair_width": 0.2, + "line_style": 0, + "microvia_diameter": 0.3, + "microvia_drill": 0.1, + "name": "Default", + "pcb_color": "rgba(0, 0, 0, 0.000)", + "priority": 2147483647, + "schematic_color": "rgba(0, 0, 0, 0.000)", + "track_width": 0.2, + "via_diameter": 0.6, + "via_drill": 0.3, + "wire_width": 6 + } + ], + "meta": { + "version": 4 + }, + "net_colors": null, + "netclass_assignments": null, + "netclass_patterns": [] + }, + "pcbnew": { + "last_paths": { + "gencad": "", + "idf": "", + "netlist": "", + "plot": "", + "pos_files": "", + "specctra_dsn": "", + "step": "", + "svg": "", + "vrml": "" + }, + "page_layout_descr_file": "" + }, + "schematic": { + "annotate_start_num": 0, + "bom_export_filename": "${PROJECTNAME}.csv", + "bom_fmt_presets": [], + "bom_fmt_settings": { + "field_delimiter": ",", + "keep_line_breaks": false, + "keep_tabs": false, + "name": "CSV", + "ref_delimiter": ",", + "ref_range_delimiter": "", + "string_delimiter": "\"" + }, + "bom_presets": [], + "bom_settings": { + "exclude_dnp": false, + "fields_ordered": [ + { + "group_by": false, + "label": "Reference", + "name": "Reference", + "show": true + }, + { + "group_by": false, + "label": "Qty", + "name": "${QUANTITY}", + "show": true + }, + { + "group_by": true, + "label": "Value", + "name": "Value", + "show": true + }, + { + "group_by": true, + "label": "DNP", + "name": "${DNP}", + "show": true + }, + { + "group_by": true, + "label": "Exclude from BOM", + "name": "${EXCLUDE_FROM_BOM}", + "show": true + }, + { + "group_by": true, + "label": "Exclude from Board", + "name": "${EXCLUDE_FROM_BOARD}", + "show": true + }, + { + "group_by": true, + "label": "Footprint", + "name": "Footprint", + "show": true + }, + { + "group_by": false, + "label": "Datasheet", + "name": "Datasheet", + "show": true + } + ], + "filter_string": "", + "group_symbols": true, + "include_excluded_from_bom": true, + "name": "Default Editing", + "sort_asc": true, + "sort_field": "Reference" + }, + "connection_grid_size": 50.0, + "drawing": { + "dashed_lines_dash_length_ratio": 12.0, + "dashed_lines_gap_length_ratio": 3.0, + "default_line_thickness": 6.0, + "default_text_size": 50.0, + "field_names": [], + "intersheets_ref_own_page": false, + "intersheets_ref_prefix": "", + "intersheets_ref_short": false, + "intersheets_ref_show": false, + "intersheets_ref_suffix": "", + "junction_size_choice": 3, + "label_size_ratio": 0.375, + "operating_point_overlay_i_precision": 3, + "operating_point_overlay_i_range": "~A", + "operating_point_overlay_v_precision": 3, + "operating_point_overlay_v_range": "~V", + "overbar_offset_ratio": 1.23, + "pin_symbol_size": 25.0, + "text_offset_ratio": 0.15 + }, + "legacy_lib_dir": "", + "legacy_lib_list": [], + "meta": { + "version": 1 + }, + "net_format_name": "", + "page_layout_descr_file": "", + "plot_directory": "", + "space_save_all_events": true, + "spice_current_sheet_as_root": false, + "spice_external_command": "spice \"%I\"", + "spice_model_current_sheet_as_root": true, + "spice_save_all_currents": false, + "spice_save_all_dissipations": false, + "spice_save_all_voltages": false, + "subpart_first_id": 65, + "subpart_id_separator": 0 + }, + "sheets": [ + [ + "2e8012d9-ff9a-4144-ae87-c56d322b63ec", + "Root" + ] + ], + "text_variables": {} +} diff --git a/construction/micro_manipulator/balljoint_plate_pcb/balljoint_plate_pcb.kicad_sch b/construction/micro_manipulator/balljoint_plate_pcb/balljoint_plate_pcb.kicad_sch new file mode 100644 index 0000000..1e374f1 --- /dev/null +++ b/construction/micro_manipulator/balljoint_plate_pcb/balljoint_plate_pcb.kicad_sch @@ -0,0 +1,738 @@ +(kicad_sch + (version 20250114) + (generator "eeschema") + (generator_version "9.0") + (uuid "2e8012d9-ff9a-4144-ae87-c56d322b63ec") + (paper "A4") + (lib_symbols + (symbol "Mechanical:MountingHole" + (pin_names + (offset 1.016) + ) + (exclude_from_sim no) + (in_bom no) + (on_board yes) + (property "Reference" "H" + (at 0 5.08 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Value" "MountingHole" + (at 0 3.175 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "~" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Mounting Hole without connection" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "ki_keywords" "mounting hole" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "ki_fp_filters" "MountingHole*" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (symbol "MountingHole_0_1" + (circle + (center 0 0) + (radius 1.27) + (stroke + (width 1.27) + (type default) + ) + (fill + (type none) + ) + ) + ) + (embedded_fonts no) + ) + ) + (symbol + (lib_id "Mechanical:MountingHole") + (at 119.38 66.04 0) + (unit 1) + (exclude_from_sim no) + (in_bom no) + (on_board yes) + (dnp no) + (fields_autoplaced yes) + (uuid "22cd77c6-6419-49c9-a315-e5470917281d") + (property "Reference" "H7" + (at 121.92 64.7699 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "MountingHole" + (at 121.92 67.3099 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "MountingHole:MountingHole_2mm" + (at 119.38 66.04 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "~" + (at 119.38 66.04 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Mounting Hole without connection" + (at 119.38 66.04 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (instances + (project "balljoint_plate_pcb" + (path "/2e8012d9-ff9a-4144-ae87-c56d322b63ec" + (reference "H7") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Mechanical:MountingHole") + (at 96.52 66.04 0) + (unit 1) + (exclude_from_sim no) + (in_bom no) + (on_board yes) + (dnp no) + (fields_autoplaced yes) + (uuid "35b726c5-8939-42dc-9c24-6937721b1381") + (property "Reference" "H1" + (at 99.06 64.7699 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "MountingHole" + (at 99.06 67.3099 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "MountingHole:MountingHole_2mm" + (at 96.52 66.04 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "~" + (at 96.52 66.04 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Mounting Hole without connection" + (at 96.52 66.04 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (instances + (project "" + (path "/2e8012d9-ff9a-4144-ae87-c56d322b63ec" + (reference "H1") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Mechanical:MountingHole") + (at 119.38 59.69 0) + (unit 1) + (exclude_from_sim no) + (in_bom no) + (on_board yes) + (dnp no) + (fields_autoplaced yes) + (uuid "77599518-9e81-421c-a589-255563863e7d") + (property "Reference" "H6" + (at 121.92 58.4199 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "MountingHole" + (at 121.92 60.9599 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "MountingHole:MountingHole_2mm" + (at 119.38 59.69 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "~" + (at 119.38 59.69 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Mounting Hole without connection" + (at 119.38 59.69 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (instances + (project "balljoint_plate_pcb" + (path "/2e8012d9-ff9a-4144-ae87-c56d322b63ec" + (reference "H6") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Mechanical:MountingHole") + (at 119.38 53.34 0) + (unit 1) + (exclude_from_sim no) + (in_bom no) + (on_board yes) + (dnp no) + (fields_autoplaced yes) + (uuid "bf678316-db0e-4397-9446-1c043850ee54") + (property "Reference" "H5" + (at 121.92 52.0699 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "MountingHole" + (at 121.92 54.6099 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "MountingHole:MountingHole_2mm" + (at 119.38 53.34 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "~" + (at 119.38 53.34 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Mounting Hole without connection" + (at 119.38 53.34 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (instances + (project "balljoint_plate_pcb" + (path "/2e8012d9-ff9a-4144-ae87-c56d322b63ec" + (reference "H5") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Mechanical:MountingHole") + (at 68.58 66.04 0) + (unit 1) + (exclude_from_sim no) + (in_bom no) + (on_board yes) + (dnp no) + (fields_autoplaced yes) + (uuid "ce16cea6-101f-4ffc-a2f6-b65e2eb092ea") + (property "Reference" "H3" + (at 71.12 64.7699 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "MountingHole" + (at 71.12 67.3099 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "MountingHole:MountingHole_2mm" + (at 68.58 66.04 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "~" + (at 68.58 66.04 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Mounting Hole without connection" + (at 68.58 66.04 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (instances + (project "balljoint_plate_pcb" + (path "/2e8012d9-ff9a-4144-ae87-c56d322b63ec" + (reference "H3") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Mechanical:MountingHole") + (at 48.26 53.34 0) + (unit 1) + (exclude_from_sim no) + (in_bom no) + (on_board yes) + (dnp no) + (fields_autoplaced yes) + (uuid "e2172f75-ac85-4747-8e3f-8bd8f214554d") + (property "Reference" "H8" + (at 50.8 52.0699 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "MountingHole" + (at 50.8 54.6099 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "MountingHole:MountingHole_2mm" + (at 48.26 53.34 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "~" + (at 48.26 53.34 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Mounting Hole without connection" + (at 48.26 53.34 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (instances + (project "balljoint_plate_pcb" + (path "/2e8012d9-ff9a-4144-ae87-c56d322b63ec" + (reference "H8") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Mechanical:MountingHole") + (at 68.58 72.39 0) + (unit 1) + (exclude_from_sim no) + (in_bom no) + (on_board yes) + (dnp no) + (fields_autoplaced yes) + (uuid "ea0c2fa5-13e6-496d-a0ba-a48b9d6ec936") + (property "Reference" "H4" + (at 71.12 71.1199 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "MountingHole" + (at 71.12 73.6599 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "MountingHole:MountingHole_2mm" + (at 68.58 72.39 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "~" + (at 68.58 72.39 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Mounting Hole without connection" + (at 68.58 72.39 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (instances + (project "balljoint_plate_pcb" + (path "/2e8012d9-ff9a-4144-ae87-c56d322b63ec" + (reference "H4") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Mechanical:MountingHole") + (at 48.26 66.04 0) + (unit 1) + (exclude_from_sim no) + (in_bom no) + (on_board yes) + (dnp no) + (fields_autoplaced yes) + (uuid "ef8cad87-32d9-4829-8ec4-9aba40945885") + (property "Reference" "H10" + (at 50.8 64.7699 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "MountingHole" + (at 50.8 67.3099 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "MountingHole:MountingHole_2mm" + (at 48.26 66.04 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "~" + (at 48.26 66.04 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Mounting Hole without connection" + (at 48.26 66.04 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (instances + (project "balljoint_plate_pcb" + (path "/2e8012d9-ff9a-4144-ae87-c56d322b63ec" + (reference "H10") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Mechanical:MountingHole") + (at 96.52 72.39 0) + (unit 1) + (exclude_from_sim no) + (in_bom no) + (on_board yes) + (dnp no) + (fields_autoplaced yes) + (uuid "fb8c5c26-8db1-405b-b136-fb52772326a9") + (property "Reference" "H2" + (at 99.06 71.1199 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "MountingHole" + (at 99.06 73.6599 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "MountingHole:MountingHole_2mm" + (at 96.52 72.39 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "~" + (at 96.52 72.39 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Mounting Hole without connection" + (at 96.52 72.39 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (instances + (project "balljoint_plate_pcb" + (path "/2e8012d9-ff9a-4144-ae87-c56d322b63ec" + (reference "H2") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Mechanical:MountingHole") + (at 48.26 59.69 0) + (unit 1) + (exclude_from_sim no) + (in_bom no) + (on_board yes) + (dnp no) + (fields_autoplaced yes) + (uuid "fe98a2dd-c6f8-4781-ad26-1f0d6d940384") + (property "Reference" "H9" + (at 50.8 58.4199 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "MountingHole" + (at 50.8 60.9599 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "MountingHole:MountingHole_2mm" + (at 48.26 59.69 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "~" + (at 48.26 59.69 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Mounting Hole without connection" + (at 48.26 59.69 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (instances + (project "balljoint_plate_pcb" + (path "/2e8012d9-ff9a-4144-ae87-c56d322b63ec" + (reference "H9") + (unit 1) + ) + ) + ) + ) + (sheet_instances + (path "/" + (page "1") + ) + ) + (embedded_fonts no) +) diff --git a/construction/micro_manipulator/balljoint_plate_pcb/production/balljoint_plate_pcb_jlcpcb.zip b/construction/micro_manipulator/balljoint_plate_pcb/production/balljoint_plate_pcb_jlcpcb.zip new file mode 100644 index 0000000..3737545 Binary files /dev/null and b/construction/micro_manipulator/balljoint_plate_pcb/production/balljoint_plate_pcb_jlcpcb.zip differ diff --git a/construction/tools/rod_embossing_tools/ball_alignment_disc_pcb/ball_alignment_disc_pcb.kicad_pcb b/construction/tools/rod_embossing_tools/ball_alignment_disc_pcb/ball_alignment_disc_pcb.kicad_pcb new file mode 100644 index 0000000..74ffe72 --- /dev/null +++ b/construction/tools/rod_embossing_tools/ball_alignment_disc_pcb/ball_alignment_disc_pcb.kicad_pcb @@ -0,0 +1,183 @@ +(kicad_pcb + (version 20241229) + (generator "pcbnew") + (generator_version "9.0") + (general + (thickness 1.6) + (legacy_teardrops no) + ) + (paper "A4") + (layers + (0 "F.Cu" signal) + (2 "B.Cu" signal) + (9 "F.Adhes" user "F.Adhesive") + (11 "B.Adhes" user "B.Adhesive") + (13 "F.Paste" user) + (15 "B.Paste" user) + (5 "F.SilkS" user "F.Silkscreen") + (7 "B.SilkS" user "B.Silkscreen") + (1 "F.Mask" user) + (3 "B.Mask" user) + (17 "Dwgs.User" user "User.Drawings") + (19 "Cmts.User" user "User.Comments") + (21 "Eco1.User" user "User.Eco1") + (23 "Eco2.User" user "User.Eco2") + (25 "Edge.Cuts" user) + (27 "Margin" user) + (31 "F.CrtYd" user "F.Courtyard") + (29 "B.CrtYd" user "B.Courtyard") + (35 "F.Fab" user) + (33 "B.Fab" user) + (39 "User.1" user) + (41 "User.2" user) + (43 "User.3" user) + (45 "User.4" user) + ) + (setup + (pad_to_mask_clearance 0) + (allow_soldermask_bridges_in_footprints no) + (tenting front back) + (pcbplotparams + (layerselection 0x00000000_00000000_55555555_5755f5ff) + (plot_on_all_layers_selection 0x00000000_00000000_00000000_00000000) + (disableapertmacros no) + (usegerberextensions no) + (usegerberattributes yes) + (usegerberadvancedattributes yes) + (creategerberjobfile yes) + (dashed_line_dash_ratio 12.000000) + (dashed_line_gap_ratio 3.000000) + (svgprecision 4) + (plotframeref no) + (mode 1) + (useauxorigin no) + (hpglpennumber 1) + (hpglpenspeed 20) + (hpglpendiameter 15.000000) + (pdf_front_fp_property_popups yes) + (pdf_back_fp_property_popups yes) + (pdf_metadata yes) + (pdf_single_document no) + (dxfpolygonmode yes) + (dxfimperialunits yes) + (dxfusepcbnewfont yes) + (psnegative no) + (psa4output no) + (plot_black_and_white yes) + (sketchpadsonfab no) + (plotpadnumbers no) + (hidednponfab no) + (sketchdnponfab yes) + (crossoutdnponfab yes) + (subtractmaskfromsilk no) + (outputformat 1) + (mirror no) + (drillshape 1) + (scaleselection 1) + (outputdirectory "") + ) + ) + (net 0 "") + (footprint "MountingHole:MountingHole_2.1mm" + (layer "F.Cu") + (uuid "ed2aaa6b-5540-4a25-b7e9-ac5d652620c5") + (at 200 100) + (descr "Mounting Hole 2.1mm, no annular, generated by kicad-footprint-generator mountinghole.py") + (tags "mountinghole") + (property "Reference" "H1" + (at 0 -3.05 0) + (layer "F.SilkS") + (hide yes) + (uuid "fbe2e5cd-8ff5-4647-939e-dd0ce550d54b") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Value" "MountingHole" + (at 0 3.05 0) + (layer "F.Fab") + (hide yes) + (uuid "efaf7238-551f-42f4-9d49-e8e793241c12") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Datasheet" "" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "9905b809-f32a-45b5-8697-736e838bd016") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property "Description" "Mounting Hole without connection" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "8f1f216c-eab1-4bba-acf3-9e9e03db4f0f") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property ki_fp_filters "MountingHole*") + (path "/e3431358-f109-41e1-8abd-e7609e5abada") + (sheetname "/") + (sheetfile "ball_alignment_disc_pcb.kicad_sch") + (attr exclude_from_pos_files exclude_from_bom) + (pad "" np_thru_hole circle + (at 0 0) + (size 1 1) + (drill 1) + (layers "*.Cu" "*.Mask") + (uuid "1f69a6ec-ea69-46af-a4f5-2440b716d18f") + ) + (embedded_fonts no) + ) + (gr_circle + (center 200 100) + (end 206 100) + (stroke + (width 0.1) + (type solid) + ) + (fill yes) + (layer "F.Mask") + (uuid "dde5242d-1496-4d55-8821-ba405bdd666d") + ) + (gr_circle + (center 200 100) + (end 206 100) + (stroke + (width 0.1) + (type solid) + ) + (fill yes) + (layer "B.Mask") + (uuid "af62cc96-00a1-4ff1-84ee-660a587d88d7") + ) + (gr_circle + (center 200 100) + (end 204 100) + (stroke + (width 0.05) + (type default) + ) + (fill no) + (layer "Edge.Cuts") + (uuid "5abbc2ab-0559-4408-94b5-cf7e8005ef3e") + ) + (embedded_fonts no) +) diff --git a/construction/tools/rod_embossing_tools/ball_alignment_disc_pcb/ball_alignment_disc_pcb.kicad_pro b/construction/tools/rod_embossing_tools/ball_alignment_disc_pcb/ball_alignment_disc_pcb.kicad_pro new file mode 100644 index 0000000..660a838 --- /dev/null +++ b/construction/tools/rod_embossing_tools/ball_alignment_disc_pcb/ball_alignment_disc_pcb.kicad_pro @@ -0,0 +1,618 @@ +{ + "board": { + "3dviewports": [], + "design_settings": { + "defaults": { + "apply_defaults_to_fp_fields": false, + "apply_defaults_to_fp_shapes": false, + "apply_defaults_to_fp_text": false, + "board_outline_line_width": 0.05, + "copper_line_width": 0.2, + "copper_text_italic": false, + "copper_text_size_h": 1.5, + "copper_text_size_v": 1.5, + "copper_text_thickness": 0.3, + "copper_text_upright": false, + "courtyard_line_width": 0.05, + "dimension_precision": 4, + "dimension_units": 3, + "dimensions": { + "arrow_length": 1270000, + "extension_offset": 500000, + "keep_text_aligned": true, + "suppress_zeroes": true, + "text_position": 0, + "units_format": 0 + }, + "fab_line_width": 0.1, + "fab_text_italic": false, + "fab_text_size_h": 1.0, + "fab_text_size_v": 1.0, + "fab_text_thickness": 0.15, + "fab_text_upright": false, + "other_line_width": 0.1, + "other_text_italic": false, + "other_text_size_h": 1.0, + "other_text_size_v": 1.0, + "other_text_thickness": 0.15, + "other_text_upright": false, + "pads": { + "drill": 0.8, + "height": 1.27, + "width": 2.54 + }, + "silk_line_width": 0.1, + "silk_text_italic": false, + "silk_text_size_h": 1.0, + "silk_text_size_v": 1.0, + "silk_text_thickness": 0.1, + "silk_text_upright": false, + "zones": { + "min_clearance": 0.5 + } + }, + "diff_pair_dimensions": [], + "drc_exclusions": [], + "meta": { + "version": 2 + }, + "rule_severities": { + "annular_width": "error", + "clearance": "error", + "connection_width": "warning", + "copper_edge_clearance": "error", + "copper_sliver": "warning", + "courtyards_overlap": "error", + "creepage": "error", + "diff_pair_gap_out_of_range": "error", + "diff_pair_uncoupled_length_too_long": "error", + "drill_out_of_range": "error", + "duplicate_footprints": "warning", + "extra_footprint": "warning", + "footprint": "error", + "footprint_filters_mismatch": "ignore", + "footprint_symbol_mismatch": "warning", + "footprint_type_mismatch": "ignore", + "hole_clearance": "error", + "hole_to_hole": "warning", + "holes_co_located": "warning", + "invalid_outline": "error", + "isolated_copper": "warning", + "item_on_disabled_layer": "error", + "items_not_allowed": "error", + "length_out_of_range": "error", + "lib_footprint_issues": "warning", + "lib_footprint_mismatch": "warning", + "malformed_courtyard": "error", + "microvia_drill_out_of_range": "error", + "mirrored_text_on_front_layer": "warning", + "missing_courtyard": "ignore", + "missing_footprint": "warning", + "net_conflict": "warning", + "nonmirrored_text_on_back_layer": "warning", + "npth_inside_courtyard": "ignore", + "padstack": "warning", + "pth_inside_courtyard": "ignore", + "shorting_items": "error", + "silk_edge_clearance": "warning", + "silk_over_copper": "warning", + "silk_overlap": "warning", + "skew_out_of_range": "error", + "solder_mask_bridge": "error", + "starved_thermal": "error", + "text_height": "warning", + "text_on_edge_cuts": "error", + "text_thickness": "warning", + "through_hole_pad_without_hole": "error", + "too_many_vias": "error", + "track_angle": "error", + "track_dangling": "warning", + "track_segment_length": "error", + "track_width": "error", + "tracks_crossing": "error", + "unconnected_items": "error", + "unresolved_variable": "error", + "via_dangling": "warning", + "zones_intersect": "error" + }, + "rules": { + "max_error": 0.005, + "min_clearance": 0.0, + "min_connection": 0.0, + "min_copper_edge_clearance": 0.5, + "min_groove_width": 0.0, + "min_hole_clearance": 0.25, + "min_hole_to_hole": 0.25, + "min_microvia_diameter": 0.2, + "min_microvia_drill": 0.1, + "min_resolved_spokes": 2, + "min_silk_clearance": 0.0, + "min_text_height": 0.8, + "min_text_thickness": 0.08, + "min_through_hole_diameter": 0.3, + "min_track_width": 0.0, + "min_via_annular_width": 0.1, + "min_via_diameter": 0.5, + "solder_mask_to_copper_clearance": 0.005, + "use_height_for_length_calcs": true + }, + "teardrop_options": [ + { + "td_onpthpad": true, + "td_onroundshapesonly": false, + "td_onsmdpad": true, + "td_ontrackend": false, + "td_onvia": true + } + ], + "teardrop_parameters": [ + { + "td_allow_use_two_tracks": true, + "td_curve_segcount": 0, + "td_height_ratio": 1.0, + "td_length_ratio": 0.5, + "td_maxheight": 2.0, + "td_maxlen": 1.0, + "td_on_pad_in_zone": false, + "td_target_name": "td_round_shape", + "td_width_to_size_filter_ratio": 0.9 + }, + { + "td_allow_use_two_tracks": true, + "td_curve_segcount": 0, + "td_height_ratio": 1.0, + "td_length_ratio": 0.5, + "td_maxheight": 2.0, + "td_maxlen": 1.0, + "td_on_pad_in_zone": false, + "td_target_name": "td_rect_shape", + "td_width_to_size_filter_ratio": 0.9 + }, + { + "td_allow_use_two_tracks": true, + "td_curve_segcount": 0, + "td_height_ratio": 1.0, + "td_length_ratio": 0.5, + "td_maxheight": 2.0, + "td_maxlen": 1.0, + "td_on_pad_in_zone": false, + "td_target_name": "td_track_end", + "td_width_to_size_filter_ratio": 0.9 + } + ], + "track_widths": [], + "tuning_pattern_settings": { + "diff_pair_defaults": { + "corner_radius_percentage": 80, + "corner_style": 1, + "max_amplitude": 1.0, + "min_amplitude": 0.2, + "single_sided": false, + "spacing": 1.0 + }, + "diff_pair_skew_defaults": { + "corner_radius_percentage": 80, + "corner_style": 1, + "max_amplitude": 1.0, + "min_amplitude": 0.2, + "single_sided": false, + "spacing": 0.6 + }, + "single_track_defaults": { + "corner_radius_percentage": 80, + "corner_style": 1, + "max_amplitude": 1.0, + "min_amplitude": 0.2, + "single_sided": false, + "spacing": 0.6 + } + }, + "via_dimensions": [], + "zones_allow_external_fillets": false + }, + "ipc2581": { + "dist": "", + "distpn": "", + "internal_id": "", + "mfg": "", + "mpn": "" + }, + "layer_pairs": [], + "layer_presets": [], + "viewports": [] + }, + "boards": [], + "cvpcb": { + "equivalence_files": [] + }, + "erc": { + "erc_exclusions": [], + "meta": { + "version": 0 + }, + "pin_map": [ + [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 2, + 0, + 1, + 0, + 0, + 1, + 0, + 2, + 2, + 2, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 2 + ], + [ + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 1, + 1, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2 + ], + [ + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 2 + ], + [ + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 2, + 1, + 2, + 0, + 0, + 1, + 0, + 2, + 2, + 2, + 2 + ], + [ + 0, + 2, + 0, + 1, + 0, + 0, + 1, + 0, + 2, + 0, + 0, + 2 + ], + [ + 0, + 2, + 1, + 1, + 0, + 0, + 1, + 0, + 2, + 0, + 0, + 2 + ], + [ + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2 + ] + ], + "rule_severities": { + "bus_definition_conflict": "error", + "bus_entry_needed": "error", + "bus_to_bus_conflict": "error", + "bus_to_net_conflict": "error", + "different_unit_footprint": "error", + "different_unit_net": "error", + "duplicate_reference": "error", + "duplicate_sheet_names": "error", + "endpoint_off_grid": "warning", + "extra_units": "error", + "footprint_filter": "ignore", + "footprint_link_issues": "warning", + "four_way_junction": "ignore", + "global_label_dangling": "warning", + "hier_label_mismatch": "error", + "label_dangling": "error", + "label_multiple_wires": "warning", + "lib_symbol_issues": "warning", + "lib_symbol_mismatch": "warning", + "missing_bidi_pin": "warning", + "missing_input_pin": "warning", + "missing_power_pin": "error", + "missing_unit": "warning", + "multiple_net_names": "warning", + "net_not_bus_member": "warning", + "no_connect_connected": "warning", + "no_connect_dangling": "warning", + "pin_not_connected": "error", + "pin_not_driven": "error", + "pin_to_pin": "warning", + "power_pin_not_driven": "error", + "same_local_global_label": "warning", + "similar_label_and_power": "warning", + "similar_labels": "warning", + "similar_power": "warning", + "simulation_model_issue": "ignore", + "single_global_label": "ignore", + "unannotated": "error", + "unconnected_wire_endpoint": "warning", + "unit_value_mismatch": "error", + "unresolved_variable": "error", + "wire_dangling": "error" + } + }, + "libraries": { + "pinned_footprint_libs": [], + "pinned_symbol_libs": [] + }, + "meta": { + "filename": "ball_alignment_disc_pcb.kicad_pro", + "version": 3 + }, + "net_settings": { + "classes": [ + { + "bus_width": 12, + "clearance": 0.2, + "diff_pair_gap": 0.25, + "diff_pair_via_gap": 0.25, + "diff_pair_width": 0.2, + "line_style": 0, + "microvia_diameter": 0.3, + "microvia_drill": 0.1, + "name": "Default", + "pcb_color": "rgba(0, 0, 0, 0.000)", + "priority": 2147483647, + "schematic_color": "rgba(0, 0, 0, 0.000)", + "track_width": 0.2, + "via_diameter": 0.6, + "via_drill": 0.3, + "wire_width": 6 + } + ], + "meta": { + "version": 4 + }, + "net_colors": null, + "netclass_assignments": null, + "netclass_patterns": [] + }, + "pcbnew": { + "last_paths": { + "gencad": "", + "idf": "", + "netlist": "", + "plot": "", + "pos_files": "", + "specctra_dsn": "", + "step": "", + "svg": "", + "vrml": "" + }, + "page_layout_descr_file": "" + }, + "schematic": { + "annotate_start_num": 0, + "bom_export_filename": "${PROJECTNAME}.csv", + "bom_fmt_presets": [], + "bom_fmt_settings": { + "field_delimiter": ",", + "keep_line_breaks": false, + "keep_tabs": false, + "name": "CSV", + "ref_delimiter": ",", + "ref_range_delimiter": "", + "string_delimiter": "\"" + }, + "bom_presets": [], + "bom_settings": { + "exclude_dnp": false, + "fields_ordered": [ + { + "group_by": false, + "label": "Reference", + "name": "Reference", + "show": true + }, + { + "group_by": false, + "label": "Qty", + "name": "${QUANTITY}", + "show": true + }, + { + "group_by": true, + "label": "Value", + "name": "Value", + "show": true + }, + { + "group_by": true, + "label": "DNP", + "name": "${DNP}", + "show": true + }, + { + "group_by": true, + "label": "Exclude from BOM", + "name": "${EXCLUDE_FROM_BOM}", + "show": true + }, + { + "group_by": true, + "label": "Exclude from Board", + "name": "${EXCLUDE_FROM_BOARD}", + "show": true + }, + { + "group_by": true, + "label": "Footprint", + "name": "Footprint", + "show": true + }, + { + "group_by": false, + "label": "Datasheet", + "name": "Datasheet", + "show": true + } + ], + "filter_string": "", + "group_symbols": true, + "include_excluded_from_bom": true, + "name": "Default Editing", + "sort_asc": true, + "sort_field": "Reference" + }, + "connection_grid_size": 50.0, + "drawing": { + "dashed_lines_dash_length_ratio": 12.0, + "dashed_lines_gap_length_ratio": 3.0, + "default_line_thickness": 6.0, + "default_text_size": 50.0, + "field_names": [], + "intersheets_ref_own_page": false, + "intersheets_ref_prefix": "", + "intersheets_ref_short": false, + "intersheets_ref_show": false, + "intersheets_ref_suffix": "", + "junction_size_choice": 3, + "label_size_ratio": 0.375, + "operating_point_overlay_i_precision": 3, + "operating_point_overlay_i_range": "~A", + "operating_point_overlay_v_precision": 3, + "operating_point_overlay_v_range": "~V", + "overbar_offset_ratio": 1.23, + "pin_symbol_size": 25.0, + "text_offset_ratio": 0.15 + }, + "legacy_lib_dir": "", + "legacy_lib_list": [], + "meta": { + "version": 1 + }, + "net_format_name": "", + "page_layout_descr_file": "", + "plot_directory": "", + "space_save_all_events": true, + "spice_current_sheet_as_root": false, + "spice_external_command": "spice \"%I\"", + "spice_model_current_sheet_as_root": true, + "spice_save_all_currents": false, + "spice_save_all_dissipations": false, + "spice_save_all_voltages": false, + "subpart_first_id": 65, + "subpart_id_separator": 0 + }, + "sheets": [ + [ + "fbd80f03-6df8-4a15-a16d-0e5ad187d22b", + "Root" + ] + ], + "text_variables": {} +} diff --git a/construction/tools/rod_embossing_tools/ball_alignment_disc_pcb/ball_alignment_disc_pcb.kicad_sch b/construction/tools/rod_embossing_tools/ball_alignment_disc_pcb/ball_alignment_disc_pcb.kicad_sch new file mode 100644 index 0000000..e20d662 --- /dev/null +++ b/construction/tools/rod_embossing_tools/ball_alignment_disc_pcb/ball_alignment_disc_pcb.kicad_sch @@ -0,0 +1,162 @@ +(kicad_sch + (version 20250114) + (generator "eeschema") + (generator_version "9.0") + (uuid "fbd80f03-6df8-4a15-a16d-0e5ad187d22b") + (paper "A4") + (lib_symbols + (symbol "Mechanical:MountingHole" + (pin_names + (offset 1.016) + ) + (exclude_from_sim no) + (in_bom no) + (on_board yes) + (property "Reference" "H" + (at 0 5.08 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Value" "MountingHole" + (at 0 3.175 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "~" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Mounting Hole without connection" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "ki_keywords" "mounting hole" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "ki_fp_filters" "MountingHole*" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (symbol "MountingHole_0_1" + (circle + (center 0 0) + (radius 1.27) + (stroke + (width 1.27) + (type default) + ) + (fill + (type none) + ) + ) + ) + (embedded_fonts no) + ) + ) + (symbol + (lib_id "Mechanical:MountingHole") + (at 133.35 91.44 0) + (unit 1) + (exclude_from_sim no) + (in_bom no) + (on_board yes) + (dnp no) + (fields_autoplaced yes) + (uuid "e3431358-f109-41e1-8abd-e7609e5abada") + (property "Reference" "H1" + (at 135.89 90.1699 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "MountingHole" + (at 135.89 92.7099 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "MountingHole:MountingHole_2.1mm" + (at 133.35 91.44 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "~" + (at 133.35 91.44 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Mounting Hole without connection" + (at 133.35 91.44 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (instances + (project "" + (path "/fbd80f03-6df8-4a15-a16d-0e5ad187d22b" + (reference "H1") + (unit 1) + ) + ) + ) + ) + (sheet_instances + (path "/" + (page "1") + ) + ) + (embedded_fonts no) +) diff --git a/construction/tools/rod_embossing_tools/ball_alignment_disc_pcb/production/ball_alignment_disc_pcb.zip b/construction/tools/rod_embossing_tools/ball_alignment_disc_pcb/production/ball_alignment_disc_pcb.zip new file mode 100644 index 0000000..59013e7 Binary files /dev/null and b/construction/tools/rod_embossing_tools/ball_alignment_disc_pcb/production/ball_alignment_disc_pcb.zip differ diff --git a/construction/tools/rod_embossing_tools/rod_lenth_setting_press/RodGrindingJig_A.FCStd b/construction/tools/rod_embossing_tools/rod_lenth_setting_press/RodGrindingJig_A.FCStd new file mode 100644 index 0000000..b45cd2b Binary files /dev/null and b/construction/tools/rod_embossing_tools/rod_lenth_setting_press/RodGrindingJig_A.FCStd differ diff --git a/construction/tools/rod_embossing_tools/rod_lenth_setting_press/RodGrindingJig_B.FCStd b/construction/tools/rod_embossing_tools/rod_lenth_setting_press/RodGrindingJig_B.FCStd new file mode 100644 index 0000000..d65ebd7 Binary files /dev/null and b/construction/tools/rod_embossing_tools/rod_lenth_setting_press/RodGrindingJig_B.FCStd differ diff --git a/construction/tools/rod_embossing_tools/rod_lenth_setting_press/caliper_clamp.FCStd b/construction/tools/rod_embossing_tools/rod_lenth_setting_press/caliper_clamp.FCStd new file mode 100644 index 0000000..6b82a59 Binary files /dev/null and b/construction/tools/rod_embossing_tools/rod_lenth_setting_press/caliper_clamp.FCStd differ diff --git a/construction/tools/rod_embossing_tools/rod_lenth_setting_press/rod_collet.FCStd b/construction/tools/rod_embossing_tools/rod_lenth_setting_press/rod_collet.FCStd new file mode 100644 index 0000000..ff27f80 Binary files /dev/null and b/construction/tools/rod_embossing_tools/rod_lenth_setting_press/rod_collet.FCStd differ diff --git a/construction/tools/rod_embossing_tools/rod_lenth_setting_press/rod_guide.FCStd b/construction/tools/rod_embossing_tools/rod_lenth_setting_press/rod_guide.FCStd new file mode 100644 index 0000000..bc89f0c Binary files /dev/null and b/construction/tools/rod_embossing_tools/rod_lenth_setting_press/rod_guide.FCStd differ diff --git a/construction/tools/rod_embossing_tools/rod_sharper/BladeCarrier.FCStd b/construction/tools/rod_embossing_tools/rod_sharper/BladeCarrier.FCStd new file mode 100644 index 0000000..ae94da3 Binary files /dev/null and b/construction/tools/rod_embossing_tools/rod_sharper/BladeCarrier.FCStd differ diff --git a/construction/tools/rod_embossing_tools/rod_sharper/RodGuide.FCStd b/construction/tools/rod_embossing_tools/rod_sharper/RodGuide.FCStd new file mode 100644 index 0000000..828b9de Binary files /dev/null and b/construction/tools/rod_embossing_tools/rod_sharper/RodGuide.FCStd differ diff --git a/construction/v3/Assembly_Actuator.FCStd b/construction/v3/Assembly_Actuator.FCStd deleted file mode 100644 index 79c1b87..0000000 Binary files a/construction/v3/Assembly_Actuator.FCStd and /dev/null differ diff --git a/construction/v3/Assembly_EndEffector.FCStd b/construction/v3/Assembly_EndEffector.FCStd deleted file mode 100644 index 9175a13..0000000 Binary files a/construction/v3/Assembly_EndEffector.FCStd and /dev/null differ diff --git a/construction/v3/Assembly_MicroManipulator.FCStd b/construction/v3/Assembly_MicroManipulator.FCStd deleted file mode 100644 index 4cb3e78..0000000 Binary files a/construction/v3/Assembly_MicroManipulator.FCStd and /dev/null differ diff --git a/construction/v3/Assembly_MicroManipulator_backup.FCStd b/construction/v3/Assembly_MicroManipulator_backup.FCStd deleted file mode 100644 index 79c6c78..0000000 Binary files a/construction/v3/Assembly_MicroManipulator_backup.FCStd and /dev/null differ diff --git a/construction/v3/Assembly_WireFlexureUnit.FCStd b/construction/v3/Assembly_WireFlexureUnit.FCStd deleted file mode 100644 index 1a4c460..0000000 Binary files a/construction/v3/Assembly_WireFlexureUnit.FCStd and /dev/null differ diff --git a/construction/v3/BallJointMount.FCStd b/construction/v3/BallJointMount.FCStd deleted file mode 100644 index be879de..0000000 Binary files a/construction/v3/BallJointMount.FCStd and /dev/null differ diff --git a/construction/v3/BaseBlock.FCStd b/construction/v3/BaseBlock.FCStd deleted file mode 100644 index 4f6f2f1..0000000 Binary files a/construction/v3/BaseBlock.FCStd and /dev/null differ diff --git a/construction/v3/EncoderMagnetArray.FCStd b/construction/v3/EncoderMagnetArray.FCStd deleted file mode 100644 index 2c2d254..0000000 Binary files a/construction/v3/EncoderMagnetArray.FCStd and /dev/null differ diff --git a/construction/v3/EndEffector.FCStd b/construction/v3/EndEffector.FCStd deleted file mode 100644 index 6a426f3..0000000 Binary files a/construction/v3/EndEffector.FCStd and /dev/null differ diff --git a/construction/v3/JointBall.FCStd b/construction/v3/JointBall.FCStd deleted file mode 100644 index 0ad0c94..0000000 Binary files a/construction/v3/JointBall.FCStd and /dev/null differ diff --git a/construction/v3/MT6835.FCStd b/construction/v3/MT6835.FCStd deleted file mode 100644 index 5ac26f8..0000000 Binary files a/construction/v3/MT6835.FCStd and /dev/null differ diff --git a/construction/v3/MotorHorn.FCStd b/construction/v3/MotorHorn.FCStd deleted file mode 100644 index 4f6341b..0000000 Binary files a/construction/v3/MotorHorn.FCStd and /dev/null differ diff --git a/construction/v3/MotorMount2_KM.FCStd b/construction/v3/MotorMount2_KM.FCStd deleted file mode 100644 index c9de67c..0000000 Binary files a/construction/v3/MotorMount2_KM.FCStd and /dev/null differ diff --git a/construction/v3/RubberBand.FCStd b/construction/v3/RubberBand.FCStd deleted file mode 100644 index 42634c2..0000000 Binary files a/construction/v3/RubberBand.FCStd and /dev/null differ diff --git a/construction/v3/RubberBandCollet.FCStd b/construction/v3/RubberBandCollet.FCStd deleted file mode 100644 index 49f814c..0000000 Binary files a/construction/v3/RubberBandCollet.FCStd and /dev/null differ diff --git a/construction/v3/StepperMotorNema17.FCStd b/construction/v3/StepperMotorNema17.FCStd deleted file mode 100644 index 61dd2be..0000000 Binary files a/construction/v3/StepperMotorNema17.FCStd and /dev/null differ diff --git a/construction/v3/WireFlexure.FCStd b/construction/v3/WireFlexure.FCStd deleted file mode 100644 index 1d45b28..0000000 Binary files a/construction/v3/WireFlexure.FCStd and /dev/null differ diff --git a/construction/v3/WireFlexureMount.FCStd b/construction/v3/WireFlexureMount.FCStd deleted file mode 100644 index aca5cee..0000000 Binary files a/construction/v3/WireFlexureMount.FCStd and /dev/null differ diff --git a/construction/v3_3dprinting_stl/BallJointMount.stl b/construction/v3_3dprinting_stl/BallJointMount.stl deleted file mode 100644 index f67afb3..0000000 Binary files a/construction/v3_3dprinting_stl/BallJointMount.stl and /dev/null differ diff --git a/construction/v3_3dprinting_stl/BaseBlock.stl b/construction/v3_3dprinting_stl/BaseBlock.stl deleted file mode 100644 index b46e925..0000000 Binary files a/construction/v3_3dprinting_stl/BaseBlock.stl and /dev/null differ diff --git a/construction/v3_3dprinting_stl/EndEffector.stl b/construction/v3_3dprinting_stl/EndEffector.stl deleted file mode 100644 index f1628c3..0000000 Binary files a/construction/v3_3dprinting_stl/EndEffector.stl and /dev/null differ diff --git a/construction/v3_3dprinting_stl/MotorHorn.stl b/construction/v3_3dprinting_stl/MotorHorn.stl deleted file mode 100644 index 51346c5..0000000 Binary files a/construction/v3_3dprinting_stl/MotorHorn.stl and /dev/null differ diff --git a/construction/v3_3dprinting_stl/MotorMount.stl b/construction/v3_3dprinting_stl/MotorMount.stl deleted file mode 100644 index 0f51870..0000000 Binary files a/construction/v3_3dprinting_stl/MotorMount.stl and /dev/null differ diff --git a/construction/v3_3dprinting_stl/RubberBandCollet.stl b/construction/v3_3dprinting_stl/RubberBandCollet.stl deleted file mode 100644 index 6c069e3..0000000 Binary files a/construction/v3_3dprinting_stl/RubberBandCollet.stl and /dev/null differ diff --git a/construction/v3_3dprinting_stl/WireFlexureMount.stl b/construction/v3_3dprinting_stl/WireFlexureMount.stl deleted file mode 100644 index efd29db..0000000 Binary files a/construction/v3_3dprinting_stl/WireFlexureMount.stl and /dev/null differ diff --git a/construction/v4_3dprinting_stl/machine/BaseBlock.stl b/construction/v4_3dprinting_stl/machine/BaseBlock.stl new file mode 100644 index 0000000..447f27c Binary files /dev/null and b/construction/v4_3dprinting_stl/machine/BaseBlock.stl differ diff --git a/construction/v4_3dprinting_stl/machine/EndEffector.stl b/construction/v4_3dprinting_stl/machine/EndEffector.stl new file mode 100644 index 0000000..35a23af Binary files /dev/null and b/construction/v4_3dprinting_stl/machine/EndEffector.stl differ diff --git a/construction/v4_3dprinting_stl/machine/MotorHorn.stl b/construction/v4_3dprinting_stl/machine/MotorHorn.stl new file mode 100644 index 0000000..95bc063 Binary files /dev/null and b/construction/v4_3dprinting_stl/machine/MotorHorn.stl differ diff --git a/construction/v4_3dprinting_stl/machine/MotorMount.stl b/construction/v4_3dprinting_stl/machine/MotorMount.stl new file mode 100644 index 0000000..a1fff4c Binary files /dev/null and b/construction/v4_3dprinting_stl/machine/MotorMount.stl differ diff --git a/construction/v4_3dprinting_stl/machine/RubberBandCollet.stl b/construction/v4_3dprinting_stl/machine/RubberBandCollet.stl new file mode 100644 index 0000000..7f3972d Binary files /dev/null and b/construction/v4_3dprinting_stl/machine/RubberBandCollet.stl differ diff --git a/construction/v4_3dprinting_stl/tools/rod_length_setting_press/CaliperClamp.stl b/construction/v4_3dprinting_stl/tools/rod_length_setting_press/CaliperClamp.stl new file mode 100644 index 0000000..2d5c954 Binary files /dev/null and b/construction/v4_3dprinting_stl/tools/rod_length_setting_press/CaliperClamp.stl differ diff --git a/construction/v4_3dprinting_stl/tools/rod_length_setting_press/RodCollet.stl b/construction/v4_3dprinting_stl/tools/rod_length_setting_press/RodCollet.stl new file mode 100644 index 0000000..9513b59 Binary files /dev/null and b/construction/v4_3dprinting_stl/tools/rod_length_setting_press/RodCollet.stl differ diff --git a/construction/v4_3dprinting_stl/tools/rod_length_setting_press/RodGrindingJigA.stl b/construction/v4_3dprinting_stl/tools/rod_length_setting_press/RodGrindingJigA.stl new file mode 100644 index 0000000..63b88ce Binary files /dev/null and b/construction/v4_3dprinting_stl/tools/rod_length_setting_press/RodGrindingJigA.stl differ diff --git a/construction/v4_3dprinting_stl/tools/rod_length_setting_press/RodGrindingJigB.stl b/construction/v4_3dprinting_stl/tools/rod_length_setting_press/RodGrindingJigB.stl new file mode 100644 index 0000000..3de128a Binary files /dev/null and b/construction/v4_3dprinting_stl/tools/rod_length_setting_press/RodGrindingJigB.stl differ diff --git a/construction/v4_3dprinting_stl/tools/rod_length_setting_press/RodGuide.stl b/construction/v4_3dprinting_stl/tools/rod_length_setting_press/RodGuide.stl new file mode 100644 index 0000000..50ab4bc Binary files /dev/null and b/construction/v4_3dprinting_stl/tools/rod_length_setting_press/RodGuide.stl differ diff --git a/construction/v4_3dprinting_stl/tools/rod_sharpener/BladeCarrier.stl b/construction/v4_3dprinting_stl/tools/rod_sharpener/BladeCarrier.stl new file mode 100644 index 0000000..42196d0 Binary files /dev/null and b/construction/v4_3dprinting_stl/tools/rod_sharpener/BladeCarrier.stl differ diff --git a/construction/v4_3dprinting_stl/tools/rod_sharpener/RodGuide.stl b/construction/v4_3dprinting_stl/tools/rod_sharpener/RodGuide.stl new file mode 100644 index 0000000..0acaf6c Binary files /dev/null and b/construction/v4_3dprinting_stl/tools/rod_sharpener/RodGuide.stl differ diff --git a/documentation/bom/bom.md b/documentation/bom/bom.md index 411914a..963a0f7 100644 --- a/documentation/bom/bom.md +++ b/documentation/bom/bom.md @@ -1,19 +1,25 @@ # Bill of Materials (BOM) ## Mechanics -| Name | Qty | Description | Comments | Suggested link | Image | -|------|-----|-------------|----------|----------------|-------| -| Steel ball | 12 | Ø1.25 mm (0.05") | Precision G10 or better. Can be sourced from small ball bearings | | -| PU stretch cord | 1 m | Ø1mm | e.g. "Stretch Magic" or "Magic String" | [Aliexpress](https://www.aliexpress.us/item/3256805953910514.html)| ![Pu strech cord](images/PU_StretchCord.png)| -| Neodym Cylinder Magnet | 70 | Ø3mm h=5 mm | N52 Grade | [Ebay Link]()| -| Brass Pipe | 1 m | OD=Ø2mm ID=Ø1 mm | | [Amazon](https://a.co/d/1pRFmtf)| ![Brass Pipe](images/BrassPipe.png)| -| M2 Screw | 12 | M2×12 mm, Countersunk | | | -| M3 Grub Screw | 6 | M3×4 | | | -## Electronics | Name | Qty | Description | Comments | Suggested link | Image | |------|-----|-------------|----------|----------------|-------| -| DC-DC Step Down Module | 1 | 4.75–23 V Step-Down Buck Converter | | [Aliexpress](https://www.aliexpress.us/item/3256806752772875.html)| ![DC-DC Step Down](images/DC_DC-StepDown.png)| +| Steel ball | 12 | Ø1 mm (0.04") | Precision G10 or better. Can be sourced from small ball bearings | | +| PU stretch cord | 1 m | Ø1mm | e.g. "Stretch Magic" or "Magic String" | [Aliexpress](https://www.aliexpress.us/item/3256805953910514.html)| ![Pu strech cord](images/PU_StretchCord.png)| +| Neodym Cylinder Magnet | 70 | Ø3mm h=5 mm | N52 Grade | [NeoMagnets](https://www.buyneomagnets.com/p/3mm-dia-x-5mm-thick-n52-neodymium-rare-earth-disc-magnets-100-pack/)| +| Brass Pipe | 1 m | OD=Ø2mm ID=Ø1 mm | | [Amazon](https://a.co/d/1pRFmtf)| ![Brass Pipe](images/BrassPipe.png)| +| M2-8 dowel | 9 | | | | | +| SHCS M2-8 | 9 | | | | | +| Set Screw M3-6 | 3 | | | | | +| FHCS M3-6 | 3 | | | | | +| FHCS M3-10 | 9 | | | | | +| FHCS M3-20 | 12 | | | | | +| Crimp Beads | 12 | | Used to affix the ends of the PU cord | | | +## Electronics + +| Name | Qty | Description | Comments | Suggested link | Image | +|------|-----|-------------|----------|----------------|-------| +| DC-DC Step Down Module | 1 | 5V Fixed Output Step-Down Buck Converter | | [Aliexpress](https://www.aliexpress.com/item/1005008257960729.html)| ![DC-DC Step Down](images/Fixed_DC_DC-StepDown.png)| | (1N5819) OR (PMEG4010) | 1 | Diode (through-hole or SMD) | | | | Raspberry Pi Pico 2 | 1 | Microcontroller board | | | ![Raspberry Pi Pico 2](images/RaspberryPiPico2.png)| | MT6835 Magnetic Encoder Module | 3 | Magnetic encoder | | [Aliexpress](https://www.aliexpress.us/item/3256808005140674.html)| ![MT6835 Magnetic Encoder Module](images/MT6835.png)| @@ -21,17 +27,51 @@ | 470 µF Electrolytic Capacitor | 3 | > 100 µF | anything > 100µF will work well | | | 10 µF Ceramic Capacitor 0603 | 3 | Optional | | | | 4.7 k Resistor 0603 | 2 | Optional | | | -| 2 Pin Power Header | 1 | 7.5 mm pitch | | | -| 4 Pin Header | 4 | 2.5 mm pitch | | | -| 8 Pin Header | 1 | 2.0 mm pitch | | | | NEMA 17 Stepper Motor | 3 | Body ≤ 38 mm | Body length <= 38mm | | +| JST XH2.54 4P connector | 3 | 4P Housing & Header 2.54mm pitch | J1, J2, J3 (motors) | [Aliexpress](https://www.aliexpress.com/item/1005007080333485.html?spm=a2g0o.order_list.order_list_main.53.3d5d1802JZg5Wb) | ![JST XH2.54 Connector](images/JST_XH2.54_Connector.png) | +| XT60H Connector | 1 | 2P Male & Female pair 7.5mm pitch | Power connector | [Aliexpress](https://www.aliexpress.com/item/1005007605928815.html?spm=a2g0o.order_list.order_list_main.409.3d5d1802JZg5Wb) | ![XT60H Connector](images/XT60H_Pairs.png) | +| PH2.0 4P Housing
PH2.0 8P Housing | 1
1 | 4P 2mm pitch Housing
8P 2mm pitch Housing | J5 (tool/I2C)
J4 (encoders) | [Aliexpress](https://www.aliexpress.com/item/1005010491403413.html?spm=a2g0o.order_detail.order_detail_item.3.2b60126a5SMahl) | ![PH2.0 Housings](images/PH2_Housings.png) | +| PH2.0 4P Header
PH2.0 8P Header | 1
1 | 4P 2mm pitch Header
8P 2mm pitch Header | J5 (tool/I2C)
J4 (encoders) | [Aliexpress](https://www.aliexpress.com/item/1005010491403413.html?spm=a2g0o.order_detail.order_detail_item.3.2b60126a5SMahl) | ![PH2.0 Headers](images/PH2_Headers.png) | +## PCBs + +| Name | Qty | Description | Comments | Image | +| ------------------- | --- | ----------- | -------- | ----- | +| Control Board | 1 | | | | +| balljoint_plate_pcb | 6 | | | | ## 3D Printing -| Name | Qty | Description | Comments | Image | -|------|-----|-------------|----------|-------| -| Motor Horn | 3 | | 0.4 mm+ nozzle may require post-processing | ![Motor Horn](images/MotorHorn.png)| -| RubberBandCollet | 12 | | 0.4 mm nozzle, 0.1mm Layer height + may require post-processing | ![Rubber Band Collet](images/RubberBandCollet.png)| -| BallJointMount | 6 | | 0.4 mm nozzle, 0.1mm Layer height + may require post-processing | ![Ball Joint Mount](images/BallJointMount.png)| -| Motor Mount | 3 | | | ![Motor Mount](images/MotorMount.png)| -| End Effector | 1 | | | ![End Effector](images/EndEffector.png)| -| Base Block | 1 | | | ![Base Block](images/BaseBlock.png)| + +| Name | Qty | Description | Comments | Image | +| ------------------- | --- | ----------- | --------------------------------------------------------------- | -------------------------------------------------- | +| Motor Horn | 3 | | 0.4 mm+ nozzle may require post-processing | ![Motor Horn](images/MotorHorn.png) | +| RubberBandCollet | 12 | | 0.4 mm nozzle, 0.1mm Layer height + may require post-processing | ![Rubber Band Collet](images/RubberBandCollet.png) | +| Motor Mount | 3 | | | ![Motor Mount](images/MotorMount.png) | +| End Effector | 1 | | | ![End Effector](images/EndEffector.png) | +| Base Block | 1 | | | ![Base Block](images/BaseBlock.png) | + +# Tool - Rod Sharpener + +## 3D Printing + +| Name | Qty | Description | Comments | Image | +| ------------- | --- | ----------- | -------- | ----- | +| Rod Guide | 1 | | | | +| Blade Carrier | 1 | | | | + +# Tool - Rod Length Setting Press + +## PCBs + +| Name | Qty | Description | Comments | Image | +| ----------------------- | --- | ----------- | -------- | ----- | +| ball_alignment_disc_pcb | 1 | | | | + +## 3D Printing + +| Name | Qty | Description | Comments | Image | +| ----------------------- | --- | ----------- | -------- | ----- | +| RodGrindingJigA | 1 | | | | +| RodGrindingJigB | 1 | | | | +| RodGuide | 1 | | | | +| RodCollet | 2 | | | | +| CaliperClamp | 2 | | | | diff --git a/documentation/bom/images/Fixed_DC_DC-StepDown.png b/documentation/bom/images/Fixed_DC_DC-StepDown.png new file mode 100644 index 0000000..6804f30 Binary files /dev/null and b/documentation/bom/images/Fixed_DC_DC-StepDown.png differ diff --git a/documentation/bom/images/JST_XH2.54_Connector.png b/documentation/bom/images/JST_XH2.54_Connector.png new file mode 100644 index 0000000..a38864a Binary files /dev/null and b/documentation/bom/images/JST_XH2.54_Connector.png differ diff --git a/documentation/bom/images/PH2_Headers.png b/documentation/bom/images/PH2_Headers.png new file mode 100644 index 0000000..1310723 Binary files /dev/null and b/documentation/bom/images/PH2_Headers.png differ diff --git a/documentation/bom/images/PH2_Housings.png b/documentation/bom/images/PH2_Housings.png new file mode 100644 index 0000000..6e0b352 Binary files /dev/null and b/documentation/bom/images/PH2_Housings.png differ diff --git a/documentation/bom/images/XT60H_Pairs.png b/documentation/bom/images/XT60H_Pairs.png new file mode 100644 index 0000000..c41532a Binary files /dev/null and b/documentation/bom/images/XT60H_Pairs.png differ diff --git a/documentation/setup_guide/bad_calibration.jpg b/documentation/setup_guide/bad_calibration.jpg new file mode 100644 index 0000000..4e10faf Binary files /dev/null and b/documentation/setup_guide/bad_calibration.jpg differ diff --git a/documentation/setup_guide/good_calibration.jpg b/documentation/setup_guide/good_calibration.jpg new file mode 100644 index 0000000..84208a2 Binary files /dev/null and b/documentation/setup_guide/good_calibration.jpg differ diff --git a/documentation/setup_guide/homing_direction.jpg b/documentation/setup_guide/homing_direction.jpg new file mode 100644 index 0000000..d365912 Binary files /dev/null and b/documentation/setup_guide/homing_direction.jpg differ diff --git a/documentation/setup_guide/mechanical_limit_pin.jpg b/documentation/setup_guide/mechanical_limit_pin.jpg new file mode 100644 index 0000000..c991da2 Binary files /dev/null and b/documentation/setup_guide/mechanical_limit_pin.jpg differ diff --git a/documentation/setup_guide/setup_guide.md b/documentation/setup_guide/setup_guide.md new file mode 100644 index 0000000..82b7eb6 --- /dev/null +++ b/documentation/setup_guide/setup_guide.md @@ -0,0 +1,36 @@ +# Setup Guide + +This guide walks you through the setup of your new **Open Micro-Manipulator** device. + +## Checklist for New Devices + +1. **Was the mechanical limit pin added to the rotor?** + This pin is required for proper homing of the device. + +
+ Mechanical Limit Pin +
+ + +2. **Are the screws that secure the rotor to the motor shaft installed?** + If the rotor is not firmly attached, it may slip imperceptibly during homing or other movements, leading to problems during calibration and homing. + +3. **Is the homing direction correct?** + During the homing command (`G28`), the end effector should move toward the base. + If it moves in the opposite direction, rewire the motor to reverse its direction. + +
+ Mechanical Limit Pin +
+ + +## Calibration and Checking the Encoders + +You can use the calibration plotter to check if your encoders are working as expected. +On the left you see a good calibration on the right a bad calibration. + +| | | +:--:|:--: +| **Good calibration** | **Bad calibration** | + +THIS DOCUMENT IS UNFINISHED AND WORK IN PROGRESS... diff --git a/electronics/EncoderBoard.kicad_pcb b/electronics/EncoderBoard.kicad_pcb new file mode 100644 index 0000000..6afeb00 --- /dev/null +++ b/electronics/EncoderBoard.kicad_pcb @@ -0,0 +1,5066 @@ +(kicad_pcb + (version 20241229) + (generator "pcbnew") + (generator_version "9.0") + (general + (thickness 1.6) + (legacy_teardrops no) + ) + (paper "A4") + (layers + (0 "F.Cu" signal) + (2 "B.Cu" signal) + (9 "F.Adhes" user "F.Adhesive") + (11 "B.Adhes" user "B.Adhesive") + (13 "F.Paste" user) + (15 "B.Paste" user) + (5 "F.SilkS" user "F.Silkscreen") + (7 "B.SilkS" user "B.Silkscreen") + (1 "F.Mask" user) + (3 "B.Mask" user) + (17 "Dwgs.User" user "User.Drawings") + (19 "Cmts.User" user "User.Comments") + (21 "Eco1.User" user "User.Eco1") + (23 "Eco2.User" user "User.Eco2") + (25 "Edge.Cuts" user) + (27 "Margin" user) + (31 "F.CrtYd" user "F.Courtyard") + (29 "B.CrtYd" user "B.Courtyard") + (35 "F.Fab" user) + (33 "B.Fab" user) + (39 "User.1" user) + (41 "User.2" user) + (43 "User.3" user) + (45 "User.4" user) + ) + (setup + (stackup + (layer "F.SilkS" + (type "Top Silk Screen") + ) + (layer "F.Paste" + (type "Top Solder Paste") + ) + (layer "F.Mask" + (type "Top Solder Mask") + (thickness 0.01) + ) + (layer "F.Cu" + (type "copper") + (thickness 0.035) + ) + (layer "dielectric 1" + (type "core") + (thickness 1.51) + (material "FR4") + (epsilon_r 4.5) + (loss_tangent 0.02) + ) + (layer "B.Cu" + (type "copper") + (thickness 0.035) + ) + (layer "B.Mask" + (type "Bottom Solder Mask") + (thickness 0.01) + ) + (layer "B.Paste" + (type "Bottom Solder Paste") + ) + (layer "B.SilkS" + (type "Bottom Silk Screen") + ) + (copper_finish "None") + (dielectric_constraints no) + ) + (pad_to_mask_clearance 0) + (allow_soldermask_bridges_in_footprints no) + (tenting front back) + (pcbplotparams + (layerselection 0x00000000_00000000_55555555_575555ff) + (plot_on_all_layers_selection 0x00000000_00000000_00000000_00000000) + (disableapertmacros no) + (usegerberextensions no) + (usegerberattributes yes) + (usegerberadvancedattributes yes) + (creategerberjobfile yes) + (dashed_line_dash_ratio 12.000000) + (dashed_line_gap_ratio 3.000000) + (svgprecision 4) + (plotframeref no) + (mode 1) + (useauxorigin no) + (hpglpennumber 1) + (hpglpenspeed 20) + (hpglpendiameter 15.000000) + (pdf_front_fp_property_popups yes) + (pdf_back_fp_property_popups yes) + (pdf_metadata yes) + (pdf_single_document no) + (dxfpolygonmode yes) + (dxfimperialunits yes) + (dxfusepcbnewfont yes) + (psnegative no) + (psa4output no) + (plot_black_and_white yes) + (sketchpadsonfab no) + (plotpadnumbers no) + (hidednponfab no) + (sketchdnponfab yes) + (crossoutdnponfab yes) + (subtractmaskfromsilk no) + (outputformat 1) + (mirror no) + (drillshape 0) + (scaleselection 1) + (outputdirectory "encoder-gerber") + ) + ) + (net 0 "") + (net 1 "/Encoder3_CS") + (net 2 "+3.3V") + (net 3 "/Encoder_MISO") + (net 4 "GND") + (net 5 "/Encoder2_CS") + (net 6 "/Encoder1_CS") + (net 7 "/Encoder_MOSI") + (net 8 "/Encoder_SCK") + (net 9 "unconnected-(H1-Pad1)") + (net 10 "unconnected-(H2-Pad1)") + (net 11 "unconnected-(H3-Pad1)") + (net 12 "unconnected-(H4-Pad1)") + (footprint "Connector_JST:JST_PH_B8B-PH-K_1x08_P2.00mm_Vertical" + (layer "F.Cu") + (uuid "000f8650-4bff-4a24-9497-90b8f77dad69") + (at 159 79 180) + (descr "JST PH series connector, B8B-PH-K (http://www.jst-mfg.com/product/pdf/eng/ePH.pdf), generated with kicad-footprint-generator") + (tags "connector JST PH vertical") + (property "Reference" "J4" + (at -4 -2 0) + (layer "F.SilkS") + (uuid "96ca3c64-95a0-426b-836a-9634f4a51e0f") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Value" "Conn_01x08_Pin" + (at 7 4 0) + (layer "F.Fab") + (uuid "a66f9f58-de35-4f86-9f4e-edc135ed37fd") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Datasheet" "~" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "6ca4b388-76bc-49f3-8de2-78f264796143") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property "Description" "Generic connector, single row, 01x08, script generated" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "a068423c-8c06-4c68-af91-59d8ecd350c2") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property ki_fp_filters "Connector*:*_1x??_*") + (path "/06f6d8de-1779-48c3-8896-175e2062e7dc") + (sheetname "/") + (sheetfile "EncoderBoard.kicad_sch") + (attr through_hole) + (fp_line + (start 16.06 2.91) + (end 16.06 -1.81) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "55b1ff01-85f0-4dd7-ae4a-125efd472734") + ) + (fp_line + (start 16.06 0.8) + (end 15.45 0.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "6c0edb27-cd53-4ff3-996d-b3d6794f0d9c") + ) + (fp_line + (start 16.06 -0.5) + (end 15.45 -0.5) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "c1184f9d-0653-491e-9c27-788d4e7945e7") + ) + (fp_line + (start 16.06 -1.81) + (end -2.06 -1.81) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "61e60299-e351-4d56-a239-16d84c3b4a56") + ) + (fp_line + (start 15.45 2.3) + (end 15.45 -1.2) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "782a4ef7-9f2a-48eb-81fc-b3cdb2110111") + ) + (fp_line + (start 15.45 -1.2) + (end 13.5 -1.2) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "c6a043a7-f001-4b24-9031-0f9167a8b864") + ) + (fp_line + (start 13.5 -1.2) + (end 13.5 -1.81) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "2b943908-ca0f-4ca0-9bed-9126862c2115") + ) + (fp_line + (start 13.1 1.8) + (end 13.1 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "16b3c81c-2ba0-4337-a512-8891561130c7") + ) + (fp_line + (start 13 2.3) + (end 13 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "b52f82d5-2fcd-4e63-91b7-3587bbae15ec") + ) + (fp_line + (start 12.9 2.3) + (end 12.9 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "28d892e0-5d34-4daa-8f60-ee6e5c5e8b20") + ) + (fp_line + (start 12.9 1.8) + (end 13.1 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "73507f7d-8a3c-4731-baff-cc3f30b52b12") + ) + (fp_line + (start 11.1 1.8) + (end 11.1 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "23f583c7-0c95-45a7-8d10-256d52fc452f") + ) + (fp_line + (start 11 2.3) + (end 11 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "6427c9ef-65e9-4583-a73a-cc0b83195e59") + ) + (fp_line + (start 10.9 2.3) + (end 10.9 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "f1fe4821-7375-42aa-9488-288827483aaf") + ) + (fp_line + (start 10.9 1.8) + (end 11.1 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "b7e5ef25-b953-4518-b757-c10cf49e4425") + ) + (fp_line + (start 9.1 1.8) + (end 9.1 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "603f2cf9-9e4d-4898-8709-0995d7d715a0") + ) + (fp_line + (start 9 2.3) + (end 9 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "c99cb88d-febc-4d5d-981a-dab9e9d0e8be") + ) + (fp_line + (start 8.9 2.3) + (end 8.9 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "5242c891-bfee-49a1-819a-eebed8f223bc") + ) + (fp_line + (start 8.9 1.8) + (end 9.1 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "f998482c-7268-41b6-86be-074ee88a1041") + ) + (fp_line + (start 7.1 1.8) + (end 7.1 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "197318f1-fe30-4335-bc4d-2fce5eeb3a16") + ) + (fp_line + (start 7 2.3) + (end 7 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "33efb727-fc0b-4eea-8e69-24bb1912f1e2") + ) + (fp_line + (start 6.9 2.3) + (end 6.9 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "e873e7df-b75f-4bdf-a21a-ad39db961f09") + ) + (fp_line + (start 6.9 1.8) + (end 7.1 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "dda8154a-9ae2-4fbd-841f-8757485f66bb") + ) + (fp_line + (start 5.1 1.8) + (end 5.1 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "7884a1ad-bc26-4262-a4cb-5d3da4db8ce1") + ) + (fp_line + (start 5 2.3) + (end 5 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "2d1110f9-8896-4467-9fa2-1962417d2565") + ) + (fp_line + (start 4.9 2.3) + (end 4.9 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "da80fdd8-dad7-4fcf-9ccc-d41a099451a8") + ) + (fp_line + (start 4.9 1.8) + (end 5.1 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "8bf2caad-1f93-4377-9a70-ca18c63070da") + ) + (fp_line + (start 3.1 1.8) + (end 3.1 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "bde41ef7-c24b-4453-99e9-f52c23f3a650") + ) + (fp_line + (start 3 2.3) + (end 3 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "049d823f-f78a-42dd-a6c1-d2dfc50598ce") + ) + (fp_line + (start 2.9 2.3) + (end 2.9 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "e2b38dec-be56-4976-bd6a-b3098e4f7a56") + ) + (fp_line + (start 2.9 1.8) + (end 3.1 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "3ce54286-475a-43af-83c4-f493fd30f857") + ) + (fp_line + (start 1.1 1.8) + (end 1.1 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "1345a42b-2a41-4d21-9919-0feed7fb72ec") + ) + (fp_line + (start 1 2.3) + (end 1 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "102e9f9f-4e09-4bb3-a41c-d3dcba7205b1") + ) + (fp_line + (start 0.9 2.3) + (end 0.9 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "2c046b21-09f1-43ec-ac41-f98787045020") + ) + (fp_line + (start 0.9 1.8) + (end 1.1 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "1bb7bf11-76da-4254-9ef4-8c7b1e66eeb0") + ) + (fp_line + (start 0.5 -1.2) + (end -1.45 -1.2) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "34e1bbdc-cc0b-4c09-af8e-60a917e4a5b2") + ) + (fp_line + (start 0.5 -1.81) + (end 0.5 -1.2) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "60c72f4f-3015-455d-ac45-f7a9dea975df") + ) + (fp_line + (start -0.3 -1.81) + (end -0.3 -2.01) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "af990713-5b3f-473e-be6c-e0491eb3d6e0") + ) + (fp_line + (start -0.3 -1.91) + (end -0.6 -1.91) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "cc06a07e-6e57-4f5d-a710-afab304246ad") + ) + (fp_line + (start -0.3 -2.01) + (end -0.6 -2.01) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "ffd69982-fe66-4324-b55a-3b7eb93b8c6b") + ) + (fp_line + (start -0.6 -2.01) + (end -0.6 -1.81) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "90036d1d-cea4-4f88-8731-64fc80c6ebba") + ) + (fp_line + (start -1.11 -2.11) + (end -2.36 -2.11) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "c25cba3c-18f0-4c83-b5e0-05cfa11ba882") + ) + (fp_line + (start -1.45 2.3) + (end 15.45 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "7a4b0c45-19a7-4781-9120-7faf269f7479") + ) + (fp_line + (start -1.45 -1.2) + (end -1.45 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "9844a8f7-dcd7-4f4c-a847-0bb89d2b3920") + ) + (fp_line + (start -2.06 2.91) + (end 16.06 2.91) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "98c2b119-2e83-4891-adc4-ec662258f669") + ) + (fp_line + (start -2.06 0.8) + (end -1.45 0.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "e8ee10af-4f10-4efc-9eec-be8d16a8b3cf") + ) + (fp_line + (start -2.06 -0.5) + (end -1.45 -0.5) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "66ebca8d-c0f8-44be-a99c-c75a064ba6a9") + ) + (fp_line + (start -2.06 -1.81) + (end -2.06 2.91) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "3a112a8d-1b13-4e39-86d5-eb038ee86738") + ) + (fp_line + (start -2.36 -2.11) + (end -2.36 -0.86) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "df0750a3-987b-4298-8c4a-1e04728c645d") + ) + (fp_line + (start 16.45 3.3) + (end 16.45 -2.2) + (stroke + (width 0.05) + (type solid) + ) + (layer "F.CrtYd") + (uuid "ec91e894-82a2-4777-bc5c-5ed90f99fee4") + ) + (fp_line + (start 16.45 -2.2) + (end -2.45 -2.2) + (stroke + (width 0.05) + (type solid) + ) + (layer "F.CrtYd") + (uuid "fce0b9ec-fa66-44d0-abd9-a812876e2ca9") + ) + (fp_line + (start -2.45 3.3) + (end 16.45 3.3) + (stroke + (width 0.05) + (type solid) + ) + (layer "F.CrtYd") + (uuid "808bdd95-6608-4a6e-859d-b6caca8ff17c") + ) + (fp_line + (start -2.45 -2.2) + (end -2.45 3.3) + (stroke + (width 0.05) + (type solid) + ) + (layer "F.CrtYd") + (uuid "d8481e5a-f3cd-4498-acad-495ef6f0af83") + ) + (fp_line + (start 15.95 2.8) + (end 15.95 -1.7) + (stroke + (width 0.1) + (type solid) + ) + (layer "F.Fab") + (uuid "92e47d2d-48cb-426f-9739-0eade4a266d6") + ) + (fp_line + (start 15.95 -1.7) + (end -1.95 -1.7) + (stroke + (width 0.1) + (type solid) + ) + (layer "F.Fab") + (uuid "57f209dc-fa3e-4e26-ba40-6fc88e91ced8") + ) + (fp_line + (start -1.11 -2.11) + (end -2.36 -2.11) + (stroke + (width 0.1) + (type solid) + ) + (layer "F.Fab") + (uuid "02f6c69b-49e6-41b5-b4d4-900e47c73ffb") + ) + (fp_line + (start -1.95 2.8) + (end 15.95 2.8) + (stroke + (width 0.1) + (type solid) + ) + (layer "F.Fab") + (uuid "a8585e79-ec13-4495-89c5-2a38cbf05333") + ) + (fp_line + (start -1.95 -1.7) + (end -1.95 2.8) + (stroke + (width 0.1) + (type solid) + ) + (layer "F.Fab") + (uuid "8813a597-4259-4734-9cba-7ca87ed2e7eb") + ) + (fp_line + (start -2.36 -2.11) + (end -2.36 -0.86) + (stroke + (width 0.1) + (type solid) + ) + (layer "F.Fab") + (uuid "c866a1d5-dedf-433a-a028-968e17ad0cd6") + ) + (fp_text user "${REFERENCE}" + (at 7 1.5 0) + (layer "F.Fab") + (uuid "c0257a35-7e4c-4c85-8371-c2eec82fe389") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (pad "1" thru_hole roundrect + (at 0 0 180) + (size 1.2 1.75) + (drill 0.75) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (roundrect_rratio 0.208333) + (net 4 "GND") + (pinfunction "Pin_1") + (pintype "passive") + (uuid "51e7f92e-bf11-4996-b169-7098f469c7b2") + ) + (pad "2" thru_hole oval + (at 2 0 180) + (size 1.2 1.75) + (drill 0.75) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 2 "+3.3V") + (pinfunction "Pin_2") + (pintype "passive") + (uuid "3176510a-6059-4d03-a125-5bc661bcc294") + ) + (pad "3" thru_hole oval + (at 4 0 180) + (size 1.2 1.75) + (drill 0.75) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 7 "/Encoder_MOSI") + (pinfunction "Pin_3") + (pintype "passive") + (uuid "ae37be4f-9779-43bf-a1fe-71b98d387610") + ) + (pad "4" thru_hole oval + (at 6 0 180) + (size 1.2 1.75) + (drill 0.75) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 3 "/Encoder_MISO") + (pinfunction "Pin_4") + (pintype "passive") + (uuid "329119d5-7e4c-48f1-bcaa-041875df85bb") + ) + (pad "5" thru_hole oval + (at 8 0 180) + (size 1.2 1.75) + (drill 0.75) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 8 "/Encoder_SCK") + (pinfunction "Pin_5") + (pintype "passive") + (uuid "fc98beb7-a19f-4b3c-8e87-0ae11ca43137") + ) + (pad "6" thru_hole oval + (at 10 0 180) + (size 1.2 1.75) + (drill 0.75) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 6 "/Encoder1_CS") + (pinfunction "Pin_6") + (pintype "passive") + (uuid "675c1796-e317-4cf3-8e27-ce76437734d5") + ) + (pad "7" thru_hole oval + (at 12 0 180) + (size 1.2 1.75) + (drill 0.75) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 5 "/Encoder2_CS") + (pinfunction "Pin_7") + (pintype "passive") + (uuid "52229df1-4afb-4d19-a7ff-d18549acfa6a") + ) + (pad "8" thru_hole oval + (at 14 0 180) + (size 1.2 1.75) + (drill 0.75) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 1 "/Encoder3_CS") + (pinfunction "Pin_8") + (pintype "passive") + (uuid "153921ed-40af-47fa-833d-5b5e1456c434") + ) + (embedded_fonts no) + (model "${KICAD9_3DMODEL_DIR}/Connector_JST.3dshapes/JST_PH_B8B-PH-K_1x08_P2.00mm_Vertical.step" + (offset + (xyz 0 0 0) + ) + (scale + (xyz 1 1 1) + ) + (rotate + (xyz 0 0 0) + ) + ) + ) + (footprint "MountingHole:MountingHole_2.7mm_M2.5_Pad_Via" + (layer "F.Cu") + (uuid "3b9416a9-eda5-4066-b6db-33974e7bc2ec") + (at 166 78) + (descr "Mounting Hole 2.7mm, M2.5, generated by kicad-footprint-generator mountinghole.py") + (tags "mountinghole M2.5") + (property "Reference" "H2" + (at 0 4.025 0) + (layer "F.SilkS") + (hide yes) + (uuid "23487818-3e27-47c2-a225-74f06364beb7") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Value" "MountingHole_Pad" + (at 1 -5.5 0) + (layer "F.Fab") + (uuid "6e9ad6e5-da3c-487b-886e-8f7648d550e6") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Datasheet" "~" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "11ae498b-b6c3-48dd-b3c3-095a94a22865") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property "Description" "Mounting Hole with connection" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "6ab70ae5-6bb0-474f-a57f-8abc64c9cbfe") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property ki_fp_filters "MountingHole*Pad*") + (path "/4902fc81-dc1d-478f-891f-f1b754c57f22") + (sheetname "/") + (sheetfile "EncoderBoard.kicad_sch") + (attr exclude_from_pos_files exclude_from_bom) + (fp_circle + (center 0 0) + (end 2.7 0) + (stroke + (width 0.15) + (type solid) + ) + (fill no) + (layer "Cmts.User") + (uuid "1ae430b0-59a1-4df3-8b01-456a2ce69e16") + ) + (fp_circle + (center 0 0) + (end 2.95 0) + (stroke + (width 0.05) + (type solid) + ) + (fill no) + (layer "F.CrtYd") + (uuid "d1d04383-b59b-482b-a250-74f80b35684d") + ) + (fp_text user "${REFERENCE}" + (at 0 0 0) + (layer "F.Fab") + (uuid "73ec7923-f8f3-43f7-bef7-cb6ebade3c73") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (pad "1" thru_hole circle + (at -2.025 0) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 10 "unconnected-(H2-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "fd57896c-1a3b-40d4-b079-4aee6859d6a7") + ) + (pad "1" thru_hole circle + (at -1.431891 -1.431891) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 10 "unconnected-(H2-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "4663e289-08fb-4138-a66b-b6e0ea3355a8") + ) + (pad "1" thru_hole circle + (at -1.431891 1.431891) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 10 "unconnected-(H2-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "c2de264e-6bdb-48d4-9798-11c918afb006") + ) + (pad "1" thru_hole circle + (at 0 -2.025) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 10 "unconnected-(H2-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "911a23b5-f053-40f9-9891-042b4a4fa8f6") + ) + (pad "1" thru_hole circle + (at 0 0) + (size 5.4 5.4) + (drill 2.7) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 10 "unconnected-(H2-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "7e47eda0-68fe-4cca-a4b2-2d619dd3582d") + ) + (pad "1" thru_hole circle + (at 0 2.025) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 10 "unconnected-(H2-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "0dac44d9-ff3b-4c1b-b629-19b17d61d918") + ) + (pad "1" thru_hole circle + (at 1.431891 -1.431891) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 10 "unconnected-(H2-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "4b0a16cb-7761-4cc7-9c83-83d66e6c8093") + ) + (pad "1" thru_hole circle + (at 1.431891 1.431891) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 10 "unconnected-(H2-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "73ed2975-5f92-4cc5-a69a-347b7c82ac63") + ) + (pad "1" thru_hole circle + (at 2.025 0) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 10 "unconnected-(H2-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "b270127f-1d4b-4547-9b3c-6c4a70b279fa") + ) + (embedded_fonts no) + ) + (footprint "Connector_JST:JST_PH_B6B-PH-K_1x06_P2.00mm_Vertical" + (layer "F.Cu") + (uuid "433179e8-25f5-4fd9-b2d1-b5df816fc148") + (at 157 88 180) + (descr "JST PH series connector, B6B-PH-K (http://www.jst-mfg.com/product/pdf/eng/ePH.pdf), generated with kicad-footprint-generator") + (tags "connector JST PH vertical") + (property "Reference" "J3" + (at -4 -1 0) + (layer "F.SilkS") + (uuid "5659e244-5014-48c7-95ae-8617779f3922") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Value" "Conn_01x06_Pin" + (at 5 4 0) + (layer "F.Fab") + (uuid "fb9f3f7b-06da-40e8-9606-f09bd40a09b8") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Datasheet" "~" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "f29c72a1-000a-4bb6-80bb-c26e2eabac94") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property "Description" "Generic connector, single row, 01x06, script generated" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "47f0dc7b-bf2b-4be6-bc29-52c070d2fe8d") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property ki_fp_filters "Connector*:*_1x??_*") + (path "/24e02eae-0658-4b1e-b654-f9323214dc85") + (sheetname "/") + (sheetfile "EncoderBoard.kicad_sch") + (attr through_hole) + (fp_line + (start 12.06 2.91) + (end 12.06 -1.81) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "ab351db8-5827-4226-908d-3a6279168953") + ) + (fp_line + (start 12.06 0.8) + (end 11.45 0.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "60dc52dc-21ec-4cac-8b25-97cf2f6b5f74") + ) + (fp_line + (start 12.06 -0.5) + (end 11.45 -0.5) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "36da1984-3cca-4da8-bf02-3ffef1ffa50d") + ) + (fp_line + (start 12.06 -1.81) + (end -2.06 -1.81) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "5656e359-2705-4aed-a8c6-82d84a184cc4") + ) + (fp_line + (start 11.45 2.3) + (end 11.45 -1.2) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "0726fb0e-12ac-4f59-8ed4-126540464bce") + ) + (fp_line + (start 11.45 -1.2) + (end 9.5 -1.2) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "9b33954d-4f68-4c9a-98e2-ea53dc58e113") + ) + (fp_line + (start 9.5 -1.2) + (end 9.5 -1.81) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "e94ce4dd-6712-4617-baab-311451197120") + ) + (fp_line + (start 9.1 1.8) + (end 9.1 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "1ea5d0e3-0bca-4350-a4b3-93c5b2de4610") + ) + (fp_line + (start 9 2.3) + (end 9 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "9597fdbf-1dec-4446-bf30-54eab23e6525") + ) + (fp_line + (start 8.9 2.3) + (end 8.9 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "9ed319f8-aaee-40b7-98d0-197dd987ddf8") + ) + (fp_line + (start 8.9 1.8) + (end 9.1 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "ab79e9c9-c9d6-4edd-80c5-60c0241b161f") + ) + (fp_line + (start 7.1 1.8) + (end 7.1 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "468ae856-a8e1-4655-bb44-b5ce4506deb0") + ) + (fp_line + (start 7 2.3) + (end 7 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "3d997777-8c8d-463c-98e3-5d2ad4d63b38") + ) + (fp_line + (start 6.9 2.3) + (end 6.9 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "12a5081c-e109-42de-af0a-01d7a62a9192") + ) + (fp_line + (start 6.9 1.8) + (end 7.1 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "a7ee07f4-99df-4c59-a9fb-cf54d2bc39ed") + ) + (fp_line + (start 5.1 1.8) + (end 5.1 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "bc9a766a-18a6-4e8e-9883-814e2da56d79") + ) + (fp_line + (start 5 2.3) + (end 5 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "5cf64f64-c267-4f4a-8ca8-13891f8772d5") + ) + (fp_line + (start 4.9 2.3) + (end 4.9 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "5f356e79-2f47-4963-8a92-70e70523f478") + ) + (fp_line + (start 4.9 1.8) + (end 5.1 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "a4ad238d-71b9-49f7-9945-24ba5f0430c7") + ) + (fp_line + (start 3.1 1.8) + (end 3.1 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "b66a3c20-53ed-4f69-9035-5e184ab58581") + ) + (fp_line + (start 3 2.3) + (end 3 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "c409dd10-27f6-455c-9e6b-58d183ed2b3d") + ) + (fp_line + (start 2.9 2.3) + (end 2.9 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "71a86ae8-c596-49c2-a64a-bf34020c2025") + ) + (fp_line + (start 2.9 1.8) + (end 3.1 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "d41bec30-1347-4f4c-8512-dbd39ec9d5ca") + ) + (fp_line + (start 1.1 1.8) + (end 1.1 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "9fab4a24-283f-4b85-aadc-f259b3f482b9") + ) + (fp_line + (start 1 2.3) + (end 1 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "40f0f3f7-b040-4fa9-abf8-dec8581b9976") + ) + (fp_line + (start 0.9 2.3) + (end 0.9 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "02e88161-fd88-4814-93e4-a3d40bef0804") + ) + (fp_line + (start 0.9 1.8) + (end 1.1 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "612b858c-d27b-4e91-b155-2e40e70b9d79") + ) + (fp_line + (start 0.5 -1.2) + (end -1.45 -1.2) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "c09f0a84-f3a8-4b66-9450-680009ef75b8") + ) + (fp_line + (start 0.5 -1.81) + (end 0.5 -1.2) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "6eb476e4-cc11-4600-a068-07251923db9e") + ) + (fp_line + (start -0.3 -1.81) + (end -0.3 -2.01) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "c6bb5e7d-eceb-413e-a393-8fd8e00eb1d7") + ) + (fp_line + (start -0.3 -1.91) + (end -0.6 -1.91) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "7dee0d3c-d6c9-4ece-8afd-d7da2a4f7315") + ) + (fp_line + (start -0.3 -2.01) + (end -0.6 -2.01) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "918a5fcb-b5c1-481b-ba6f-e87b5fde9a02") + ) + (fp_line + (start -0.6 -2.01) + (end -0.6 -1.81) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "5bfc381b-a150-452b-9b14-76d2eceeab1f") + ) + (fp_line + (start -1.11 -2.11) + (end -2.36 -2.11) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "259b2cad-6f8d-418b-b661-16b846250706") + ) + (fp_line + (start -1.45 2.3) + (end 11.45 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "12c96a04-6824-4b2c-9f48-b3281359a47f") + ) + (fp_line + (start -1.45 -1.2) + (end -1.45 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "2ac6e154-be69-42d1-bad9-9d0c4b842a10") + ) + (fp_line + (start -2.06 2.91) + (end 12.06 2.91) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "7cd73d0b-f9af-4aa8-8ccc-1989933488a1") + ) + (fp_line + (start -2.06 0.8) + (end -1.45 0.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "689d8ef1-808f-42cb-b866-4c5106932cd0") + ) + (fp_line + (start -2.06 -0.5) + (end -1.45 -0.5) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "b8e5d05a-13f8-4cb6-bd0f-e2d96e044c9c") + ) + (fp_line + (start -2.06 -1.81) + (end -2.06 2.91) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "e1c13103-b88b-4708-8004-5a78573787aa") + ) + (fp_line + (start -2.36 -2.11) + (end -2.36 -0.86) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "a88cef29-9d31-48e4-83fa-21228afc458e") + ) + (fp_line + (start 12.45 3.3) + (end 12.45 -2.2) + (stroke + (width 0.05) + (type solid) + ) + (layer "F.CrtYd") + (uuid "16366216-d4d2-4bfd-a821-1b971887d195") + ) + (fp_line + (start 12.45 -2.2) + (end -2.45 -2.2) + (stroke + (width 0.05) + (type solid) + ) + (layer "F.CrtYd") + (uuid "9fe027f8-13e4-4c74-9cf9-84c3d8e20baf") + ) + (fp_line + (start -2.45 3.3) + (end 12.45 3.3) + (stroke + (width 0.05) + (type solid) + ) + (layer "F.CrtYd") + (uuid "29f62209-827b-4403-ad84-4d744c8f4d4a") + ) + (fp_line + (start -2.45 -2.2) + (end -2.45 3.3) + (stroke + (width 0.05) + (type solid) + ) + (layer "F.CrtYd") + (uuid "da90dc6c-8e40-4a13-b492-c522e15ce1e1") + ) + (fp_line + (start 11.95 2.8) + (end 11.95 -1.7) + (stroke + (width 0.1) + (type solid) + ) + (layer "F.Fab") + (uuid "4f1fc5c4-5ed0-4935-be15-d71a2cacbdb6") + ) + (fp_line + (start 11.95 -1.7) + (end -1.95 -1.7) + (stroke + (width 0.1) + (type solid) + ) + (layer "F.Fab") + (uuid "b60fdf2b-c58e-4a74-a778-93bcc9a86f41") + ) + (fp_line + (start -1.11 -2.11) + (end -2.36 -2.11) + (stroke + (width 0.1) + (type solid) + ) + (layer "F.Fab") + (uuid "7b0c9cef-a74a-4ba0-8e02-1ddcf25ec103") + ) + (fp_line + (start -1.95 2.8) + (end 11.95 2.8) + (stroke + (width 0.1) + (type solid) + ) + (layer "F.Fab") + (uuid "416f8927-8706-4a99-8bbc-5b34daeb2dfa") + ) + (fp_line + (start -1.95 -1.7) + (end -1.95 2.8) + (stroke + (width 0.1) + (type solid) + ) + (layer "F.Fab") + (uuid "a17bf7f3-acc0-4d47-966b-a1a43f9fe56e") + ) + (fp_line + (start -2.36 -2.11) + (end -2.36 -0.86) + (stroke + (width 0.1) + (type solid) + ) + (layer "F.Fab") + (uuid "7e722bda-47ea-4fe1-a76a-a3dad46e85e7") + ) + (fp_text user "${REFERENCE}" + (at 5 1.5 0) + (layer "F.Fab") + (uuid "fdb47b92-9d3a-46a8-b0d0-d23904e99032") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (pad "1" thru_hole roundrect + (at 0 0 180) + (size 1.2 1.75) + (drill 0.75) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (roundrect_rratio 0.208333) + (net 4 "GND") + (pinfunction "Pin_1") + (pintype "passive") + (uuid "98a3590a-c09f-4f22-830a-5e3e43916e70") + ) + (pad "2" thru_hole oval + (at 2 0 180) + (size 1.2 1.75) + (drill 0.75) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 1 "/Encoder3_CS") + (pinfunction "Pin_2") + (pintype "passive") + (uuid "f7771478-c9c4-427d-806a-c4c21d6603ec") + ) + (pad "3" thru_hole oval + (at 4 0 180) + (size 1.2 1.75) + (drill 0.75) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 8 "/Encoder_SCK") + (pinfunction "Pin_3") + (pintype "passive") + (uuid "d12eaeb5-f196-4fe8-a08d-84ba1ebdac6c") + ) + (pad "4" thru_hole oval + (at 6 0 180) + (size 1.2 1.75) + (drill 0.75) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 7 "/Encoder_MOSI") + (pinfunction "Pin_4") + (pintype "passive") + (uuid "ac36ed37-f098-4cf8-b8ed-cba1267d1337") + ) + (pad "5" thru_hole oval + (at 8 0 180) + (size 1.2 1.75) + (drill 0.75) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 3 "/Encoder_MISO") + (pinfunction "Pin_5") + (pintype "passive") + (uuid "62ec2070-e9b8-4812-a9f2-81b601d4e5b1") + ) + (pad "6" thru_hole oval + (at 10 0 180) + (size 1.2 1.75) + (drill 0.75) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 2 "+3.3V") + (pinfunction "Pin_6") + (pintype "passive") + (uuid "195c1856-1990-4ded-93d5-26bd8234d164") + ) + (embedded_fonts no) + (model "${KICAD9_3DMODEL_DIR}/Connector_JST.3dshapes/JST_PH_B6B-PH-K_1x06_P2.00mm_Vertical.step" + (offset + (xyz 0 0 0) + ) + (scale + (xyz 1 1 1) + ) + (rotate + (xyz 0 0 0) + ) + ) + ) + (footprint "MountingHole:MountingHole_2.7mm_M2.5_Pad_Via" + (layer "F.Cu") + (uuid "59039ad9-b6ec-40c5-b26c-c99e1a78b228") + (at 138 106) + (descr "Mounting Hole 2.7mm, M2.5, generated by kicad-footprint-generator mountinghole.py") + (tags "mountinghole M2.5") + (property "Reference" "H3" + (at 0 -3.65 0) + (layer "F.SilkS") + (hide yes) + (uuid "cfa1edeb-fce2-4bd6-a01e-aa95b678af65") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Value" "MountingHole_Pad" + (at 0 5.5 0) + (layer "F.Fab") + (uuid "10ade39b-c17e-4fbd-8136-de8e21d90946") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Datasheet" "~" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "600ef32e-2136-47eb-9dfd-a5052242b0cc") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property "Description" "Mounting Hole with connection" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "a9a4ffa9-2836-4193-8d13-2d32f2383dbd") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property ki_fp_filters "MountingHole*Pad*") + (path "/a3f04b2f-9a0c-4cda-93c7-b160fdf8dc03") + (sheetname "/") + (sheetfile "EncoderBoard.kicad_sch") + (attr exclude_from_pos_files exclude_from_bom) + (fp_circle + (center 0 0) + (end 2.7 0) + (stroke + (width 0.15) + (type solid) + ) + (fill no) + (layer "Cmts.User") + (uuid "9a4181b9-9af5-41f5-800f-9a975e099234") + ) + (fp_circle + (center 0 0) + (end 2.95 0) + (stroke + (width 0.05) + (type solid) + ) + (fill no) + (layer "F.CrtYd") + (uuid "94bd7caf-181c-4b99-a5d9-118a24f6be9d") + ) + (fp_text user "${REFERENCE}" + (at 0 0 0) + (layer "F.Fab") + (uuid "a107d0b0-5bc9-4bde-a615-412708cad53f") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (pad "1" thru_hole circle + (at -2.025 0) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 11 "unconnected-(H3-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "2462884e-538b-40fe-896d-610c40b30660") + ) + (pad "1" thru_hole circle + (at -1.431891 -1.431891) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 11 "unconnected-(H3-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "548b0fbb-a6a9-4ba5-9b78-2cd23467125d") + ) + (pad "1" thru_hole circle + (at -1.431891 1.431891) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 11 "unconnected-(H3-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "b5db1b04-4515-41d5-b5b2-2b903e7a8612") + ) + (pad "1" thru_hole circle + (at 0 -2.025) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 11 "unconnected-(H3-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "732354bc-eec2-4472-8f13-e3821a9ecb85") + ) + (pad "1" thru_hole circle + (at 0 0) + (size 5.4 5.4) + (drill 2.7) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 11 "unconnected-(H3-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "680d6d12-4b57-4a3b-a110-bcb96cedf00e") + ) + (pad "1" thru_hole circle + (at 0 2.025) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 11 "unconnected-(H3-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "531123d7-3555-4ea4-b23e-d6e3ef0c39b6") + ) + (pad "1" thru_hole circle + (at 1.431891 -1.431891) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 11 "unconnected-(H3-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "36abcafb-6172-4797-9b8e-f94cf920e536") + ) + (pad "1" thru_hole circle + (at 1.431891 1.431891) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 11 "unconnected-(H3-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "14b72e69-b260-4786-87d1-8dc7fc20e7c6") + ) + (pad "1" thru_hole circle + (at 2.025 0) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 11 "unconnected-(H3-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "1f1bd00d-5a57-4e6e-b25b-79560fd8fe8e") + ) + (embedded_fonts no) + ) + (footprint "MountingHole:MountingHole_2.7mm_M2.5_Pad_Via" + (layer "F.Cu") + (uuid "65933f13-3ec9-41e6-a2bf-b1a67c7c6350") + (at 138 78) + (descr "Mounting Hole 2.7mm, M2.5, generated by kicad-footprint-generator mountinghole.py") + (tags "mountinghole M2.5") + (property "Reference" "H1" + (at 0.431891 4.431891 0) + (layer "F.SilkS") + (hide yes) + (uuid "db801a5f-0ac1-431e-ac07-50dc73a11d69") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Value" "MountingHole_Pad" + (at 0 -5.5 0) + (layer "F.Fab") + (uuid "90a8f908-7d87-4656-98b8-bebba9ad1484") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Datasheet" "~" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "8245efd1-6d10-43c2-9f9a-f97f50c66bbd") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property "Description" "Mounting Hole with connection" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "55723dc4-bed3-4b2a-a425-56b227e9ead0") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property ki_fp_filters "MountingHole*Pad*") + (path "/e278849c-6d8c-4be9-a093-6ef8686112d4") + (sheetname "/") + (sheetfile "EncoderBoard.kicad_sch") + (attr exclude_from_pos_files exclude_from_bom) + (fp_circle + (center 0 0) + (end 2.7 0) + (stroke + (width 0.15) + (type solid) + ) + (fill no) + (layer "Cmts.User") + (uuid "9c1ad44d-80c7-4ea5-a158-74d2167afecc") + ) + (fp_circle + (center 0 0) + (end 2.95 0) + (stroke + (width 0.05) + (type solid) + ) + (fill no) + (layer "F.CrtYd") + (uuid "528d167d-09d7-4f37-a8ee-9dd49d019404") + ) + (fp_text user "${REFERENCE}" + (at 0 0 0) + (layer "F.Fab") + (uuid "40cc6746-ee3e-44d4-8f02-9d6177e29148") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (pad "1" thru_hole circle + (at -2.025 0) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 9 "unconnected-(H1-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "d4045fa4-dcd2-4410-98eb-de17bae64fa1") + ) + (pad "1" thru_hole circle + (at -1.431891 -1.431891) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 9 "unconnected-(H1-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "66bcb457-28a9-4ba6-8eac-cd599c47936b") + ) + (pad "1" thru_hole circle + (at -1.431891 1.431891) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 9 "unconnected-(H1-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "ad360ed2-1c6e-4330-a6f4-5d70bb09456c") + ) + (pad "1" thru_hole circle + (at 0 -2.025) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 9 "unconnected-(H1-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "86ac345e-18ce-4116-906a-c838a42318e3") + ) + (pad "1" thru_hole circle + (at 0 0) + (size 5.4 5.4) + (drill 2.7) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 9 "unconnected-(H1-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "d1790247-16b0-4abd-98d6-a64690f2d174") + ) + (pad "1" thru_hole circle + (at 0 2.025) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 9 "unconnected-(H1-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "203f4b33-8a1f-4225-bca3-4997096a74c2") + ) + (pad "1" thru_hole circle + (at 1.431891 -1.431891) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 9 "unconnected-(H1-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "51915136-ef51-49c5-aef4-adeb3d6ee478") + ) + (pad "1" thru_hole circle + (at 1.431891 1.431891) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 9 "unconnected-(H1-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "294eb928-61e8-4ccb-89af-8ee8a82813a3") + ) + (pad "1" thru_hole circle + (at 2.025 0) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 9 "unconnected-(H1-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "72deaf82-33dc-4788-9ef4-ec3b23510faf") + ) + (embedded_fonts no) + ) + (footprint "Connector_JST:JST_PH_B6B-PH-K_1x06_P2.00mm_Vertical" + (layer "F.Cu") + (uuid "80c89321-5cbc-4e17-880f-f38da7136071") + (at 157 97 180) + (descr "JST PH series connector, B6B-PH-K (http://www.jst-mfg.com/product/pdf/eng/ePH.pdf), generated with kicad-footprint-generator") + (tags "connector JST PH vertical") + (property "Reference" "J2" + (at -4 -1 0) + (layer "F.SilkS") + (uuid "cd6f6722-416f-4aff-822f-e5181e6439d5") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Value" "Conn_01x06_Pin" + (at 5 4 0) + (layer "F.Fab") + (uuid "140186b9-1a66-4016-8787-ddb23cfb603b") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Datasheet" "~" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "f38f938b-836d-467c-b28c-fa104b7da0d1") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property "Description" "Generic connector, single row, 01x06, script generated" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "2a254e3e-1541-44e6-957e-4c5d79d37803") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property ki_fp_filters "Connector*:*_1x??_*") + (path "/ba0e7cf5-533c-4cb0-adfa-05d42f98b4c0") + (sheetname "/") + (sheetfile "EncoderBoard.kicad_sch") + (attr through_hole) + (fp_line + (start 12.06 2.91) + (end 12.06 -1.81) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "6ac499b9-d12a-4eca-a52e-d4cbab585bae") + ) + (fp_line + (start 12.06 0.8) + (end 11.45 0.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "b63955f1-192f-4808-a2f7-695b505758ad") + ) + (fp_line + (start 12.06 -0.5) + (end 11.45 -0.5) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "9ae3ede2-bafd-4c28-971f-73b66d8f2e6e") + ) + (fp_line + (start 12.06 -1.81) + (end -2.06 -1.81) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "c0327772-01dc-471e-ab1b-16f669be8b63") + ) + (fp_line + (start 11.45 2.3) + (end 11.45 -1.2) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "9dc1024a-f1e3-4f30-a43a-63176d227550") + ) + (fp_line + (start 11.45 -1.2) + (end 9.5 -1.2) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "bf3287e5-2440-493c-b5dd-e91499086ba3") + ) + (fp_line + (start 9.5 -1.2) + (end 9.5 -1.81) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "bb874927-9481-4371-9f04-c2efff839a04") + ) + (fp_line + (start 9.1 1.8) + (end 9.1 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "ff28c42b-efc7-40a5-8026-6588f6f65512") + ) + (fp_line + (start 9 2.3) + (end 9 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "fad5dd00-d24c-4856-a9bc-1206a08e7c89") + ) + (fp_line + (start 8.9 2.3) + (end 8.9 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "49517eae-6bd2-4d67-ab1f-764f14fca80e") + ) + (fp_line + (start 8.9 1.8) + (end 9.1 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "9a0621dd-0590-405a-a224-429ea599887d") + ) + (fp_line + (start 7.1 1.8) + (end 7.1 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "bc576279-c70c-411e-9cb9-97f52534e14a") + ) + (fp_line + (start 7 2.3) + (end 7 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "10b727db-c969-44a2-9ed8-2cfbf6b4572a") + ) + (fp_line + (start 6.9 2.3) + (end 6.9 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "d55f8a75-6218-4302-876f-888c1b55e891") + ) + (fp_line + (start 6.9 1.8) + (end 7.1 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "93481039-1329-4f28-b7f8-08b79b896126") + ) + (fp_line + (start 5.1 1.8) + (end 5.1 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "54953669-07ea-4857-95be-02a5ede39439") + ) + (fp_line + (start 5 2.3) + (end 5 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "1b27b230-ca7e-4f25-aa23-ac3ecd920aa8") + ) + (fp_line + (start 4.9 2.3) + (end 4.9 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "1442e05f-8a6e-4952-a78b-87d2e4ae79f9") + ) + (fp_line + (start 4.9 1.8) + (end 5.1 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "af14fc90-9031-4e2c-9446-68672577efa9") + ) + (fp_line + (start 3.1 1.8) + (end 3.1 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "17043c23-3e42-4049-83ca-777be16c1f51") + ) + (fp_line + (start 3 2.3) + (end 3 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "32d4b257-7609-44fb-a4bb-097dee2c3191") + ) + (fp_line + (start 2.9 2.3) + (end 2.9 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "5e9196ab-6076-40af-8c16-a291be843bff") + ) + (fp_line + (start 2.9 1.8) + (end 3.1 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "a7b0dc33-3484-416a-b208-a3d738436b2c") + ) + (fp_line + (start 1.1 1.8) + (end 1.1 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "1d431b7d-5f3f-4f96-9c97-f3947933ff27") + ) + (fp_line + (start 1 2.3) + (end 1 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "405478cc-7949-4916-b8c5-dd45c6cde395") + ) + (fp_line + (start 0.9 2.3) + (end 0.9 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "b045ee00-f0d4-4afe-a59a-79b6fa265a58") + ) + (fp_line + (start 0.9 1.8) + (end 1.1 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "6b74cc6a-5d1d-44c8-9950-50ca58f72eed") + ) + (fp_line + (start 0.5 -1.2) + (end -1.45 -1.2) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "e09b00ae-286b-4f87-99a0-237f62539f6c") + ) + (fp_line + (start 0.5 -1.81) + (end 0.5 -1.2) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "baddb5c0-73ac-4469-a4d7-ae948f352df8") + ) + (fp_line + (start -0.3 -1.81) + (end -0.3 -2.01) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "d35496c4-7b8a-4b73-993d-c13f5d50783a") + ) + (fp_line + (start -0.3 -1.91) + (end -0.6 -1.91) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "2280442f-78b2-4902-9c22-eb0adc1c0c14") + ) + (fp_line + (start -0.3 -2.01) + (end -0.6 -2.01) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "2fe0fb7f-5ac6-4def-8cbd-910abad3590c") + ) + (fp_line + (start -0.6 -2.01) + (end -0.6 -1.81) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "a7c2b875-c02f-4f09-b6b6-6d08d58e5159") + ) + (fp_line + (start -1.11 -2.11) + (end -2.36 -2.11) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "5fb7962a-7ee5-4514-b0a6-9423b637ef0f") + ) + (fp_line + (start -1.45 2.3) + (end 11.45 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "dbdd016d-334e-4a83-a329-aa311fc8802b") + ) + (fp_line + (start -1.45 -1.2) + (end -1.45 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "f541a5a0-c87d-4621-ba1a-7af8bd16ca1c") + ) + (fp_line + (start -2.06 2.91) + (end 12.06 2.91) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "a696a069-26af-4727-ab3e-9756dbdb3776") + ) + (fp_line + (start -2.06 0.8) + (end -1.45 0.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "2d7380d1-2733-484a-8547-d95f2b20a009") + ) + (fp_line + (start -2.06 -0.5) + (end -1.45 -0.5) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "0f054a76-929f-4379-b9d6-88b315d86d04") + ) + (fp_line + (start -2.06 -1.81) + (end -2.06 2.91) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "c2c16a01-5cbb-4aef-9769-a297997dfbe7") + ) + (fp_line + (start -2.36 -2.11) + (end -2.36 -0.86) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "0b29f82a-54f2-4a6d-ba22-0b66b5f2dfd0") + ) + (fp_line + (start 12.45 3.3) + (end 12.45 -2.2) + (stroke + (width 0.05) + (type solid) + ) + (layer "F.CrtYd") + (uuid "6d1fccf4-1a66-4dd1-bf7c-69d1454ea6ad") + ) + (fp_line + (start 12.45 -2.2) + (end -2.45 -2.2) + (stroke + (width 0.05) + (type solid) + ) + (layer "F.CrtYd") + (uuid "710c79ad-f5e3-40ae-b7a1-477fc836baa5") + ) + (fp_line + (start -2.45 3.3) + (end 12.45 3.3) + (stroke + (width 0.05) + (type solid) + ) + (layer "F.CrtYd") + (uuid "ccc6e209-6fd8-455a-88cf-6d146eaf8f05") + ) + (fp_line + (start -2.45 -2.2) + (end -2.45 3.3) + (stroke + (width 0.05) + (type solid) + ) + (layer "F.CrtYd") + (uuid "6eb23bb5-925c-4b82-ad67-bdeb53c345e8") + ) + (fp_line + (start 11.95 2.8) + (end 11.95 -1.7) + (stroke + (width 0.1) + (type solid) + ) + (layer "F.Fab") + (uuid "8b0a243b-1165-4d8f-8b0b-5db74bcdef1d") + ) + (fp_line + (start 11.95 -1.7) + (end -1.95 -1.7) + (stroke + (width 0.1) + (type solid) + ) + (layer "F.Fab") + (uuid "a95f9395-3f8c-46c5-b57e-45bcb9ecef32") + ) + (fp_line + (start -1.11 -2.11) + (end -2.36 -2.11) + (stroke + (width 0.1) + (type solid) + ) + (layer "F.Fab") + (uuid "c6f9af85-0af0-4e35-a967-dc29ac9953b9") + ) + (fp_line + (start -1.95 2.8) + (end 11.95 2.8) + (stroke + (width 0.1) + (type solid) + ) + (layer "F.Fab") + (uuid "d08082a9-8f5f-4c0a-9930-f6726a450ebd") + ) + (fp_line + (start -1.95 -1.7) + (end -1.95 2.8) + (stroke + (width 0.1) + (type solid) + ) + (layer "F.Fab") + (uuid "963c160d-381d-474d-b144-20ee06b47ed0") + ) + (fp_line + (start -2.36 -2.11) + (end -2.36 -0.86) + (stroke + (width 0.1) + (type solid) + ) + (layer "F.Fab") + (uuid "0dd8bff2-d959-4bd8-ac24-26ee33d05dfb") + ) + (fp_text user "${REFERENCE}" + (at 5 1.5 0) + (layer "F.Fab") + (uuid "a6989133-0219-4e14-8bce-570037b2154c") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (pad "1" thru_hole roundrect + (at 0 0 180) + (size 1.2 1.75) + (drill 0.75) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (roundrect_rratio 0.208333) + (net 4 "GND") + (pinfunction "Pin_1") + (pintype "passive") + (uuid "6642fd44-8695-4ed5-9dd4-478e6e317fe4") + ) + (pad "2" thru_hole oval + (at 2 0 180) + (size 1.2 1.75) + (drill 0.75) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 5 "/Encoder2_CS") + (pinfunction "Pin_2") + (pintype "passive") + (uuid "d4ce3400-66e8-4a8d-9f5e-21bc03395705") + ) + (pad "3" thru_hole oval + (at 4 0 180) + (size 1.2 1.75) + (drill 0.75) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 8 "/Encoder_SCK") + (pinfunction "Pin_3") + (pintype "passive") + (uuid "de7b3e16-1f36-4946-8858-3d23aad28b67") + ) + (pad "4" thru_hole oval + (at 6 0 180) + (size 1.2 1.75) + (drill 0.75) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 7 "/Encoder_MOSI") + (pinfunction "Pin_4") + (pintype "passive") + (uuid "1ac738a5-f28f-4031-87cb-e05813eca515") + ) + (pad "5" thru_hole oval + (at 8 0 180) + (size 1.2 1.75) + (drill 0.75) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 3 "/Encoder_MISO") + (pinfunction "Pin_5") + (pintype "passive") + (uuid "9b4808e6-4fe4-4e53-b0cd-9d56274c15b7") + ) + (pad "6" thru_hole oval + (at 10 0 180) + (size 1.2 1.75) + (drill 0.75) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 2 "+3.3V") + (pinfunction "Pin_6") + (pintype "passive") + (uuid "022caffb-75c4-4f9b-937f-4a1ecbb0228c") + ) + (embedded_fonts no) + (model "${KICAD9_3DMODEL_DIR}/Connector_JST.3dshapes/JST_PH_B6B-PH-K_1x06_P2.00mm_Vertical.step" + (offset + (xyz 0 0 0) + ) + (scale + (xyz 1 1 1) + ) + (rotate + (xyz 0 0 0) + ) + ) + ) + (footprint "MountingHole:MountingHole_2.7mm_M2.5_Pad_Via" + (layer "F.Cu") + (uuid "eb59f3d6-3909-4146-9f9b-f228adde27ed") + (at 166 106) + (descr "Mounting Hole 2.7mm, M2.5, generated by kicad-footprint-generator mountinghole.py") + (tags "mountinghole M2.5") + (property "Reference" "H4" + (at 0 -3.65 0) + (layer "F.SilkS") + (hide yes) + (uuid "83e1fbfa-1288-4e19-8a1a-319d81aed517") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Value" "MountingHole_Pad" + (at 0 5.5 0) + (layer "F.Fab") + (uuid "84b17bb4-e099-4193-b5c1-8f86cef87fa1") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Datasheet" "~" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "23b30709-d3a5-4257-bc40-de52ff7a11ce") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property "Description" "Mounting Hole with connection" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "733e6ab6-2ffa-4d07-8ac5-188087a55ccf") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property ki_fp_filters "MountingHole*Pad*") + (path "/76ce9e78-7d5e-4582-b46d-916b9410dc77") + (sheetname "/") + (sheetfile "EncoderBoard.kicad_sch") + (attr exclude_from_pos_files exclude_from_bom) + (fp_circle + (center 0 0) + (end 2.7 0) + (stroke + (width 0.15) + (type solid) + ) + (fill no) + (layer "Cmts.User") + (uuid "b807b354-b654-45ab-a3e4-f182788489bd") + ) + (fp_circle + (center 0 0) + (end 2.95 0) + (stroke + (width 0.05) + (type solid) + ) + (fill no) + (layer "F.CrtYd") + (uuid "12d0b8af-9ad5-4f74-85b7-bf8b863e42e3") + ) + (fp_text user "${REFERENCE}" + (at 0 0 0) + (layer "F.Fab") + (uuid "01ca95d1-a311-4c06-bab6-cc5c7b8ca413") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (pad "1" thru_hole circle + (at -2.025 0) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 12 "unconnected-(H4-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "deb02260-53f8-420e-a3f2-833982d031fb") + ) + (pad "1" thru_hole circle + (at -1.431891 -1.431891) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 12 "unconnected-(H4-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "feac62d1-6f0c-4918-98f4-5f53cec3ae2d") + ) + (pad "1" thru_hole circle + (at -1.431891 1.431891) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 12 "unconnected-(H4-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "ac01c9d9-9003-4f1e-8774-f773bebf73de") + ) + (pad "1" thru_hole circle + (at 0 -2.025) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 12 "unconnected-(H4-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "b8f45449-5a57-4090-940c-0ad252c71464") + ) + (pad "1" thru_hole circle + (at 0 0) + (size 5.4 5.4) + (drill 2.7) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 12 "unconnected-(H4-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "bd633e4d-8c1e-411f-86ce-7f6ba388175a") + ) + (pad "1" thru_hole circle + (at 0 2.025) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 12 "unconnected-(H4-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "1623fac7-6607-41c5-9a1e-4d142445aabf") + ) + (pad "1" thru_hole circle + (at 1.431891 -1.431891) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 12 "unconnected-(H4-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "9c410cf0-393d-43e8-a37a-65ab99d83383") + ) + (pad "1" thru_hole circle + (at 1.431891 1.431891) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 12 "unconnected-(H4-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "e259b135-c48e-4d4e-99a6-20aed7a2d843") + ) + (pad "1" thru_hole circle + (at 2.025 0) + (size 0.8 0.8) + (drill 0.5) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 12 "unconnected-(H4-Pad1)") + (pinfunction "1") + (pintype "input") + (zone_connect 2) + (uuid "3bba88e8-4fb5-4e54-a301-13295bac2868") + ) + (embedded_fonts no) + ) + (footprint "Connector_JST:JST_PH_B6B-PH-K_1x06_P2.00mm_Vertical" + (layer "F.Cu") + (uuid "fe03be02-437e-4111-adf2-39a6dc42c4fe") + (at 157 106 180) + (descr "JST PH series connector, B6B-PH-K (http://www.jst-mfg.com/product/pdf/eng/ePH.pdf), generated with kicad-footprint-generator") + (tags "connector JST PH vertical") + (property "Reference" "J1" + (at -4 -1 0) + (layer "F.SilkS") + (uuid "4ae5b12c-f780-4d8f-8c6b-044dbbb4f312") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Value" "Conn_01x06_Pin" + (at 5 4 0) + (layer "F.Fab") + (uuid "6d78ded6-bc3c-4206-a334-00c8d1a9cadd") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Datasheet" "~" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "09c2d826-321e-4322-ba95-14e61ef73511") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property "Description" "Generic connector, single row, 01x06, script generated" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "39731ac4-727f-43ef-a509-dd4431433404") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property ki_fp_filters "Connector*:*_1x??_*") + (path "/35afe6a0-7425-418f-9adc-7b693ee639d5") + (sheetname "/") + (sheetfile "EncoderBoard.kicad_sch") + (attr through_hole) + (fp_line + (start 12.06 2.91) + (end 12.06 -1.81) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "cc251e8e-c023-4ae1-bb6f-3220635f05a4") + ) + (fp_line + (start 12.06 0.8) + (end 11.45 0.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "24f92723-d524-4733-95ae-6f855077902d") + ) + (fp_line + (start 12.06 -0.5) + (end 11.45 -0.5) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "d6d463ab-4543-4628-8cdc-a56011ba9d36") + ) + (fp_line + (start 12.06 -1.81) + (end -2.06 -1.81) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "b6e6e367-1107-4a6f-8ab9-bdde0cab26d4") + ) + (fp_line + (start 11.45 2.3) + (end 11.45 -1.2) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "26450f3c-fe48-4c58-8224-29cc02990f24") + ) + (fp_line + (start 11.45 -1.2) + (end 9.5 -1.2) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "c37764ff-7f0d-4ccc-9734-9337cab683af") + ) + (fp_line + (start 9.5 -1.2) + (end 9.5 -1.81) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "a3f6d76d-8b96-4615-90aa-c3c86eecd42f") + ) + (fp_line + (start 9.1 1.8) + (end 9.1 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "f43efc82-9429-4abc-b4b6-aeee3c7a8aa2") + ) + (fp_line + (start 9 2.3) + (end 9 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "e777b0fa-8542-4872-bfd0-cf746c2401fd") + ) + (fp_line + (start 8.9 2.3) + (end 8.9 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "057c5737-f846-450a-8401-999d5a6e0786") + ) + (fp_line + (start 8.9 1.8) + (end 9.1 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "969857ad-e56e-4cfc-a0b5-84e9ef268dc5") + ) + (fp_line + (start 7.1 1.8) + (end 7.1 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "6528ed53-676c-4292-a863-e92d14a9be6c") + ) + (fp_line + (start 7 2.3) + (end 7 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "3f5f5c22-3373-4f8e-bda8-ad8bfdad3f61") + ) + (fp_line + (start 6.9 2.3) + (end 6.9 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "84dced41-8198-4d44-994f-3da2d8a03b6c") + ) + (fp_line + (start 6.9 1.8) + (end 7.1 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "68c58485-f219-42e7-a2d9-9d65836e3663") + ) + (fp_line + (start 5.1 1.8) + (end 5.1 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "999a3f9b-49ab-459f-888b-2eedb9dcf953") + ) + (fp_line + (start 5 2.3) + (end 5 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "1d69f3ca-af28-4ff7-92af-b01cc6cbcf06") + ) + (fp_line + (start 4.9 2.3) + (end 4.9 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "70789da0-99c5-4c6d-873e-fd8248a95d40") + ) + (fp_line + (start 4.9 1.8) + (end 5.1 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "cdafa6b5-2b2f-4c4e-bfd3-fb95c1dd139b") + ) + (fp_line + (start 3.1 1.8) + (end 3.1 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "ca7eae35-8de5-44c0-90fb-e5c6894ae61b") + ) + (fp_line + (start 3 2.3) + (end 3 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "7a6eeba4-6b32-4e8d-8945-c204b4e092ce") + ) + (fp_line + (start 2.9 2.3) + (end 2.9 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "011a4a2b-91bb-4def-a97e-b9c56f146c35") + ) + (fp_line + (start 2.9 1.8) + (end 3.1 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "ac722a06-6c85-4f4c-a651-4e772dc402d4") + ) + (fp_line + (start 1.1 1.8) + (end 1.1 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "8a15eaf7-d465-46eb-af7d-c9548934a12c") + ) + (fp_line + (start 1 2.3) + (end 1 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "afdadca0-04c9-4272-a3f9-8ed8b9e1de02") + ) + (fp_line + (start 0.9 2.3) + (end 0.9 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "471da9e0-a43e-4dc3-8f9f-21a9266c0d2b") + ) + (fp_line + (start 0.9 1.8) + (end 1.1 1.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "0bd7c652-6f96-4f25-be33-9a934b44dbae") + ) + (fp_line + (start 0.5 -1.2) + (end -1.45 -1.2) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "1c264f5f-c193-44af-a29b-77dc73eb5c83") + ) + (fp_line + (start 0.5 -1.81) + (end 0.5 -1.2) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "c43d07f4-ed76-4e93-9fb1-6a9b35febc5e") + ) + (fp_line + (start -0.3 -1.81) + (end -0.3 -2.01) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "7d50746d-db19-4fbd-89f5-276e496cb29d") + ) + (fp_line + (start -0.3 -1.91) + (end -0.6 -1.91) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "210c620c-28af-4063-beb0-48cf30d423a6") + ) + (fp_line + (start -0.3 -2.01) + (end -0.6 -2.01) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "acc0eb4f-1172-4076-bce5-9824c3d3b38f") + ) + (fp_line + (start -0.6 -2.01) + (end -0.6 -1.81) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "7ef4d6cc-c339-464d-b75f-602a08257172") + ) + (fp_line + (start -1.11 -2.11) + (end -2.36 -2.11) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "e432a859-702e-4efa-bfba-d4e8da055d74") + ) + (fp_line + (start -1.45 2.3) + (end 11.45 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "f11226f6-6832-4ca2-b236-a333a4800c10") + ) + (fp_line + (start -1.45 -1.2) + (end -1.45 2.3) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "422447f8-2a21-47d9-95d0-62a42a521024") + ) + (fp_line + (start -2.06 2.91) + (end 12.06 2.91) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "6722bcb3-24ec-4c66-a233-b76bd070568c") + ) + (fp_line + (start -2.06 0.8) + (end -1.45 0.8) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "bbc29179-1d5a-4031-b0d1-7f7f150ae5bf") + ) + (fp_line + (start -2.06 -0.5) + (end -1.45 -0.5) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "48d10941-4b65-457b-b7cc-0c9bffd2dc2d") + ) + (fp_line + (start -2.06 -1.81) + (end -2.06 2.91) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "9b7508cd-3b55-4c54-adc2-9d4b15b29764") + ) + (fp_line + (start -2.36 -2.11) + (end -2.36 -0.86) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "c0306d5a-eefa-43d1-862a-6bf64e2b7c45") + ) + (fp_line + (start 12.45 3.3) + (end 12.45 -2.2) + (stroke + (width 0.05) + (type solid) + ) + (layer "F.CrtYd") + (uuid "6679e347-be42-4c5c-be17-197ea499e93c") + ) + (fp_line + (start 12.45 -2.2) + (end -2.45 -2.2) + (stroke + (width 0.05) + (type solid) + ) + (layer "F.CrtYd") + (uuid "a7c01a89-79dd-49fb-ba35-e011127dd96a") + ) + (fp_line + (start -2.45 3.3) + (end 12.45 3.3) + (stroke + (width 0.05) + (type solid) + ) + (layer "F.CrtYd") + (uuid "abe69c2a-d177-4f70-a85d-968792c90c3b") + ) + (fp_line + (start -2.45 -2.2) + (end -2.45 3.3) + (stroke + (width 0.05) + (type solid) + ) + (layer "F.CrtYd") + (uuid "5f6c613a-5acf-489b-92ea-20f0585b7f85") + ) + (fp_line + (start 11.95 2.8) + (end 11.95 -1.7) + (stroke + (width 0.1) + (type solid) + ) + (layer "F.Fab") + (uuid "08ea64bb-47ed-4b24-a9c4-397a7a507360") + ) + (fp_line + (start 11.95 -1.7) + (end -1.95 -1.7) + (stroke + (width 0.1) + (type solid) + ) + (layer "F.Fab") + (uuid "9a746fa9-ed75-42a8-83ec-ce6be483ec6d") + ) + (fp_line + (start -1.11 -2.11) + (end -2.36 -2.11) + (stroke + (width 0.1) + (type solid) + ) + (layer "F.Fab") + (uuid "3f28f930-9584-4fa4-99c9-250e4aa9c462") + ) + (fp_line + (start -1.95 2.8) + (end 11.95 2.8) + (stroke + (width 0.1) + (type solid) + ) + (layer "F.Fab") + (uuid "21fab669-ad73-43dc-bdc4-9d9fcbe0fe22") + ) + (fp_line + (start -1.95 -1.7) + (end -1.95 2.8) + (stroke + (width 0.1) + (type solid) + ) + (layer "F.Fab") + (uuid "280a2d6f-fb79-4608-aaae-180a3a90297c") + ) + (fp_line + (start -2.36 -2.11) + (end -2.36 -0.86) + (stroke + (width 0.1) + (type solid) + ) + (layer "F.Fab") + (uuid "8c1fa08d-68ba-42ad-a284-d36fea529fc4") + ) + (fp_text user "${REFERENCE}" + (at 5 1.5 0) + (layer "F.Fab") + (uuid "3476a7f8-08aa-4583-ad5e-0511564d2578") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (pad "1" thru_hole roundrect + (at 0 0 180) + (size 1.2 1.75) + (drill 0.75) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (roundrect_rratio 0.208333) + (net 4 "GND") + (pinfunction "Pin_1") + (pintype "passive") + (uuid "a79a3576-000e-4ce7-854d-e8f2f872cc17") + ) + (pad "2" thru_hole oval + (at 2 0 180) + (size 1.2 1.75) + (drill 0.75) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 6 "/Encoder1_CS") + (pinfunction "Pin_2") + (pintype "passive") + (uuid "1a01620a-4f9e-4f00-b85b-4bea6a44d0d3") + ) + (pad "3" thru_hole oval + (at 4 0 180) + (size 1.2 1.75) + (drill 0.75) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 8 "/Encoder_SCK") + (pinfunction "Pin_3") + (pintype "passive") + (uuid "10f3eb28-b428-49b0-a45f-f1ede8ecef76") + ) + (pad "4" thru_hole oval + (at 6 0 180) + (size 1.2 1.75) + (drill 0.75) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 7 "/Encoder_MOSI") + (pinfunction "Pin_4") + (pintype "passive") + (uuid "68ae2dc6-9e88-4628-966b-9e68fc449fb7") + ) + (pad "5" thru_hole oval + (at 8 0 180) + (size 1.2 1.75) + (drill 0.75) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 3 "/Encoder_MISO") + (pinfunction "Pin_5") + (pintype "passive") + (uuid "324a9a37-45ab-42c2-84ad-dbe694e5c1d6") + ) + (pad "6" thru_hole oval + (at 10 0 180) + (size 1.2 1.75) + (drill 0.75) + (layers "*.Cu" "*.Mask") + (remove_unused_layers no) + (net 2 "+3.3V") + (pinfunction "Pin_6") + (pintype "passive") + (uuid "4dfcfd37-b515-4e99-9e20-ca94c499d07d") + ) + (embedded_fonts no) + (model "${KICAD9_3DMODEL_DIR}/Connector_JST.3dshapes/JST_PH_B6B-PH-K_1x06_P2.00mm_Vertical.step" + (offset + (xyz 0 0 0) + ) + (scale + (xyz 1 1 1) + ) + (rotate + (xyz 0 0 0) + ) + ) + ) + (gr_line + (start 160.5 96.5) + (end 162.5 96.5) + (stroke + (width 0.1) + (type default) + ) + (layer "F.SilkS") + (uuid "1869644c-a79b-48b5-a4a3-b3aeefcfec91") + ) + (gr_line + (start 161.5 104.5) + (end 163 103) + (stroke + (width 0.1) + (type default) + ) + (layer "F.SilkS") + (uuid "77f2b6a5-26ba-4376-9066-62545268e2cc") + ) + (gr_line + (start 160.5 104.5) + (end 161.5 104.5) + (stroke + (width 0.1) + (type default) + ) + (layer "F.SilkS") + (uuid "af6914dd-670f-482b-9474-75dc9fdb4f13") + ) + (gr_line + (start 160.5 87.5) + (end 162.5 87.5) + (stroke + (width 0.1) + (type default) + ) + (layer "F.SilkS") + (uuid "de698b1c-012a-452e-a954-9667acfd7222") + ) + (gr_line + (start 170 74) + (end 170 110) + (stroke + (width 0.05) + (type default) + ) + (layer "Edge.Cuts") + (uuid "7cc06b3b-105f-4b3f-869d-3817b274f998") + ) + (gr_line + (start 134 110) + (end 134 74) + (stroke + (width 0.05) + (type default) + ) + (layer "Edge.Cuts") + (uuid "9da0ab59-a502-46d9-b649-77b6b5de883b") + ) + (gr_line + (start 170 110) + (end 134 110) + (stroke + (width 0.05) + (type default) + ) + (layer "Edge.Cuts") + (uuid "c30bcc43-ce62-4b5e-927c-aa47ffcdfb82") + ) + (gr_line + (start 134 74) + (end 170 74) + (stroke + (width 0.05) + (type default) + ) + (layer "Edge.Cuts") + (uuid "f9d6dba5-8dac-4b5f-861d-60c9514740f5") + ) + (gr_text "Enc. 2" + (at 163 97 0) + (layer "F.SilkS") + (uuid "6e1d49a9-3b44-4180-9c81-9a3c79105201") + (effects + (font + (size 1 1) + (thickness 0.1875) + ) + (justify left bottom) + ) + ) + (gr_text "v0.9" + (at 136 102 0) + (layer "F.SilkS") + (uuid "7976217e-6cc7-47c2-9cdd-3070085b884a") + (effects + (font + (size 1 1) + (thickness 0.1875) + (bold yes) + ) + (justify left bottom) + ) + ) + (gr_text "Enc. 1" + (at 163 102 0) + (layer "F.SilkS") + (uuid "b5ada66c-b8e1-40c3-aee8-cf3f8db74515") + (effects + (font + (size 1 1) + (thickness 0.1875) + ) + (justify left bottom) + ) + ) + (gr_text "Enc. 3" + (at 163 88 0) + (layer "F.SilkS") + (uuid "f7a9761a-1853-4245-8fd4-1cf7b58b0959") + (effects + (font + (size 1 1) + (thickness 0.1875) + ) + (justify left bottom) + ) + ) + (segment + (start 140 86) + (end 145 81) + (width 0.2) + (layer "F.Cu") + (net 1) + (uuid "556a78d8-ff92-427c-9c8f-0588261dc9d3") + ) + (segment + (start 145 81) + (end 145 79) + (width 0.2) + (layer "F.Cu") + (net 1) + (uuid "94564110-8b0a-45f7-89b5-b0bf72a3cd4a") + ) + (segment + (start 140 91) + (end 140 86) + (width 0.2) + (layer "F.Cu") + (net 1) + (uuid "e3cdf3db-c08f-43b5-ad7b-46bd9dde2405") + ) + (via + (at 140 91) + (size 0.6) + (drill 0.3) + (layers "F.Cu" "B.Cu") + (net 1) + (uuid "de12b276-f6e5-4f78-aa87-0b908ccb5a51") + ) + (segment + (start 155 90) + (end 155 88) + (width 0.2) + (layer "B.Cu") + (net 1) + (uuid "5def190f-1ed4-4a6d-9d27-23e88765511f") + ) + (segment + (start 140 91) + (end 154 91) + (width 0.2) + (layer "B.Cu") + (net 1) + (uuid "b2f584f0-1fe9-4529-a64b-f5d7af6ceefa") + ) + (segment + (start 154 91) + (end 155 90) + (width 0.2) + (layer "B.Cu") + (net 1) + (uuid "fee85762-51ed-4e42-8497-e9da8870ef5c") + ) + (segment + (start 153 81) + (end 149 85) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "0aa4c1f2-d3b9-4513-ac5f-978ea20e73db") + ) + (segment + (start 153 79) + (end 153 81) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "29775bf8-1122-4d0e-b9fb-b10365ed3b5b") + ) + (segment + (start 149 97) + (end 149 106) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "4c3e18fc-fed6-445b-952c-c73649232d7b") + ) + (segment + (start 149 85) + (end 149 88) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "67a1d3ee-b1c9-4dba-90ac-0f64dec5aa0d") + ) + (segment + (start 149 88) + (end 149 97) + (width 0.2) + (layer "F.Cu") + (net 3) + (uuid "f8fa104c-25af-40b6-abb6-981346e5c926") + ) + (segment + (start 142 100) + (end 142 86) + (width 0.2) + (layer "F.Cu") + (net 5) + (uuid "1407ba5c-4dea-4dc9-948f-f924d4e821c0") + ) + (segment + (start 142 86) + (end 147 81) + (width 0.2) + (layer "F.Cu") + (net 5) + (uuid "bba91d21-cc24-4a1c-a19f-597a8f6a70f3") + ) + (segment + (start 147 81) + (end 147 79) + (width 0.2) + (layer "F.Cu") + (net 5) + (uuid "e8f5dbbb-5ec4-4980-ba69-3547ae465bc1") + ) + (via + (at 142 100) + (size 0.6) + (drill 0.3) + (layers "F.Cu" "B.Cu") + (net 5) + (uuid "bfa9820f-0033-4841-8321-42ae8157d758") + ) + (segment + (start 154 100) + (end 155 99) + (width 0.2) + (layer "B.Cu") + (net 5) + (uuid "2a398156-0fa7-43ee-b2e4-0c384325dec4") + ) + (segment + (start 155 99) + (end 155 97) + (width 0.2) + (layer "B.Cu") + (net 5) + (uuid "7b729e49-aed8-4bd6-9ab8-b4ed483cea47") + ) + (segment + (start 142 100) + (end 154 100) + (width 0.2) + (layer "B.Cu") + (net 5) + (uuid "e84dcf0d-ea53-4c02-9628-70783f6c8209") + ) + (segment + (start 149 79) + (end 149 81) + (width 0.2) + (layer "F.Cu") + (net 6) + (uuid "06268cae-dd8c-42cc-949f-8c92a72e1845") + ) + (segment + (start 149 81) + (end 144 86) + (width 0.2) + (layer "F.Cu") + (net 6) + (uuid "1fa37a58-5399-4aeb-a48f-bc85cc91cbfa") + ) + (segment + (start 144 101) + (end 144 102) + (width 0.2) + (layer "F.Cu") + (net 6) + (uuid "24e2803e-05ac-4a3e-b11b-60535834ac8c") + ) + (segment + (start 144 86) + (end 144 101) + (width 0.2) + (layer "F.Cu") + (net 6) + (uuid "50a995e0-b5af-40f2-affe-6d4e6ec6f59d") + ) + (via + (at 144 102) + (size 0.6) + (drill 0.3) + (layers "F.Cu" "B.Cu") + (net 6) + (uuid "da19a4cb-916f-46f3-b37c-8ac743872552") + ) + (segment + (start 144 102) + (end 154 102) + (width 0.2) + (layer "B.Cu") + (net 6) + (uuid "2be0868b-d6b4-4442-bacb-15f0c7c4fc17") + ) + (segment + (start 154 102) + (end 155 103) + (width 0.2) + (layer "B.Cu") + (net 6) + (uuid "d307df8e-bef2-40e9-b714-643a712541d2") + ) + (segment + (start 155 103) + (end 155 106) + (width 0.2) + (layer "B.Cu") + (net 6) + (uuid "e587191c-9898-42d0-8d0c-0b93f5b707b9") + ) + (segment + (start 155 79) + (end 155 81) + (width 0.2) + (layer "F.Cu") + (net 7) + (uuid "3b8c9528-cd02-4d35-8e45-e40ad9408dfa") + ) + (segment + (start 151 97) + (end 151 88) + (width 0.2) + (layer "F.Cu") + (net 7) + (uuid "516afc01-6935-46fd-8514-c42dbc7e8e46") + ) + (segment + (start 151 85) + (end 151 88) + (width 0.2) + (layer "F.Cu") + (net 7) + (uuid "71bd6753-0366-498d-b059-16c66e754724") + ) + (segment + (start 151 106) + (end 151 97) + (width 0.2) + (layer "F.Cu") + (net 7) + (uuid "8869a1ae-4a3e-420e-88e7-febaf17a7858") + ) + (segment + (start 155 81) + (end 151 85) + (width 0.2) + (layer "F.Cu") + (net 7) + (uuid "be892b5d-596a-42db-91a3-6a01ef92bddd") + ) + (segment + (start 153 88) + (end 153 97) + (width 0.2) + (layer "F.Cu") + (net 8) + (uuid "5c96a566-a660-42fc-a060-069d8e99ccf9") + ) + (segment + (start 153 97) + (end 153 106) + (width 0.2) + (layer "F.Cu") + (net 8) + (uuid "91f23c22-822f-4694-8ea4-662254fda820") + ) + (segment + (start 151 82) + (end 153 84) + (width 0.2) + (layer "B.Cu") + (net 8) + (uuid "00313e7c-1782-4860-92a0-c36fafd2575d") + ) + (segment + (start 151 79) + (end 151 82) + (width 0.2) + (layer "B.Cu") + (net 8) + (uuid "8ffe48e4-57bf-4257-9166-4de2aa1dae04") + ) + (segment + (start 153 84) + (end 153 88) + (width 0.2) + (layer "B.Cu") + (net 8) + (uuid "cd5c552b-6ef3-483d-a3ce-cfb75e9e7173") + ) + (zone + (net 4) + (net_name "GND") + (layer "F.Cu") + (uuid "caa0a2a9-c02d-4179-bac3-7fc2518e213b") + (hatch edge 0.5) + (connect_pads + (clearance 0.25) + ) + (min_thickness 0.25) + (filled_areas_thickness no) + (fill yes + (thermal_gap 0.25) + (thermal_bridge_width 0.25) + ) + (polygon + (pts + (xy 134.5 74.5) (xy 169.5 74.5) (xy 169.5 109.5) (xy 134.5 109.5) + ) + ) + (filled_polygon + (layer "F.Cu") + (pts + (xy 169.442539 74.520185) (xy 169.488294 74.572989) (xy 169.4995 74.6245) (xy 169.4995 109.3755) + (xy 169.479815 109.442539) (xy 169.427011 109.488294) (xy 169.3755 109.4995) (xy 134.6245 109.4995) + (xy 134.557461 109.479815) (xy 134.511706 109.427011) (xy 134.5005 109.3755) (xy 134.5005 105.834296) + (xy 135.0495 105.834296) (xy 135.0495 106.165703) (xy 135.086601 106.494991) (xy 135.086603 106.495003) + (xy 135.086604 106.495006) (xy 135.093012 106.523082) (xy 135.160346 106.818093) (xy 135.160349 106.818101) + (xy 135.269799 107.13089) (xy 135.413582 107.429458) (xy 135.413584 107.429461) (xy 135.589896 107.71006) + (xy 135.796516 107.969153) (xy 136.030847 108.203484) (xy 136.28994 108.410104) (xy 136.570539 108.586416) + (xy 136.869113 108.730202) (xy 137.104037 108.812405) (xy 137.181898 108.83965) (xy 137.181906 108.839653) + (xy 137.181909 108.839653) (xy 137.18191 108.839654) (xy 137.504994 108.913396) (xy 137.505003 108.913397) + (xy 137.505008 108.913398) (xy 137.724533 108.938132) (xy 137.834297 108.950499) (xy 137.8343 108.9505) + (xy 137.834303 108.9505) (xy 138.1657 108.9505) (xy 138.165701 108.950499) (xy 138.333996 108.931537) + (xy 138.494991 108.913398) (xy 138.494994 108.913397) (xy 138.495006 108.913396) (xy 138.81809 108.839654) + (xy 139.130887 108.730202) (xy 139.429461 108.586416) (xy 139.71006 108.410104) (xy 139.969153 108.203484) + (xy 140.203484 107.969153) (xy 140.410104 107.71006) (xy 140.586416 107.429461) (xy 140.730202 107.130887) + (xy 140.839654 106.81809) (xy 140.913396 106.495006) (xy 140.9505 106.165697) (xy 140.9505 105.834303) + (xy 140.943226 105.769745) (xy 140.929625 105.649024) (xy 140.928746 105.641228) (xy 146.1495 105.641228) + (xy 146.1495 106.358771) (xy 146.182182 106.523074) (xy 146.182184 106.523082) (xy 146.246295 106.67786) + (xy 146.339373 106.817162) (xy 146.457837 106.935626) (xy 146.550494 106.997537) (xy 146.597137 107.028703) + (xy 146.751918 107.092816) (xy 146.881524 107.118596) (xy 146.916228 107.125499) (xy 146.916232 107.1255) + (xy 146.916233 107.1255) (xy 147.083768 107.1255) (xy 147.083769 107.125499) (xy 147.248082 107.092816) + (xy 147.402863 107.028703) (xy 147.542162 106.935626) (xy 147.660626 106.817162) (xy 147.753703 106.677863) + (xy 147.817816 106.523082) (xy 147.8505 106.358767) (xy 147.8505 105.641233) (xy 147.817816 105.476918) + (xy 147.753703 105.322137) (xy 147.717276 105.26762) (xy 147.660626 105.182837) (xy 147.542162 105.064373) + (xy 147.40286 104.971295) (xy 147.248082 104.907184) (xy 147.248074 104.907182) (xy 147.083771 104.8745) + (xy 147.083767 104.8745) (xy 146.916233 104.8745) (xy 146.916228 104.8745) (xy 146.751925 104.907182) + (xy 146.751917 104.907184) (xy 146.597139 104.971295) (xy 146.457837 105.064373) (xy 146.339373 105.182837) + (xy 146.246295 105.322139) (xy 146.182184 105.476917) (xy 146.182182 105.476925) (xy 146.1495 105.641228) + (xy 140.928746 105.641228) (xy 140.918314 105.548649) (xy 140.913396 105.504994) (xy 140.839654 105.18191) + (xy 140.730202 104.869113) (xy 140.586416 104.570539) (xy 140.410104 104.28994) (xy 140.203484 104.030847) + (xy 139.969153 103.796516) (xy 139.71006 103.589896) (xy 139.429461 103.413584) (xy 139.429458 103.413582) + (xy 139.13089 103.269799) (xy 138.818101 103.160349) (xy 138.818093 103.160346) (xy 138.575777 103.105039) + (xy 138.495006 103.086604) (xy 138.495003 103.086603) (xy 138.494991 103.086601) (xy 138.165703 103.0495) + (xy 138.165697 103.0495) (xy 137.834303 103.0495) (xy 137.834296 103.0495) (xy 137.505008 103.086601) + (xy 137.504994 103.086604) (xy 137.181906 103.160346) (xy 137.181898 103.160349) (xy 136.869109 103.269799) + (xy 136.570541 103.413582) (xy 136.289941 103.589895) (xy 136.030847 103.796515) (xy 135.796515 104.030847) + (xy 135.589895 104.289941) (xy 135.413582 104.570541) (xy 135.269799 104.869109) (xy 135.160349 105.181898) + (xy 135.160346 105.181906) (xy 135.086604 105.504994) (xy 135.086601 105.505008) (xy 135.0495 105.834296) + (xy 134.5005 105.834296) (xy 134.5005 101.927525) (xy 143.4495 101.927525) (xy 143.4495 102.072475) + (xy 143.487016 102.212485) (xy 143.487017 102.212488) (xy 143.559488 102.338011) (xy 143.55949 102.338013) + (xy 143.559491 102.338015) (xy 143.661985 102.440509) (xy 143.661986 102.44051) (xy 143.661988 102.440511) + (xy 143.787511 102.512982) (xy 143.787512 102.512982) (xy 143.787515 102.512984) (xy 143.927525 102.5505) + (xy 143.927528 102.5505) (xy 144.072472 102.5505) (xy 144.072475 102.5505) (xy 144.212485 102.512984) + (xy 144.338015 102.440509) (xy 144.440509 102.338015) (xy 144.512984 102.212485) (xy 144.5505 102.072475) + (xy 144.5505 101.927525) (xy 144.512984 101.787515) (xy 144.440509 101.661985) (xy 144.386819 101.608295) + (xy 144.353334 101.546972) (xy 144.3505 101.520614) (xy 144.3505 96.641228) (xy 146.1495 96.641228) + (xy 146.1495 97.358771) (xy 146.182182 97.523074) (xy 146.182184 97.523082) (xy 146.246295 97.67786) + (xy 146.339373 97.817162) (xy 146.457837 97.935626) (xy 146.550494 97.997537) (xy 146.597137 98.028703) + (xy 146.751918 98.092816) (xy 146.881524 98.118596) (xy 146.916228 98.125499) (xy 146.916232 98.1255) + (xy 146.916233 98.1255) (xy 147.083768 98.1255) (xy 147.083769 98.125499) (xy 147.248082 98.092816) + (xy 147.402863 98.028703) (xy 147.542162 97.935626) (xy 147.660626 97.817162) (xy 147.753703 97.677863) + (xy 147.817816 97.523082) (xy 147.8505 97.358767) (xy 147.8505 96.641233) (xy 147.817816 96.476918) + (xy 147.753703 96.322137) (xy 147.717276 96.26762) (xy 147.660626 96.182837) (xy 147.542162 96.064373) + (xy 147.40286 95.971295) (xy 147.248082 95.907184) (xy 147.248074 95.907182) (xy 147.083771 95.8745) + (xy 147.083767 95.8745) (xy 146.916233 95.8745) (xy 146.916228 95.8745) (xy 146.751925 95.907182) + (xy 146.751917 95.907184) (xy 146.597139 95.971295) (xy 146.457837 96.064373) (xy 146.339373 96.182837) + (xy 146.246295 96.322139) (xy 146.182184 96.476917) (xy 146.182182 96.476925) (xy 146.1495 96.641228) + (xy 144.3505 96.641228) (xy 144.3505 87.641228) (xy 146.1495 87.641228) (xy 146.1495 88.358771) + (xy 146.182182 88.523074) (xy 146.182184 88.523082) (xy 146.246295 88.67786) (xy 146.339373 88.817162) + (xy 146.457837 88.935626) (xy 146.550494 88.997537) (xy 146.597137 89.028703) (xy 146.751918 89.092816) + (xy 146.881524 89.118596) (xy 146.916228 89.125499) (xy 146.916232 89.1255) (xy 146.916233 89.1255) + (xy 147.083768 89.1255) (xy 147.083769 89.125499) (xy 147.248082 89.092816) (xy 147.402863 89.028703) + (xy 147.542162 88.935626) (xy 147.660626 88.817162) (xy 147.753703 88.677863) (xy 147.817816 88.523082) + (xy 147.8505 88.358767) (xy 147.8505 87.641233) (xy 147.850499 87.641228) (xy 148.1495 87.641228) + (xy 148.1495 88.358771) (xy 148.182182 88.523074) (xy 148.182184 88.523082) (xy 148.246295 88.67786) + (xy 148.339373 88.817162) (xy 148.457837 88.935626) (xy 148.594391 89.026868) (xy 148.639196 89.08048) + (xy 148.6495 89.12997) (xy 148.6495 95.87003) (xy 148.629815 95.937069) (xy 148.594391 95.973132) + (xy 148.457837 96.064373) (xy 148.339373 96.182837) (xy 148.246295 96.322139) (xy 148.182184 96.476917) + (xy 148.182182 96.476925) (xy 148.1495 96.641228) (xy 148.1495 97.358771) (xy 148.182182 97.523074) + (xy 148.182184 97.523082) (xy 148.246295 97.67786) (xy 148.339373 97.817162) (xy 148.457837 97.935626) + (xy 148.594391 98.026868) (xy 148.639196 98.08048) (xy 148.6495 98.12997) (xy 148.6495 104.87003) + (xy 148.629815 104.937069) (xy 148.594391 104.973132) (xy 148.457837 105.064373) (xy 148.339373 105.182837) + (xy 148.246295 105.322139) (xy 148.182184 105.476917) (xy 148.182182 105.476925) (xy 148.1495 105.641228) + (xy 148.1495 106.358771) (xy 148.182182 106.523074) (xy 148.182184 106.523082) (xy 148.246295 106.67786) + (xy 148.339373 106.817162) (xy 148.457837 106.935626) (xy 148.550494 106.997537) (xy 148.597137 107.028703) + (xy 148.751918 107.092816) (xy 148.881524 107.118596) (xy 148.916228 107.125499) (xy 148.916232 107.1255) + (xy 148.916233 107.1255) (xy 149.083768 107.1255) (xy 149.083769 107.125499) (xy 149.248082 107.092816) + (xy 149.402863 107.028703) (xy 149.542162 106.935626) (xy 149.660626 106.817162) (xy 149.753703 106.677863) + (xy 149.817816 106.523082) (xy 149.8505 106.358767) (xy 149.8505 105.641233) (xy 149.817816 105.476918) + (xy 149.753703 105.322137) (xy 149.717276 105.26762) (xy 149.660626 105.182837) (xy 149.542162 105.064373) + (xy 149.405609 104.973132) (xy 149.360804 104.91952) (xy 149.3505 104.87003) (xy 149.3505 98.12997) + (xy 149.370185 98.062931) (xy 149.405609 98.026868) (xy 149.542162 97.935626) (xy 149.660626 97.817162) + (xy 149.717276 97.732379) (xy 149.753703 97.677863) (xy 149.817816 97.523082) (xy 149.8505 97.358767) + (xy 149.8505 96.641233) (xy 149.817816 96.476918) (xy 149.753703 96.322137) (xy 149.717276 96.26762) + (xy 149.660626 96.182837) (xy 149.542162 96.064373) (xy 149.405609 95.973132) (xy 149.360804 95.91952) + (xy 149.3505 95.87003) (xy 149.3505 89.12997) (xy 149.370185 89.062931) (xy 149.405609 89.026868) + (xy 149.542162 88.935626) (xy 149.660626 88.817162) (xy 149.717276 88.732379) (xy 149.753703 88.677863) + (xy 149.817816 88.523082) (xy 149.8505 88.358767) (xy 149.8505 87.641233) (xy 149.850499 87.641228) + (xy 150.1495 87.641228) (xy 150.1495 88.358771) (xy 150.182182 88.523074) (xy 150.182184 88.523082) + (xy 150.246295 88.67786) (xy 150.339373 88.817162) (xy 150.457837 88.935626) (xy 150.594391 89.026868) + (xy 150.639196 89.08048) (xy 150.6495 89.12997) (xy 150.6495 95.87003) (xy 150.629815 95.937069) + (xy 150.594391 95.973132) (xy 150.457837 96.064373) (xy 150.339373 96.182837) (xy 150.246295 96.322139) + (xy 150.182184 96.476917) (xy 150.182182 96.476925) (xy 150.1495 96.641228) (xy 150.1495 97.358771) + (xy 150.182182 97.523074) (xy 150.182184 97.523082) (xy 150.246295 97.67786) (xy 150.339373 97.817162) + (xy 150.457837 97.935626) (xy 150.594391 98.026868) (xy 150.639196 98.08048) (xy 150.6495 98.12997) + (xy 150.6495 104.87003) (xy 150.629815 104.937069) (xy 150.594391 104.973132) (xy 150.457837 105.064373) + (xy 150.339373 105.182837) (xy 150.246295 105.322139) (xy 150.182184 105.476917) (xy 150.182182 105.476925) + (xy 150.1495 105.641228) (xy 150.1495 106.358771) (xy 150.182182 106.523074) (xy 150.182184 106.523082) + (xy 150.246295 106.67786) (xy 150.339373 106.817162) (xy 150.457837 106.935626) (xy 150.550494 106.997537) + (xy 150.597137 107.028703) (xy 150.751918 107.092816) (xy 150.881524 107.118596) (xy 150.916228 107.125499) + (xy 150.916232 107.1255) (xy 150.916233 107.1255) (xy 151.083768 107.1255) (xy 151.083769 107.125499) + (xy 151.248082 107.092816) (xy 151.402863 107.028703) (xy 151.542162 106.935626) (xy 151.660626 106.817162) + (xy 151.753703 106.677863) (xy 151.817816 106.523082) (xy 151.8505 106.358767) (xy 151.8505 105.641233) + (xy 151.817816 105.476918) (xy 151.753703 105.322137) (xy 151.717276 105.26762) (xy 151.660626 105.182837) + (xy 151.542162 105.064373) (xy 151.405609 104.973132) (xy 151.360804 104.91952) (xy 151.3505 104.87003) + (xy 151.3505 98.12997) (xy 151.370185 98.062931) (xy 151.405609 98.026868) (xy 151.542162 97.935626) + (xy 151.660626 97.817162) (xy 151.717276 97.732379) (xy 151.753703 97.677863) (xy 151.817816 97.523082) + (xy 151.8505 97.358767) (xy 151.8505 96.641233) (xy 151.817816 96.476918) (xy 151.753703 96.322137) + (xy 151.717276 96.26762) (xy 151.660626 96.182837) (xy 151.542162 96.064373) (xy 151.405609 95.973132) + (xy 151.360804 95.91952) (xy 151.3505 95.87003) (xy 151.3505 89.12997) (xy 151.370185 89.062931) + (xy 151.405609 89.026868) (xy 151.542162 88.935626) (xy 151.660626 88.817162) (xy 151.717276 88.732379) + (xy 151.753703 88.677863) (xy 151.817816 88.523082) (xy 151.8505 88.358767) (xy 151.8505 87.641233) + (xy 151.850499 87.641228) (xy 152.1495 87.641228) (xy 152.1495 88.358771) (xy 152.182182 88.523074) + (xy 152.182184 88.523082) (xy 152.246295 88.67786) (xy 152.339373 88.817162) (xy 152.457837 88.935626) + (xy 152.594391 89.026868) (xy 152.639196 89.08048) (xy 152.6495 89.12997) (xy 152.6495 95.87003) + (xy 152.629815 95.937069) (xy 152.594391 95.973132) (xy 152.457837 96.064373) (xy 152.339373 96.182837) + (xy 152.246295 96.322139) (xy 152.182184 96.476917) (xy 152.182182 96.476925) (xy 152.1495 96.641228) + (xy 152.1495 97.358771) (xy 152.182182 97.523074) (xy 152.182184 97.523082) (xy 152.246295 97.67786) + (xy 152.339373 97.817162) (xy 152.457837 97.935626) (xy 152.594391 98.026868) (xy 152.639196 98.08048) + (xy 152.6495 98.12997) (xy 152.6495 104.87003) (xy 152.629815 104.937069) (xy 152.594391 104.973132) + (xy 152.457837 105.064373) (xy 152.339373 105.182837) (xy 152.246295 105.322139) (xy 152.182184 105.476917) + (xy 152.182182 105.476925) (xy 152.1495 105.641228) (xy 152.1495 106.358771) (xy 152.182182 106.523074) + (xy 152.182184 106.523082) (xy 152.246295 106.67786) (xy 152.339373 106.817162) (xy 152.457837 106.935626) + (xy 152.550494 106.997537) (xy 152.597137 107.028703) (xy 152.751918 107.092816) (xy 152.881524 107.118596) + (xy 152.916228 107.125499) (xy 152.916232 107.1255) (xy 152.916233 107.1255) (xy 153.083768 107.1255) + (xy 153.083769 107.125499) (xy 153.248082 107.092816) (xy 153.402863 107.028703) (xy 153.542162 106.935626) + (xy 153.660626 106.817162) (xy 153.753703 106.677863) (xy 153.817816 106.523082) (xy 153.8505 106.358767) + (xy 153.8505 105.641233) (xy 153.850499 105.641228) (xy 154.1495 105.641228) (xy 154.1495 106.358771) + (xy 154.182182 106.523074) (xy 154.182184 106.523082) (xy 154.246295 106.67786) (xy 154.339373 106.817162) + (xy 154.457837 106.935626) (xy 154.550494 106.997537) (xy 154.597137 107.028703) (xy 154.751918 107.092816) + (xy 154.881524 107.118596) (xy 154.916228 107.125499) (xy 154.916232 107.1255) (xy 154.916233 107.1255) + (xy 155.083768 107.1255) (xy 155.083769 107.125499) (xy 155.248082 107.092816) (xy 155.402863 107.028703) + (xy 155.542162 106.935626) (xy 155.660626 106.817162) (xy 155.753703 106.677863) (xy 155.817816 106.523082) + (xy 155.8505 106.358767) (xy 155.8505 105.641233) (xy 155.817816 105.476918) (xy 155.755782 105.327155) + (xy 156.15 105.327155) (xy 156.15 105.875) (xy 156.645265 105.875) (xy 156.625 105.95063) (xy 156.625 106.04937) + (xy 156.645265 106.125) (xy 156.15 106.125) (xy 156.15 106.672844) (xy 156.156401 106.732372) (xy 156.156403 106.732379) + (xy 156.206645 106.867086) (xy 156.206649 106.867093) (xy 156.292809 106.982187) (xy 156.292812 106.98219) + (xy 156.407906 107.06835) (xy 156.407913 107.068354) (xy 156.54262 107.118596) (xy 156.542627 107.118598) + (xy 156.602155 107.124999) (xy 156.602172 107.125) (xy 156.875 107.125) (xy 156.875 106.354734) + (xy 156.95063 106.375) (xy 157.04937 106.375) (xy 157.125 106.354734) (xy 157.125 107.125) (xy 157.397828 107.125) + (xy 157.397844 107.124999) (xy 157.457372 107.118598) (xy 157.457379 107.118596) (xy 157.592086 107.068354) + (xy 157.592093 107.06835) (xy 157.707187 106.98219) (xy 157.70719 106.982187) (xy 157.79335 106.867093) + (xy 157.793354 106.867086) (xy 157.843596 106.732379) (xy 157.843598 106.732372) (xy 157.849999 106.672844) + (xy 157.85 106.672827) (xy 157.85 106.125) (xy 157.354735 106.125) (xy 157.375 106.04937) (xy 157.375 105.95063) + (xy 157.354735 105.875) (xy 157.85 105.875) (xy 157.85 105.834296) (xy 163.0495 105.834296) (xy 163.0495 106.165703) + (xy 163.086601 106.494991) (xy 163.086603 106.495003) (xy 163.086604 106.495006) (xy 163.093012 106.523082) + (xy 163.160346 106.818093) (xy 163.160349 106.818101) (xy 163.269799 107.13089) (xy 163.413582 107.429458) + (xy 163.413584 107.429461) (xy 163.589896 107.71006) (xy 163.796516 107.969153) (xy 164.030847 108.203484) + (xy 164.28994 108.410104) (xy 164.570539 108.586416) (xy 164.869113 108.730202) (xy 165.104037 108.812405) + (xy 165.181898 108.83965) (xy 165.181906 108.839653) (xy 165.181909 108.839653) (xy 165.18191 108.839654) + (xy 165.504994 108.913396) (xy 165.505003 108.913397) (xy 165.505008 108.913398) (xy 165.724533 108.938132) + (xy 165.834297 108.950499) (xy 165.8343 108.9505) (xy 165.834303 108.9505) (xy 166.1657 108.9505) + (xy 166.165701 108.950499) (xy 166.333996 108.931537) (xy 166.494991 108.913398) (xy 166.494994 108.913397) + (xy 166.495006 108.913396) (xy 166.81809 108.839654) (xy 167.130887 108.730202) (xy 167.429461 108.586416) + (xy 167.71006 108.410104) (xy 167.969153 108.203484) (xy 168.203484 107.969153) (xy 168.410104 107.71006) + (xy 168.586416 107.429461) (xy 168.730202 107.130887) (xy 168.839654 106.81809) (xy 168.913396 106.495006) + (xy 168.9505 106.165697) (xy 168.9505 105.834303) (xy 168.929624 105.649024) (xy 168.913398 105.505008) + (xy 168.913397 105.505003) (xy 168.913396 105.504994) (xy 168.839654 105.18191) (xy 168.730202 104.869113) + (xy 168.586416 104.570539) (xy 168.410104 104.28994) (xy 168.203484 104.030847) (xy 167.969153 103.796516) + (xy 167.71006 103.589896) (xy 167.429461 103.413584) (xy 167.429458 103.413582) (xy 167.13089 103.269799) + (xy 166.818101 103.160349) (xy 166.818093 103.160346) (xy 166.575777 103.105039) (xy 166.495006 103.086604) + (xy 166.495003 103.086603) (xy 166.494991 103.086601) (xy 166.165703 103.0495) (xy 166.165697 103.0495) + (xy 165.834303 103.0495) (xy 165.834296 103.0495) (xy 165.505008 103.086601) (xy 165.504994 103.086604) + (xy 165.181906 103.160346) (xy 165.181898 103.160349) (xy 164.869109 103.269799) (xy 164.570541 103.413582) + (xy 164.289941 103.589895) (xy 164.030847 103.796515) (xy 163.796515 104.030847) (xy 163.589895 104.289941) + (xy 163.413582 104.570541) (xy 163.269799 104.869109) (xy 163.160349 105.181898) (xy 163.160346 105.181906) + (xy 163.086604 105.504994) (xy 163.086601 105.505008) (xy 163.0495 105.834296) (xy 157.85 105.834296) + (xy 157.85 105.327172) (xy 157.849999 105.327155) (xy 157.843598 105.267627) (xy 157.843596 105.26762) + (xy 157.793354 105.132913) (xy 157.79335 105.132906) (xy 157.70719 105.017812) (xy 157.707187 105.017809) + (xy 157.592093 104.931649) (xy 157.592086 104.931645) (xy 157.457379 104.881403) (xy 157.457372 104.881401) + (xy 157.397844 104.875) (xy 157.125 104.875) (xy 157.125 105.645265) (xy 157.04937 105.625) (xy 156.95063 105.625) + (xy 156.875 105.645265) (xy 156.875 104.875) (xy 156.602155 104.875) (xy 156.542627 104.881401) + (xy 156.54262 104.881403) (xy 156.407913 104.931645) (xy 156.407906 104.931649) (xy 156.292812 105.017809) + (xy 156.292809 105.017812) (xy 156.206649 105.132906) (xy 156.206645 105.132913) (xy 156.156403 105.26762) + (xy 156.156401 105.267627) (xy 156.15 105.327155) (xy 155.755782 105.327155) (xy 155.753703 105.322137) + (xy 155.717276 105.26762) (xy 155.660626 105.182837) (xy 155.542162 105.064373) (xy 155.40286 104.971295) + (xy 155.248082 104.907184) (xy 155.248074 104.907182) (xy 155.083771 104.8745) (xy 155.083767 104.8745) + (xy 154.916233 104.8745) (xy 154.916228 104.8745) (xy 154.751925 104.907182) (xy 154.751917 104.907184) + (xy 154.597139 104.971295) (xy 154.457837 105.064373) (xy 154.339373 105.182837) (xy 154.246295 105.322139) + (xy 154.182184 105.476917) (xy 154.182182 105.476925) (xy 154.1495 105.641228) (xy 153.850499 105.641228) + (xy 153.817816 105.476918) (xy 153.753703 105.322137) (xy 153.717276 105.26762) (xy 153.660626 105.182837) + (xy 153.542162 105.064373) (xy 153.405609 104.973132) (xy 153.360804 104.91952) (xy 153.3505 104.87003) + (xy 153.3505 98.12997) (xy 153.370185 98.062931) (xy 153.405609 98.026868) (xy 153.542162 97.935626) + (xy 153.660626 97.817162) (xy 153.717276 97.732379) (xy 153.753703 97.677863) (xy 153.817816 97.523082) + (xy 153.8505 97.358767) (xy 153.8505 96.641233) (xy 153.850499 96.641228) (xy 154.1495 96.641228) + (xy 154.1495 97.358771) (xy 154.182182 97.523074) (xy 154.182184 97.523082) (xy 154.246295 97.67786) + (xy 154.339373 97.817162) (xy 154.457837 97.935626) (xy 154.550494 97.997537) (xy 154.597137 98.028703) + (xy 154.751918 98.092816) (xy 154.881524 98.118596) (xy 154.916228 98.125499) (xy 154.916232 98.1255) + (xy 154.916233 98.1255) (xy 155.083768 98.1255) (xy 155.083769 98.125499) (xy 155.248082 98.092816) + (xy 155.402863 98.028703) (xy 155.542162 97.935626) (xy 155.660626 97.817162) (xy 155.753703 97.677863) + (xy 155.817816 97.523082) (xy 155.8505 97.358767) (xy 155.8505 96.641233) (xy 155.817816 96.476918) + (xy 155.755782 96.327155) (xy 156.15 96.327155) (xy 156.15 96.875) (xy 156.645265 96.875) (xy 156.625 96.95063) + (xy 156.625 97.04937) (xy 156.645265 97.125) (xy 156.15 97.125) (xy 156.15 97.672844) (xy 156.156401 97.732372) + (xy 156.156403 97.732379) (xy 156.206645 97.867086) (xy 156.206649 97.867093) (xy 156.292809 97.982187) + (xy 156.292812 97.98219) (xy 156.407906 98.06835) (xy 156.407913 98.068354) (xy 156.54262 98.118596) + (xy 156.542627 98.118598) (xy 156.602155 98.124999) (xy 156.602172 98.125) (xy 156.875 98.125) (xy 156.875 97.354734) + (xy 156.95063 97.375) (xy 157.04937 97.375) (xy 157.125 97.354734) (xy 157.125 98.125) (xy 157.397828 98.125) + (xy 157.397844 98.124999) (xy 157.457372 98.118598) (xy 157.457379 98.118596) (xy 157.592086 98.068354) + (xy 157.592093 98.06835) (xy 157.707187 97.98219) (xy 157.70719 97.982187) (xy 157.79335 97.867093) + (xy 157.793354 97.867086) (xy 157.843596 97.732379) (xy 157.843598 97.732372) (xy 157.849999 97.672844) + (xy 157.85 97.672827) (xy 157.85 97.125) (xy 157.354735 97.125) (xy 157.375 97.04937) (xy 157.375 96.95063) + (xy 157.354735 96.875) (xy 157.85 96.875) (xy 157.85 96.327172) (xy 157.849999 96.327155) (xy 157.843598 96.267627) + (xy 157.843596 96.26762) (xy 157.793354 96.132913) (xy 157.79335 96.132906) (xy 157.70719 96.017812) + (xy 157.707187 96.017809) (xy 157.592093 95.931649) (xy 157.592086 95.931645) (xy 157.457379 95.881403) + (xy 157.457372 95.881401) (xy 157.397844 95.875) (xy 157.125 95.875) (xy 157.125 96.645265) (xy 157.04937 96.625) + (xy 156.95063 96.625) (xy 156.875 96.645265) (xy 156.875 95.875) (xy 156.602155 95.875) (xy 156.542627 95.881401) + (xy 156.54262 95.881403) (xy 156.407913 95.931645) (xy 156.407906 95.931649) (xy 156.292812 96.017809) + (xy 156.292809 96.017812) (xy 156.206649 96.132906) (xy 156.206645 96.132913) (xy 156.156403 96.26762) + (xy 156.156401 96.267627) (xy 156.15 96.327155) (xy 155.755782 96.327155) (xy 155.753703 96.322137) + (xy 155.717276 96.26762) (xy 155.660626 96.182837) (xy 155.542162 96.064373) (xy 155.40286 95.971295) + (xy 155.248082 95.907184) (xy 155.248074 95.907182) (xy 155.083771 95.8745) (xy 155.083767 95.8745) + (xy 154.916233 95.8745) (xy 154.916228 95.8745) (xy 154.751925 95.907182) (xy 154.751917 95.907184) + (xy 154.597139 95.971295) (xy 154.457837 96.064373) (xy 154.339373 96.182837) (xy 154.246295 96.322139) + (xy 154.182184 96.476917) (xy 154.182182 96.476925) (xy 154.1495 96.641228) (xy 153.850499 96.641228) + (xy 153.817816 96.476918) (xy 153.753703 96.322137) (xy 153.717276 96.26762) (xy 153.660626 96.182837) + (xy 153.542162 96.064373) (xy 153.405609 95.973132) (xy 153.360804 95.91952) (xy 153.3505 95.87003) + (xy 153.3505 89.12997) (xy 153.370185 89.062931) (xy 153.405609 89.026868) (xy 153.542162 88.935626) + (xy 153.660626 88.817162) (xy 153.717276 88.732379) (xy 153.753703 88.677863) (xy 153.817816 88.523082) + (xy 153.8505 88.358767) (xy 153.8505 87.641233) (xy 153.850499 87.641228) (xy 154.1495 87.641228) + (xy 154.1495 88.358771) (xy 154.182182 88.523074) (xy 154.182184 88.523082) (xy 154.246295 88.67786) + (xy 154.339373 88.817162) (xy 154.457837 88.935626) (xy 154.550494 88.997537) (xy 154.597137 89.028703) + (xy 154.751918 89.092816) (xy 154.881524 89.118596) (xy 154.916228 89.125499) (xy 154.916232 89.1255) + (xy 154.916233 89.1255) (xy 155.083768 89.1255) (xy 155.083769 89.125499) (xy 155.248082 89.092816) + (xy 155.402863 89.028703) (xy 155.542162 88.935626) (xy 155.660626 88.817162) (xy 155.753703 88.677863) + (xy 155.817816 88.523082) (xy 155.8505 88.358767) (xy 155.8505 87.641233) (xy 155.817816 87.476918) + (xy 155.755782 87.327155) (xy 156.15 87.327155) (xy 156.15 87.875) (xy 156.645265 87.875) (xy 156.625 87.95063) + (xy 156.625 88.04937) (xy 156.645265 88.125) (xy 156.15 88.125) (xy 156.15 88.672844) (xy 156.156401 88.732372) + (xy 156.156403 88.732379) (xy 156.206645 88.867086) (xy 156.206649 88.867093) (xy 156.292809 88.982187) + (xy 156.292812 88.98219) (xy 156.407906 89.06835) (xy 156.407913 89.068354) (xy 156.54262 89.118596) + (xy 156.542627 89.118598) (xy 156.602155 89.124999) (xy 156.602172 89.125) (xy 156.875 89.125) (xy 156.875 88.354734) + (xy 156.95063 88.375) (xy 157.04937 88.375) (xy 157.125 88.354734) (xy 157.125 89.125) (xy 157.397828 89.125) + (xy 157.397844 89.124999) (xy 157.457372 89.118598) (xy 157.457379 89.118596) (xy 157.592086 89.068354) + (xy 157.592093 89.06835) (xy 157.707187 88.98219) (xy 157.70719 88.982187) (xy 157.79335 88.867093) + (xy 157.793354 88.867086) (xy 157.843596 88.732379) (xy 157.843598 88.732372) (xy 157.849999 88.672844) + (xy 157.85 88.672827) (xy 157.85 88.125) (xy 157.354735 88.125) (xy 157.375 88.04937) (xy 157.375 87.95063) + (xy 157.354735 87.875) (xy 157.85 87.875) (xy 157.85 87.327172) (xy 157.849999 87.327155) (xy 157.843598 87.267627) + (xy 157.843596 87.26762) (xy 157.793354 87.132913) (xy 157.79335 87.132906) (xy 157.70719 87.017812) + (xy 157.707187 87.017809) (xy 157.592093 86.931649) (xy 157.592086 86.931645) (xy 157.457379 86.881403) + (xy 157.457372 86.881401) (xy 157.397844 86.875) (xy 157.125 86.875) (xy 157.125 87.645265) (xy 157.04937 87.625) + (xy 156.95063 87.625) (xy 156.875 87.645265) (xy 156.875 86.875) (xy 156.602155 86.875) (xy 156.542627 86.881401) + (xy 156.54262 86.881403) (xy 156.407913 86.931645) (xy 156.407906 86.931649) (xy 156.292812 87.017809) + (xy 156.292809 87.017812) (xy 156.206649 87.132906) (xy 156.206645 87.132913) (xy 156.156403 87.26762) + (xy 156.156401 87.267627) (xy 156.15 87.327155) (xy 155.755782 87.327155) (xy 155.753703 87.322137) + (xy 155.717276 87.26762) (xy 155.660626 87.182837) (xy 155.542162 87.064373) (xy 155.40286 86.971295) + (xy 155.248082 86.907184) (xy 155.248074 86.907182) (xy 155.083771 86.8745) (xy 155.083767 86.8745) + (xy 154.916233 86.8745) (xy 154.916228 86.8745) (xy 154.751925 86.907182) (xy 154.751917 86.907184) + (xy 154.597139 86.971295) (xy 154.457837 87.064373) (xy 154.339373 87.182837) (xy 154.246295 87.322139) + (xy 154.182184 87.476917) (xy 154.182182 87.476925) (xy 154.1495 87.641228) (xy 153.850499 87.641228) + (xy 153.817816 87.476918) (xy 153.753703 87.322137) (xy 153.717276 87.26762) (xy 153.660626 87.182837) + (xy 153.542162 87.064373) (xy 153.40286 86.971295) (xy 153.248082 86.907184) (xy 153.248074 86.907182) + (xy 153.083771 86.8745) (xy 153.083767 86.8745) (xy 152.916233 86.8745) (xy 152.916228 86.8745) + (xy 152.751925 86.907182) (xy 152.751917 86.907184) (xy 152.597139 86.971295) (xy 152.457837 87.064373) + (xy 152.339373 87.182837) (xy 152.246295 87.322139) (xy 152.182184 87.476917) (xy 152.182182 87.476925) + (xy 152.1495 87.641228) (xy 151.850499 87.641228) (xy 151.817816 87.476918) (xy 151.753703 87.322137) + (xy 151.717276 87.26762) (xy 151.660626 87.182837) (xy 151.542162 87.064373) (xy 151.405609 86.973132) + (xy 151.360804 86.91952) (xy 151.3505 86.87003) (xy 151.3505 85.196543) (xy 151.370185 85.129504) + (xy 151.386819 85.108862) (xy 151.710895 84.784786) (xy 155.280469 81.215212) (xy 155.326614 81.135288) + (xy 155.3505 81.046144) (xy 155.3505 80.12997) (xy 155.370185 80.062931) (xy 155.405609 80.026868) + (xy 155.491986 79.969153) (xy 155.542162 79.935626) (xy 155.660626 79.817162) (xy 155.753703 79.677863) + (xy 155.817816 79.523082) (xy 155.8505 79.358767) (xy 155.8505 78.641233) (xy 155.850499 78.641228) + (xy 156.1495 78.641228) (xy 156.1495 79.358771) (xy 156.182182 79.523074) (xy 156.182184 79.523082) + (xy 156.246295 79.67786) (xy 156.339373 79.817162) (xy 156.457837 79.935626) (xy 156.550494 79.997537) + (xy 156.597137 80.028703) (xy 156.751918 80.092816) (xy 156.881524 80.118596) (xy 156.916228 80.125499) + (xy 156.916232 80.1255) (xy 156.916233 80.1255) (xy 157.083768 80.1255) (xy 157.083769 80.125499) + (xy 157.248082 80.092816) (xy 157.402863 80.028703) (xy 157.542162 79.935626) (xy 157.660626 79.817162) + (xy 157.753703 79.677863) (xy 157.817816 79.523082) (xy 157.8505 79.358767) (xy 157.8505 78.641233) + (xy 157.817816 78.476918) (xy 157.755782 78.327155) (xy 158.15 78.327155) (xy 158.15 78.875) (xy 158.645265 78.875) + (xy 158.625 78.95063) (xy 158.625 79.04937) (xy 158.645265 79.125) (xy 158.15 79.125) (xy 158.15 79.672844) + (xy 158.156401 79.732372) (xy 158.156403 79.732379) (xy 158.206645 79.867086) (xy 158.206649 79.867093) + (xy 158.292809 79.982187) (xy 158.292812 79.98219) (xy 158.407906 80.06835) (xy 158.407913 80.068354) + (xy 158.54262 80.118596) (xy 158.542627 80.118598) (xy 158.602155 80.124999) (xy 158.602172 80.125) + (xy 158.875 80.125) (xy 158.875 79.354734) (xy 158.95063 79.375) (xy 159.04937 79.375) (xy 159.125 79.354734) + (xy 159.125 80.125) (xy 159.397828 80.125) (xy 159.397844 80.124999) (xy 159.457372 80.118598) (xy 159.457379 80.118596) + (xy 159.592086 80.068354) (xy 159.592093 80.06835) (xy 159.707187 79.98219) (xy 159.70719 79.982187) + (xy 159.79335 79.867093) (xy 159.793354 79.867086) (xy 159.843596 79.732379) (xy 159.843598 79.732372) + (xy 159.849999 79.672844) (xy 159.85 79.672827) (xy 159.85 79.125) (xy 159.354735 79.125) (xy 159.375 79.04937) + (xy 159.375 78.95063) (xy 159.354735 78.875) (xy 159.85 78.875) (xy 159.85 78.327172) (xy 159.849999 78.327155) + (xy 159.843598 78.267627) (xy 159.843596 78.26762) (xy 159.793354 78.132913) (xy 159.79335 78.132906) + (xy 159.70719 78.017812) (xy 159.707187 78.017809) (xy 159.592092 77.931648) (xy 159.592086 77.931645) + (xy 159.457379 77.881403) (xy 159.457372 77.881401) (xy 159.397844 77.875) (xy 159.125 77.875) (xy 159.125 78.645265) + (xy 159.04937 78.625) (xy 158.95063 78.625) (xy 158.875 78.645265) (xy 158.875 77.875) (xy 158.602155 77.875) + (xy 158.542627 77.881401) (xy 158.54262 77.881403) (xy 158.407913 77.931645) (xy 158.407906 77.931649) + (xy 158.292812 78.017809) (xy 158.292809 78.017812) (xy 158.206649 78.132906) (xy 158.206645 78.132913) + (xy 158.156403 78.26762) (xy 158.156401 78.267627) (xy 158.15 78.327155) (xy 157.755782 78.327155) + (xy 157.753703 78.322137) (xy 157.717276 78.26762) (xy 157.660626 78.182837) (xy 157.542162 78.064373) + (xy 157.40286 77.971295) (xy 157.248082 77.907184) (xy 157.248074 77.907182) (xy 157.083771 77.8745) + (xy 157.083767 77.8745) (xy 156.916233 77.8745) (xy 156.916228 77.8745) (xy 156.751925 77.907182) + (xy 156.751917 77.907184) (xy 156.597139 77.971295) (xy 156.457837 78.064373) (xy 156.339373 78.182837) + (xy 156.246295 78.322139) (xy 156.182184 78.476917) (xy 156.182182 78.476925) (xy 156.1495 78.641228) + (xy 155.850499 78.641228) (xy 155.817816 78.476918) (xy 155.753703 78.322137) (xy 155.717276 78.26762) + (xy 155.660626 78.182837) (xy 155.542162 78.064373) (xy 155.40286 77.971295) (xy 155.248082 77.907184) + (xy 155.248074 77.907182) (xy 155.083771 77.8745) (xy 155.083767 77.8745) (xy 154.916233 77.8745) + (xy 154.916228 77.8745) (xy 154.751925 77.907182) (xy 154.751917 77.907184) (xy 154.597139 77.971295) + (xy 154.457837 78.064373) (xy 154.339373 78.182837) (xy 154.246295 78.322139) (xy 154.182184 78.476917) + (xy 154.182182 78.476925) (xy 154.1495 78.641228) (xy 154.1495 79.358771) (xy 154.182182 79.523074) + (xy 154.182184 79.523082) (xy 154.246295 79.67786) (xy 154.339373 79.817162) (xy 154.457837 79.935626) + (xy 154.594391 80.026868) (xy 154.639196 80.08048) (xy 154.6495 80.12997) (xy 154.6495 80.803456) + (xy 154.629815 80.870495) (xy 154.613181 80.891137) (xy 150.719531 84.784786) (xy 150.719527 84.784791) + (xy 150.673387 84.864709) (xy 150.673386 84.864712) (xy 150.6495 84.953856) (xy 150.6495 86.87003) + (xy 150.629815 86.937069) (xy 150.594391 86.973132) (xy 150.457837 87.064373) (xy 150.339373 87.182837) + (xy 150.246295 87.322139) (xy 150.182184 87.476917) (xy 150.182182 87.476925) (xy 150.1495 87.641228) + (xy 149.850499 87.641228) (xy 149.817816 87.476918) (xy 149.753703 87.322137) (xy 149.717276 87.26762) + (xy 149.660626 87.182837) (xy 149.542162 87.064373) (xy 149.405609 86.973132) (xy 149.360804 86.91952) + (xy 149.3505 86.87003) (xy 149.3505 85.196543) (xy 149.370185 85.129504) (xy 149.386819 85.108862) + (xy 149.710895 84.784786) (xy 153.280469 81.215212) (xy 153.326614 81.135288) (xy 153.3505 81.046144) + (xy 153.3505 80.12997) (xy 153.370185 80.062931) (xy 153.405609 80.026868) (xy 153.491986 79.969153) + (xy 153.542162 79.935626) (xy 153.660626 79.817162) (xy 153.753703 79.677863) (xy 153.817816 79.523082) + (xy 153.8505 79.358767) (xy 153.8505 78.641233) (xy 153.817816 78.476918) (xy 153.753703 78.322137) + (xy 153.717276 78.26762) (xy 153.660626 78.182837) (xy 153.542162 78.064373) (xy 153.40286 77.971295) + (xy 153.248082 77.907184) (xy 153.248074 77.907182) (xy 153.083771 77.8745) (xy 153.083767 77.8745) + (xy 152.916233 77.8745) (xy 152.916228 77.8745) (xy 152.751925 77.907182) (xy 152.751917 77.907184) + (xy 152.597139 77.971295) (xy 152.457837 78.064373) (xy 152.339373 78.182837) (xy 152.246295 78.322139) + (xy 152.182184 78.476917) (xy 152.182182 78.476925) (xy 152.1495 78.641228) (xy 152.1495 79.358771) + (xy 152.182182 79.523074) (xy 152.182184 79.523082) (xy 152.246295 79.67786) (xy 152.339373 79.817162) + (xy 152.457837 79.935626) (xy 152.594391 80.026868) (xy 152.639196 80.08048) (xy 152.6495 80.12997) + (xy 152.6495 80.803456) (xy 152.629815 80.870495) (xy 152.613181 80.891137) (xy 148.719531 84.784786) + (xy 148.719527 84.784791) (xy 148.673387 84.864709) (xy 148.673386 84.864712) (xy 148.6495 84.953856) + (xy 148.6495 86.87003) (xy 148.629815 86.937069) (xy 148.594391 86.973132) (xy 148.457837 87.064373) + (xy 148.339373 87.182837) (xy 148.246295 87.322139) (xy 148.182184 87.476917) (xy 148.182182 87.476925) + (xy 148.1495 87.641228) (xy 147.850499 87.641228) (xy 147.817816 87.476918) (xy 147.753703 87.322137) + (xy 147.717276 87.26762) (xy 147.660626 87.182837) (xy 147.542162 87.064373) (xy 147.40286 86.971295) + (xy 147.248082 86.907184) (xy 147.248074 86.907182) (xy 147.083771 86.8745) (xy 147.083767 86.8745) + (xy 146.916233 86.8745) (xy 146.916228 86.8745) (xy 146.751925 86.907182) (xy 146.751917 86.907184) + (xy 146.597139 86.971295) (xy 146.457837 87.064373) (xy 146.339373 87.182837) (xy 146.246295 87.322139) + (xy 146.182184 87.476917) (xy 146.182182 87.476925) (xy 146.1495 87.641228) (xy 144.3505 87.641228) + (xy 144.3505 86.196544) (xy 144.370185 86.129505) (xy 144.386819 86.108863) (xy 145.710896 84.784786) + (xy 149.28047 81.215212) (xy 149.326614 81.135288) (xy 149.3505 81.046144) (xy 149.3505 80.953856) + (xy 149.3505 80.12997) (xy 149.370185 80.062931) (xy 149.405609 80.026868) (xy 149.491986 79.969153) + (xy 149.542162 79.935626) (xy 149.660626 79.817162) (xy 149.753703 79.677863) (xy 149.817816 79.523082) + (xy 149.8505 79.358767) (xy 149.8505 78.641233) (xy 149.850499 78.641228) (xy 150.1495 78.641228) + (xy 150.1495 79.358771) (xy 150.182182 79.523074) (xy 150.182184 79.523082) (xy 150.246295 79.67786) + (xy 150.339373 79.817162) (xy 150.457837 79.935626) (xy 150.550494 79.997537) (xy 150.597137 80.028703) + (xy 150.751918 80.092816) (xy 150.881524 80.118596) (xy 150.916228 80.125499) (xy 150.916232 80.1255) + (xy 150.916233 80.1255) (xy 151.083768 80.1255) (xy 151.083769 80.125499) (xy 151.248082 80.092816) + (xy 151.402863 80.028703) (xy 151.542162 79.935626) (xy 151.660626 79.817162) (xy 151.753703 79.677863) + (xy 151.817816 79.523082) (xy 151.8505 79.358767) (xy 151.8505 78.641233) (xy 151.817816 78.476918) + (xy 151.753703 78.322137) (xy 151.717276 78.26762) (xy 151.660626 78.182837) (xy 151.542162 78.064373) + (xy 151.40286 77.971295) (xy 151.248082 77.907184) (xy 151.248074 77.907182) (xy 151.083771 77.8745) + (xy 151.083767 77.8745) (xy 150.916233 77.8745) (xy 150.916228 77.8745) (xy 150.751925 77.907182) + (xy 150.751917 77.907184) (xy 150.597139 77.971295) (xy 150.457837 78.064373) (xy 150.339373 78.182837) + (xy 150.246295 78.322139) (xy 150.182184 78.476917) (xy 150.182182 78.476925) (xy 150.1495 78.641228) + (xy 149.850499 78.641228) (xy 149.817816 78.476918) (xy 149.753703 78.322137) (xy 149.717276 78.26762) + (xy 149.660626 78.182837) (xy 149.542162 78.064373) (xy 149.40286 77.971295) (xy 149.248082 77.907184) + (xy 149.248074 77.907182) (xy 149.083771 77.8745) (xy 149.083767 77.8745) (xy 148.916233 77.8745) + (xy 148.916228 77.8745) (xy 148.751925 77.907182) (xy 148.751917 77.907184) (xy 148.597139 77.971295) + (xy 148.457837 78.064373) (xy 148.339373 78.182837) (xy 148.246295 78.322139) (xy 148.182184 78.476917) + (xy 148.182182 78.476925) (xy 148.1495 78.641228) (xy 148.1495 79.358771) (xy 148.182182 79.523074) + (xy 148.182184 79.523082) (xy 148.246295 79.67786) (xy 148.339373 79.817162) (xy 148.457837 79.935626) + (xy 148.594391 80.026868) (xy 148.639196 80.08048) (xy 148.6495 80.12997) (xy 148.6495 80.803456) + (xy 148.629815 80.870495) (xy 148.613181 80.891137) (xy 143.719531 85.784786) (xy 143.719527 85.784791) + (xy 143.673387 85.864709) (xy 143.673386 85.864712) (xy 143.6495 85.953856) (xy 143.6495 101.520614) + (xy 143.629815 101.587653) (xy 143.613181 101.608295) (xy 143.559493 101.661982) (xy 143.559488 101.661988) + (xy 143.487017 101.787511) (xy 143.487016 101.787515) (xy 143.4495 101.927525) (xy 134.5005 101.927525) + (xy 134.5005 99.927525) (xy 141.4495 99.927525) (xy 141.4495 100.072475) (xy 141.487016 100.212485) + (xy 141.487017 100.212488) (xy 141.559488 100.338011) (xy 141.55949 100.338013) (xy 141.559491 100.338015) + (xy 141.661985 100.440509) (xy 141.661986 100.44051) (xy 141.661988 100.440511) (xy 141.787511 100.512982) + (xy 141.787512 100.512982) (xy 141.787515 100.512984) (xy 141.927525 100.5505) (xy 141.927528 100.5505) + (xy 142.072472 100.5505) (xy 142.072475 100.5505) (xy 142.212485 100.512984) (xy 142.338015 100.440509) + (xy 142.440509 100.338015) (xy 142.512984 100.212485) (xy 142.5505 100.072475) (xy 142.5505 99.927525) + (xy 142.512984 99.787515) (xy 142.440509 99.661985) (xy 142.386819 99.608295) (xy 142.353334 99.546972) + (xy 142.3505 99.520614) (xy 142.3505 86.196544) (xy 142.370185 86.129505) (xy 142.386819 86.108863) + (xy 143.710896 84.784786) (xy 147.28047 81.215212) (xy 147.326614 81.135288) (xy 147.3505 81.046144) + (xy 147.3505 80.953856) (xy 147.3505 80.12997) (xy 147.370185 80.062931) (xy 147.405609 80.026868) + (xy 147.491986 79.969153) (xy 147.542162 79.935626) (xy 147.660626 79.817162) (xy 147.753703 79.677863) + (xy 147.817816 79.523082) (xy 147.8505 79.358767) (xy 147.8505 78.641233) (xy 147.817816 78.476918) + (xy 147.753703 78.322137) (xy 147.717276 78.26762) (xy 147.660626 78.182837) (xy 147.542162 78.064373) + (xy 147.40286 77.971295) (xy 147.248082 77.907184) (xy 147.248074 77.907182) (xy 147.083771 77.8745) + (xy 147.083767 77.8745) (xy 146.916233 77.8745) (xy 146.916228 77.8745) (xy 146.751925 77.907182) + (xy 146.751917 77.907184) (xy 146.597139 77.971295) (xy 146.457837 78.064373) (xy 146.339373 78.182837) + (xy 146.246295 78.322139) (xy 146.182184 78.476917) (xy 146.182182 78.476925) (xy 146.1495 78.641228) + (xy 146.1495 79.358771) (xy 146.182182 79.523074) (xy 146.182184 79.523082) (xy 146.246295 79.67786) + (xy 146.339373 79.817162) (xy 146.457837 79.935626) (xy 146.594391 80.026868) (xy 146.639196 80.08048) + (xy 146.6495 80.12997) (xy 146.6495 80.803456) (xy 146.629815 80.870495) (xy 146.613181 80.891137) + (xy 141.719531 85.784786) (xy 141.719527 85.784791) (xy 141.673387 85.864709) (xy 141.673386 85.864712) + (xy 141.6495 85.953856) (xy 141.6495 99.520614) (xy 141.629815 99.587653) (xy 141.613181 99.608295) + (xy 141.559493 99.661982) (xy 141.559488 99.661988) (xy 141.487017 99.787511) (xy 141.487016 99.787515) + (xy 141.4495 99.927525) (xy 134.5005 99.927525) (xy 134.5005 90.927525) (xy 139.4495 90.927525) + (xy 139.4495 91.072475) (xy 139.487016 91.212485) (xy 139.487017 91.212488) (xy 139.559488 91.338011) + (xy 139.55949 91.338013) (xy 139.559491 91.338015) (xy 139.661985 91.440509) (xy 139.661986 91.44051) + (xy 139.661988 91.440511) (xy 139.787511 91.512982) (xy 139.787512 91.512982) (xy 139.787515 91.512984) + (xy 139.927525 91.5505) (xy 139.927528 91.5505) (xy 140.072472 91.5505) (xy 140.072475 91.5505) + (xy 140.212485 91.512984) (xy 140.338015 91.440509) (xy 140.440509 91.338015) (xy 140.512984 91.212485) + (xy 140.5505 91.072475) (xy 140.5505 90.927525) (xy 140.512984 90.787515) (xy 140.440509 90.661985) + (xy 140.386819 90.608295) (xy 140.353334 90.546972) (xy 140.3505 90.520614) (xy 140.3505 86.196544) + (xy 140.370185 86.129505) (xy 140.386819 86.108863) (xy 141.710896 84.784786) (xy 145.28047 81.215212) + (xy 145.326614 81.135288) (xy 145.3505 81.046144) (xy 145.3505 80.953856) (xy 145.3505 80.12997) + (xy 145.370185 80.062931) (xy 145.405609 80.026868) (xy 145.491986 79.969153) (xy 145.542162 79.935626) + (xy 145.660626 79.817162) (xy 145.753703 79.677863) (xy 145.817816 79.523082) (xy 145.8505 79.358767) + (xy 145.8505 78.641233) (xy 145.817816 78.476918) (xy 145.753703 78.322137) (xy 145.717276 78.26762) + (xy 145.660626 78.182837) (xy 145.542162 78.064373) (xy 145.40286 77.971295) (xy 145.248082 77.907184) + (xy 145.248074 77.907182) (xy 145.083771 77.8745) (xy 145.083767 77.8745) (xy 144.916233 77.8745) + (xy 144.916228 77.8745) (xy 144.751925 77.907182) (xy 144.751917 77.907184) (xy 144.597139 77.971295) + (xy 144.457837 78.064373) (xy 144.339373 78.182837) (xy 144.246295 78.322139) (xy 144.182184 78.476917) + (xy 144.182182 78.476925) (xy 144.1495 78.641228) (xy 144.1495 79.358771) (xy 144.182182 79.523074) + (xy 144.182184 79.523082) (xy 144.246295 79.67786) (xy 144.339373 79.817162) (xy 144.457837 79.935626) + (xy 144.594391 80.026868) (xy 144.639196 80.08048) (xy 144.6495 80.12997) (xy 144.6495 80.803456) + (xy 144.629815 80.870495) (xy 144.613181 80.891137) (xy 139.719531 85.784786) (xy 139.719527 85.784791) + (xy 139.673387 85.864709) (xy 139.673386 85.864712) (xy 139.6495 85.953856) (xy 139.6495 90.520614) + (xy 139.629815 90.587653) (xy 139.613181 90.608295) (xy 139.559493 90.661982) (xy 139.559488 90.661988) + (xy 139.487017 90.787511) (xy 139.487016 90.787515) (xy 139.4495 90.927525) (xy 134.5005 90.927525) + (xy 134.5005 77.834296) (xy 135.0495 77.834296) (xy 135.0495 78.165703) (xy 135.086601 78.494991) + (xy 135.086604 78.495005) (xy 135.160346 78.818093) (xy 135.160349 78.818101) (xy 135.269799 79.13089) + (xy 135.413582 79.429458) (xy 135.413584 79.429461) (xy 135.589896 79.71006) (xy 135.796516 79.969153) + (xy 136.030847 80.203484) (xy 136.28994 80.410104) (xy 136.570539 80.586416) (xy 136.869113 80.730202) + (xy 137.078462 80.803456) (xy 137.181898 80.83965) (xy 137.181906 80.839653) (xy 137.181909 80.839653) + (xy 137.18191 80.839654) (xy 137.504994 80.913396) (xy 137.505003 80.913397) (xy 137.505008 80.913398) + (xy 137.724533 80.938132) (xy 137.834297 80.950499) (xy 137.8343 80.9505) (xy 137.834303 80.9505) + (xy 138.1657 80.9505) (xy 138.165701 80.950499) (xy 138.333996 80.931537) (xy 138.494991 80.913398) + (xy 138.494994 80.913397) (xy 138.495006 80.913396) (xy 138.81809 80.839654) (xy 139.130887 80.730202) + (xy 139.429461 80.586416) (xy 139.71006 80.410104) (xy 139.969153 80.203484) (xy 140.203484 79.969153) + (xy 140.410104 79.71006) (xy 140.586416 79.429461) (xy 140.730202 79.130887) (xy 140.839654 78.81809) + (xy 140.913396 78.495006) (xy 140.915434 78.476925) (xy 140.939016 78.26762) (xy 140.9505 78.165697) + (xy 140.9505 77.834303) (xy 140.950499 77.834296) (xy 163.0495 77.834296) (xy 163.0495 78.165703) + (xy 163.086601 78.494991) (xy 163.086604 78.495005) (xy 163.160346 78.818093) (xy 163.160349 78.818101) + (xy 163.269799 79.13089) (xy 163.413582 79.429458) (xy 163.413584 79.429461) (xy 163.589896 79.71006) + (xy 163.796516 79.969153) (xy 164.030847 80.203484) (xy 164.28994 80.410104) (xy 164.570539 80.586416) + (xy 164.869113 80.730202) (xy 165.078462 80.803456) (xy 165.181898 80.83965) (xy 165.181906 80.839653) + (xy 165.181909 80.839653) (xy 165.18191 80.839654) (xy 165.504994 80.913396) (xy 165.505003 80.913397) + (xy 165.505008 80.913398) (xy 165.724533 80.938132) (xy 165.834297 80.950499) (xy 165.8343 80.9505) + (xy 165.834303 80.9505) (xy 166.1657 80.9505) (xy 166.165701 80.950499) (xy 166.333996 80.931537) + (xy 166.494991 80.913398) (xy 166.494994 80.913397) (xy 166.495006 80.913396) (xy 166.81809 80.839654) + (xy 167.130887 80.730202) (xy 167.429461 80.586416) (xy 167.71006 80.410104) (xy 167.969153 80.203484) + (xy 168.203484 79.969153) (xy 168.410104 79.71006) (xy 168.586416 79.429461) (xy 168.730202 79.130887) + (xy 168.839654 78.81809) (xy 168.913396 78.495006) (xy 168.915434 78.476925) (xy 168.939016 78.26762) + (xy 168.9505 78.165697) (xy 168.9505 77.834303) (xy 168.913396 77.504994) (xy 168.839654 77.18191) + (xy 168.730202 76.869113) (xy 168.586416 76.570539) (xy 168.410104 76.28994) (xy 168.203484 76.030847) + (xy 167.969153 75.796516) (xy 167.71006 75.589896) (xy 167.429461 75.413584) (xy 167.429458 75.413582) + (xy 167.13089 75.269799) (xy 166.818101 75.160349) (xy 166.818093 75.160346) (xy 166.575777 75.105039) + (xy 166.495006 75.086604) (xy 166.495003 75.086603) (xy 166.494991 75.086601) (xy 166.165703 75.0495) + (xy 166.165697 75.0495) (xy 165.834303 75.0495) (xy 165.834296 75.0495) (xy 165.505008 75.086601) + (xy 165.504994 75.086604) (xy 165.181906 75.160346) (xy 165.181898 75.160349) (xy 164.869109 75.269799) + (xy 164.570541 75.413582) (xy 164.289941 75.589895) (xy 164.030847 75.796515) (xy 163.796515 76.030847) + (xy 163.589895 76.289941) (xy 163.413582 76.570541) (xy 163.269799 76.869109) (xy 163.160349 77.181898) + (xy 163.160346 77.181906) (xy 163.086604 77.504994) (xy 163.086601 77.505008) (xy 163.0495 77.834296) + (xy 140.950499 77.834296) (xy 140.913396 77.504994) (xy 140.839654 77.18191) (xy 140.730202 76.869113) + (xy 140.586416 76.570539) (xy 140.410104 76.28994) (xy 140.203484 76.030847) (xy 139.969153 75.796516) + (xy 139.71006 75.589896) (xy 139.429461 75.413584) (xy 139.429458 75.413582) (xy 139.13089 75.269799) + (xy 138.818101 75.160349) (xy 138.818093 75.160346) (xy 138.575777 75.105039) (xy 138.495006 75.086604) + (xy 138.495003 75.086603) (xy 138.494991 75.086601) (xy 138.165703 75.0495) (xy 138.165697 75.0495) + (xy 137.834303 75.0495) (xy 137.834296 75.0495) (xy 137.505008 75.086601) (xy 137.504994 75.086604) + (xy 137.181906 75.160346) (xy 137.181898 75.160349) (xy 136.869109 75.269799) (xy 136.570541 75.413582) + (xy 136.289941 75.589895) (xy 136.030847 75.796515) (xy 135.796515 76.030847) (xy 135.589895 76.289941) + (xy 135.413582 76.570541) (xy 135.269799 76.869109) (xy 135.160349 77.181898) (xy 135.160346 77.181906) + (xy 135.086604 77.504994) (xy 135.086601 77.505008) (xy 135.0495 77.834296) (xy 134.5005 77.834296) + (xy 134.5005 74.6245) (xy 134.520185 74.557461) (xy 134.572989 74.511706) (xy 134.6245 74.5005) + (xy 169.3755 74.5005) + ) + ) + ) + (zone + (net 2) + (net_name "+3.3V") + (layer "B.Cu") + (uuid "1ece25c2-07e8-4442-85e3-391d176cd631") + (hatch edge 0.5) + (priority 1) + (connect_pads + (clearance 0.25) + ) + (min_thickness 0.25) + (filled_areas_thickness no) + (fill yes + (thermal_gap 0.25) + (thermal_bridge_width 0.25) + ) + (polygon + (pts + (xy 134.5 74.5) (xy 169.5 74.5) (xy 169.5 109.5) (xy 134.5 109.5) + ) + ) + (filled_polygon + (layer "B.Cu") + (pts + (xy 169.442539 74.520185) (xy 169.488294 74.572989) (xy 169.4995 74.6245) (xy 169.4995 109.3755) + (xy 169.479815 109.442539) (xy 169.427011 109.488294) (xy 169.3755 109.4995) (xy 134.6245 109.4995) + (xy 134.557461 109.479815) (xy 134.511706 109.427011) (xy 134.5005 109.3755) (xy 134.5005 105.834296) + (xy 135.0495 105.834296) (xy 135.0495 106.165703) (xy 135.086601 106.494991) (xy 135.086603 106.495003) + (xy 135.086604 106.495006) (xy 135.093012 106.523082) (xy 135.160346 106.818093) (xy 135.160349 106.818101) + (xy 135.269799 107.13089) (xy 135.413582 107.429458) (xy 135.413584 107.429461) (xy 135.589896 107.71006) + (xy 135.796516 107.969153) (xy 136.030847 108.203484) (xy 136.28994 108.410104) (xy 136.570539 108.586416) + (xy 136.869113 108.730202) (xy 137.104037 108.812405) (xy 137.181898 108.83965) (xy 137.181906 108.839653) + (xy 137.181909 108.839653) (xy 137.18191 108.839654) (xy 137.504994 108.913396) (xy 137.505003 108.913397) + (xy 137.505008 108.913398) (xy 137.724533 108.938132) (xy 137.834297 108.950499) (xy 137.8343 108.9505) + (xy 137.834303 108.9505) (xy 138.1657 108.9505) (xy 138.165701 108.950499) (xy 138.333996 108.931537) + (xy 138.494991 108.913398) (xy 138.494994 108.913397) (xy 138.495006 108.913396) (xy 138.81809 108.839654) + (xy 139.130887 108.730202) (xy 139.429461 108.586416) (xy 139.71006 108.410104) (xy 139.969153 108.203484) + (xy 140.203484 107.969153) (xy 140.410104 107.71006) (xy 140.586416 107.429461) (xy 140.730202 107.130887) + (xy 140.839654 106.81809) (xy 140.913396 106.495006) (xy 140.9505 106.165697) (xy 140.9505 105.834303) + (xy 140.92963 105.649073) (xy 140.928752 105.641277) (xy 146.15 105.641277) (xy 146.15 105.875) + (xy 146.645265 105.875) (xy 146.625 105.95063) (xy 146.625 106.04937) (xy 146.645265 106.125) (xy 146.15 106.125) + (xy 146.15 106.358722) (xy 146.182663 106.522928) (xy 146.182665 106.522936) (xy 146.24674 106.677627) + (xy 146.24674 106.677628) (xy 146.339758 106.816839) (xy 146.339764 106.816847) (xy 146.458152 106.935235) + (xy 146.45816 106.935241) (xy 146.597371 107.028259) (xy 146.752063 107.092334) (xy 146.752071 107.092336) + (xy 146.874999 107.116788) (xy 146.875 107.116788) (xy 146.875 106.354734) (xy 146.95063 106.375) + (xy 147.04937 106.375) (xy 147.125 106.354734) (xy 147.125 107.116788) (xy 147.247928 107.092336) + (xy 147.247936 107.092334) (xy 147.402627 107.028259) (xy 147.402628 107.028259) (xy 147.541839 106.935241) + (xy 147.541847 106.935235) (xy 147.660235 106.816847) (xy 147.660241 106.816839) (xy 147.753259 106.677628) + (xy 147.753259 106.677627) (xy 147.817334 106.522936) (xy 147.817336 106.522928) (xy 147.849999 106.358722) + (xy 147.85 106.35872) (xy 147.85 106.125) (xy 147.354735 106.125) (xy 147.375 106.04937) (xy 147.375 105.95063) + (xy 147.354735 105.875) (xy 147.85 105.875) (xy 147.85 105.641278) (xy 147.84999 105.641228) (xy 148.1495 105.641228) + (xy 148.1495 106.358771) (xy 148.182182 106.523074) (xy 148.182184 106.523082) (xy 148.246295 106.67786) + (xy 148.339373 106.817162) (xy 148.457837 106.935626) (xy 148.528055 106.982544) (xy 148.597137 107.028703) + (xy 148.751918 107.092816) (xy 148.916223 107.125498) (xy 148.916228 107.125499) (xy 148.916232 107.1255) + (xy 148.916233 107.1255) (xy 149.083768 107.1255) (xy 149.083769 107.125499) (xy 149.248082 107.092816) + (xy 149.402863 107.028703) (xy 149.542162 106.935626) (xy 149.660626 106.817162) (xy 149.753703 106.677863) + (xy 149.817816 106.523082) (xy 149.8505 106.358767) (xy 149.8505 105.641233) (xy 149.850499 105.641228) + (xy 150.1495 105.641228) (xy 150.1495 106.358771) (xy 150.182182 106.523074) (xy 150.182184 106.523082) + (xy 150.246295 106.67786) (xy 150.339373 106.817162) (xy 150.457837 106.935626) (xy 150.528055 106.982544) + (xy 150.597137 107.028703) (xy 150.751918 107.092816) (xy 150.916223 107.125498) (xy 150.916228 107.125499) + (xy 150.916232 107.1255) (xy 150.916233 107.1255) (xy 151.083768 107.1255) (xy 151.083769 107.125499) + (xy 151.248082 107.092816) (xy 151.402863 107.028703) (xy 151.542162 106.935626) (xy 151.660626 106.817162) + (xy 151.753703 106.677863) (xy 151.817816 106.523082) (xy 151.8505 106.358767) (xy 151.8505 105.641233) + (xy 151.850499 105.641228) (xy 152.1495 105.641228) (xy 152.1495 106.358771) (xy 152.182182 106.523074) + (xy 152.182184 106.523082) (xy 152.246295 106.67786) (xy 152.339373 106.817162) (xy 152.457837 106.935626) + (xy 152.528055 106.982544) (xy 152.597137 107.028703) (xy 152.751918 107.092816) (xy 152.916223 107.125498) + (xy 152.916228 107.125499) (xy 152.916232 107.1255) (xy 152.916233 107.1255) (xy 153.083768 107.1255) + (xy 153.083769 107.125499) (xy 153.248082 107.092816) (xy 153.402863 107.028703) (xy 153.542162 106.935626) + (xy 153.660626 106.817162) (xy 153.753703 106.677863) (xy 153.817816 106.523082) (xy 153.8505 106.358767) + (xy 153.8505 105.641233) (xy 153.817816 105.476918) (xy 153.755771 105.327129) (xy 153.753704 105.322139) + (xy 153.660626 105.182837) (xy 153.542162 105.064373) (xy 153.40286 104.971295) (xy 153.248082 104.907184) + (xy 153.248074 104.907182) (xy 153.083771 104.8745) (xy 153.083767 104.8745) (xy 152.916233 104.8745) + (xy 152.916228 104.8745) (xy 152.751925 104.907182) (xy 152.751917 104.907184) (xy 152.597139 104.971295) + (xy 152.457837 105.064373) (xy 152.339373 105.182837) (xy 152.246295 105.322139) (xy 152.182184 105.476917) + (xy 152.182182 105.476925) (xy 152.1495 105.641228) (xy 151.850499 105.641228) (xy 151.817816 105.476918) + (xy 151.755771 105.327129) (xy 151.753704 105.322139) (xy 151.660626 105.182837) (xy 151.542162 105.064373) + (xy 151.40286 104.971295) (xy 151.248082 104.907184) (xy 151.248074 104.907182) (xy 151.083771 104.8745) + (xy 151.083767 104.8745) (xy 150.916233 104.8745) (xy 150.916228 104.8745) (xy 150.751925 104.907182) + (xy 150.751917 104.907184) (xy 150.597139 104.971295) (xy 150.457837 105.064373) (xy 150.339373 105.182837) + (xy 150.246295 105.322139) (xy 150.182184 105.476917) (xy 150.182182 105.476925) (xy 150.1495 105.641228) + (xy 149.850499 105.641228) (xy 149.817816 105.476918) (xy 149.755771 105.327129) (xy 149.753704 105.322139) + (xy 149.660626 105.182837) (xy 149.542162 105.064373) (xy 149.40286 104.971295) (xy 149.248082 104.907184) + (xy 149.248074 104.907182) (xy 149.083771 104.8745) (xy 149.083767 104.8745) (xy 148.916233 104.8745) + (xy 148.916228 104.8745) (xy 148.751925 104.907182) (xy 148.751917 104.907184) (xy 148.597139 104.971295) + (xy 148.457837 105.064373) (xy 148.339373 105.182837) (xy 148.246295 105.322139) (xy 148.182184 105.476917) + (xy 148.182182 105.476925) (xy 148.1495 105.641228) (xy 147.84999 105.641228) (xy 147.817336 105.477071) + (xy 147.817334 105.477063) (xy 147.753259 105.322372) (xy 147.753259 105.322371) (xy 147.660241 105.18316) + (xy 147.660235 105.183152) (xy 147.541847 105.064764) (xy 147.541839 105.064758) (xy 147.402628 104.97174) + (xy 147.247936 104.907665) (xy 147.24793 104.907663) (xy 147.125 104.88321) (xy 147.125 105.645265) + (xy 147.04937 105.625) (xy 146.95063 105.625) (xy 146.875 105.645265) (xy 146.875 104.883211) (xy 146.874999 104.88321) + (xy 146.752069 104.907663) (xy 146.752063 104.907665) (xy 146.597372 104.97174) (xy 146.597371 104.97174) + (xy 146.45816 105.064758) (xy 146.458152 105.064764) (xy 146.339764 105.183152) (xy 146.339758 105.18316) + (xy 146.24674 105.322371) (xy 146.24674 105.322372) (xy 146.182665 105.477063) (xy 146.182663 105.477071) + (xy 146.15 105.641277) (xy 140.928752 105.641277) (xy 140.913398 105.505008) (xy 140.913397 105.505003) + (xy 140.913396 105.504994) (xy 140.839654 105.18191) (xy 140.730202 104.869113) (xy 140.586416 104.570539) + (xy 140.410104 104.28994) (xy 140.203484 104.030847) (xy 139.969153 103.796516) (xy 139.71006 103.589896) + (xy 139.429461 103.413584) (xy 139.429458 103.413582) (xy 139.13089 103.269799) (xy 138.818101 103.160349) + (xy 138.818093 103.160346) (xy 138.575777 103.105039) (xy 138.495006 103.086604) (xy 138.495003 103.086603) + (xy 138.494991 103.086601) (xy 138.165703 103.0495) (xy 138.165697 103.0495) (xy 137.834303 103.0495) + (xy 137.834296 103.0495) (xy 137.505008 103.086601) (xy 137.504994 103.086604) (xy 137.181906 103.160346) + (xy 137.181898 103.160349) (xy 136.869109 103.269799) (xy 136.570541 103.413582) (xy 136.289941 103.589895) + (xy 136.030847 103.796515) (xy 135.796515 104.030847) (xy 135.589895 104.289941) (xy 135.413582 104.570541) + (xy 135.269799 104.869109) (xy 135.160349 105.181898) (xy 135.160346 105.181906) (xy 135.086604 105.504994) + (xy 135.086601 105.505008) (xy 135.0495 105.834296) (xy 134.5005 105.834296) (xy 134.5005 101.927525) + (xy 143.4495 101.927525) (xy 143.4495 102.072475) (xy 143.487016 102.212485) (xy 143.487017 102.212488) + (xy 143.559488 102.338011) (xy 143.55949 102.338013) (xy 143.559491 102.338015) (xy 143.661985 102.440509) + (xy 143.661986 102.44051) (xy 143.661988 102.440511) (xy 143.787511 102.512982) (xy 143.787512 102.512982) + (xy 143.787515 102.512984) (xy 143.927525 102.5505) (xy 143.927528 102.5505) (xy 144.072472 102.5505) + (xy 144.072475 102.5505) (xy 144.212485 102.512984) (xy 144.338015 102.440509) (xy 144.391705 102.386819) + (xy 144.453028 102.353334) (xy 144.479386 102.3505) (xy 153.803456 102.3505) (xy 153.870495 102.370185) + (xy 153.891137 102.386819) (xy 154.613181 103.108863) (xy 154.646666 103.170186) (xy 154.6495 103.196544) + (xy 154.6495 104.87003) (xy 154.629815 104.937069) (xy 154.594391 104.973132) (xy 154.457837 105.064373) + (xy 154.339373 105.182837) (xy 154.246295 105.322139) (xy 154.182184 105.476917) (xy 154.182182 105.476925) + (xy 154.1495 105.641228) (xy 154.1495 106.358771) (xy 154.182182 106.523074) (xy 154.182184 106.523082) + (xy 154.246295 106.67786) (xy 154.339373 106.817162) (xy 154.457837 106.935626) (xy 154.528055 106.982544) + (xy 154.597137 107.028703) (xy 154.751918 107.092816) (xy 154.916223 107.125498) (xy 154.916228 107.125499) + (xy 154.916232 107.1255) (xy 154.916233 107.1255) (xy 155.083768 107.1255) (xy 155.083769 107.125499) + (xy 155.248082 107.092816) (xy 155.402863 107.028703) (xy 155.542162 106.935626) (xy 155.660626 106.817162) + (xy 155.753703 106.677863) (xy 155.817816 106.523082) (xy 155.8505 106.358767) (xy 155.8505 105.641233) + (xy 155.817816 105.476918) (xy 155.763577 105.345975) (xy 155.755774 105.327135) (xy 156.1495 105.327135) + (xy 156.1495 106.67287) (xy 156.149501 106.672876) (xy 156.155908 106.732483) (xy 156.206202 106.867328) + (xy 156.206206 106.867335) (xy 156.292452 106.982544) (xy 156.292455 106.982547) (xy 156.407664 107.068793) + (xy 156.407671 107.068797) (xy 156.542517 107.119091) (xy 156.542516 107.119091) (xy 156.549444 107.119835) + (xy 156.602127 107.1255) (xy 157.397872 107.125499) (xy 157.457483 107.119091) (xy 157.592331 107.068796) + (xy 157.707546 106.982546) (xy 157.793796 106.867331) (xy 157.844091 106.732483) (xy 157.8505 106.672873) + (xy 157.850499 105.834296) (xy 163.0495 105.834296) (xy 163.0495 106.165703) (xy 163.086601 106.494991) + (xy 163.086603 106.495003) (xy 163.086604 106.495006) (xy 163.093012 106.523082) (xy 163.160346 106.818093) + (xy 163.160349 106.818101) (xy 163.269799 107.13089) (xy 163.413582 107.429458) (xy 163.413584 107.429461) + (xy 163.589896 107.71006) (xy 163.796516 107.969153) (xy 164.030847 108.203484) (xy 164.28994 108.410104) + (xy 164.570539 108.586416) (xy 164.869113 108.730202) (xy 165.104037 108.812405) (xy 165.181898 108.83965) + (xy 165.181906 108.839653) (xy 165.181909 108.839653) (xy 165.18191 108.839654) (xy 165.504994 108.913396) + (xy 165.505003 108.913397) (xy 165.505008 108.913398) (xy 165.724533 108.938132) (xy 165.834297 108.950499) + (xy 165.8343 108.9505) (xy 165.834303 108.9505) (xy 166.1657 108.9505) (xy 166.165701 108.950499) + (xy 166.333996 108.931537) (xy 166.494991 108.913398) (xy 166.494994 108.913397) (xy 166.495006 108.913396) + (xy 166.81809 108.839654) (xy 167.130887 108.730202) (xy 167.429461 108.586416) (xy 167.71006 108.410104) + (xy 167.969153 108.203484) (xy 168.203484 107.969153) (xy 168.410104 107.71006) (xy 168.586416 107.429461) + (xy 168.730202 107.130887) (xy 168.839654 106.81809) (xy 168.913396 106.495006) (xy 168.9505 106.165697) + (xy 168.9505 105.834303) (xy 168.950499 105.834298) (xy 168.950499 105.834296) (xy 168.913398 105.505008) + (xy 168.913397 105.505003) (xy 168.913396 105.504994) (xy 168.839654 105.18191) (xy 168.730202 104.869113) + (xy 168.586416 104.570539) (xy 168.410104 104.28994) (xy 168.203484 104.030847) (xy 167.969153 103.796516) + (xy 167.71006 103.589896) (xy 167.429461 103.413584) (xy 167.429458 103.413582) (xy 167.13089 103.269799) + (xy 166.818101 103.160349) (xy 166.818093 103.160346) (xy 166.575777 103.105039) (xy 166.495006 103.086604) + (xy 166.495003 103.086603) (xy 166.494991 103.086601) (xy 166.165703 103.0495) (xy 166.165697 103.0495) + (xy 165.834303 103.0495) (xy 165.834296 103.0495) (xy 165.505008 103.086601) (xy 165.504994 103.086604) + (xy 165.181906 103.160346) (xy 165.181898 103.160349) (xy 164.869109 103.269799) (xy 164.570541 103.413582) + (xy 164.289941 103.589895) (xy 164.030847 103.796515) (xy 163.796515 104.030847) (xy 163.589895 104.289941) + (xy 163.413582 104.570541) (xy 163.269799 104.869109) (xy 163.160349 105.181898) (xy 163.160346 105.181906) + (xy 163.086604 105.504994) (xy 163.086601 105.505008) (xy 163.0495 105.834296) (xy 157.850499 105.834296) + (xy 157.850499 105.327128) (xy 157.844091 105.267517) (xy 157.812507 105.182837) (xy 157.793797 105.132671) + (xy 157.793793 105.132664) (xy 157.707547 105.017455) (xy 157.707544 105.017452) (xy 157.592335 104.931206) + (xy 157.592328 104.931202) (xy 157.457482 104.880908) (xy 157.457483 104.880908) (xy 157.397883 104.874501) + (xy 157.397881 104.8745) (xy 157.397873 104.8745) (xy 157.397864 104.8745) (xy 156.602129 104.8745) + (xy 156.602123 104.874501) (xy 156.542516 104.880908) (xy 156.407671 104.931202) (xy 156.407664 104.931206) + (xy 156.292455 105.017452) (xy 156.292452 105.017455) (xy 156.206206 105.132664) (xy 156.206202 105.132671) + (xy 156.155908 105.267517) (xy 156.150036 105.322139) (xy 156.149501 105.327123) (xy 156.1495 105.327135) + (xy 155.755774 105.327135) (xy 155.753705 105.322141) (xy 155.753704 105.322139) (xy 155.660626 105.182837) + (xy 155.542162 105.064373) (xy 155.405609 104.973132) (xy 155.360804 104.91952) (xy 155.3505 104.87003) + (xy 155.3505 102.953858) (xy 155.3505 102.953856) (xy 155.326614 102.864712) (xy 155.28047 102.784788) + (xy 154.215212 101.71953) (xy 154.215211 101.719529) (xy 154.215208 101.719527) (xy 154.13529 101.673387) + (xy 154.135289 101.673386) (xy 154.135288 101.673386) (xy 154.046144 101.6495) (xy 154.046143 101.6495) + (xy 144.479386 101.6495) (xy 144.412347 101.629815) (xy 144.391705 101.613181) (xy 144.338017 101.559493) + (xy 144.338011 101.559488) (xy 144.212488 101.487017) (xy 144.212489 101.487017) (xy 144.201006 101.48394) + (xy 144.072475 101.4495) (xy 143.927525 101.4495) (xy 143.798993 101.48394) (xy 143.787511 101.487017) + (xy 143.661988 101.559488) (xy 143.661982 101.559493) (xy 143.559493 101.661982) (xy 143.559488 101.661988) + (xy 143.487017 101.787511) (xy 143.487016 101.787515) (xy 143.4495 101.927525) (xy 134.5005 101.927525) + (xy 134.5005 99.927525) (xy 141.4495 99.927525) (xy 141.4495 100.072475) (xy 141.487016 100.212485) + (xy 141.487017 100.212488) (xy 141.559488 100.338011) (xy 141.55949 100.338013) (xy 141.559491 100.338015) + (xy 141.661985 100.440509) (xy 141.661986 100.44051) (xy 141.661988 100.440511) (xy 141.787511 100.512982) + (xy 141.787512 100.512982) (xy 141.787515 100.512984) (xy 141.927525 100.5505) (xy 141.927528 100.5505) + (xy 142.072472 100.5505) (xy 142.072475 100.5505) (xy 142.212485 100.512984) (xy 142.338015 100.440509) + (xy 142.391705 100.386819) (xy 142.453028 100.353334) (xy 142.479386 100.3505) (xy 154.046142 100.3505) + (xy 154.046144 100.3505) (xy 154.135288 100.326614) (xy 154.145912 100.32048) (xy 154.215212 100.28047) + (xy 155.28047 99.215212) (xy 155.326614 99.135288) (xy 155.3505 99.046143) (xy 155.3505 98.953856) + (xy 155.3505 98.12997) (xy 155.370185 98.062931) (xy 155.405609 98.026868) (xy 155.471942 97.982546) + (xy 155.542162 97.935626) (xy 155.660626 97.817162) (xy 155.753703 97.677863) (xy 155.817816 97.523082) + (xy 155.8505 97.358767) (xy 155.8505 96.641233) (xy 155.817816 96.476918) (xy 155.763577 96.345975) + (xy 155.755774 96.327135) (xy 156.1495 96.327135) (xy 156.1495 97.67287) (xy 156.149501 97.672876) + (xy 156.155908 97.732483) (xy 156.206202 97.867328) (xy 156.206206 97.867335) (xy 156.292452 97.982544) + (xy 156.292455 97.982547) (xy 156.407664 98.068793) (xy 156.407671 98.068797) (xy 156.542517 98.119091) + (xy 156.542516 98.119091) (xy 156.549444 98.119835) (xy 156.602127 98.1255) (xy 157.397872 98.125499) + (xy 157.457483 98.119091) (xy 157.592331 98.068796) (xy 157.707546 97.982546) (xy 157.793796 97.867331) + (xy 157.844091 97.732483) (xy 157.8505 97.672873) (xy 157.850499 96.327128) (xy 157.844091 96.267517) + (xy 157.812507 96.182837) (xy 157.793797 96.132671) (xy 157.793793 96.132664) (xy 157.707547 96.017455) + (xy 157.707544 96.017452) (xy 157.592335 95.931206) (xy 157.592328 95.931202) (xy 157.457482 95.880908) + (xy 157.457483 95.880908) (xy 157.397883 95.874501) (xy 157.397881 95.8745) (xy 157.397873 95.8745) + (xy 157.397864 95.8745) (xy 156.602129 95.8745) (xy 156.602123 95.874501) (xy 156.542516 95.880908) + (xy 156.407671 95.931202) (xy 156.407664 95.931206) (xy 156.292455 96.017452) (xy 156.292452 96.017455) + (xy 156.206206 96.132664) (xy 156.206202 96.132671) (xy 156.155908 96.267517) (xy 156.150036 96.322139) + (xy 156.149501 96.327123) (xy 156.1495 96.327135) (xy 155.755774 96.327135) (xy 155.753705 96.322141) + (xy 155.753704 96.322139) (xy 155.660626 96.182837) (xy 155.542162 96.064373) (xy 155.40286 95.971295) + (xy 155.248082 95.907184) (xy 155.248074 95.907182) (xy 155.083771 95.8745) (xy 155.083767 95.8745) + (xy 154.916233 95.8745) (xy 154.916228 95.8745) (xy 154.751925 95.907182) (xy 154.751917 95.907184) + (xy 154.597139 95.971295) (xy 154.457837 96.064373) (xy 154.339373 96.182837) (xy 154.246295 96.322139) + (xy 154.182184 96.476917) (xy 154.182182 96.476925) (xy 154.1495 96.641228) (xy 154.1495 97.358771) + (xy 154.182182 97.523074) (xy 154.182184 97.523082) (xy 154.246295 97.67786) (xy 154.339373 97.817162) + (xy 154.457837 97.935626) (xy 154.594391 98.026868) (xy 154.639196 98.08048) (xy 154.6495 98.12997) + (xy 154.6495 98.803456) (xy 154.629815 98.870495) (xy 154.613181 98.891137) (xy 153.891137 99.613181) + (xy 153.829814 99.646666) (xy 153.803456 99.6495) (xy 142.479386 99.6495) (xy 142.412347 99.629815) + (xy 142.391705 99.613181) (xy 142.338017 99.559493) (xy 142.338011 99.559488) (xy 142.212488 99.487017) + (xy 142.212489 99.487017) (xy 142.201006 99.48394) (xy 142.072475 99.4495) (xy 141.927525 99.4495) + (xy 141.798993 99.48394) (xy 141.787511 99.487017) (xy 141.661988 99.559488) (xy 141.661982 99.559493) + (xy 141.559493 99.661982) (xy 141.559488 99.661988) (xy 141.487017 99.787511) (xy 141.487016 99.787515) + (xy 141.4495 99.927525) (xy 134.5005 99.927525) (xy 134.5005 96.641277) (xy 146.15 96.641277) (xy 146.15 96.875) + (xy 146.645265 96.875) (xy 146.625 96.95063) (xy 146.625 97.04937) (xy 146.645265 97.125) (xy 146.15 97.125) + (xy 146.15 97.358722) (xy 146.182663 97.522928) (xy 146.182665 97.522936) (xy 146.24674 97.677627) + (xy 146.24674 97.677628) (xy 146.339758 97.816839) (xy 146.339764 97.816847) (xy 146.458152 97.935235) + (xy 146.45816 97.935241) (xy 146.597371 98.028259) (xy 146.752063 98.092334) (xy 146.752071 98.092336) + (xy 146.874999 98.116788) (xy 146.875 98.116788) (xy 146.875 97.354734) (xy 146.95063 97.375) (xy 147.04937 97.375) + (xy 147.125 97.354734) (xy 147.125 98.116788) (xy 147.247928 98.092336) (xy 147.247936 98.092334) + (xy 147.402627 98.028259) (xy 147.402628 98.028259) (xy 147.541839 97.935241) (xy 147.541847 97.935235) + (xy 147.660235 97.816847) (xy 147.660241 97.816839) (xy 147.753259 97.677628) (xy 147.753259 97.677627) + (xy 147.817334 97.522936) (xy 147.817336 97.522928) (xy 147.849999 97.358722) (xy 147.85 97.35872) + (xy 147.85 97.125) (xy 147.354735 97.125) (xy 147.375 97.04937) (xy 147.375 96.95063) (xy 147.354735 96.875) + (xy 147.85 96.875) (xy 147.85 96.641278) (xy 147.84999 96.641228) (xy 148.1495 96.641228) (xy 148.1495 97.358771) + (xy 148.182182 97.523074) (xy 148.182184 97.523082) (xy 148.246295 97.67786) (xy 148.339373 97.817162) + (xy 148.457837 97.935626) (xy 148.528055 97.982544) (xy 148.597137 98.028703) (xy 148.751918 98.092816) + (xy 148.916223 98.125498) (xy 148.916228 98.125499) (xy 148.916232 98.1255) (xy 148.916233 98.1255) + (xy 149.083768 98.1255) (xy 149.083769 98.125499) (xy 149.248082 98.092816) (xy 149.402863 98.028703) + (xy 149.542162 97.935626) (xy 149.660626 97.817162) (xy 149.753703 97.677863) (xy 149.817816 97.523082) + (xy 149.8505 97.358767) (xy 149.8505 96.641233) (xy 149.850499 96.641228) (xy 150.1495 96.641228) + (xy 150.1495 97.358771) (xy 150.182182 97.523074) (xy 150.182184 97.523082) (xy 150.246295 97.67786) + (xy 150.339373 97.817162) (xy 150.457837 97.935626) (xy 150.528055 97.982544) (xy 150.597137 98.028703) + (xy 150.751918 98.092816) (xy 150.916223 98.125498) (xy 150.916228 98.125499) (xy 150.916232 98.1255) + (xy 150.916233 98.1255) (xy 151.083768 98.1255) (xy 151.083769 98.125499) (xy 151.248082 98.092816) + (xy 151.402863 98.028703) (xy 151.542162 97.935626) (xy 151.660626 97.817162) (xy 151.753703 97.677863) + (xy 151.817816 97.523082) (xy 151.8505 97.358767) (xy 151.8505 96.641233) (xy 151.850499 96.641228) + (xy 152.1495 96.641228) (xy 152.1495 97.358771) (xy 152.182182 97.523074) (xy 152.182184 97.523082) + (xy 152.246295 97.67786) (xy 152.339373 97.817162) (xy 152.457837 97.935626) (xy 152.528055 97.982544) + (xy 152.597137 98.028703) (xy 152.751918 98.092816) (xy 152.916223 98.125498) (xy 152.916228 98.125499) + (xy 152.916232 98.1255) (xy 152.916233 98.1255) (xy 153.083768 98.1255) (xy 153.083769 98.125499) + (xy 153.248082 98.092816) (xy 153.402863 98.028703) (xy 153.542162 97.935626) (xy 153.660626 97.817162) + (xy 153.753703 97.677863) (xy 153.817816 97.523082) (xy 153.8505 97.358767) (xy 153.8505 96.641233) + (xy 153.817816 96.476918) (xy 153.755771 96.327129) (xy 153.753704 96.322139) (xy 153.660626 96.182837) + (xy 153.542162 96.064373) (xy 153.40286 95.971295) (xy 153.248082 95.907184) (xy 153.248074 95.907182) + (xy 153.083771 95.8745) (xy 153.083767 95.8745) (xy 152.916233 95.8745) (xy 152.916228 95.8745) + (xy 152.751925 95.907182) (xy 152.751917 95.907184) (xy 152.597139 95.971295) (xy 152.457837 96.064373) + (xy 152.339373 96.182837) (xy 152.246295 96.322139) (xy 152.182184 96.476917) (xy 152.182182 96.476925) + (xy 152.1495 96.641228) (xy 151.850499 96.641228) (xy 151.817816 96.476918) (xy 151.755771 96.327129) + (xy 151.753704 96.322139) (xy 151.660626 96.182837) (xy 151.542162 96.064373) (xy 151.40286 95.971295) + (xy 151.248082 95.907184) (xy 151.248074 95.907182) (xy 151.083771 95.8745) (xy 151.083767 95.8745) + (xy 150.916233 95.8745) (xy 150.916228 95.8745) (xy 150.751925 95.907182) (xy 150.751917 95.907184) + (xy 150.597139 95.971295) (xy 150.457837 96.064373) (xy 150.339373 96.182837) (xy 150.246295 96.322139) + (xy 150.182184 96.476917) (xy 150.182182 96.476925) (xy 150.1495 96.641228) (xy 149.850499 96.641228) + (xy 149.817816 96.476918) (xy 149.755771 96.327129) (xy 149.753704 96.322139) (xy 149.660626 96.182837) + (xy 149.542162 96.064373) (xy 149.40286 95.971295) (xy 149.248082 95.907184) (xy 149.248074 95.907182) + (xy 149.083771 95.8745) (xy 149.083767 95.8745) (xy 148.916233 95.8745) (xy 148.916228 95.8745) + (xy 148.751925 95.907182) (xy 148.751917 95.907184) (xy 148.597139 95.971295) (xy 148.457837 96.064373) + (xy 148.339373 96.182837) (xy 148.246295 96.322139) (xy 148.182184 96.476917) (xy 148.182182 96.476925) + (xy 148.1495 96.641228) (xy 147.84999 96.641228) (xy 147.817336 96.477071) (xy 147.817334 96.477063) + (xy 147.753259 96.322372) (xy 147.753259 96.322371) (xy 147.660241 96.18316) (xy 147.660235 96.183152) + (xy 147.541847 96.064764) (xy 147.541839 96.064758) (xy 147.402628 95.97174) (xy 147.247936 95.907665) + (xy 147.24793 95.907663) (xy 147.125 95.88321) (xy 147.125 96.645265) (xy 147.04937 96.625) (xy 146.95063 96.625) + (xy 146.875 96.645265) (xy 146.875 95.883211) (xy 146.874999 95.88321) (xy 146.752069 95.907663) + (xy 146.752063 95.907665) (xy 146.597372 95.97174) (xy 146.597371 95.97174) (xy 146.45816 96.064758) + (xy 146.458152 96.064764) (xy 146.339764 96.183152) (xy 146.339758 96.18316) (xy 146.24674 96.322371) + (xy 146.24674 96.322372) (xy 146.182665 96.477063) (xy 146.182663 96.477071) (xy 146.15 96.641277) + (xy 134.5005 96.641277) (xy 134.5005 90.927525) (xy 139.4495 90.927525) (xy 139.4495 91.072475) + (xy 139.487016 91.212485) (xy 139.487017 91.212488) (xy 139.559488 91.338011) (xy 139.55949 91.338013) + (xy 139.559491 91.338015) (xy 139.661985 91.440509) (xy 139.661986 91.44051) (xy 139.661988 91.440511) + (xy 139.787511 91.512982) (xy 139.787512 91.512982) (xy 139.787515 91.512984) (xy 139.927525 91.5505) + (xy 139.927528 91.5505) (xy 140.072472 91.5505) (xy 140.072475 91.5505) (xy 140.212485 91.512984) + (xy 140.338015 91.440509) (xy 140.391705 91.386819) (xy 140.453028 91.353334) (xy 140.479386 91.3505) + (xy 154.046142 91.3505) (xy 154.046144 91.3505) (xy 154.135288 91.326614) (xy 154.145912 91.32048) + (xy 154.215212 91.28047) (xy 155.28047 90.215212) (xy 155.326614 90.135288) (xy 155.3505 90.046143) + (xy 155.3505 89.953856) (xy 155.3505 89.12997) (xy 155.370185 89.062931) (xy 155.405609 89.026868) + (xy 155.471942 88.982546) (xy 155.542162 88.935626) (xy 155.660626 88.817162) (xy 155.753703 88.677863) + (xy 155.817816 88.523082) (xy 155.8505 88.358767) (xy 155.8505 87.641233) (xy 155.817816 87.476918) + (xy 155.763577 87.345975) (xy 155.755774 87.327135) (xy 156.1495 87.327135) (xy 156.1495 88.67287) + (xy 156.149501 88.672876) (xy 156.155908 88.732483) (xy 156.206202 88.867328) (xy 156.206206 88.867335) + (xy 156.292452 88.982544) (xy 156.292455 88.982547) (xy 156.407664 89.068793) (xy 156.407671 89.068797) + (xy 156.542517 89.119091) (xy 156.542516 89.119091) (xy 156.549444 89.119835) (xy 156.602127 89.1255) + (xy 157.397872 89.125499) (xy 157.457483 89.119091) (xy 157.592331 89.068796) (xy 157.707546 88.982546) + (xy 157.793796 88.867331) (xy 157.844091 88.732483) (xy 157.8505 88.672873) (xy 157.850499 87.327128) + (xy 157.844091 87.267517) (xy 157.812507 87.182837) (xy 157.793797 87.132671) (xy 157.793793 87.132664) + (xy 157.707547 87.017455) (xy 157.707544 87.017452) (xy 157.592335 86.931206) (xy 157.592328 86.931202) + (xy 157.457482 86.880908) (xy 157.457483 86.880908) (xy 157.397883 86.874501) (xy 157.397881 86.8745) + (xy 157.397873 86.8745) (xy 157.397864 86.8745) (xy 156.602129 86.8745) (xy 156.602123 86.874501) + (xy 156.542516 86.880908) (xy 156.407671 86.931202) (xy 156.407664 86.931206) (xy 156.292455 87.017452) + (xy 156.292452 87.017455) (xy 156.206206 87.132664) (xy 156.206202 87.132671) (xy 156.155908 87.267517) + (xy 156.150036 87.322139) (xy 156.149501 87.327123) (xy 156.1495 87.327135) (xy 155.755774 87.327135) + (xy 155.753705 87.322141) (xy 155.753704 87.322139) (xy 155.660626 87.182837) (xy 155.542162 87.064373) + (xy 155.40286 86.971295) (xy 155.248082 86.907184) (xy 155.248074 86.907182) (xy 155.083771 86.8745) + (xy 155.083767 86.8745) (xy 154.916233 86.8745) (xy 154.916228 86.8745) (xy 154.751925 86.907182) + (xy 154.751917 86.907184) (xy 154.597139 86.971295) (xy 154.457837 87.064373) (xy 154.339373 87.182837) + (xy 154.246295 87.322139) (xy 154.182184 87.476917) (xy 154.182182 87.476925) (xy 154.1495 87.641228) + (xy 154.1495 88.358771) (xy 154.182182 88.523074) (xy 154.182184 88.523082) (xy 154.246295 88.67786) + (xy 154.339373 88.817162) (xy 154.457837 88.935626) (xy 154.594391 89.026868) (xy 154.639196 89.08048) + (xy 154.6495 89.12997) (xy 154.6495 89.803456) (xy 154.629815 89.870495) (xy 154.613181 89.891137) + (xy 153.891137 90.613181) (xy 153.829814 90.646666) (xy 153.803456 90.6495) (xy 140.479386 90.6495) + (xy 140.412347 90.629815) (xy 140.391705 90.613181) (xy 140.338017 90.559493) (xy 140.338011 90.559488) + (xy 140.212488 90.487017) (xy 140.212489 90.487017) (xy 140.201006 90.48394) (xy 140.072475 90.4495) + (xy 139.927525 90.4495) (xy 139.798993 90.48394) (xy 139.787511 90.487017) (xy 139.661988 90.559488) + (xy 139.661982 90.559493) (xy 139.559493 90.661982) (xy 139.559488 90.661988) (xy 139.487017 90.787511) + (xy 139.487016 90.787515) (xy 139.4495 90.927525) (xy 134.5005 90.927525) (xy 134.5005 87.641277) + (xy 146.15 87.641277) (xy 146.15 87.875) (xy 146.645265 87.875) (xy 146.625 87.95063) (xy 146.625 88.04937) + (xy 146.645265 88.125) (xy 146.15 88.125) (xy 146.15 88.358722) (xy 146.182663 88.522928) (xy 146.182665 88.522936) + (xy 146.24674 88.677627) (xy 146.24674 88.677628) (xy 146.339758 88.816839) (xy 146.339764 88.816847) + (xy 146.458152 88.935235) (xy 146.45816 88.935241) (xy 146.597371 89.028259) (xy 146.752063 89.092334) + (xy 146.752071 89.092336) (xy 146.874999 89.116788) (xy 146.875 89.116788) (xy 146.875 88.354734) + (xy 146.95063 88.375) (xy 147.04937 88.375) (xy 147.125 88.354734) (xy 147.125 89.116788) (xy 147.247928 89.092336) + (xy 147.247936 89.092334) (xy 147.402627 89.028259) (xy 147.402628 89.028259) (xy 147.541839 88.935241) + (xy 147.541847 88.935235) (xy 147.660235 88.816847) (xy 147.660241 88.816839) (xy 147.753259 88.677628) + (xy 147.753259 88.677627) (xy 147.817334 88.522936) (xy 147.817336 88.522928) (xy 147.849999 88.358722) + (xy 147.85 88.35872) (xy 147.85 88.125) (xy 147.354735 88.125) (xy 147.375 88.04937) (xy 147.375 87.95063) + (xy 147.354735 87.875) (xy 147.85 87.875) (xy 147.85 87.641278) (xy 147.84999 87.641228) (xy 148.1495 87.641228) + (xy 148.1495 88.358771) (xy 148.182182 88.523074) (xy 148.182184 88.523082) (xy 148.246295 88.67786) + (xy 148.339373 88.817162) (xy 148.457837 88.935626) (xy 148.528055 88.982544) (xy 148.597137 89.028703) + (xy 148.751918 89.092816) (xy 148.916223 89.125498) (xy 148.916228 89.125499) (xy 148.916232 89.1255) + (xy 148.916233 89.1255) (xy 149.083768 89.1255) (xy 149.083769 89.125499) (xy 149.248082 89.092816) + (xy 149.402863 89.028703) (xy 149.542162 88.935626) (xy 149.660626 88.817162) (xy 149.753703 88.677863) + (xy 149.817816 88.523082) (xy 149.8505 88.358767) (xy 149.8505 87.641233) (xy 149.850499 87.641228) + (xy 150.1495 87.641228) (xy 150.1495 88.358771) (xy 150.182182 88.523074) (xy 150.182184 88.523082) + (xy 150.246295 88.67786) (xy 150.339373 88.817162) (xy 150.457837 88.935626) (xy 150.528055 88.982544) + (xy 150.597137 89.028703) (xy 150.751918 89.092816) (xy 150.916223 89.125498) (xy 150.916228 89.125499) + (xy 150.916232 89.1255) (xy 150.916233 89.1255) (xy 151.083768 89.1255) (xy 151.083769 89.125499) + (xy 151.248082 89.092816) (xy 151.402863 89.028703) (xy 151.542162 88.935626) (xy 151.660626 88.817162) + (xy 151.753703 88.677863) (xy 151.817816 88.523082) (xy 151.8505 88.358767) (xy 151.8505 87.641233) + (xy 151.817816 87.476918) (xy 151.755771 87.327129) (xy 151.753704 87.322139) (xy 151.660626 87.182837) + (xy 151.542162 87.064373) (xy 151.40286 86.971295) (xy 151.248082 86.907184) (xy 151.248074 86.907182) + (xy 151.083771 86.8745) (xy 151.083767 86.8745) (xy 150.916233 86.8745) (xy 150.916228 86.8745) + (xy 150.751925 86.907182) (xy 150.751917 86.907184) (xy 150.597139 86.971295) (xy 150.457837 87.064373) + (xy 150.339373 87.182837) (xy 150.246295 87.322139) (xy 150.182184 87.476917) (xy 150.182182 87.476925) + (xy 150.1495 87.641228) (xy 149.850499 87.641228) (xy 149.817816 87.476918) (xy 149.755771 87.327129) + (xy 149.753704 87.322139) (xy 149.660626 87.182837) (xy 149.542162 87.064373) (xy 149.40286 86.971295) + (xy 149.248082 86.907184) (xy 149.248074 86.907182) (xy 149.083771 86.8745) (xy 149.083767 86.8745) + (xy 148.916233 86.8745) (xy 148.916228 86.8745) (xy 148.751925 86.907182) (xy 148.751917 86.907184) + (xy 148.597139 86.971295) (xy 148.457837 87.064373) (xy 148.339373 87.182837) (xy 148.246295 87.322139) + (xy 148.182184 87.476917) (xy 148.182182 87.476925) (xy 148.1495 87.641228) (xy 147.84999 87.641228) + (xy 147.817336 87.477071) (xy 147.817334 87.477063) (xy 147.753259 87.322372) (xy 147.753259 87.322371) + (xy 147.660241 87.18316) (xy 147.660235 87.183152) (xy 147.541847 87.064764) (xy 147.541839 87.064758) + (xy 147.402628 86.97174) (xy 147.247936 86.907665) (xy 147.24793 86.907663) (xy 147.125 86.88321) + (xy 147.125 87.645265) (xy 147.04937 87.625) (xy 146.95063 87.625) (xy 146.875 87.645265) (xy 146.875 86.883211) + (xy 146.874999 86.88321) (xy 146.752069 86.907663) (xy 146.752063 86.907665) (xy 146.597372 86.97174) + (xy 146.597371 86.97174) (xy 146.45816 87.064758) (xy 146.458152 87.064764) (xy 146.339764 87.183152) + (xy 146.339758 87.18316) (xy 146.24674 87.322371) (xy 146.24674 87.322372) (xy 146.182665 87.477063) + (xy 146.182663 87.477071) (xy 146.15 87.641277) (xy 134.5005 87.641277) (xy 134.5005 77.834296) + (xy 135.0495 77.834296) (xy 135.0495 78.165703) (xy 135.086601 78.494991) (xy 135.086604 78.495005) + (xy 135.160346 78.818093) (xy 135.160349 78.818101) (xy 135.269799 79.13089) (xy 135.413582 79.429458) + (xy 135.413584 79.429461) (xy 135.589896 79.71006) (xy 135.796516 79.969153) (xy 136.030847 80.203484) + (xy 136.28994 80.410104) (xy 136.570539 80.586416) (xy 136.869113 80.730202) (xy 137.104037 80.812405) + (xy 137.181898 80.83965) (xy 137.181906 80.839653) (xy 137.181909 80.839653) (xy 137.18191 80.839654) + (xy 137.504994 80.913396) (xy 137.505003 80.913397) (xy 137.505008 80.913398) (xy 137.724533 80.938132) + (xy 137.834297 80.950499) (xy 137.8343 80.9505) (xy 137.834303 80.9505) (xy 138.1657 80.9505) (xy 138.165701 80.950499) + (xy 138.333996 80.931537) (xy 138.494991 80.913398) (xy 138.494994 80.913397) (xy 138.495006 80.913396) + (xy 138.81809 80.839654) (xy 139.130887 80.730202) (xy 139.429461 80.586416) (xy 139.71006 80.410104) + (xy 139.969153 80.203484) (xy 140.203484 79.969153) (xy 140.410104 79.71006) (xy 140.586416 79.429461) + (xy 140.730202 79.130887) (xy 140.839654 78.81809) (xy 140.880022 78.641228) (xy 144.1495 78.641228) + (xy 144.1495 79.358771) (xy 144.182182 79.523074) (xy 144.182184 79.523082) (xy 144.246295 79.67786) + (xy 144.339373 79.817162) (xy 144.457837 79.935626) (xy 144.508013 79.969152) (xy 144.597137 80.028703) + (xy 144.751918 80.092816) (xy 144.916223 80.125498) (xy 144.916228 80.125499) (xy 144.916232 80.1255) + (xy 144.916233 80.1255) (xy 145.083768 80.1255) (xy 145.083769 80.125499) (xy 145.248082 80.092816) + (xy 145.402863 80.028703) (xy 145.542162 79.935626) (xy 145.660626 79.817162) (xy 145.753703 79.677863) + (xy 145.817816 79.523082) (xy 145.8505 79.358767) (xy 145.8505 78.641233) (xy 145.850499 78.641228) + (xy 146.1495 78.641228) (xy 146.1495 79.358771) (xy 146.182182 79.523074) (xy 146.182184 79.523082) + (xy 146.246295 79.67786) (xy 146.339373 79.817162) (xy 146.457837 79.935626) (xy 146.508013 79.969152) + (xy 146.597137 80.028703) (xy 146.751918 80.092816) (xy 146.916223 80.125498) (xy 146.916228 80.125499) + (xy 146.916232 80.1255) (xy 146.916233 80.1255) (xy 147.083768 80.1255) (xy 147.083769 80.125499) + (xy 147.248082 80.092816) (xy 147.402863 80.028703) (xy 147.542162 79.935626) (xy 147.660626 79.817162) + (xy 147.753703 79.677863) (xy 147.817816 79.523082) (xy 147.8505 79.358767) (xy 147.8505 78.641233) + (xy 147.850499 78.641228) (xy 148.1495 78.641228) (xy 148.1495 79.358771) (xy 148.182182 79.523074) + (xy 148.182184 79.523082) (xy 148.246295 79.67786) (xy 148.339373 79.817162) (xy 148.457837 79.935626) + (xy 148.508013 79.969152) (xy 148.597137 80.028703) (xy 148.751918 80.092816) (xy 148.916223 80.125498) + (xy 148.916228 80.125499) (xy 148.916232 80.1255) (xy 148.916233 80.1255) (xy 149.083768 80.1255) + (xy 149.083769 80.125499) (xy 149.248082 80.092816) (xy 149.402863 80.028703) (xy 149.542162 79.935626) + (xy 149.660626 79.817162) (xy 149.753703 79.677863) (xy 149.817816 79.523082) (xy 149.8505 79.358767) + (xy 149.8505 78.641233) (xy 149.850499 78.641228) (xy 150.1495 78.641228) (xy 150.1495 79.358771) + (xy 150.182182 79.523074) (xy 150.182184 79.523082) (xy 150.246295 79.67786) (xy 150.339373 79.817162) + (xy 150.457837 79.935626) (xy 150.594391 80.026868) (xy 150.639196 80.08048) (xy 150.6495 80.12997) + (xy 150.6495 82.046143) (xy 150.673386 82.135287) (xy 150.673387 82.13529) (xy 150.719527 82.215208) + (xy 150.719531 82.215213) (xy 152.613181 84.108863) (xy 152.646666 84.170186) (xy 152.6495 84.196544) + (xy 152.6495 86.87003) (xy 152.629815 86.937069) (xy 152.594391 86.973132) (xy 152.457837 87.064373) + (xy 152.339373 87.182837) (xy 152.246295 87.322139) (xy 152.182184 87.476917) (xy 152.182182 87.476925) + (xy 152.1495 87.641228) (xy 152.1495 88.358771) (xy 152.182182 88.523074) (xy 152.182184 88.523082) + (xy 152.246295 88.67786) (xy 152.339373 88.817162) (xy 152.457837 88.935626) (xy 152.528055 88.982544) + (xy 152.597137 89.028703) (xy 152.751918 89.092816) (xy 152.916223 89.125498) (xy 152.916228 89.125499) + (xy 152.916232 89.1255) (xy 152.916233 89.1255) (xy 153.083768 89.1255) (xy 153.083769 89.125499) + (xy 153.248082 89.092816) (xy 153.402863 89.028703) (xy 153.542162 88.935626) (xy 153.660626 88.817162) + (xy 153.753703 88.677863) (xy 153.817816 88.523082) (xy 153.8505 88.358767) (xy 153.8505 87.641233) + (xy 153.817816 87.476918) (xy 153.755771 87.327129) (xy 153.753704 87.322139) (xy 153.660626 87.182837) + (xy 153.542162 87.064373) (xy 153.405609 86.973132) (xy 153.360804 86.91952) (xy 153.3505 86.87003) + (xy 153.3505 83.953858) (xy 153.3505 83.953856) (xy 153.326614 83.864712) (xy 153.28047 83.784788) + (xy 151.386819 81.891137) (xy 151.353334 81.829814) (xy 151.3505 81.803456) (xy 151.3505 80.12997) + (xy 151.370185 80.062931) (xy 151.405609 80.026868) (xy 151.471942 79.982546) (xy 151.542162 79.935626) + (xy 151.660626 79.817162) (xy 151.753703 79.677863) (xy 151.817816 79.523082) (xy 151.8505 79.358767) + (xy 151.8505 78.641233) (xy 151.850499 78.641228) (xy 152.1495 78.641228) (xy 152.1495 79.358771) + (xy 152.182182 79.523074) (xy 152.182184 79.523082) (xy 152.246295 79.67786) (xy 152.339373 79.817162) + (xy 152.457837 79.935626) (xy 152.508013 79.969152) (xy 152.597137 80.028703) (xy 152.751918 80.092816) + (xy 152.916223 80.125498) (xy 152.916228 80.125499) (xy 152.916232 80.1255) (xy 152.916233 80.1255) + (xy 153.083768 80.1255) (xy 153.083769 80.125499) (xy 153.248082 80.092816) (xy 153.402863 80.028703) + (xy 153.542162 79.935626) (xy 153.660626 79.817162) (xy 153.753703 79.677863) (xy 153.817816 79.523082) + (xy 153.8505 79.358767) (xy 153.8505 78.641233) (xy 153.850499 78.641228) (xy 154.1495 78.641228) + (xy 154.1495 79.358771) (xy 154.182182 79.523074) (xy 154.182184 79.523082) (xy 154.246295 79.67786) + (xy 154.339373 79.817162) (xy 154.457837 79.935626) (xy 154.508013 79.969152) (xy 154.597137 80.028703) + (xy 154.751918 80.092816) (xy 154.916223 80.125498) (xy 154.916228 80.125499) (xy 154.916232 80.1255) + (xy 154.916233 80.1255) (xy 155.083768 80.1255) (xy 155.083769 80.125499) (xy 155.248082 80.092816) + (xy 155.402863 80.028703) (xy 155.542162 79.935626) (xy 155.660626 79.817162) (xy 155.753703 79.677863) + (xy 155.817816 79.523082) (xy 155.8505 79.358767) (xy 155.8505 78.641277) (xy 156.15 78.641277) + (xy 156.15 78.875) (xy 156.645265 78.875) (xy 156.625 78.95063) (xy 156.625 79.04937) (xy 156.645265 79.125) + (xy 156.15 79.125) (xy 156.15 79.358722) (xy 156.182663 79.522928) (xy 156.182665 79.522936) (xy 156.24674 79.677627) + (xy 156.24674 79.677628) (xy 156.339758 79.816839) (xy 156.339764 79.816847) (xy 156.458152 79.935235) + (xy 156.45816 79.935241) (xy 156.597371 80.028259) (xy 156.752063 80.092334) (xy 156.752071 80.092336) + (xy 156.874999 80.116788) (xy 156.875 80.116788) (xy 156.875 79.354734) (xy 156.95063 79.375) (xy 157.04937 79.375) + (xy 157.125 79.354734) (xy 157.125 80.116788) (xy 157.247928 80.092336) (xy 157.247936 80.092334) + (xy 157.402627 80.028259) (xy 157.402628 80.028259) (xy 157.541839 79.935241) (xy 157.541847 79.935235) + (xy 157.660235 79.816847) (xy 157.660241 79.816839) (xy 157.753259 79.677628) (xy 157.753259 79.677627) + (xy 157.817334 79.522936) (xy 157.817336 79.522928) (xy 157.849999 79.358722) (xy 157.85 79.35872) + (xy 157.85 79.125) (xy 157.354735 79.125) (xy 157.375 79.04937) (xy 157.375 78.95063) (xy 157.354735 78.875) + (xy 157.85 78.875) (xy 157.85 78.641279) (xy 157.849999 78.641277) (xy 157.817336 78.477071) (xy 157.817334 78.477063) + (xy 157.773509 78.371259) (xy 157.755232 78.327135) (xy 158.1495 78.327135) (xy 158.1495 79.67287) + (xy 158.149501 79.672876) (xy 158.155908 79.732483) (xy 158.206202 79.867328) (xy 158.206206 79.867335) + (xy 158.292452 79.982544) (xy 158.292455 79.982547) (xy 158.407664 80.068793) (xy 158.407671 80.068797) + (xy 158.542517 80.119091) (xy 158.542516 80.119091) (xy 158.549444 80.119835) (xy 158.602127 80.1255) + (xy 159.397872 80.125499) (xy 159.457483 80.119091) (xy 159.592331 80.068796) (xy 159.707546 79.982546) + (xy 159.793796 79.867331) (xy 159.844091 79.732483) (xy 159.8505 79.672873) (xy 159.850499 78.327128) + (xy 159.844091 78.267517) (xy 159.812507 78.182837) (xy 159.793797 78.132671) (xy 159.793793 78.132664) + (xy 159.707547 78.017455) (xy 159.707544 78.017452) (xy 159.592335 77.931206) (xy 159.592328 77.931202) + (xy 159.457482 77.880908) (xy 159.457483 77.880908) (xy 159.397883 77.874501) (xy 159.397881 77.8745) + (xy 159.397873 77.8745) (xy 159.397864 77.8745) (xy 158.602129 77.8745) (xy 158.602123 77.874501) + (xy 158.542516 77.880908) (xy 158.407671 77.931202) (xy 158.407664 77.931206) (xy 158.292455 78.017452) + (xy 158.292452 78.017455) (xy 158.206206 78.132664) (xy 158.206202 78.132671) (xy 158.155908 78.267517) + (xy 158.150036 78.322139) (xy 158.149501 78.327123) (xy 158.1495 78.327135) (xy 157.755232 78.327135) + (xy 157.753259 78.322372) (xy 157.753259 78.322371) (xy 157.660241 78.18316) (xy 157.660235 78.183152) + (xy 157.541847 78.064764) (xy 157.541839 78.064758) (xy 157.402628 77.97174) (xy 157.247936 77.907665) + (xy 157.24793 77.907663) (xy 157.125 77.88321) (xy 157.125 78.645265) (xy 157.04937 78.625) (xy 156.95063 78.625) + (xy 156.875 78.645265) (xy 156.875 77.883211) (xy 156.874999 77.88321) (xy 156.752069 77.907663) + (xy 156.752063 77.907665) (xy 156.597372 77.97174) (xy 156.597371 77.97174) (xy 156.45816 78.064758) + (xy 156.458152 78.064764) (xy 156.339764 78.183152) (xy 156.339758 78.18316) (xy 156.24674 78.322371) + (xy 156.24674 78.322372) (xy 156.182665 78.477063) (xy 156.182663 78.477071) (xy 156.15 78.641277) + (xy 155.8505 78.641277) (xy 155.8505 78.641233) (xy 155.817816 78.476918) (xy 155.755771 78.327129) + (xy 155.753704 78.322139) (xy 155.660626 78.182837) (xy 155.542162 78.064373) (xy 155.40286 77.971295) + (xy 155.248082 77.907184) (xy 155.248074 77.907182) (xy 155.083771 77.8745) (xy 155.083767 77.8745) + (xy 154.916233 77.8745) (xy 154.916228 77.8745) (xy 154.751925 77.907182) (xy 154.751917 77.907184) + (xy 154.597139 77.971295) (xy 154.457837 78.064373) (xy 154.339373 78.182837) (xy 154.246295 78.322139) + (xy 154.182184 78.476917) (xy 154.182182 78.476925) (xy 154.1495 78.641228) (xy 153.850499 78.641228) + (xy 153.817816 78.476918) (xy 153.755771 78.327129) (xy 153.753704 78.322139) (xy 153.660626 78.182837) + (xy 153.542162 78.064373) (xy 153.40286 77.971295) (xy 153.248082 77.907184) (xy 153.248074 77.907182) + (xy 153.083771 77.8745) (xy 153.083767 77.8745) (xy 152.916233 77.8745) (xy 152.916228 77.8745) + (xy 152.751925 77.907182) (xy 152.751917 77.907184) (xy 152.597139 77.971295) (xy 152.457837 78.064373) + (xy 152.339373 78.182837) (xy 152.246295 78.322139) (xy 152.182184 78.476917) (xy 152.182182 78.476925) + (xy 152.1495 78.641228) (xy 151.850499 78.641228) (xy 151.817816 78.476918) (xy 151.755771 78.327129) + (xy 151.753704 78.322139) (xy 151.660626 78.182837) (xy 151.542162 78.064373) (xy 151.40286 77.971295) + (xy 151.248082 77.907184) (xy 151.248074 77.907182) (xy 151.083771 77.8745) (xy 151.083767 77.8745) + (xy 150.916233 77.8745) (xy 150.916228 77.8745) (xy 150.751925 77.907182) (xy 150.751917 77.907184) + (xy 150.597139 77.971295) (xy 150.457837 78.064373) (xy 150.339373 78.182837) (xy 150.246295 78.322139) + (xy 150.182184 78.476917) (xy 150.182182 78.476925) (xy 150.1495 78.641228) (xy 149.850499 78.641228) + (xy 149.817816 78.476918) (xy 149.755771 78.327129) (xy 149.753704 78.322139) (xy 149.660626 78.182837) + (xy 149.542162 78.064373) (xy 149.40286 77.971295) (xy 149.248082 77.907184) (xy 149.248074 77.907182) + (xy 149.083771 77.8745) (xy 149.083767 77.8745) (xy 148.916233 77.8745) (xy 148.916228 77.8745) + (xy 148.751925 77.907182) (xy 148.751917 77.907184) (xy 148.597139 77.971295) (xy 148.457837 78.064373) + (xy 148.339373 78.182837) (xy 148.246295 78.322139) (xy 148.182184 78.476917) (xy 148.182182 78.476925) + (xy 148.1495 78.641228) (xy 147.850499 78.641228) (xy 147.817816 78.476918) (xy 147.755771 78.327129) + (xy 147.753704 78.322139) (xy 147.660626 78.182837) (xy 147.542162 78.064373) (xy 147.40286 77.971295) + (xy 147.248082 77.907184) (xy 147.248074 77.907182) (xy 147.083771 77.8745) (xy 147.083767 77.8745) + (xy 146.916233 77.8745) (xy 146.916228 77.8745) (xy 146.751925 77.907182) (xy 146.751917 77.907184) + (xy 146.597139 77.971295) (xy 146.457837 78.064373) (xy 146.339373 78.182837) (xy 146.246295 78.322139) + (xy 146.182184 78.476917) (xy 146.182182 78.476925) (xy 146.1495 78.641228) (xy 145.850499 78.641228) + (xy 145.817816 78.476918) (xy 145.755771 78.327129) (xy 145.753704 78.322139) (xy 145.660626 78.182837) + (xy 145.542162 78.064373) (xy 145.40286 77.971295) (xy 145.248082 77.907184) (xy 145.248074 77.907182) + (xy 145.083771 77.8745) (xy 145.083767 77.8745) (xy 144.916233 77.8745) (xy 144.916228 77.8745) + (xy 144.751925 77.907182) (xy 144.751917 77.907184) (xy 144.597139 77.971295) (xy 144.457837 78.064373) + (xy 144.339373 78.182837) (xy 144.246295 78.322139) (xy 144.182184 78.476917) (xy 144.182182 78.476925) + (xy 144.1495 78.641228) (xy 140.880022 78.641228) (xy 140.913396 78.495006) (xy 140.915434 78.476925) + (xy 140.948533 78.183152) (xy 140.9505 78.165697) (xy 140.9505 77.834303) (xy 140.950499 77.834296) + (xy 163.0495 77.834296) (xy 163.0495 78.165703) (xy 163.086601 78.494991) (xy 163.086604 78.495005) + (xy 163.160346 78.818093) (xy 163.160349 78.818101) (xy 163.269799 79.13089) (xy 163.413582 79.429458) + (xy 163.413584 79.429461) (xy 163.589896 79.71006) (xy 163.796516 79.969153) (xy 164.030847 80.203484) + (xy 164.28994 80.410104) (xy 164.570539 80.586416) (xy 164.869113 80.730202) (xy 165.104037 80.812405) + (xy 165.181898 80.83965) (xy 165.181906 80.839653) (xy 165.181909 80.839653) (xy 165.18191 80.839654) + (xy 165.504994 80.913396) (xy 165.505003 80.913397) (xy 165.505008 80.913398) (xy 165.724533 80.938132) + (xy 165.834297 80.950499) (xy 165.8343 80.9505) (xy 165.834303 80.9505) (xy 166.1657 80.9505) (xy 166.165701 80.950499) + (xy 166.333996 80.931537) (xy 166.494991 80.913398) (xy 166.494994 80.913397) (xy 166.495006 80.913396) + (xy 166.81809 80.839654) (xy 167.130887 80.730202) (xy 167.429461 80.586416) (xy 167.71006 80.410104) + (xy 167.969153 80.203484) (xy 168.203484 79.969153) (xy 168.410104 79.71006) (xy 168.586416 79.429461) + (xy 168.730202 79.130887) (xy 168.839654 78.81809) (xy 168.913396 78.495006) (xy 168.915434 78.476925) + (xy 168.948533 78.183152) (xy 168.9505 78.165697) (xy 168.9505 77.834303) (xy 168.913396 77.504994) + (xy 168.839654 77.18191) (xy 168.730202 76.869113) (xy 168.586416 76.570539) (xy 168.410104 76.28994) + (xy 168.203484 76.030847) (xy 167.969153 75.796516) (xy 167.71006 75.589896) (xy 167.429461 75.413584) + (xy 167.429458 75.413582) (xy 167.13089 75.269799) (xy 166.818101 75.160349) (xy 166.818093 75.160346) + (xy 166.575777 75.105039) (xy 166.495006 75.086604) (xy 166.495003 75.086603) (xy 166.494991 75.086601) + (xy 166.165703 75.0495) (xy 166.165697 75.0495) (xy 165.834303 75.0495) (xy 165.834296 75.0495) + (xy 165.505008 75.086601) (xy 165.504994 75.086604) (xy 165.181906 75.160346) (xy 165.181898 75.160349) + (xy 164.869109 75.269799) (xy 164.570541 75.413582) (xy 164.289941 75.589895) (xy 164.030847 75.796515) + (xy 163.796515 76.030847) (xy 163.589895 76.289941) (xy 163.413582 76.570541) (xy 163.269799 76.869109) + (xy 163.160349 77.181898) (xy 163.160346 77.181906) (xy 163.086604 77.504994) (xy 163.086601 77.505008) + (xy 163.0495 77.834296) (xy 140.950499 77.834296) (xy 140.913396 77.504994) (xy 140.839654 77.18191) + (xy 140.730202 76.869113) (xy 140.586416 76.570539) (xy 140.410104 76.28994) (xy 140.203484 76.030847) + (xy 139.969153 75.796516) (xy 139.71006 75.589896) (xy 139.429461 75.413584) (xy 139.429458 75.413582) + (xy 139.13089 75.269799) (xy 138.818101 75.160349) (xy 138.818093 75.160346) (xy 138.575777 75.105039) + (xy 138.495006 75.086604) (xy 138.495003 75.086603) (xy 138.494991 75.086601) (xy 138.165703 75.0495) + (xy 138.165697 75.0495) (xy 137.834303 75.0495) (xy 137.834296 75.0495) (xy 137.505008 75.086601) + (xy 137.504994 75.086604) (xy 137.181906 75.160346) (xy 137.181898 75.160349) (xy 136.869109 75.269799) + (xy 136.570541 75.413582) (xy 136.289941 75.589895) (xy 136.030847 75.796515) (xy 135.796515 76.030847) + (xy 135.589895 76.289941) (xy 135.413582 76.570541) (xy 135.269799 76.869109) (xy 135.160349 77.181898) + (xy 135.160346 77.181906) (xy 135.086604 77.504994) (xy 135.086601 77.505008) (xy 135.0495 77.834296) + (xy 134.5005 77.834296) (xy 134.5005 74.6245) (xy 134.520185 74.557461) (xy 134.572989 74.511706) + (xy 134.6245 74.5005) (xy 169.3755 74.5005) + ) + ) + ) + (embedded_fonts no) +) diff --git a/electronics/EncoderBoard.kicad_pro b/electronics/EncoderBoard.kicad_pro new file mode 100644 index 0000000..9e89390 --- /dev/null +++ b/electronics/EncoderBoard.kicad_pro @@ -0,0 +1,632 @@ +{ + "board": { + "3dviewports": [], + "design_settings": { + "defaults": { + "apply_defaults_to_fp_fields": false, + "apply_defaults_to_fp_shapes": false, + "apply_defaults_to_fp_text": false, + "board_outline_line_width": 0.05, + "copper_line_width": 0.2, + "copper_text_italic": false, + "copper_text_size_h": 1.5, + "copper_text_size_v": 1.5, + "copper_text_thickness": 0.3, + "copper_text_upright": false, + "courtyard_line_width": 0.05, + "dimension_precision": 4, + "dimension_units": 3, + "dimensions": { + "arrow_length": 1270000, + "extension_offset": 500000, + "keep_text_aligned": true, + "suppress_zeroes": true, + "text_position": 0, + "units_format": 0 + }, + "fab_line_width": 0.1, + "fab_text_italic": false, + "fab_text_size_h": 1.0, + "fab_text_size_v": 1.0, + "fab_text_thickness": 0.15, + "fab_text_upright": false, + "other_line_width": 0.1, + "other_text_italic": false, + "other_text_size_h": 1.0, + "other_text_size_v": 1.0, + "other_text_thickness": 0.15, + "other_text_upright": false, + "pads": { + "drill": 0.8, + "height": 1.27, + "width": 2.54 + }, + "silk_line_width": 0.1, + "silk_text_italic": false, + "silk_text_size_h": 1.0, + "silk_text_size_v": 1.0, + "silk_text_thickness": 0.1, + "silk_text_upright": false, + "zones": { + "min_clearance": 0.25 + } + }, + "diff_pair_dimensions": [ + { + "gap": 0.0, + "via_gap": 0.0, + "width": 0.0 + } + ], + "drc_exclusions": [], + "meta": { + "version": 2 + }, + "rule_severities": { + "annular_width": "error", + "clearance": "error", + "connection_width": "warning", + "copper_edge_clearance": "error", + "copper_sliver": "warning", + "courtyards_overlap": "error", + "creepage": "error", + "diff_pair_gap_out_of_range": "error", + "diff_pair_uncoupled_length_too_long": "error", + "drill_out_of_range": "error", + "duplicate_footprints": "warning", + "extra_footprint": "warning", + "footprint": "error", + "footprint_filters_mismatch": "ignore", + "footprint_symbol_mismatch": "warning", + "footprint_type_mismatch": "ignore", + "hole_clearance": "error", + "hole_to_hole": "warning", + "holes_co_located": "warning", + "invalid_outline": "error", + "isolated_copper": "warning", + "item_on_disabled_layer": "error", + "items_not_allowed": "error", + "length_out_of_range": "error", + "lib_footprint_issues": "warning", + "lib_footprint_mismatch": "warning", + "malformed_courtyard": "error", + "microvia_drill_out_of_range": "error", + "mirrored_text_on_front_layer": "warning", + "missing_courtyard": "ignore", + "missing_footprint": "warning", + "net_conflict": "warning", + "nonmirrored_text_on_back_layer": "warning", + "npth_inside_courtyard": "ignore", + "padstack": "warning", + "pth_inside_courtyard": "ignore", + "shorting_items": "error", + "silk_edge_clearance": "warning", + "silk_over_copper": "warning", + "silk_overlap": "warning", + "skew_out_of_range": "error", + "solder_mask_bridge": "error", + "starved_thermal": "error", + "text_height": "warning", + "text_on_edge_cuts": "error", + "text_thickness": "warning", + "through_hole_pad_without_hole": "error", + "too_many_vias": "error", + "track_angle": "error", + "track_dangling": "warning", + "track_segment_length": "error", + "track_width": "error", + "tracks_crossing": "error", + "unconnected_items": "error", + "unresolved_variable": "error", + "via_dangling": "warning", + "zones_intersect": "error" + }, + "rules": { + "max_error": 0.005, + "min_clearance": 0.0, + "min_connection": 0.0, + "min_copper_edge_clearance": 0.5, + "min_groove_width": 0.0, + "min_hole_clearance": 0.25, + "min_hole_to_hole": 0.25, + "min_microvia_diameter": 0.2, + "min_microvia_drill": 0.1, + "min_resolved_spokes": 2, + "min_silk_clearance": 0.0, + "min_text_height": 0.8, + "min_text_thickness": 0.08, + "min_through_hole_diameter": 0.3, + "min_track_width": 0.0, + "min_via_annular_width": 0.1, + "min_via_diameter": 0.5, + "solder_mask_to_copper_clearance": 0.0, + "use_height_for_length_calcs": true + }, + "teardrop_options": [ + { + "td_onpthpad": true, + "td_onroundshapesonly": false, + "td_onsmdpad": true, + "td_ontrackend": false, + "td_onvia": true + } + ], + "teardrop_parameters": [ + { + "td_allow_use_two_tracks": true, + "td_curve_segcount": 0, + "td_height_ratio": 1.0, + "td_length_ratio": 0.5, + "td_maxheight": 2.0, + "td_maxlen": 1.0, + "td_on_pad_in_zone": false, + "td_target_name": "td_round_shape", + "td_width_to_size_filter_ratio": 0.9 + }, + { + "td_allow_use_two_tracks": true, + "td_curve_segcount": 0, + "td_height_ratio": 1.0, + "td_length_ratio": 0.5, + "td_maxheight": 2.0, + "td_maxlen": 1.0, + "td_on_pad_in_zone": false, + "td_target_name": "td_rect_shape", + "td_width_to_size_filter_ratio": 0.9 + }, + { + "td_allow_use_two_tracks": true, + "td_curve_segcount": 0, + "td_height_ratio": 1.0, + "td_length_ratio": 0.5, + "td_maxheight": 2.0, + "td_maxlen": 1.0, + "td_on_pad_in_zone": false, + "td_target_name": "td_track_end", + "td_width_to_size_filter_ratio": 0.9 + } + ], + "track_widths": [ + 0.0 + ], + "tuning_pattern_settings": { + "diff_pair_defaults": { + "corner_radius_percentage": 80, + "corner_style": 1, + "max_amplitude": 1.0, + "min_amplitude": 0.2, + "single_sided": false, + "spacing": 1.0 + }, + "diff_pair_skew_defaults": { + "corner_radius_percentage": 80, + "corner_style": 1, + "max_amplitude": 1.0, + "min_amplitude": 0.2, + "single_sided": false, + "spacing": 0.6 + }, + "single_track_defaults": { + "corner_radius_percentage": 80, + "corner_style": 1, + "max_amplitude": 1.0, + "min_amplitude": 0.2, + "single_sided": false, + "spacing": 0.6 + } + }, + "via_dimensions": [ + { + "diameter": 0.0, + "drill": 0.0 + } + ], + "zones_allow_external_fillets": false + }, + "ipc2581": { + "dist": "", + "distpn": "", + "internal_id": "", + "mfg": "", + "mpn": "" + }, + "layer_pairs": [], + "layer_presets": [], + "viewports": [] + }, + "boards": [], + "cvpcb": { + "equivalence_files": [] + }, + "erc": { + "erc_exclusions": [], + "meta": { + "version": 0 + }, + "pin_map": [ + [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 2, + 0, + 1, + 0, + 0, + 1, + 0, + 2, + 2, + 2, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 2 + ], + [ + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 1, + 1, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2 + ], + [ + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 2 + ], + [ + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 2, + 1, + 2, + 0, + 0, + 1, + 0, + 2, + 2, + 2, + 2 + ], + [ + 0, + 2, + 0, + 1, + 0, + 0, + 1, + 0, + 2, + 0, + 0, + 2 + ], + [ + 0, + 2, + 1, + 1, + 0, + 0, + 1, + 0, + 2, + 0, + 0, + 2 + ], + [ + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2 + ] + ], + "rule_severities": { + "bus_definition_conflict": "error", + "bus_entry_needed": "error", + "bus_to_bus_conflict": "error", + "bus_to_net_conflict": "error", + "different_unit_footprint": "error", + "different_unit_net": "error", + "duplicate_reference": "error", + "duplicate_sheet_names": "error", + "endpoint_off_grid": "warning", + "extra_units": "error", + "footprint_filter": "ignore", + "footprint_link_issues": "warning", + "four_way_junction": "ignore", + "global_label_dangling": "warning", + "hier_label_mismatch": "error", + "label_dangling": "error", + "label_multiple_wires": "warning", + "lib_symbol_issues": "warning", + "lib_symbol_mismatch": "warning", + "missing_bidi_pin": "warning", + "missing_input_pin": "warning", + "missing_power_pin": "error", + "missing_unit": "warning", + "multiple_net_names": "warning", + "net_not_bus_member": "warning", + "no_connect_connected": "warning", + "no_connect_dangling": "warning", + "pin_not_connected": "error", + "pin_not_driven": "error", + "pin_to_pin": "warning", + "power_pin_not_driven": "error", + "same_local_global_label": "warning", + "similar_label_and_power": "warning", + "similar_labels": "warning", + "similar_power": "warning", + "simulation_model_issue": "ignore", + "single_global_label": "ignore", + "unannotated": "error", + "unconnected_wire_endpoint": "warning", + "undefined_netclass": "error", + "unit_value_mismatch": "error", + "unresolved_variable": "error", + "wire_dangling": "error" + } + }, + "libraries": { + "pinned_footprint_libs": [], + "pinned_symbol_libs": [] + }, + "meta": { + "filename": "EncoderBoard.kicad_pro", + "version": 3 + }, + "net_settings": { + "classes": [ + { + "bus_width": 12, + "clearance": 0.2, + "diff_pair_gap": 0.25, + "diff_pair_via_gap": 0.25, + "diff_pair_width": 0.2, + "line_style": 0, + "microvia_diameter": 0.3, + "microvia_drill": 0.1, + "name": "Default", + "pcb_color": "rgba(0, 0, 0, 0.000)", + "priority": 2147483647, + "schematic_color": "rgba(0, 0, 0, 0.000)", + "track_width": 0.2, + "via_diameter": 0.6, + "via_drill": 0.3, + "wire_width": 6 + } + ], + "meta": { + "version": 4 + }, + "net_colors": null, + "netclass_assignments": null, + "netclass_patterns": [] + }, + "pcbnew": { + "last_paths": { + "gencad": "", + "idf": "", + "netlist": "", + "plot": "encoder-gerber", + "pos_files": "", + "specctra_dsn": "", + "step": "", + "svg": "", + "vrml": "" + }, + "page_layout_descr_file": "" + }, + "schematic": { + "annotate_start_num": 0, + "bom_export_filename": "${PROJECTNAME}.csv", + "bom_fmt_presets": [], + "bom_fmt_settings": { + "field_delimiter": ",", + "keep_line_breaks": false, + "keep_tabs": false, + "name": "CSV", + "ref_delimiter": ",", + "ref_range_delimiter": "", + "string_delimiter": "\"" + }, + "bom_presets": [], + "bom_settings": { + "exclude_dnp": false, + "fields_ordered": [ + { + "group_by": false, + "label": "Reference", + "name": "Reference", + "show": true + }, + { + "group_by": false, + "label": "Qty", + "name": "${QUANTITY}", + "show": true + }, + { + "group_by": true, + "label": "Value", + "name": "Value", + "show": true + }, + { + "group_by": true, + "label": "DNP", + "name": "${DNP}", + "show": true + }, + { + "group_by": true, + "label": "Exclude from BOM", + "name": "${EXCLUDE_FROM_BOM}", + "show": true + }, + { + "group_by": true, + "label": "Exclude from Board", + "name": "${EXCLUDE_FROM_BOARD}", + "show": true + }, + { + "group_by": true, + "label": "Footprint", + "name": "Footprint", + "show": true + }, + { + "group_by": false, + "label": "Datasheet", + "name": "Datasheet", + "show": true + } + ], + "filter_string": "", + "group_symbols": true, + "include_excluded_from_bom": true, + "name": "Default Editing", + "sort_asc": true, + "sort_field": "Reference" + }, + "connection_grid_size": 50.0, + "drawing": { + "dashed_lines_dash_length_ratio": 12.0, + "dashed_lines_gap_length_ratio": 3.0, + "default_line_thickness": 6.0, + "default_text_size": 50.0, + "field_names": [], + "intersheets_ref_own_page": false, + "intersheets_ref_prefix": "", + "intersheets_ref_short": false, + "intersheets_ref_show": false, + "intersheets_ref_suffix": "", + "junction_size_choice": 3, + "label_size_ratio": 0.375, + "operating_point_overlay_i_precision": 3, + "operating_point_overlay_i_range": "~A", + "operating_point_overlay_v_precision": 3, + "operating_point_overlay_v_range": "~V", + "overbar_offset_ratio": 1.23, + "pin_symbol_size": 25.0, + "text_offset_ratio": 0.15 + }, + "legacy_lib_dir": "", + "legacy_lib_list": [], + "meta": { + "version": 1 + }, + "net_format_name": "", + "page_layout_descr_file": "", + "plot_directory": "", + "space_save_all_events": true, + "spice_current_sheet_as_root": false, + "spice_external_command": "spice \"%I\"", + "spice_model_current_sheet_as_root": true, + "spice_save_all_currents": false, + "spice_save_all_dissipations": false, + "spice_save_all_voltages": false, + "subpart_first_id": 65, + "subpart_id_separator": 0 + }, + "sheets": [ + [ + "76a3543d-18d5-494b-9749-b3ee4fa138fc", + "Root" + ] + ], + "text_variables": {} +} diff --git a/electronics/EncoderBoard.kicad_sch b/electronics/EncoderBoard.kicad_sch new file mode 100644 index 0000000..85f2ddb --- /dev/null +++ b/electronics/EncoderBoard.kicad_sch @@ -0,0 +1,2768 @@ +(kicad_sch + (version 20250114) + (generator "eeschema") + (generator_version "9.0") + (uuid "76a3543d-18d5-494b-9749-b3ee4fa138fc") + (paper "A4") + (lib_symbols + (symbol "Connector:Conn_01x06_Pin" + (pin_names + (offset 1.016) + (hide yes) + ) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (property "Reference" "J" + (at 0 7.62 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Value" "Conn_01x06_Pin" + (at 0 -10.16 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "~" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Generic connector, single row, 01x06, script generated" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "ki_locked" "" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_keywords" "connector" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "ki_fp_filters" "Connector*:*_1x??_*" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (symbol "Conn_01x06_Pin_1_1" + (rectangle + (start 0.8636 5.207) + (end 0 4.953) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type outline) + ) + ) + (rectangle + (start 0.8636 2.667) + (end 0 2.413) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type outline) + ) + ) + (rectangle + (start 0.8636 0.127) + (end 0 -0.127) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type outline) + ) + ) + (rectangle + (start 0.8636 -2.413) + (end 0 -2.667) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type outline) + ) + ) + (rectangle + (start 0.8636 -4.953) + (end 0 -5.207) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type outline) + ) + ) + (rectangle + (start 0.8636 -7.493) + (end 0 -7.747) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type outline) + ) + ) + (polyline + (pts + (xy 1.27 5.08) (xy 0.8636 5.08) + ) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 1.27 2.54) (xy 0.8636 2.54) + ) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 1.27 0) (xy 0.8636 0) + ) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 1.27 -2.54) (xy 0.8636 -2.54) + ) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 1.27 -5.08) (xy 0.8636 -5.08) + ) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 1.27 -7.62) (xy 0.8636 -7.62) + ) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type none) + ) + ) + (pin passive line + (at 5.08 5.08 180) + (length 3.81) + (name "Pin_1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 5.08 2.54 180) + (length 3.81) + (name "Pin_2" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "2" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 5.08 0 180) + (length 3.81) + (name "Pin_3" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "3" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 5.08 -2.54 180) + (length 3.81) + (name "Pin_4" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "4" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 5.08 -5.08 180) + (length 3.81) + (name "Pin_5" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "5" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 5.08 -7.62 180) + (length 3.81) + (name "Pin_6" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "6" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + ) + (embedded_fonts no) + ) + (symbol "Connector:Conn_01x08_Pin" + (pin_names + (offset 1.016) + (hide yes) + ) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (property "Reference" "J" + (at 0 10.16 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Value" "Conn_01x08_Pin" + (at 0 -12.7 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "~" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Generic connector, single row, 01x08, script generated" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "ki_locked" "" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_keywords" "connector" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "ki_fp_filters" "Connector*:*_1x??_*" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (symbol "Conn_01x08_Pin_1_1" + (rectangle + (start 0.8636 7.747) + (end 0 7.493) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type outline) + ) + ) + (rectangle + (start 0.8636 5.207) + (end 0 4.953) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type outline) + ) + ) + (rectangle + (start 0.8636 2.667) + (end 0 2.413) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type outline) + ) + ) + (rectangle + (start 0.8636 0.127) + (end 0 -0.127) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type outline) + ) + ) + (rectangle + (start 0.8636 -2.413) + (end 0 -2.667) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type outline) + ) + ) + (rectangle + (start 0.8636 -4.953) + (end 0 -5.207) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type outline) + ) + ) + (rectangle + (start 0.8636 -7.493) + (end 0 -7.747) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type outline) + ) + ) + (rectangle + (start 0.8636 -10.033) + (end 0 -10.287) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type outline) + ) + ) + (polyline + (pts + (xy 1.27 7.62) (xy 0.8636 7.62) + ) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 1.27 5.08) (xy 0.8636 5.08) + ) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 1.27 2.54) (xy 0.8636 2.54) + ) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 1.27 0) (xy 0.8636 0) + ) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 1.27 -2.54) (xy 0.8636 -2.54) + ) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 1.27 -5.08) (xy 0.8636 -5.08) + ) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 1.27 -7.62) (xy 0.8636 -7.62) + ) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 1.27 -10.16) (xy 0.8636 -10.16) + ) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type none) + ) + ) + (pin passive line + (at 5.08 7.62 180) + (length 3.81) + (name "Pin_1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 5.08 5.08 180) + (length 3.81) + (name "Pin_2" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "2" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 5.08 2.54 180) + (length 3.81) + (name "Pin_3" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "3" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 5.08 0 180) + (length 3.81) + (name "Pin_4" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "4" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 5.08 -2.54 180) + (length 3.81) + (name "Pin_5" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "5" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 5.08 -5.08 180) + (length 3.81) + (name "Pin_6" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "6" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 5.08 -7.62 180) + (length 3.81) + (name "Pin_7" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "7" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 5.08 -10.16 180) + (length 3.81) + (name "Pin_8" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "8" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + ) + (embedded_fonts no) + ) + (symbol "Mechanical:MountingHole_Pad" + (pin_numbers + (hide yes) + ) + (pin_names + (offset 1.016) + (hide yes) + ) + (exclude_from_sim no) + (in_bom no) + (on_board yes) + (property "Reference" "H" + (at 0 6.35 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Value" "MountingHole_Pad" + (at 0 4.445 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "~" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Mounting Hole with connection" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "ki_keywords" "mounting hole" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "ki_fp_filters" "MountingHole*Pad*" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (symbol "MountingHole_Pad_0_1" + (circle + (center 0 1.27) + (radius 1.27) + (stroke + (width 1.27) + (type default) + ) + (fill + (type none) + ) + ) + ) + (symbol "MountingHole_Pad_1_1" + (pin input line + (at 0 -2.54 90) + (length 2.54) + (name "1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + ) + (embedded_fonts no) + ) + (symbol "power:+3.3V" + (power) + (pin_numbers + (hide yes) + ) + (pin_names + (offset 0) + (hide yes) + ) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (property "Reference" "#PWR" + (at 0 -3.81 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Value" "+3.3V" + (at 0 3.556 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Power symbol creates a global label with name \"+3.3V\"" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "ki_keywords" "global power" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (symbol "+3.3V_0_1" + (polyline + (pts + (xy -0.762 1.27) (xy 0 2.54) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 0 2.54) (xy 0.762 1.27) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 0 0) (xy 0 2.54) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + ) + (symbol "+3.3V_1_1" + (pin power_in line + (at 0 0 90) + (length 0) + (name "~" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + ) + (embedded_fonts no) + ) + (symbol "power:GND" + (power) + (pin_numbers + (hide yes) + ) + (pin_names + (offset 0) + (hide yes) + ) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (property "Reference" "#PWR" + (at 0 -6.35 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Value" "GND" + (at 0 -3.81 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Power symbol creates a global label with name \"GND\" , ground" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "ki_keywords" "global power" + (at 0 0 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (symbol "GND_0_1" + (polyline + (pts + (xy 0 0) (xy 0 -1.27) (xy 1.27 -1.27) (xy 0 -2.54) (xy -1.27 -1.27) (xy 0 -1.27) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + ) + (symbol "GND_1_1" + (pin power_in line + (at 0 0 270) + (length 0) + (name "~" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + ) + (embedded_fonts no) + ) + ) + (text "VCC" + (exclude_from_sim no) + (at 160.274 116.078 0) + (effects + (font + (size 1.27 1.27) + ) + ) + (uuid "1bb07c6f-06ea-4d9a-84e5-035c40fa97ba") + ) + (text "CS" + (exclude_from_sim no) + (at 159.512 80.518 0) + (effects + (font + (size 1.27 1.27) + ) + ) + (uuid "298ca554-133e-4f76-9bf6-6b15d729c2db") + ) + (text "Encoder 2" + (exclude_from_sim no) + (at 192.786 100.33 0) + (effects + (font + (size 1.778 1.778) + (thickness 0.3048) + (bold yes) + ) + ) + (uuid "39f54b9b-7b2e-4d27-9d9f-b118a775e90d") + ) + (text "CLK" + (exclude_from_sim no) + (at 160.02 100.838 0) + (effects + (font + (size 1.27 1.27) + ) + ) + (uuid "4cbe38da-e541-4897-b7ab-cb9901881c6f") + ) + (text "MISO" + (exclude_from_sim no) + (at 160.782 118.618 0) + (effects + (font + (size 1.27 1.27) + ) + ) + (uuid "4e6b843c-f2fa-4cd6-84fe-c214e6388c8c") + ) + (text "VCC" + (exclude_from_sim no) + (at 160.274 93.218 0) + (effects + (font + (size 1.27 1.27) + ) + ) + (uuid "5031b042-128f-4959-b684-7b214a0d9529") + ) + (text "CS" + (exclude_from_sim no) + (at 159.512 103.378 0) + (effects + (font + (size 1.27 1.27) + ) + ) + (uuid "567d2caf-414a-46ee-9c55-babe5aa5250e") + ) + (text "VCC" + (exclude_from_sim no) + (at 160.274 70.358 0) + (effects + (font + (size 1.27 1.27) + ) + ) + (uuid "5f2d8f78-9acc-42d1-ab7e-08ffd3a71099") + ) + (text "To Control Board J4" + (exclude_from_sim no) + (at 68.834 89.154 0) + (effects + (font + (size 1.778 1.778) + (thickness 0.3556) + (bold yes) + ) + ) + (uuid "773f6503-9d74-436f-8ed8-54864fb352fe") + ) + (text "MOSI" + (exclude_from_sim no) + (at 160.782 75.438 0) + (effects + (font + (size 1.27 1.27) + ) + ) + (uuid "7807abdc-8701-40cf-8b04-c77db8807c23") + ) + (text "Encoder 3" + (exclude_from_sim no) + (at 192.532 123.444 0) + (effects + (font + (size 1.778 1.778) + (thickness 0.3556) + (bold yes) + ) + ) + (uuid "8310ec4e-51d8-4ca1-8a46-2aacfcdf3200") + ) + (text "SPI breakout board to encoders" + (exclude_from_sim no) + (at 149.606 36.83 0) + (effects + (font + (size 3.048 3.048) + (thickness 0.6096) + (bold yes) + ) + ) + (uuid "8746ab45-ed58-4b22-b412-ef09356b1e0a") + ) + (text "MOSI" + (exclude_from_sim no) + (at 160.782 121.158 0) + (effects + (font + (size 1.27 1.27) + ) + ) + (uuid "937e374b-9459-4dd5-92e3-bd6d65d12a30") + ) + (text "MOSI" + (exclude_from_sim no) + (at 160.782 98.298 0) + (effects + (font + (size 1.27 1.27) + ) + ) + (uuid "9b2b328b-5ae7-4dbb-8de9-3f8ea66ab048") + ) + (text "GND" + (exclude_from_sim no) + (at 160.274 128.778 0) + (effects + (font + (size 1.27 1.27) + ) + ) + (uuid "9caf8091-03cd-4dba-9da4-cf223c6fbe9f") + ) + (text "GND" + (exclude_from_sim no) + (at 160.274 83.058 0) + (effects + (font + (size 1.27 1.27) + ) + ) + (uuid "9d233b0c-76f4-423c-8fcc-f64cd5f82e9f") + ) + (text "CLK" + (exclude_from_sim no) + (at 160.02 123.698 0) + (effects + (font + (size 1.27 1.27) + ) + ) + (uuid "a5f1a788-57f9-485d-a7c2-bf2e9e32fc5c") + ) + (text "Encoder 1" + (exclude_from_sim no) + (at 192.278 78.486 0) + (effects + (font + (size 1.778 1.778) + (thickness 0.3556) + (bold yes) + ) + ) + (uuid "bb0a66b0-eec4-4ca0-8758-bd84b935575e") + ) + (text "CS" + (exclude_from_sim no) + (at 159.512 126.238 0) + (effects + (font + (size 1.27 1.27) + ) + ) + (uuid "c59688a0-b6c1-486c-9764-89a908414f13") + ) + (text "CLK" + (exclude_from_sim no) + (at 160.02 77.978 0) + (effects + (font + (size 1.27 1.27) + ) + ) + (uuid "cdf764b0-d89d-4c49-a975-ab281572abe7") + ) + (text "GND" + (exclude_from_sim no) + (at 160.274 105.918 0) + (effects + (font + (size 1.27 1.27) + ) + ) + (uuid "d68820e6-0048-497e-9cbd-3b3b7819ca50") + ) + (text "MISO" + (exclude_from_sim no) + (at 160.782 72.898 0) + (effects + (font + (size 1.27 1.27) + ) + ) + (uuid "eda33ac5-708c-4bc1-a8f6-4c56a68a51d3") + ) + (text "MISO" + (exclude_from_sim no) + (at 160.782 95.758 0) + (effects + (font + (size 1.27 1.27) + ) + ) + (uuid "fe4941b7-f0cd-4604-bf34-c27997aa70f2") + ) + (junction + (at 154.94 71.12) + (diameter 0) + (color 0 0 0 0) + (uuid "1d1eacdc-ed7a-45a0-bdfc-c979002cd8c5") + ) + (junction + (at 152.4 129.54) + (diameter 0) + (color 0 0 0 0) + (uuid "6dc1e908-ff9a-4d77-a279-d32a57bf0d91") + ) + (junction + (at 154.94 93.98) + (diameter 0) + (color 0 0 0 0) + (uuid "82659984-1e26-4be5-b679-d32d0ff3c1ff") + ) + (junction + (at 135.89 90.17) + (diameter 0) + (color 0 0 0 0) + (uuid "8d53174b-a601-40b5-ba5f-d4139cea80c4") + ) + (junction + (at 152.4 106.68) + (diameter 0) + (color 0 0 0 0) + (uuid "b88b04f4-e05d-4be6-bef7-72daf5c3ac86") + ) + (junction + (at 138.43 92.71) + (diameter 0) + (color 0 0 0 0) + (uuid "cf063800-507e-43f4-9f98-29f9c9de44f5") + ) + (junction + (at 140.97 101.6) + (diameter 0) + (color 0 0 0 0) + (uuid "df8527de-130f-4961-968f-db596339abf5") + ) + (junction + (at 138.43 99.06) + (diameter 0) + (color 0 0 0 0) + (uuid "e9b8afe7-7279-4ca7-8105-55b7a4bed4d6") + ) + (junction + (at 140.97 87.63) + (diameter 0) + (color 0 0 0 0) + (uuid "f1731c96-eb27-4360-be65-035414c5b44d") + ) + (junction + (at 135.89 96.52) + (diameter 0) + (color 0 0 0 0) + (uuid "f4c1264a-d129-4046-bdc5-25723caa121f") + ) + (wire + (pts + (xy 140.97 87.63) (xy 140.97 101.6) + ) + (stroke + (width 0) + (type default) + ) + (uuid "042adc26-4540-407b-9cb4-94760e1dcbeb") + ) + (wire + (pts + (xy 154.94 71.12) (xy 165.1 71.12) + ) + (stroke + (width 0) + (type default) + ) + (uuid "0b14b34a-9abb-482a-a9c8-095af63759e3") + ) + (wire + (pts + (xy 165.1 116.84) (xy 154.94 116.84) + ) + (stroke + (width 0) + (type default) + ) + (uuid "1ba37629-a0f0-4d4b-9afb-3bc54848a82f") + ) + (wire + (pts + (xy 106.68 85.09) (xy 148.59 85.09) + ) + (stroke + (width 0) + (type default) + ) + (uuid "1d783ea9-da73-4048-856a-a9b336bd34f3") + ) + (wire + (pts + (xy 152.4 106.68) (xy 152.4 129.54) + ) + (stroke + (width 0) + (type default) + ) + (uuid "20189509-122c-406f-8506-2ace77fa3199") + ) + (wire + (pts + (xy 106.68 87.63) (xy 140.97 87.63) + ) + (stroke + (width 0) + (type default) + ) + (uuid "22a79bea-2d41-451e-80f3-3df64e284a94") + ) + (wire + (pts + (xy 106.68 95.25) (xy 110.49 95.25) + ) + (stroke + (width 0) + (type default) + ) + (uuid "22b75abe-a7f7-4dbb-b6c4-25ed9edc6198") + ) + (wire + (pts + (xy 146.05 82.55) (xy 146.05 104.14) + ) + (stroke + (width 0) + (type default) + ) + (uuid "28b2e0b3-06c4-444a-b76c-f6c8a1be1015") + ) + (wire + (pts + (xy 135.89 90.17) (xy 135.89 96.52) + ) + (stroke + (width 0) + (type default) + ) + (uuid "2b82d8f1-96f0-45bc-8036-cf753220e074") + ) + (wire + (pts + (xy 135.89 73.66) (xy 165.1 73.66) + ) + (stroke + (width 0) + (type default) + ) + (uuid "2d6e471a-6ce4-4a99-8c30-731945fe09af") + ) + (wire + (pts + (xy 148.59 85.09) (xy 148.59 81.28) + ) + (stroke + (width 0) + (type default) + ) + (uuid "2f4d0d9a-8d37-40e0-b9c2-78d867fc583a") + ) + (wire + (pts + (xy 110.49 97.79) (xy 110.49 101.6) + ) + (stroke + (width 0) + (type default) + ) + (uuid "34ab467c-b416-4b51-bbe0-29d9b6d2f837") + ) + (wire + (pts + (xy 154.94 71.12) (xy 154.94 64.77) + ) + (stroke + (width 0) + (type default) + ) + (uuid "3b0025d8-618d-4278-ab51-1cfcc30bfd3c") + ) + (wire + (pts + (xy 152.4 129.54) (xy 152.4 133.35) + ) + (stroke + (width 0) + (type default) + ) + (uuid "3c02fe87-fe23-4590-beaf-109519f05f41") + ) + (wire + (pts + (xy 135.89 96.52) (xy 135.89 119.38) + ) + (stroke + (width 0) + (type default) + ) + (uuid "3fd6c09b-1fd3-4c17-97eb-1b681e6ec94c") + ) + (wire + (pts + (xy 154.94 116.84) (xy 154.94 93.98) + ) + (stroke + (width 0) + (type default) + ) + (uuid "4657fecf-3d0d-449e-a8f5-88f8bc4c20f2") + ) + (wire + (pts + (xy 135.89 96.52) (xy 165.1 96.52) + ) + (stroke + (width 0) + (type default) + ) + (uuid "47653d82-ae22-4739-97fb-92a40c153ecc") + ) + (wire + (pts + (xy 106.68 92.71) (xy 138.43 92.71) + ) + (stroke + (width 0) + (type default) + ) + (uuid "516f4b97-8bdc-4426-9a77-017b56c6578b") + ) + (wire + (pts + (xy 152.4 106.68) (xy 165.1 106.68) + ) + (stroke + (width 0) + (type default) + ) + (uuid "528c91e7-5a2a-49f9-80d1-e72647231e3b") + ) + (wire + (pts + (xy 138.43 99.06) (xy 165.1 99.06) + ) + (stroke + (width 0) + (type default) + ) + (uuid "579b9fa3-a9d2-4c52-bbb6-ae2bb582992b") + ) + (wire + (pts + (xy 154.94 93.98) (xy 165.1 93.98) + ) + (stroke + (width 0) + (type default) + ) + (uuid "64aa2c0c-a98d-456d-80b1-79cfbcdfaaf1") + ) + (wire + (pts + (xy 165.1 83.82) (xy 152.4 83.82) + ) + (stroke + (width 0) + (type default) + ) + (uuid "6a21344b-f46d-4459-90e0-33d12d4d9e4b") + ) + (wire + (pts + (xy 152.4 129.54) (xy 165.1 129.54) + ) + (stroke + (width 0) + (type default) + ) + (uuid "6c6202da-7abb-477a-b1ad-dc8e70a2c477") + ) + (wire + (pts + (xy 135.89 90.17) (xy 135.89 73.66) + ) + (stroke + (width 0) + (type default) + ) + (uuid "72d6d89d-9c9f-40f9-a2af-545e5567542d") + ) + (wire + (pts + (xy 143.51 80.01) (xy 143.51 127) + ) + (stroke + (width 0) + (type default) + ) + (uuid "7fe5c89f-db6c-4305-a3a2-5f3b530e3d04") + ) + (wire + (pts + (xy 152.4 83.82) (xy 152.4 106.68) + ) + (stroke + (width 0) + (type default) + ) + (uuid "8498306b-0923-4bf2-9f2e-507c69d965b1") + ) + (wire + (pts + (xy 106.68 80.01) (xy 143.51 80.01) + ) + (stroke + (width 0) + (type default) + ) + (uuid "858240db-1790-4484-ab2f-1dcc7d232ba5") + ) + (wire + (pts + (xy 110.49 95.25) (xy 110.49 73.66) + ) + (stroke + (width 0) + (type default) + ) + (uuid "863577c2-5188-4b09-9bd8-81e41d21c927") + ) + (wire + (pts + (xy 140.97 87.63) (xy 140.97 78.74) + ) + (stroke + (width 0) + (type default) + ) + (uuid "895ca900-78d2-4002-b6db-c90e46cd38f4") + ) + (wire + (pts + (xy 138.43 92.71) (xy 138.43 76.2) + ) + (stroke + (width 0) + (type default) + ) + (uuid "89623538-c25f-4def-9f53-032ed4482d0d") + ) + (wire + (pts + (xy 143.51 127) (xy 165.1 127) + ) + (stroke + (width 0) + (type default) + ) + (uuid "8c06b70f-ac18-43b8-a990-29b514b0c227") + ) + (wire + (pts + (xy 140.97 124.46) (xy 165.1 124.46) + ) + (stroke + (width 0) + (type default) + ) + (uuid "91548c94-e0b5-4f78-b2db-6503d2560b51") + ) + (wire + (pts + (xy 106.68 82.55) (xy 146.05 82.55) + ) + (stroke + (width 0) + (type default) + ) + (uuid "a19fb925-792a-4c9c-9aac-a5e7fdff059c") + ) + (wire + (pts + (xy 138.43 99.06) (xy 138.43 121.92) + ) + (stroke + (width 0) + (type default) + ) + (uuid "a4b5ca0e-c23a-4127-8b2d-d015f1a17b49") + ) + (wire + (pts + (xy 106.68 97.79) (xy 110.49 97.79) + ) + (stroke + (width 0) + (type default) + ) + (uuid "af50aef1-599c-4cbb-b041-cac2d192008f") + ) + (wire + (pts + (xy 154.94 93.98) (xy 154.94 71.12) + ) + (stroke + (width 0) + (type default) + ) + (uuid "c4484222-a454-469f-b90f-3afa24b29185") + ) + (wire + (pts + (xy 146.05 104.14) (xy 165.1 104.14) + ) + (stroke + (width 0) + (type default) + ) + (uuid "c8e25b8f-a631-4e05-88e0-00a1c44b2b30") + ) + (wire + (pts + (xy 140.97 101.6) (xy 140.97 124.46) + ) + (stroke + (width 0) + (type default) + ) + (uuid "cc312df5-302b-42da-a153-f2956431dd9d") + ) + (wire + (pts + (xy 138.43 76.2) (xy 165.1 76.2) + ) + (stroke + (width 0) + (type default) + ) + (uuid "d9c4b4e7-5dac-4006-9d15-e16798b916b4") + ) + (wire + (pts + (xy 148.59 81.28) (xy 165.1 81.28) + ) + (stroke + (width 0) + (type default) + ) + (uuid "e13ad928-16ef-4835-b32b-dfec454a297e") + ) + (wire + (pts + (xy 135.89 119.38) (xy 165.1 119.38) + ) + (stroke + (width 0) + (type default) + ) + (uuid "eeb9213e-152a-45c1-a9fc-c2d89b41b448") + ) + (wire + (pts + (xy 106.68 90.17) (xy 135.89 90.17) + ) + (stroke + (width 0) + (type default) + ) + (uuid "f0dea039-2c2f-403a-afd6-8df9fd1c97bb") + ) + (wire + (pts + (xy 140.97 101.6) (xy 165.1 101.6) + ) + (stroke + (width 0) + (type default) + ) + (uuid "f1afb02d-ef52-4c4d-98b9-d6a2b83d2e47") + ) + (wire + (pts + (xy 140.97 78.74) (xy 165.1 78.74) + ) + (stroke + (width 0) + (type default) + ) + (uuid "f3123061-029d-442c-b416-9657d5d8d5ae") + ) + (wire + (pts + (xy 138.43 92.71) (xy 138.43 99.06) + ) + (stroke + (width 0) + (type default) + ) + (uuid "f72ba828-ee9e-4089-bc87-6e8dd091e860") + ) + (wire + (pts + (xy 138.43 121.92) (xy 165.1 121.92) + ) + (stroke + (width 0) + (type default) + ) + (uuid "febc638a-999e-425d-890a-b2058e3276a4") + ) + (label "Encoder_MOSI" + (at 111.76 92.71 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left bottom) + ) + (uuid "06b38bc1-7670-4197-aa7e-ea57f7c7d4e4") + ) + (label "Encoder_MISO" + (at 111.76 90.17 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left bottom) + ) + (uuid "18bcf869-fda7-4874-8ba3-3a56420bc1a4") + ) + (label "Encoder1_CS" + (at 111.76 85.09 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left bottom) + ) + (uuid "2998987c-c79b-4c1d-b6d5-06165490f08c") + ) + (label "Encoder2_CS" + (at 111.76 82.55 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left bottom) + ) + (uuid "5a6bd8b4-7bcf-45c4-9826-c64181341cca") + ) + (label "Encoder_SCK" + (at 111.76 87.63 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left bottom) + ) + (uuid "7cc49152-ac6a-40ec-a9ba-33d2223f5424") + ) + (label "Encoder3_CS" + (at 111.76 80.01 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left bottom) + ) + (uuid "8f0bd8ff-90bd-4245-a60a-3cd90ecc5503") + ) + (symbol + (lib_id "Connector:Conn_01x08_Pin") + (at 101.6 90.17 0) + (mirror x) + (unit 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (dnp no) + (uuid "06f6d8de-1779-48c3-8896-175e2062e7dc") + (property "Reference" "J4" + (at 96.774 89.408 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Value" "Conn_01x08_Pin" + (at 85.09 88.9 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Footprint" "Connector_JST:JST_PH_B8B-PH-K_1x08_P2.00mm_Vertical" + (at 101.6 90.17 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "~" + (at 101.6 90.17 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Generic connector, single row, 01x08, script generated" + (at 101.6 90.17 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (pin "2" + (uuid "8c470e94-b1ad-40f9-9fd6-dce19e7497dd") + ) + (pin "4" + (uuid "9cd17f7e-c9b8-4367-bf44-3b1b1f2e9392") + ) + (pin "3" + (uuid "ea5932f8-5f7d-40d7-8bbe-b5066f449cfa") + ) + (pin "6" + (uuid "b859f592-4fa9-4bb5-bad0-1a1848e1a6b1") + ) + (pin "7" + (uuid "94434742-c0b6-42c2-b718-778191b22ac1") + ) + (pin "5" + (uuid "513114a5-6036-4fbf-aa9f-6e74937bdb66") + ) + (pin "8" + (uuid "6e18ab41-b09a-40b2-be6f-60ace2b91482") + ) + (pin "1" + (uuid "3c497e05-6b29-4244-bd78-6e3ca85ec230") + ) + (instances + (project "" + (path "/76a3543d-18d5-494b-9749-b3ee4fa138fc" + (reference "J4") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Connector:Conn_01x06_Pin") + (at 170.18 124.46 180) + (unit 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (dnp no) + (uuid "24e02eae-0658-4b1e-b654-f9323214dc85") + (property "Reference" "J3" + (at 173.482 123.19 0) + (effects + (font + (size 1.27 1.27) + ) + (justify right) + ) + ) + (property "Value" "Conn_01x06_Pin" + (at 171.45 124.4599 0) + (effects + (font + (size 1.27 1.27) + ) + (justify right) + (hide yes) + ) + ) + (property "Footprint" "Connector_JST:JST_PH_B6B-PH-K_1x06_P2.00mm_Vertical" + (at 170.18 124.46 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "~" + (at 170.18 124.46 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Generic connector, single row, 01x06, script generated" + (at 170.18 124.46 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (pin "5" + (uuid "3021cd0e-611b-472b-8738-47cac0c6eb44") + ) + (pin "2" + (uuid "98c58e24-e96b-4a2a-9d54-fb66e92b06f5") + ) + (pin "1" + (uuid "10360949-d8c6-4786-bb92-ede2587a3d8e") + ) + (pin "6" + (uuid "3aa8c183-59f2-4bc1-9016-4e8735678802") + ) + (pin "4" + (uuid "55414990-e9ab-4c11-9c05-818c9362e8ad") + ) + (pin "3" + (uuid "860496b3-2160-4049-b813-cae493040872") + ) + (instances + (project "" + (path "/76a3543d-18d5-494b-9749-b3ee4fa138fc" + (reference "J3") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Connector:Conn_01x06_Pin") + (at 170.18 78.74 180) + (unit 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (dnp no) + (uuid "35afe6a0-7425-418f-9adc-7b693ee639d5") + (property "Reference" "J1" + (at 173.482 77.978 0) + (effects + (font + (size 1.27 1.27) + ) + (justify right) + ) + ) + (property "Value" "Conn_01x06_Pin" + (at 171.45 78.7399 0) + (effects + (font + (size 1.27 1.27) + ) + (justify right) + (hide yes) + ) + ) + (property "Footprint" "Connector_JST:JST_PH_B6B-PH-K_1x06_P2.00mm_Vertical" + (at 170.18 78.74 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "~" + (at 170.18 78.74 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Generic connector, single row, 01x06, script generated" + (at 170.18 78.74 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (pin "2" + (uuid "12397db2-387e-4378-bebe-64ffe395ad22") + ) + (pin "1" + (uuid "f6a48b91-2224-4563-8144-9565bcc3bd92") + ) + (pin "5" + (uuid "ec59ffe8-136d-4c87-95cd-eb96fd64bece") + ) + (pin "3" + (uuid "f04580a0-18ca-4312-baba-c41e7d58b7dc") + ) + (pin "4" + (uuid "0d9da94c-e4d0-4e7f-b9e6-2ff9c37df67c") + ) + (pin "6" + (uuid "99889f4e-19c9-4ce9-a5a3-d0a936d538a4") + ) + (instances + (project "" + (path "/76a3543d-18d5-494b-9749-b3ee4fa138fc" + (reference "J1") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "power:+3.3V") + (at 110.49 73.66 0) + (unit 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (dnp no) + (fields_autoplaced yes) + (uuid "46d90bba-dd16-4d50-90ec-b5eec940557b") + (property "Reference" "#PWR03" + (at 110.49 77.47 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Value" "+3.3V" + (at 110.49 68.58 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "" + (at 110.49 73.66 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "" + (at 110.49 73.66 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Power symbol creates a global label with name \"+3.3V\"" + (at 110.49 73.66 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (pin "1" + (uuid "ad5f32f1-9643-4a99-9a2b-462f08e3a097") + ) + (instances + (project "" + (path "/76a3543d-18d5-494b-9749-b3ee4fa138fc" + (reference "#PWR03") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Mechanical:MountingHole_Pad") + (at 80.01 154.94 0) + (unit 1) + (exclude_from_sim no) + (in_bom no) + (on_board yes) + (dnp no) + (fields_autoplaced yes) + (uuid "4902fc81-dc1d-478f-891f-f1b754c57f22") + (property "Reference" "H2" + (at 82.55 152.3999 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "MountingHole_Pad" + (at 82.55 154.9399 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "MountingHole:MountingHole_2.7mm_M2.5_Pad_Via" + (at 80.01 154.94 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "~" + (at 80.01 154.94 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Mounting Hole with connection" + (at 80.01 154.94 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (pin "1" + (uuid "e0591e6a-c5ff-49b5-b3b7-ed2920fef1dc") + ) + (instances + (project "" + (path "/76a3543d-18d5-494b-9749-b3ee4fa138fc" + (reference "H2") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "power:GND") + (at 110.49 101.6 0) + (unit 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (dnp no) + (fields_autoplaced yes) + (uuid "5a11e10e-fd90-4f83-9f8f-f7f50bb6159b") + (property "Reference" "#PWR01" + (at 110.49 107.95 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Value" "GND" + (at 110.49 106.68 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "" + (at 110.49 101.6 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "" + (at 110.49 101.6 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Power symbol creates a global label with name \"GND\" , ground" + (at 110.49 101.6 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (pin "1" + (uuid "7f5e408b-ed49-47b8-9d61-5467ca051bd3") + ) + (instances + (project "" + (path "/76a3543d-18d5-494b-9749-b3ee4fa138fc" + (reference "#PWR01") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Mechanical:MountingHole_Pad") + (at 80.01 165.1 0) + (unit 1) + (exclude_from_sim no) + (in_bom no) + (on_board yes) + (dnp no) + (fields_autoplaced yes) + (uuid "76ce9e78-7d5e-4582-b46d-916b9410dc77") + (property "Reference" "H4" + (at 82.55 162.5599 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "MountingHole_Pad" + (at 82.55 165.0999 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "MountingHole:MountingHole_2.7mm_M2.5_Pad_Via" + (at 80.01 165.1 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "~" + (at 80.01 165.1 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Mounting Hole with connection" + (at 80.01 165.1 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (pin "1" + (uuid "e0591e6a-c5ff-49b5-b3b7-ed2920fef1dd") + ) + (instances + (project "" + (path "/76a3543d-18d5-494b-9749-b3ee4fa138fc" + (reference "H4") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Mechanical:MountingHole_Pad") + (at 53.34 165.1 0) + (unit 1) + (exclude_from_sim no) + (in_bom no) + (on_board yes) + (dnp no) + (fields_autoplaced yes) + (uuid "a3f04b2f-9a0c-4cda-93c7-b160fdf8dc03") + (property "Reference" "H3" + (at 55.88 162.5599 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "MountingHole_Pad" + (at 55.88 165.0999 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "MountingHole:MountingHole_2.7mm_M2.5_Pad_Via" + (at 53.34 165.1 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "~" + (at 53.34 165.1 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Mounting Hole with connection" + (at 53.34 165.1 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (pin "1" + (uuid "e0591e6a-c5ff-49b5-b3b7-ed2920fef1de") + ) + (instances + (project "" + (path "/76a3543d-18d5-494b-9749-b3ee4fa138fc" + (reference "H3") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "power:GND") + (at 152.4 133.35 0) + (unit 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (dnp no) + (fields_autoplaced yes) + (uuid "abc73abc-d2e5-4d23-b346-6a4ce707b431") + (property "Reference" "#PWR02" + (at 152.4 139.7 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Value" "GND" + (at 152.4 138.43 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "" + (at 152.4 133.35 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "" + (at 152.4 133.35 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Power symbol creates a global label with name \"GND\" , ground" + (at 152.4 133.35 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (pin "1" + (uuid "7f5e408b-ed49-47b8-9d61-5467ca051bd4") + ) + (instances + (project "" + (path "/76a3543d-18d5-494b-9749-b3ee4fa138fc" + (reference "#PWR02") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Connector:Conn_01x06_Pin") + (at 170.18 101.6 180) + (unit 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (dnp no) + (uuid "ba0e7cf5-533c-4cb0-adfa-05d42f98b4c0") + (property "Reference" "J2" + (at 173.228 100.584 0) + (effects + (font + (size 1.27 1.27) + ) + (justify right) + ) + ) + (property "Value" "Conn_01x06_Pin" + (at 171.45 101.5999 0) + (effects + (font + (size 1.27 1.27) + ) + (justify right) + (hide yes) + ) + ) + (property "Footprint" "Connector_JST:JST_PH_B6B-PH-K_1x06_P2.00mm_Vertical" + (at 170.18 101.6 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "~" + (at 170.18 101.6 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Generic connector, single row, 01x06, script generated" + (at 170.18 101.6 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (pin "5" + (uuid "3021cd0e-611b-472b-8738-47cac0c6eb45") + ) + (pin "2" + (uuid "98c58e24-e96b-4a2a-9d54-fb66e92b06f6") + ) + (pin "1" + (uuid "10360949-d8c6-4786-bb92-ede2587a3d8f") + ) + (pin "6" + (uuid "3aa8c183-59f2-4bc1-9016-4e8735678803") + ) + (pin "4" + (uuid "55414990-e9ab-4c11-9c05-818c9362e8ae") + ) + (pin "3" + (uuid "860496b3-2160-4049-b813-cae493040873") + ) + (instances + (project "" + (path "/76a3543d-18d5-494b-9749-b3ee4fa138fc" + (reference "J2") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "power:+3.3V") + (at 154.94 64.77 0) + (unit 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (dnp no) + (uuid "dab51caa-0d47-477e-8764-18fb04422de5") + (property "Reference" "#PWR04" + (at 154.94 68.58 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Value" "+3.3V" + (at 155.194 59.436 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "" + (at 154.94 64.77 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "" + (at 154.94 64.77 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Power symbol creates a global label with name \"+3.3V\"" + (at 154.94 64.77 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (pin "1" + (uuid "ad5f32f1-9643-4a99-9a2b-462f08e3a098") + ) + (instances + (project "" + (path "/76a3543d-18d5-494b-9749-b3ee4fa138fc" + (reference "#PWR04") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Mechanical:MountingHole_Pad") + (at 53.34 154.94 0) + (unit 1) + (exclude_from_sim no) + (in_bom no) + (on_board yes) + (dnp no) + (fields_autoplaced yes) + (uuid "e278849c-6d8c-4be9-a093-6ef8686112d4") + (property "Reference" "H1" + (at 55.88 152.3999 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "MountingHole_Pad" + (at 55.88 154.9399 0) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "MountingHole:MountingHole_2.7mm_M2.5_Pad_Via" + (at 53.34 154.94 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Datasheet" "~" + (at 53.34 154.94 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (property "Description" "Mounting Hole with connection" + (at 53.34 154.94 0) + (effects + (font + (size 1.27 1.27) + ) + (hide yes) + ) + ) + (pin "1" + (uuid "e0591e6a-c5ff-49b5-b3b7-ed2920fef1df") + ) + (instances + (project "" + (path "/76a3543d-18d5-494b-9749-b3ee4fa138fc" + (reference "H1") + (unit 1) + ) + ) + ) + ) + (sheet_instances + (path "/" + (page "1") + ) + ) + (embedded_fonts no) +) diff --git a/electronics/.gitignore b/electronics/control_board/.gitignore similarity index 100% rename from electronics/.gitignore rename to electronics/control_board/.gitignore diff --git a/electronics/ControlBoard_v1.kicad_pcb b/electronics/control_board/ControlBoard_v1.kicad_pcb similarity index 100% rename from electronics/ControlBoard_v1.kicad_pcb rename to electronics/control_board/ControlBoard_v1.kicad_pcb diff --git a/electronics/ControlBoard_v1.kicad_pro b/electronics/control_board/ControlBoard_v1.kicad_pro similarity index 100% rename from electronics/ControlBoard_v1.kicad_pro rename to electronics/control_board/ControlBoard_v1.kicad_pro diff --git a/electronics/ControlBoard_v1.kicad_sch b/electronics/control_board/ControlBoard_v1.kicad_sch similarity index 100% rename from electronics/ControlBoard_v1.kicad_sch rename to electronics/control_board/ControlBoard_v1.kicad_sch diff --git a/electronics/VersionHistory.txt b/electronics/control_board/VersionHistory.txt similarity index 100% rename from electronics/VersionHistory.txt rename to electronics/control_board/VersionHistory.txt diff --git a/electronics/fp-lib-table b/electronics/control_board/fp-lib-table similarity index 100% rename from electronics/fp-lib-table rename to electronics/control_board/fp-lib-table diff --git a/electronics/libraries/DCDC_Converter/DCDC_17mmx12mm.kicad_mod b/electronics/control_board/libraries/DCDC_Converter/DCDC_17mmx12mm.kicad_mod similarity index 100% rename from electronics/libraries/DCDC_Converter/DCDC_17mmx12mm.kicad_mod rename to electronics/control_board/libraries/DCDC_Converter/DCDC_17mmx12mm.kicad_mod diff --git a/electronics/libraries/DCDC_Converter/DCDC_Converter.kicad_sym b/electronics/control_board/libraries/DCDC_Converter/DCDC_Converter.kicad_sym similarity index 100% rename from electronics/libraries/DCDC_Converter/DCDC_Converter.kicad_sym rename to electronics/control_board/libraries/DCDC_Converter/DCDC_Converter.kicad_sym diff --git a/electronics/libraries/ROB-14450/MODULE_ROB-14450.kicad_mod b/electronics/control_board/libraries/ROB-14450/MODULE_ROB-14450.kicad_mod similarity index 100% rename from electronics/libraries/ROB-14450/MODULE_ROB-14450.kicad_mod rename to electronics/control_board/libraries/ROB-14450/MODULE_ROB-14450.kicad_mod diff --git a/electronics/libraries/ROB-14450/ROB-14450.kicad_sym b/electronics/control_board/libraries/ROB-14450/ROB-14450.kicad_sym similarity index 100% rename from electronics/libraries/ROB-14450/ROB-14450.kicad_sym rename to electronics/control_board/libraries/ROB-14450/ROB-14450.kicad_sym diff --git a/electronics/libraries/ROB-14450/ROB-14450.step b/electronics/control_board/libraries/ROB-14450/ROB-14450.step similarity index 100% rename from electronics/libraries/ROB-14450/ROB-14450.step rename to electronics/control_board/libraries/ROB-14450/ROB-14450.step diff --git a/electronics/pcb_v1.2_fix.jpg b/electronics/control_board/pcb_v1.2_fix.jpg similarity index 100% rename from electronics/pcb_v1.2_fix.jpg rename to electronics/control_board/pcb_v1.2_fix.jpg diff --git a/electronics/control_board/production/PrecisionStepperController3X_v1.3.zip b/electronics/control_board/production/PrecisionStepperController3X_v1.3.zip new file mode 100644 index 0000000..1be8ab8 Binary files /dev/null and b/electronics/control_board/production/PrecisionStepperController3X_v1.3.zip differ diff --git a/electronics/sym-lib-table b/electronics/control_board/sym-lib-table similarity index 100% rename from electronics/sym-lib-table rename to electronics/control_board/sym-lib-table diff --git a/electronics/spi_splitter_board/dummy.txt b/electronics/spi_splitter_board/dummy.txt new file mode 100644 index 0000000..e69de29 diff --git a/firmware/MotionControllerRP/Rp2040-Pico_Pinout.png b/firmware/MotionControllerRP/Rp2350-Pico_Pinout.png similarity index 100% rename from firmware/MotionControllerRP/Rp2040-Pico_Pinout.png rename to firmware/MotionControllerRP/Rp2350-Pico_Pinout.png diff --git a/firmware/MotionControllerRP/include/usb_strings.h b/firmware/MotionControllerRP/include/usb_strings.h new file mode 100644 index 0000000..5be3b96 --- /dev/null +++ b/firmware/MotionControllerRP/include/usb_strings.h @@ -0,0 +1,14 @@ +#pragma once +// Override board-level USB descriptor strings. +// This file is force-included via build_flags so it runs after all -D +// command-line defines (including the board's default "Pico 2"), giving +// these definitions the final say. +#ifdef USB_PRODUCT +#undef USB_PRODUCT +#endif +#define USB_PRODUCT "Micro-Manipulator" + +#ifdef USB_MANUFACTURER +#undef USB_MANUFACTURER +#endif +#define USB_MANUFACTURER "" diff --git a/firmware/MotionControllerRP/platformio.ini b/firmware/MotionControllerRP/platformio.ini index 7c90df7..b13de61 100644 --- a/firmware/MotionControllerRP/platformio.ini +++ b/firmware/MotionControllerRP/platformio.ini @@ -13,7 +13,7 @@ ; ON LINUX UDEV RULES NEED TO BE INSTALLED: ; sudo curl -fsSL https://raw.githubusercontent.com/platformio/platformio-core/develop/platformio/assets/system/99-platformio-udev.rules -o /etc/udev/rules.d/99-platformio-udev.rules -; sudo service udev restart +; sudo systemctl restart systemd-udevd ; replug device, then upload should work ; Also potentially uninstall official plattform with: @@ -28,6 +28,10 @@ board = rpipico2 # use this for RP2530 board_build.filesystem_size = 0.5m framework = arduino +build_flags = + -include include/usb_strings.h + lib_deps = littlefs - mryslab/NeoPixelConnect@^1.4.0 \ No newline at end of file + mryslab/NeoPixelConnect@^1.4.0 + diff --git a/firmware/MotionControllerRP/src/command_parser/command_parser.cpp b/firmware/MotionControllerRP/src/command_parser/command_parser.cpp index ab1a002..ed185a9 100644 --- a/firmware/MotionControllerRP/src/command_parser/command_parser.cpp +++ b/firmware/MotionControllerRP/src/command_parser/command_parser.cpp @@ -24,6 +24,38 @@ const std::string& GCodeCommand::get_command() const { return command; } +GCodeCommand::EParseStatus GCodeCommand::from_command_str(const char* gcode_command) { + // Copy line into a mutable buffer + char line_copy[256]; + strncpy(line_copy, gcode_command, sizeof(line_copy)); + line_copy[sizeof(line_copy) - 1] = '\0'; + + // Tokenize the first word (e.g., G0, M3, T1) + char* saveptr = nullptr; + char* token = strtok_r(line_copy, " ", &saveptr); + if (!token || token[0] < 'A' || token[0] > 'Z') { + return EParseStatus::MALFORMED_COMMAND; + } + + reset(); + set_command(token); + + // Parse remaining words (e.g., X1.0, Y2.5, F200) + while ((token = strtok_r(nullptr, " ", &saveptr))) { + if (token[0] >= 'A' && token[0] <= 'Z') { + if(token[1] == '\0') + set_value(token[0], 0.0f); + else + set_value(token[0], strtof(token + 1, nullptr)); + } else { + return EParseStatus::INVALID_PARAMETER; + } + } + + return EParseStatus::OK; +} + + void GCodeCommand::reset() { // Initialize all word values to NaN to represent "not set" for (float& value : word_values) { @@ -116,6 +148,10 @@ void CommandParser::update() { } } +bool CommandParser::is_command_ready() { + return command_ready; +} + // Feed input chars one by one void CommandParser::add_input_character(char c) { if (c == '\n' || c == '\r') { @@ -132,41 +168,19 @@ void CommandParser::add_input_character(char c) { bool CommandParser::parse_line(const char* line) { command_ready = false; - // Copy line into a mutable buffer - char line_copy[256]; - strncpy(line_copy, line, sizeof(line_copy)); - line_copy[sizeof(line_copy) - 1] = '\0'; + // reset and parse gcode command from string + GCodeCommand::EParseStatus ret = command.from_command_str(line); - // Tokenize the first word (e.g., G0, M3, T1) - char* saveptr = nullptr; - char* token = strtok_r(line_copy, " ", &saveptr); - if (!token || token[0] < 'A' || token[0] > 'Z') { + if(ret == GCodeCommand::EParseStatus::MALFORMED_COMMAND) { command_processor->send_reply("error: malformed command\n"); return false; } - command.reset(); - command.set_command(token); - - // Parse remaining words (e.g., X1.0, Y2.5, F200) - while ((token = strtok_r(nullptr, " ", &saveptr))) { - if (token[0] >= 'A' && token[0] <= 'Z') { - if(token[1] == '\0') - command.set_value(token[0], 0.0f); - else - command.set_value(token[0], strtof(token + 1, nullptr)); - } else { - command_processor->send_reply("error: invalid parameter\n"); - return false; - } + if(ret == GCodeCommand::EParseStatus::INVALID_PARAMETER) { + command_processor->send_reply("error: invalid parameter\n"); + return false; } command_ready = true; return true; -} - -// returns false if the command could not yet be processed. -// The function will be called witht the same command later to try again. -bool CommandParser::handle_gcode_command(const GCodeCommand& cmd) { - return false; -} +} \ No newline at end of file diff --git a/firmware/MotionControllerRP/src/command_parser/command_parser.h b/firmware/MotionControllerRP/src/command_parser/command_parser.h index 7eea46a..407d149 100644 --- a/firmware/MotionControllerRP/src/command_parser/command_parser.h +++ b/firmware/MotionControllerRP/src/command_parser/command_parser.h @@ -16,8 +16,16 @@ static constexpr int LETTER_COUNT = 26; class GCodeCommand { public: + enum class EParseStatus { + OK=1, + MALFORMED_COMMAND=-1, + INVALID_PARAMETER=-2 + }; + GCodeCommand(); + EParseStatus from_command_str(const char* cmd); + void reset(); void set_command(const char* cmd); const std::string& get_command() const; @@ -52,11 +60,9 @@ class CommandParser { void set_command_processor(ICommandProcessor* cp); void add_input_character(char c); // Feed input chars one by one - void update(); // Feed input chars one by one - - protected: + void update(); + bool is_command_ready(); // true if command was parsed and is waiting to be executed bool parse_line(const char* line); - bool handle_gcode_command(const GCodeCommand& cmd); private: char buffer[255]; diff --git a/firmware/MotionControllerRP/src/demo_gcode_generator.cpp b/firmware/MotionControllerRP/src/demo_gcode_generator.cpp new file mode 100644 index 0000000..74a2dda --- /dev/null +++ b/firmware/MotionControllerRP/src/demo_gcode_generator.cpp @@ -0,0 +1,151 @@ +// -------------------------------------------------------------------------------------- +// Project: MicroManipulatorStepper +// License: MIT (see LICENSE file for full description) +// All text in here must be included in any redistribution. +// Author: M. S. (diffraction limited) +// -------------------------------------------------------------------------------------- + +#include +#include "demo_gcode_generator.h" +#include "robot.h" + +//*** FUCNTION ************************************************************************** + +Vec3F rand_vec3d(float range) { + auto r = [](float s) { + return ((float)rand() / RAND_MAX) * 2*s - s; + }; + + return Vec3F(r(range), r(range), r(range)); +} + +//*** CLASS ***************************************************************************** + +DemoGcodeGenerator::DemoGcodeGenerator(Robot* robot) { + DemoGcodeGenerator::cmd_counter = 0; + DemoGcodeGenerator::robot = robot; + + wst = QuaternionF::from_axis_angle(Vec3F(-0.707106781f, 0.707106781f, 0.0f), 0.955316618); +} + +void DemoGcodeGenerator::run() { + run_command("G28"); + run_command("G0 X0 Y0 Z0 F100"); + run_command("M204 L200"); + + while(true) { + move_to(0.5, 0, 0, 10); dwell(1000); + + circle_motion(10, 0.5, 50); + // grid_motion(5, 5, 3, 2000, 150, 5000); + grid_motion(6, 6, 4, 2000, 150, 5000); + + random_motion(20, 7, 1000, 100, 200); + + // grid_motion(2, 2, 8, 1000, 150, 2000); + + move_to(0, 0, 0, 100); dwell(1000); + circle_motion(2, 10, 20); + circle_motion(3, 10, 500); + set_acceleration(500); + move_to(0, 0, 0, 100); dwell(1000); + + grid_motion(5, 5, 16, 1000, 150, 2000); + random_motion(20, 7, 1000, 200, 2000); + + + dwell(1000); + for(int i=0; i<4; i++) + grid_motion(2, 2, 16, 1000, 100, 1000); + + set_acceleration(2000); + for(int i=0; i<3; i++) { + move_to(0, 0, -12, 500); + move_to(0, 0, 12, 500); + } + + // end + move_to(0, 0, -14, 10); + run_command("G4 S5"); + } +}; + +void DemoGcodeGenerator::robot_update() { + // run robot update loop until command parse can accept a new command + do { + robot->update_command_parser(); + robot->update_path_planner(); + } while(robot->get_command_parser()->is_command_ready()); +} + +void DemoGcodeGenerator::run_command(const std::string& cmd) { + // perform robot update, this will block until command parser can accept next command + robot_update(); + robot->get_command_parser()->parse_line(cmd.c_str()); + LOG_INFO("DEMO: %s", cmd.c_str()); +} + +void DemoGcodeGenerator::move_to(Vec3F p, float feedrate) { + char b[64]; + p = wst.rotate(p); + std::snprintf(b, sizeof(b), "G0 X%.3f Y%.3f Z%.3f F%.3f", p.x, p.y, p.z, feedrate); + run_command(b); +} + +void DemoGcodeGenerator::move_to(float x, float y, float z, float feedrate) { + move_to(Vec3F(x, y, z), feedrate); +} + +void DemoGcodeGenerator::set_acceleration(int accel) { + if(accel>0) + run_command(std::string("M204 L")+std::to_string(accel)); +} + +void DemoGcodeGenerator::dwell(int time_ms) { + if(time_ms>0) + run_command(std::string("G4 P")+std::to_string(time_ms)); +} + +void DemoGcodeGenerator::random_motion(int count, float range, float feedrade, int dwell_ms, int acceleration) { + set_acceleration(acceleration); + + for(int i=0; i +#include "utilities/math3d.h" + +//*** CLASS ***************************************************************************** + +class Robot; + + +class DemoGcodeGenerator { + public: + DemoGcodeGenerator(Robot* robot); + void run(); + + private: + void robot_update(); + void run_command(const std::string& cmd); + + void move_to(Vec3F p, float feedrate); + void move_to(float x, float y, float z, float feedrate); + void set_acceleration(int accel); + void dwell(int time_ms); + + private: + void random_motion(int count, float range, float feedrade, int dwell_ms=-1, int acceleration=-1); + void circle_motion(int count, float radius, float feedrade); + void grid_motion(int w, int h, float size, float feedrate, int dwell_ms=-1, int acceleration=-1); + + private: + int cmd_counter = 0; + QuaternionF wst; + Robot* robot; +}; diff --git a/firmware/MotionControllerRP/src/hardware/MT6835_encoder.cpp b/firmware/MotionControllerRP/src/hardware/MT6835_encoder.cpp index b76acd6..df01a40 100644 --- a/firmware/MotionControllerRP/src/hardware/MT6835_encoder.cpp +++ b/firmware/MotionControllerRP/src/hardware/MT6835_encoder.cpp @@ -7,6 +7,7 @@ #include "hardware/spi.h" #include "hardware/gpio.h" #include "pico/stdlib.h" +#include "utilities/logging.h" void MT6835Encoder::setup_spi(spi_inst_t* spi, uint pin_sck, uint pin_mosi, uint pin_miso, int32_t baudrate_hz) { // Set GPIO functions to SPI @@ -17,22 +18,27 @@ void MT6835Encoder::setup_spi(spi_inst_t* spi, uint pin_sck, uint pin_mosi, uint // SPI format: 8 bits, mode 3 (CPOL=1, CPHA=1) spi_init(spi, baudrate_hz); spi_set_format(spi, 8, SPI_CPOL_1, SPI_CPHA_1, SPI_MSB_FIRST); + + sleep_ms(10); } -MT6835Encoder::MT6835Encoder(spi_inst_t* spi, uint cs_pin) : spi(spi), cs_pin(cs_pin) { - // nop +MT6835Encoder::MT6835Encoder(spi_inst_t* spi, int32_t cs_pin) : spi(spi), cs_pin(cs_pin) { + if (cs_pin >= 0) { + gpio_init(cs_pin); + gpio_set_dir(cs_pin, GPIO_OUT); + gpio_put(cs_pin, 1); // CS high + } } MT6835Encoder::~MT6835Encoder() { // nop } -void MT6835Encoder::init(uint8_t bandwidth, uint8_t hysteresis) { - if (cs_pin >= 0) { - gpio_init(cs_pin); - gpio_set_dir(cs_pin, GPIO_OUT); - gpio_put(cs_pin, 1); // CS high - } +bool MT6835Encoder::init(uint8_t bandwidth, uint8_t hysteresis) { + sleep_ms(100); + + if(is_connected() == false) + return false; set_rotation_direction(0); // needs to be set, otherwise might be random set_bandwidth(bandwidth); @@ -40,6 +46,26 @@ void MT6835Encoder::init(uint8_t bandwidth, uint8_t hysteresis) { last_raw_angle = 0; abs_raw_angle = 0; + crc_error_count = 0; + initialized = true; + + return true; +} + +bool MT6835Encoder::is_connected() { + uint8_t check_bytes[] = {37, 109, 179, 251, 1}; + for(int i=0; i> 8); @@ -312,7 +355,7 @@ uint8_t MT6835Encoder::calc_crc(uint32_t angle, uint8_t status) { uint8_t crc = 0x00; uint8_t input; - input = angle >> 13; + input = (angle >> 13) & 0xFF; crc ^= input; for (int k = 8; k > 0; k--) crc = (crc & 0x80) ? (crc << 1) ^ 0x07 : crc << 1; @@ -322,10 +365,10 @@ uint8_t MT6835Encoder::calc_crc(uint32_t angle, uint8_t status) { for (int k = 8; k > 0; k--) crc = (crc & 0x80) ? (crc << 1) ^ 0x07 : crc << 1; - input = ((angle << 3) & 0xFF) | (status & 0x07); + input = ((angle & 0x1F) << 3) | (status & 0x07); crc ^= input; for (int k = 8; k > 0; k--) crc = (crc & 0x80) ? (crc << 1) ^ 0x07 : crc << 1; return crc; -} +} \ No newline at end of file diff --git a/firmware/MotionControllerRP/src/hardware/MT6835_encoder.h b/firmware/MotionControllerRP/src/hardware/MT6835_encoder.h index 62c6084..5bb3b47 100644 --- a/firmware/MotionControllerRP/src/hardware/MT6835_encoder.h +++ b/firmware/MotionControllerRP/src/hardware/MT6835_encoder.h @@ -142,10 +142,13 @@ class MT6835Encoder { static void setup_spi(spi_inst_t* spi, uint pin_sck, uint pin_mosi, uint pin_miso, int32_t baudrate_hz); // Constructor: pass SPI instance (spi0 or spi1), CS pin - MT6835Encoder(spi_inst_t *spi, uint cs_pin); + MT6835Encoder(spi_inst_t *spi, int32_t cs_pin); virtual ~MT6835Encoder(); - void init(uint8_t bandwidth=0x5, uint8_t hysteresis=0x4); + bool init(uint8_t bandwidth=0x5, uint8_t hysteresis=0x4); + bool is_connected(); + bool is_initialized(); + void reset_abs_angle(int32_t abs_raw_angle=0); // resets the total revolutions of abs angle void reset_abs_angle_period(); // Brings abs angle into [0..2pi) float read_abs_angle(); // returns the absolute angle in radians @@ -189,6 +192,9 @@ class MT6835Encoder { void set_options4(MT6835Options4 opts); uint8_t get_status(); + void set_crc_enabled(bool enable); + bool is_crc_enabled(); + uint32_t get_crc_error_count(bool reset=false); uint8_t get_calibration_status(); @@ -198,10 +204,12 @@ class MT6835Encoder { bool check_crc = false; private: + bool initialized=false; spi_inst_t *spi; - uint cs_pin; + int32_t cs_pin; uint8_t last_status = 0; uint8_t last_crc = 0; + uint32_t crc_error_count = 0; int32_t last_raw_angle = 0; AbsRawAngleType abs_raw_angle = 0; diff --git a/firmware/MotionControllerRP/src/hardware/TB6612_motor_driver.cpp b/firmware/MotionControllerRP/src/hardware/TB6612_motor_driver.cpp index 3abe215..0457670 100644 --- a/firmware/MotionControllerRP/src/hardware/TB6612_motor_driver.cpp +++ b/firmware/MotionControllerRP/src/hardware/TB6612_motor_driver.cpp @@ -36,6 +36,7 @@ TB6612MotorDriver::TB6612MotorDriver( { max_pwm = (1 << pwm_resolution) - 1; set_amplitude(0.0f, false); + field_angle = 0.0f; } void init_output_pin(uint8_t pin, bool value) { @@ -113,6 +114,9 @@ float TB6612MotorDriver::get_amplitude() const { } void TB6612MotorDriver::rotate_field(float delta_angle, float rad_per_s, const std::function& on_step) { + if(delta_angle == 0.0f) + return; + float start = field_angle; float rad_per_µs = (delta_angle >= 0.0f) ? rad_per_s*1e-6f : -rad_per_s*1e-6f; diff --git a/firmware/MotionControllerRP/src/hardware/spi_interface.cpp b/firmware/MotionControllerRP/src/hardware/spi_interface.cpp new file mode 100644 index 0000000..258b568 --- /dev/null +++ b/firmware/MotionControllerRP/src/hardware/spi_interface.cpp @@ -0,0 +1,111 @@ +#include "spi_interface.h" + +//*** CLASS ***************************************************************************** + +SpiDma::SpiDma(spi_inst_t* spi, uint sck, uint mosi, uint miso, uint cs) + : spi(spi), sck(sck), mosi(mosi), miso(miso), cs(cs) +{ +} + +void SpiDma::begin(uint32_t baudrate_hz) { + // SPI init + spi_init(spi, baudrate_hz); + spi_set_format(spi, 8, + SPI_CPOL_0, + SPI_CPHA_0, + SPI_MSB_FIRST); + + gpio_set_function(sck, GPIO_FUNC_SPI); + gpio_set_function(mosi, GPIO_FUNC_SPI); + gpio_set_function(miso, GPIO_FUNC_SPI); + + // Manual CS + gpio_init(cs); + gpio_set_dir(cs, GPIO_OUT); + gpio_put(cs, 1); + + // DMA TX channel + dma_tx = dma_claim_unused_channel(true); + cfg_tx = dma_channel_get_default_config(dma_tx); + channel_config_set_transfer_data_size(&cfg_tx, DMA_SIZE_8); + channel_config_set_dreq(&cfg_tx, spi_get_dreq(spi, true)); + channel_config_set_read_increment(&cfg_tx, true); + channel_config_set_write_increment(&cfg_tx, false); + + // --- DMA RX channel --- + dma_rx = dma_claim_unused_channel(true); + cfg_rx = dma_channel_get_default_config(dma_rx); + channel_config_set_transfer_data_size(&cfg_rx, DMA_SIZE_8); + channel_config_set_dreq(&cfg_rx, spi_get_dreq(spi, false)); + channel_config_set_read_increment(&cfg_rx, false); + channel_config_set_write_increment(&cfg_rx, true); + + // Configure but don't start yet + dma_channel_configure( + dma_tx, &cfg_tx, + &spi_get_hw(spi)->dr, + nullptr, 0, false); + + dma_channel_configure( + dma_rx, &cfg_rx, + nullptr, + &spi_get_hw(spi)->dr, + 0, false); +} + +bool SpiDma::is_busy() const { + return dma_channel_is_busy(dma_tx) || + dma_channel_is_busy(dma_rx); +} + +void SpiDma::transfer(const void* tx_buf, void* rx_buf, size_t bytes) { + while (is_busy()) {} + + gpio_put(cs, 0); + + // Ensure minimum CS low time (50 ns) - Approx 14 cycles at 250 MHz + for (int i = 0; i < 14; i++) __asm volatile("nop"); + + // Setup RX DMA - must be set first! + if (rx_buf != nullptr) { + dma_channel_set_write_addr(dma_rx, rx_buf, false); + dma_channel_set_trans_count(dma_rx, bytes, false); + } + + // Setup TX DMA + if (tx_buf != nullptr) { + dma_channel_set_read_addr(dma_tx, tx_buf, false); + dma_channel_set_trans_count(dma_tx, bytes, true); + } +} + +void SpiDma::wait_for_finish() { + while (is_busy()) {} + gpio_put(cs, 1); + + // Ensure minimum CS low time (50 ns) - Approx 14 cycles at 250 MHz + for (int i = 0; i < 14; i++) __asm volatile("nop"); +} + +void SpiDma::abort() { + // Stop TX DMA if running + if (dma_channel_is_busy(dma_tx)) { + dma_channel_abort(dma_tx); + } + + // Stop RX DMA if running + if (dma_channel_is_busy(dma_rx)) { + dma_channel_abort(dma_rx); + } + + // Flush the SPI FIFOs to prevent leftover data + spi_get_hw(spi)->dr = 0; // clear DR (TX FIFO) + spi_get_hw(spi)->sr; // read SR to clear flags + + // Deassert CS pin to leave SPI slave in idle state + gpio_put(cs, 1); +} + + + + diff --git a/firmware/MotionControllerRP/src/hardware/spi_interface.h b/firmware/MotionControllerRP/src/hardware/spi_interface.h new file mode 100644 index 0000000..5fb8686 --- /dev/null +++ b/firmware/MotionControllerRP/src/hardware/spi_interface.h @@ -0,0 +1,37 @@ +// -------------------------------------------------------------------------------------- +// Project: MicroManipulatorStepper +// License: MIT (see LICENSE file for full description) +// All text in here must be included in any redistribution. +// Author: M. S. (diffraction limited) +// -------------------------------------------------------------------------------------- + +#pragma once + +#include "hardware/spi.h" +#include "hardware/dma.h" +#include "hardware/gpio.h" + +//*** CLASS ***************************************************************************** + +class SpiDma { + public: + SpiDma(spi_inst_t* spi, uint sck, uint mosi, uint miso, uint cs); + + void begin(uint32_t baudrate_hz); + bool is_busy() const; + void transfer(const void* tx_buf, void* rx_buf, size_t bytes); + void wait_for_finish(); + void abort(); + + private: + spi_inst_t* spi; + uint sck, mosi, miso, cs; + + int dma_tx; + int dma_rx; + dma_channel_config cfg_tx; + dma_channel_config cfg_rx; +}; + + + diff --git a/firmware/MotionControllerRP/src/hw_config.h b/firmware/MotionControllerRP/src/hw_config.h index 6869428..252e1a0 100644 --- a/firmware/MotionControllerRP/src/hw_config.h +++ b/firmware/MotionControllerRP/src/hw_config.h @@ -1,14 +1,20 @@ #pragma once #include "utilities/math_constants.h" +// #define DEMO_MODE + //--- MOTORS ------------------------------------------------------------------ // motor pole pair count // * 100 for 0.9deg stepper motors // * 50 for 1.8deg stepper motors -constexpr float MOTOR1_POLE_PAIRS = 100; -constexpr float MOTOR2_POLE_PAIRS = 100; -constexpr float MOTOR3_POLE_PAIRS = 100; +constexpr float MOTOR1_POLE_PAIRS = 50; +constexpr float MOTOR2_POLE_PAIRS = 50; +constexpr float MOTOR3_POLE_PAIRS = 50; + +// max current factor in range [0..1]. Lower values reduce pwm resolution so a +// value above 0.4 is recommended. +constexpr float MOTOR_MAX_CURRENT_FACTOR = 0.6f; //--- ENCODERS ---------------------------------------------------------------- @@ -18,28 +24,63 @@ constexpr float ENCODER_MAGNET_PITCH = 3.0f; // [mm] constexpr float ENCODER_MAGNET_RADIUS = 30.0f; // [mm] constexpr float ENCODER_ANGLE_TO_ROTOR_ANGLE = (ENCODER_MAGNET_PITCH*2.0f) / (ENCODER_MAGNET_RADIUS * Constants::TWO_PI_F); + +// enables error checking for encoders (slow) - useful for debugging +// Note: some chips seem to return always a crc of 0 producing massiv false errors +constexpr bool ENABLE_ENCODER_CRC = true; //--- HOMING ------------------------------------------------------------------ constexpr float HOMING_VELOCITY = 1.0f; // rad per s constexpr float HOMING_CURRENT = 0.15f; // range 0..1 -constexpr float HOMING_FINISH_POS = 0.5f; // in rad +// NOT IMPLEMENTED YET: constexpr float HOMING_FINISH_POS = 0.5f; // in rad //--- CALIBRATION ------------------------------------------------------------- // degrees from home position -constexpr float CALIBRATION_RANGE = 95; +constexpr float CALIBRATION_RANGE = 83; // velocity of the magnetic field during calibration (lower is more accurate) -constexpr float CALIBRATION_FIELD_VELOCITY = 40.0f; +constexpr float CALIBRATION_FIELD_VELOCITY = 20.0f; + +// angle to retract after homing before starting calibration run +// can be used if the encoder measurements at the beginning of the calibration +// run is non-linear +constexpr float CALIBRATION_RETRACT_ANGLE = 17.5f; + +// size of the calibration lookup table +constexpr int ENCODER_LUT_SIZE = 256; + +//--- CLOSED LOOP CONTROL ----------------------------------------------------- + +// position controller +constexpr float POS_KP = 60.0f; +constexpr float POS_KI = 30000.0f; + +// velocity controller +constexpr float VEL_LOWPASS_TC = 0.004f; +constexpr float VEL_KP = 0.2f; +constexpr float VEL_KI = 90.0f; + +//--- KINEMATIC --------------------------------------------------------------- + +// Kinematic Parameters are defined kinematic_modes/kinematic_model_delta3d.cpp + +// NUM_JOINTS and NUM_TOOLS are defined in 'path_segment.h'. Note that changing +// the number of joints requires changing the kinematic model accordingly and +// also requires the initialization of the correct number of 'RobotJoint' objects +// in the Robtos init method. //--- PINS -------------------------------------------------------------------- +#define JOINT_READY_OVERRIDE + // #define SINGLE_AXIS_BOARD #ifndef SINGLE_AXIS_BOARD // Pins for 3Axis Board - #define PIN_BUILTIN_LED 23 - #define PIN_USER_BUTTON 24 + // #define PIN_BUILTIN_LED 23 // RP2040 pico clone + // #define PIN_USER_BUTTON 24 // RP2040 pico clone + #define PIN_BUILTIN_LED 25 #define PIN_M1_PWM_A_POS 13 #define PIN_M1_PWM_A_NEG 12 @@ -51,22 +92,25 @@ constexpr float CALIBRATION_FIELD_VELOCITY = 40.0f; #define PIN_M2_PWM_B_POS 10 #define PIN_M2_PWM_B_NEG 11 - #define PIN_M3_PWM_A_POS 5 - #define PIN_M3_PWM_A_NEG 4 - #define PIN_M3_PWM_B_POS 6 + #define PIN_M3_PWM_A_POS 20 + #define PIN_M3_PWM_A_NEG 21 + #define PIN_M3_PWM_B_POS 22 #define PIN_M3_PWM_B_NEG 7 #define PIN_MOTOR_EN 18 #define PIN_MOTOR_PWMAB 19 - #define PIN_ENCODER1_CS 20 - #define PIN_ENCODER2_CS 21 - #define PIN_ENCODER3_CS 22 + #define PIN_ENCODER1_CS 4 + #define PIN_ENCODER2_CS 5 + #define PIN_ENCODER3_CS 6 #define PIN_ENCODER_SCK 2 #define PIN_ENCODER_MISO 0 #define PIN_ENCODER_MOSI 3 + #define PIN_TOOL1 16 + #define PIN_TOOL2 17 + #else // Single Axis Board #define PIN_BUILTIN_LED 16 @@ -77,24 +121,27 @@ constexpr float CALIBRATION_FIELD_VELOCITY = 40.0f; #define PIN_M1_PWM_B_POS 14 #define PIN_M1_PWM_B_NEG 15 - #define PIN_M2_PWM_A_POS 9 - #define PIN_M2_PWM_A_NEG 8 + #define PIN_M2_PWM_A_POS 8 + #define PIN_M2_PWM_A_NEG 9 #define PIN_M2_PWM_B_POS 10 #define PIN_M2_PWM_B_NEG 11 - #define PIN_M3_PWM_A_POS 5 - #define PIN_M3_PWM_A_NEG 4 - #define PIN_M3_PWM_B_POS 6 + #define PIN_M3_PWM_A_POS 20 + #define PIN_M3_PWM_A_NEG 21 + #define PIN_M3_PWM_B_POS 22 #define PIN_M3_PWM_B_NEG 7 #define PIN_MOTOR_EN 18 #define PIN_MOTOR_PWMAB 19 - #define PIN_ENCODER1_CS 20 - #define PIN_ENCODER2_CS 21 - #define PIN_ENCODER3_CS 22 + #define PIN_ENCODER1_CS 4 + #define PIN_ENCODER2_CS 5 + #define PIN_ENCODER3_CS 6 #define PIN_ENCODER_SCK 2 #define PIN_ENCODER_MISO 0 #define PIN_ENCODER_MOSI 3 -#endif \ No newline at end of file + + #define PIN_TOOL1 16 + #define PIN_TOOL2 17 +#endif diff --git a/firmware/MotionControllerRP/src/kinematic_models/kinematic_model_delta3d.cpp b/firmware/MotionControllerRP/src/kinematic_models/kinematic_model_delta3d.cpp index 4e6c57b..d86cfd4 100644 --- a/firmware/MotionControllerRP/src/kinematic_models/kinematic_model_delta3d.cpp +++ b/firmware/MotionControllerRP/src/kinematic_models/kinematic_model_delta3d.cpp @@ -14,11 +14,60 @@ //*** CLASS ***************************************************************************** +#define HW_VERSION4 // remove this if you are using HW-v3 (Note geometry parameters might be slightly off for HW-v3.0!) + +#ifdef HW_VERSION4 + +/** + * Initializes the kinematic model and its geometric parameters for hardware version v4.0. + */ +KinematicModel_Delta3D::KinematicModel_Delta3D() { + const float D2R = Constants::DEG2RAD; + + // location of base origin in endeffector coordinate system (ee in neutral position) + Vec3F base_offset(-47.5f, -47.5f, -47.5f); + + // distance between the two spehere centers of the linkage rod (arms) + arm_length = 36.25f*2; + + // distance from arm attachment points to rotor axis + rotor_radius = 15.0f; + + // midpoint between the two attachment spheres on the endeffector in EE coordinate system + ee_attachment_points[0] = Vec3F(3.54f, -11.5f, 4.5f); + ee_attachment_points[1] = Vec3F(4.5f, 3.54f, -11.5f); + ee_attachment_points[2] = Vec3F(-11.5f, 4.5f, 3.54f); + + // set actuator transformations based on CAD model + actuator_to_base[0].rotation = QuaternionF::from_axis_angle(Vec3F(0.0f, 0.0f, 1.0f), 90.0f*D2R); + actuator_to_base[0].translation = Vec3F(-21.5f, 21.0f, 52.0f)+base_offset; + + actuator_to_base[1].rotation = QuaternionF::from_axis_angle(Vec3F(1.0f, 0.0f, 1.0f), 180.0f*D2R); + actuator_to_base[1].translation = Vec3F(52.0f, -21.5f, 21.0f)+base_offset; + + actuator_to_base[2].rotation = QuaternionF::from_axis_angle(Vec3F(-1.0f, 0.0f, 0.0f), 90.0f*D2R); + actuator_to_base[2].translation = Vec3F(21.0f, 52.0f, -21.5f)+base_offset; + + // angle offset from home positionto center position of the rotor + rotor_angle_offset[0] = 42.0f*Constants::DEG2RAD; + rotor_angle_offset[1] = 42.0f*Constants::DEG2RAD; + rotor_angle_offset[2] = 42.0f*Constants::DEG2RAD; + + for(int i=0; i<3; i++) + base_to_actuator[i] = actuator_to_base[i].inverse(); +} + +#else + +// Below is the old code for HW-v3.0 for compatibility, some values might be wrong and do not reflect the actual cad model. +// If you use them please check them against your build. All these problems where fixed in HW-v4 and the new function above +// uses the correct values. KinematicModel_Delta3D::KinematicModel_Delta3D() { const float D2R = Constants::DEG2RAD; // offset to move base origin defined in CAD to endeffector origin near neutral position - // real device + + // REAL DEVICE <--- These might be slightly wrong Vec3F base_offset(-32.5f, -32.5f, -32.5f); arm_length = 73.8f; rotor_radius = 15.0f; @@ -26,8 +75,7 @@ KinematicModel_Delta3D::KinematicModel_Delta3D() { ee_attachment_points[1] = Vec3F(2.0f, -0.5f, -14.5f); ee_attachment_points[2] = Vec3F(-14.5f, 2.0f, -0.5f); - // endeffector attachment points - // CAD + // CAD <--- These might be be more correct but not sure /* Vec3F base_offset(-30.5f, -30.5f, -30.5f); arm_length = 2*36.5; @@ -55,6 +103,8 @@ KinematicModel_Delta3D::KinematicModel_Delta3D() { base_to_actuator[i] = actuator_to_base[i].inverse(); } +#endif + int KinematicModel_Delta3D::get_joint_count() { return 3; } @@ -65,7 +115,7 @@ bool KinematicModel_Delta3D::foreward(const float* joint_positions, Pose6DF& pos Vec3F p = arm_attachment_point(i, joint_positions[i]); p = actuator_to_base[i].transformPoint(p); - // apply ee attachment point offsets offset so that three sphere intersection can be used + // apply ee attachment point offsets so that three sphere intersection can be used // to find ee position. This only works if there is no ee rotation. arm_attachment_points[i] = p-ee_attachment_points[i]; } diff --git a/firmware/MotionControllerRP/src/main.cpp b/firmware/MotionControllerRP/src/main.cpp index 5e2a6ec..b55139c 100644 --- a/firmware/MotionControllerRP/src/main.cpp +++ b/firmware/MotionControllerRP/src/main.cpp @@ -11,7 +11,6 @@ #include "hardware/pll.h" #include "hardware/vreg.h" -#include #include #include @@ -23,9 +22,11 @@ #include "hw_config.h" #include "LittleFS.h" +#include "demo_gcode_generator.h" + //*** GLOBALS *************************************************************************** -NeoPixelConnect strip(PIN_BUILTIN_LED, 1); +// NeoPixelConnect strip(PIN_BUILTIN_LED, 1); Robot robot(0.01f); /* @@ -68,16 +69,18 @@ void overclock() { } void set_led_color(uint8_t r, uint8_t g, uint8_t b) { - strip.neoPixelSetValue(0, r, g, b, false); + /* strip.neoPixelSetValue(0, r, g, b, false); delayMicroseconds(2000); - strip.neoPixelShow(); + strip.neoPixelShow(); */ } void led_blink(uint8_t r, uint8_t g, uint8_t b, int count, int period_time_ms) { for(int i=0; irun(); // blocks forever + #endif + while(true) { // update motion controller robot.update_command_parser(); @@ -111,12 +119,17 @@ void main_core1() { } void setup() { + gpio_init(PIN_BUILTIN_LED); + gpio_set_dir(PIN_BUILTIN_LED, GPIO_OUT); + led_blink(0, 0, 30, 3, 100); // stdio_init_all(); // Initializes USB or UART stdio overclock(); // Serial.begin(921600); Logger::instance().begin(921600, false); + #ifndef DEMO_MODE while(!Serial); + #endif set_led_color(50, 10, 0); // auto* test = new KinematicModel_Delta3D(); test->test(); delete test; @@ -146,6 +159,8 @@ void setup() { LOG_INFO("Initialization finished"); LOG_INFO(" "); + gpio_put(PIN_BUILTIN_LED, 1); + return; /* diff --git a/firmware/MotionControllerRP/src/motion_control/motion_controller.cpp b/firmware/MotionControllerRP/src/motion_control/motion_controller.cpp index d9ebfa5..abfe634 100644 --- a/firmware/MotionControllerRP/src/motion_control/motion_controller.cpp +++ b/firmware/MotionControllerRP/src/motion_control/motion_controller.cpp @@ -18,7 +18,10 @@ MotionController::MotionController(PathPlanner* path_planner) { current_time = 0.0f; } -bool MotionController::update(float dt, float* joint_positions, float* joint_velocities) { +bool MotionController::update(float dt, + float* joint_positions, + float* joint_velocities, + float* tool_outputs) { // increment time counter current_time += dt; @@ -49,6 +52,6 @@ bool MotionController::update(float dt, float* joint_positions, float* joint_vel current_path_segment.initialized = false; // evaluate path segment - current_path_segment.evaluate(current_time, joint_positions, joint_velocities); + current_path_segment.evaluate(current_time, joint_positions, joint_velocities, tool_outputs); return true; } diff --git a/firmware/MotionControllerRP/src/motion_control/motion_controller.h b/firmware/MotionControllerRP/src/motion_control/motion_controller.h index 263c55c..d046d7b 100644 --- a/firmware/MotionControllerRP/src/motion_control/motion_controller.h +++ b/firmware/MotionControllerRP/src/motion_control/motion_controller.h @@ -23,7 +23,7 @@ class MotionController { // updates the motion controller and computes new joint positions and velocities // after dt has passed. Ouput array must hav space for 'NUM_JOINTS' entries. - bool update(float dt, float* joint_positions, float* joint_velocities); + bool update(float dt, float* joint_positions, float* joint_velocities, float* tool_outputs); private: PathPlanner* path_planner; diff --git a/firmware/MotionControllerRP/src/motion_control/path_segment.cpp b/firmware/MotionControllerRP/src/motion_control/path_segment.cpp index f9adcf0..74fbe82 100644 --- a/firmware/MotionControllerRP/src/motion_control/path_segment.cpp +++ b/firmware/MotionControllerRP/src/motion_control/path_segment.cpp @@ -112,12 +112,15 @@ float MotionProfileConstAcc::evaluate(float time) const { CartesianPathSegment::CartesianPathSegment() { dwell_time = 0.0f; + for(int i=0; itool_outputs, + duration); // update current joint pos for(int i=0; i 0 + float tool_outputs[NUM_TOOLS]; }; //--- JointSpacePathSegment ------------------------------------------------------------- @@ -100,11 +107,13 @@ class JointSpacePathSegment { JointSpacePathSegment(); JointSpacePathSegment(const float start_pos[NUM_JOINTS], const float end_pos[NUM_JOINTS], + const float tool_outputs[NUM_TOOLS], const float duration); void evaluate(float time, float joint_positions[NUM_JOINTS], - float joint_velocity[NUM_JOINTS]) const; + float joint_velocity[NUM_JOINTS], + float tool_outputs[NUM_TOOLS]) const; float get_duration(); @@ -116,6 +125,7 @@ class JointSpacePathSegment { float end_pos[NUM_JOINTS]; float start_velocity[NUM_JOINTS]; float end_velocity[NUM_JOINTS]; + float tool_outputs[NUM_TOOLS]; float duration; float inv_duration; diff --git a/firmware/MotionControllerRP/src/robot.cpp b/firmware/MotionControllerRP/src/robot.cpp index 7a113ad..546e407 100644 --- a/firmware/MotionControllerRP/src/robot.cpp +++ b/firmware/MotionControllerRP/src/robot.cpp @@ -13,12 +13,17 @@ #include "kinematic_models/kinematic_model_delta3d.h" #include "servo_control/homing_controller.h" #include "servo_control/actuator_calibration.h" +#include "robot_joint/robot_joint.h" #include "pico/multicore.h" #include "version.h" +#include "robot_tool/pwm_tool.h" constexpr int SPINLOCK_ID_SHARED_DATA = 0; constexpr int SPINLOCK_ID_JOINTS = 1; +#include +NeoPixelConnect led(PIN_BUILTIN_LED, 1); + //*** FUNCTION ************************************************************************** bool startswith(const std::string& str, const std::string& prefix) { @@ -28,123 +33,6 @@ bool startswith(const std::string& str, const std::string& prefix) { //*** CLASS ***************************************************************************** -//--- RobotAxis ------------------------------------------------------------------------- - -RobotJoint::RobotJoint(MT6835Encoder* encoder, - TB6612MotorDriver* motor_driver, - int pole_pairs) -{ - RobotJoint::encoder = encoder; - RobotJoint::motor_driver = motor_driver; - servo_controller = new ServoController(*motor_driver, *encoder, pole_pairs); - position = 0.0f; - velocity = 0.0f; -} - -RobotJoint::~RobotJoint() { - delete servo_controller; - delete motor_driver; - delete encoder; - servo_controller = nullptr; - motor_driver = nullptr; - encoder = nullptr; -} - -void RobotJoint::init(int joint_idx) { - RobotJoint::joint_idx = joint_idx; - - encoder->init(0x5, 0x4); - servo_controller->init(0.5); - servo_controller->set_motor_enabled(false, false); -} - -bool RobotJoint::calibrate(bool print_measurements) { - LOG_INFO("Joint-%i: calibrating joint...", joint_idx); - - HomingController homing_controller; - bool homing_ok = homing_controller.run_blocking(servo_controller, -HOMING_VELOCITY, - 360.0f*DEG_TO_RAD, HOMING_CURRENT, - ENCODER_ANGLE_TO_ROTOR_ANGLE); - if(homing_ok == false) { - LOG_ERROR("Joint-%i: Calibration failed due to unsuccessful homing sequence", joint_idx); - return false; - } - - // measure lookup tables - LookupTable encoder_raw_to_motor_pos_lut; - LookupTable motor_pos_to_field_angle_lut; - bool ok = measure_calibration_data(encoder_raw_to_motor_pos_lut, - motor_pos_to_field_angle_lut, - *servo_controller, - CALIBRATION_RANGE*DEG_TO_RAD, - CALIBRATION_FIELD_VELOCITY, - 256, - print_measurements); - if(!ok) { - LOG_ERROR("Joint-%i: calibrating failed", joint_idx); - return false; - } - - servo_controller->set_enc_to_pos_lut(encoder_raw_to_motor_pos_lut); - servo_controller->set_pos_to_field_lut(motor_pos_to_field_angle_lut); - is_calibrated = true; - is_homed = true; - - LOG_INFO("Joint-%i: calibrating joint successful.", joint_idx); - - return true; -} - -void RobotJoint::update(float dt, float one_over_dt) { - servo_controller->update(position, dt, one_over_dt); -} - -void RobotJoint::update_target(float p, float v) { - position = p; - velocity = v; -} - -bool RobotJoint::load_calibration() { - std::string fn1 = calib_data_filename("enc_to_pos_lut").c_str(); - std::string fn2 = calib_data_filename("pos_to_field_lut").c_str(); - if(!LittleFS.exists(fn1.c_str()) || !LittleFS.exists(fn2.c_str())) { - LOG_WARNING("Joint-%i: Not all calibration files found. Run joint calibration with M56.", joint_idx); - return false; - } - - LookupTable enc_to_pos_lut; - LookupTable pos_to_field_lut; - bool res = true; - res &= load_lut_from_file(enc_to_pos_lut, fn1.c_str()); - res &= load_lut_from_file(pos_to_field_lut, fn2.c_str()); - if(res == false) - return false; - - servo_controller->set_enc_to_pos_lut(enc_to_pos_lut); - servo_controller->set_pos_to_field_lut(pos_to_field_lut); - - is_calibrated = true; - LOG_INFO("Joint-%i: Encoder lookup tables loaded (size=%i,%i)", - joint_idx, enc_to_pos_lut.size(), pos_to_field_lut.size()); - - return true; -} - -bool RobotJoint::store_calibration() { - bool res = true; - - res &= save_lut_to_file(servo_controller->get_enc_to_pos_lut(), - calib_data_filename("enc_to_pos_lut").c_str()); - res &= save_lut_to_file(servo_controller->get_pos_to_field_lut(), - calib_data_filename("pos_to_field_lut").c_str()); - - return res; -} - -std::string RobotJoint::calib_data_filename(std::string data_name) const { - return std::string("joint")+std::to_string(joint_idx)+"_"+data_name+".dat"; -} - //--- Robot ----------------------------------------------------------------------------- Robot::Robot(float path_segment_time_step) : @@ -167,6 +55,9 @@ Robot::Robot(float path_segment_time_step) : max_acceleration = LinearAngular(500.0f, 50.0f); path_buffering_time_us = 50*1e3; + for(int i=0; iset_crc_enabled(ENABLE_ENCODER_CRC); joints[0] = new RobotJoint(encoder, motor_driver, MOTOR1_POLE_PAIRS); } @@ -201,6 +93,7 @@ void Robot::init() { PIN_MOTOR_EN, PIN_M2_PWM_A_POS, PIN_M2_PWM_A_NEG, PIN_MOTOR_PWMAB, PIN_MOTOR_EN, PIN_M2_PWM_B_POS, PIN_M2_PWM_B_NEG, PIN_MOTOR_PWMAB ); + encoder->set_crc_enabled(ENABLE_ENCODER_CRC); joints[1] = new RobotJoint(encoder, motor_driver, MOTOR2_POLE_PAIRS); } @@ -211,6 +104,7 @@ void Robot::init() { PIN_MOTOR_EN, PIN_M3_PWM_A_POS, PIN_M3_PWM_A_NEG, PIN_MOTOR_PWMAB, PIN_MOTOR_EN, PIN_M3_PWM_B_POS, PIN_M3_PWM_B_NEG, PIN_MOTOR_PWMAB ); + encoder->set_crc_enabled(ENABLE_ENCODER_CRC); joints[2] = new RobotJoint(encoder, motor_driver, MOTOR3_POLE_PAIRS); } @@ -220,6 +114,13 @@ void Robot::init() { joints[i]->load_calibration(); } + // add tools + robot_tools[0] = new PwmTool(); + ((PwmTool*)robot_tools[0])->init(PIN_TOOL1, 8000, 8); + + robot_tools[1] = new PwmTool(); + ((PwmTool*)robot_tools[1])->init(PIN_TOOL2, 8000, 8); + // setup timer for updating the motion controller (which evaluates joint space path // segments and produces the current target position for the servo loops) float motion_controller_update_time_us = 500; @@ -280,13 +181,14 @@ void Robot::update_path_planner() { } /** - * Updates the motion controller with a timer interrupt in regular intervals. + * Updates the motion controller with a timer interrupt in regular intervals (e.g. 2kHz). * The function evaluates joint space path segments and produces the current * target position for the servo loops. */ bool Robot::update_motion_controller_isr(repeating_timer_t* timer) { float joint_positions[NUM_JOINTS]; float joint_velocities[NUM_JOINTS]; + float tool_outputs[NUM_TOOLS]; // get robot pointer Robot* robot = (Robot*)timer->user_data; @@ -296,8 +198,8 @@ bool Robot::update_motion_controller_isr(repeating_timer_t* timer) { float dt = float(time_us - robot->last_mc_update_time)*1e-6f; robot->last_mc_update_time = time_us; - // get current joint position/velocity - bool update_ok = robot->motion_controller.update(dt, joint_positions, joint_velocities); + // get current joint position/velocity and tool outputs + bool update_ok = robot->motion_controller.update(dt, joint_positions, joint_velocities, tool_outputs); // Attempt to acquire spinlock non-blocking and set new target data for the servo loops if (update_ok && spin_try_lock_unsafe(robot->shared_data.lock)) { @@ -308,6 +210,16 @@ bool Robot::update_motion_controller_isr(repeating_timer_t* timer) { spin_unlock_unsafe(robot->shared_data.lock); } + // update tool outputs + if(update_ok) { + auto& tools = robot->robot_tools; + for(int i=0; iset_value(tool_outputs[i]); + } + } + // update frequency counter robot->motion_controller_frequency_counter.update(dt); @@ -315,7 +227,7 @@ bool Robot::update_motion_controller_isr(repeating_timer_t* timer) { } /** - * update servo loops, this is called from a second cpu core + * update servo loops, this is called from the second cpu core */ void Robot::update_servo_controllers(float dt) { float one_over_dt = 1.0f/dt; @@ -394,6 +306,10 @@ Pose6DF Robot::pose_from_joint_angles() { return pose; } +CommandParser* Robot::get_command_parser() { + return &command_parser; +} + bool Robot::check_all_joints_ready() { bool all_ready = true; for(int i=0; iencoder->read_abs_angle()*Constants::RAD2DEG; + int32_t crc_errors = joints[i]->encoder->is_crc_enabled() ? joints[i]->encoder->get_crc_error_count(false) : -1; reply += std::string("Joint ") + std::to_string(i)+":"; reply += std::string(" is_homed=") + std::to_string(joints[i]->is_homed); - reply += std::string(" is_calibrated=") + std::to_string(joints[i]->is_calibrated); - reply += std::string(" encoder_angle=") + std::to_string(angle) + " deg\n"; + reply += std::string(", is_calibrated=") + std::to_string(joints[i]->is_calibrated); + reply += std::string(", encoder_angle=") + std::to_string(angle) + " deg"; + reply += std::string(", crc_errors=") + std::to_string(crc_errors); + reply += std::string(", enc_status=") + std::to_string(joints[i]->encoder->get_status()) + "\n"; } spin_unlock_unsafe(joints_spin_lock); reply += std::string("Servo Loop: ") + std::to_string(servo_loop_freq/1000) + " kHz\n"; reply += std::string("Motion Controler: ") + std::to_string(mcontroler_freq) + " Hz\n"; + for(int i=0; iservo_controller->get_enc_to_pos_lut().print_to_log(); + return; } // set linear and angular acceleration @@ -648,16 +587,20 @@ void Robot::process_machine_command(const GCodeCommand& cmd, std::string& reply) if(cmd.has_word('L')) max_acceleration.linear = cmd.get_value('L'); if(cmd.has_word('A')) max_acceleration.angular = cmd.get_value('A'); reply += "ok\n"; + return; } } void Robot::process_motion_command(const GCodeCommand& cmd, std::string& reply) { Pose6DF end_pose; + #ifndef JOINT_READY_OVERRIDE if(!all_joints_ready) { reply = "error: not all joints calibrated and homed\n"; return; } + #endif + if(path_planner.input_queue_full()) { reply = "busy\n"; return; @@ -684,9 +627,11 @@ void Robot::process_motion_command(const GCodeCommand& cmd, std::string& reply) } // create path segment - CartesianPathSegment path_segment(current_pose, end_pose, + CartesianPathSegment path_segment(current_pose, + end_pose, current_feedrate, - max_acceleration); + max_acceleration, + current_tool_outputs); bool ok = path_planner.add_cartesian_path_segment(path_segment); if(ok) { @@ -698,6 +643,10 @@ void Robot::process_motion_command(const GCodeCommand& cmd, std::string& reply) } } +/** + * Immediately sets the current pose without creating path segments or + * interpolating from current position. Useful for external realtime controll. + */ void Robot::process_set_pose_command(const GCodeCommand& cmd, std::string& reply) { Pose6DF pose; @@ -725,10 +674,17 @@ void Robot::process_set_pose_command(const GCodeCommand& cmd, std::string& reply } void Robot::process_dwell_command(const GCodeCommand& cmd, std::string& reply) { + #ifndef JOINT_READY_OVERRIDE if(!all_joints_ready) { reply = "error: not all joints calibrated and homed\n"; return; } + #endif + + if(path_planner.input_queue_full()) { + reply = "busy\n"; + return; + } // get dwell time float dwell_time = 1.0f; @@ -736,11 +692,15 @@ void Robot::process_dwell_command(const GCodeCommand& cmd, std::string& reply) { if(cmd.has_word('P')) dwell_time = cmd.get_value('P')*0.001f; // time given in milliseconds // create path segment - CartesianPathSegment path_segment(current_pose, dwell_time); - path_planner.add_cartesian_path_segment(path_segment); - path_planner.run_look_ahead_planning(); + CartesianPathSegment path_segment(current_pose, current_tool_outputs, dwell_time); + bool ok = path_planner.add_cartesian_path_segment(path_segment); - reply = "ok\n"; + if(ok) { + path_planner.run_look_ahead_planning(); + reply = "ok\n"; + } else { + reply = "error\n"; + } } void Robot::process_set_servo_parameter_command(const GCodeCommand& cmd, std::string& reply) { @@ -798,3 +758,19 @@ void Robot::process_calibrate_joint_command(const GCodeCommand& cmd, std::string bool ok = calibrate_joint(idx, store_calibration, print_measurements); reply = ok ? "ok\n" : "error\n"; } + +void Robot::process_tool_output_command(const GCodeCommand& cmd, std::string& reply) { + // get tool index + int tool_index = (int)cmd.get_value('T', 0); + if(tool_index < 0 || tool_index >= NUM_TOOLS) { + reply = "error: Tool index out of range\n"; + return; + } + + // set current tool output value + float tool_value = cmd.get_value('S', 0.0f); + current_tool_outputs[tool_index] = tool_value; + + reply = "ok\n"; +} + diff --git a/firmware/MotionControllerRP/src/robot.h b/firmware/MotionControllerRP/src/robot.h index c2e917a..cf40123 100644 --- a/firmware/MotionControllerRP/src/robot.h +++ b/firmware/MotionControllerRP/src/robot.h @@ -20,17 +20,11 @@ #include "motion_control/motion_controller.h" #include "command_parser/command_parser.h" -constexpr int ENCODER_LUT_SIZE = 256; - -//*** CALSS ***************************************************************************** +//*** CLASS ***************************************************************************** class Robot; - -//--- PersistentData -------------------------------------------------------------------- - -struct PersistentRobotData { - float encoder_lut[NUM_JOINTS][ENCODER_LUT_SIZE]; -}; +class RobotJoint; +class IRobotTool; //--- SharedData ------------------------------------------------------------------------ @@ -54,36 +48,6 @@ struct SharedData { spin_lock_t* lock = nullptr; }; -//--- RobotJoint ------------------------------------------------------------------------ - -class RobotJoint { - public: - RobotJoint(MT6835Encoder* encoder, TB6612MotorDriver* motor_driver, int pole_pairs); - ~RobotJoint(); - - void init(int joint_idx); - bool calibrate(bool print_measurements); - void update(float dt, float one_over_dt); - void update_target(float p, float v); - bool load_calibration(); - bool store_calibration(); - - private: - std::string calib_data_filename(std::string data_name) const; - - public: - int joint_idx = 0; - bool is_homed = false; - bool is_calibrated = false; - - float position; - float velocity; - - MT6835Encoder* encoder; - TB6612MotorDriver* motor_driver; - ServoController* servo_controller; -}; - //--- Robot ----------------------------------------------------------------------------- class Robot : public ICommandProcessor { @@ -103,6 +67,8 @@ class Robot : public ICommandProcessor { void set_pose(const Pose6DF& pos); Pose6DF pose_from_joint_angles(); + + CommandParser* get_command_parser(); public: void send_reply(const char* str) override; @@ -116,6 +82,7 @@ class Robot : public ICommandProcessor { void process_set_servo_parameter_command(const GCodeCommand& cmd, std::string& reply); void process_home_command(const GCodeCommand& cmd, std::string& reply); void process_calibrate_joint_command(const GCodeCommand& cmd, std::string& reply); + void process_tool_output_command(const GCodeCommand& cmd, std::string& reply); protected: bool check_all_joints_ready(); // checks if all joints are homed and calibrated @@ -136,6 +103,7 @@ class Robot : public ICommandProcessor { CommandParser command_parser; Pose6DF current_pose; + float current_tool_outputs[NUM_TOOLS]; LinearAngular max_acceleration; LinearAngular current_feedrate; @@ -146,4 +114,6 @@ class Robot : public ICommandProcessor { FrequencyCounter servo_loop_frequency_counter; FrequencyCounter motion_controller_frequency_counter; + + std::array robot_tools; }; diff --git a/firmware/MotionControllerRP/src/robot_joint/robot_joint.cpp b/firmware/MotionControllerRP/src/robot_joint/robot_joint.cpp new file mode 100644 index 0000000..2478c2f --- /dev/null +++ b/firmware/MotionControllerRP/src/robot_joint/robot_joint.cpp @@ -0,0 +1,139 @@ +// -------------------------------------------------------------------------------------- +// Project: MicroManipulatorStepper +// License: MIT (see LICENSE file for full description) +// All text in here must be included in any redistribution. +// Author: M. S. (diffraction limited) +// -------------------------------------------------------------------------------------- + +#include +#include "robot_joint.h" +#include "hw_config.h" +#include "utilities/logging.h" +#include "utilities/utilities.h" +#include "servo_control/homing_controller.h" +#include "servo_control/actuator_calibration.h" + +//*** FUNCTION ************************************************************************** + +//*** CLASS ***************************************************************************** + +//--- RobotJoint ------------------------------------------------------------------------ + +RobotJoint::RobotJoint(MT6835Encoder* encoder, + TB6612MotorDriver* motor_driver, + int pole_pairs) +{ + RobotJoint::encoder = encoder; + RobotJoint::motor_driver = motor_driver; + servo_controller = new ServoController(*motor_driver, *encoder, pole_pairs); + position = 0.0f; + velocity = 0.0f; +} + +RobotJoint::~RobotJoint() { + delete servo_controller; + delete motor_driver; + delete encoder; + servo_controller = nullptr; + motor_driver = nullptr; + encoder = nullptr; +} + +void RobotJoint::init(int joint_idx) { + RobotJoint::joint_idx = joint_idx; + + if(encoder->init(0x5, 0x4) == false) { + LOG_ERROR("Failed to initialize encoder for joint %i", joint_idx); + } + + servo_controller->init(MOTOR_MAX_CURRENT_FACTOR); + servo_controller->set_motor_enabled(false, false); +} + +bool RobotJoint::calibrate(bool print_measurements) { + LOG_INFO("Joint-%i: calibrating joint...", joint_idx); + + HomingController homing_controller; + bool homing_ok = homing_controller.run_blocking(servo_controller, -HOMING_VELOCITY, + 360.0f*DEG_TO_RAD, HOMING_CURRENT, + ENCODER_ANGLE_TO_ROTOR_ANGLE, + CALIBRATION_RETRACT_ANGLE*DEG_TO_RAD); + if(homing_ok == false) { + LOG_ERROR("Joint-%i: Calibration failed due to unsuccessful homing sequence", joint_idx); + return false; + } + + // measure lookup tables + LookupTable encoder_raw_to_motor_pos_lut; + LookupTable motor_pos_to_field_angle_lut; + bool ok = measure_calibration_data(encoder_raw_to_motor_pos_lut, + motor_pos_to_field_angle_lut, + *servo_controller, + CALIBRATION_RANGE*DEG_TO_RAD, + CALIBRATION_FIELD_VELOCITY, + 256, + print_measurements); + if(!ok) { + LOG_ERROR("Joint-%i: calibrating failed", joint_idx); + return false; + } + + servo_controller->set_enc_to_pos_lut(encoder_raw_to_motor_pos_lut); + servo_controller->set_pos_to_field_lut(motor_pos_to_field_angle_lut); + is_calibrated = true; + is_homed = true; + + LOG_INFO("Joint-%i: calibrating joint successful.", joint_idx); + + return true; +} + +void RobotJoint::update(float dt, float one_over_dt) { + servo_controller->update(position, dt, one_over_dt); +} + +void RobotJoint::update_target(float p, float v) { + position = p; + velocity = v; +} + +bool RobotJoint::load_calibration() { + std::string fn1 = calib_data_filename("enc_to_pos_lut").c_str(); + std::string fn2 = calib_data_filename("pos_to_field_lut").c_str(); + if(!LittleFS.exists(fn1.c_str()) || !LittleFS.exists(fn2.c_str())) { + LOG_WARNING("Joint-%i: Not all calibration files found. Run joint calibration with M56.", joint_idx); + return false; + } + + LookupTable enc_to_pos_lut; + LookupTable pos_to_field_lut; + bool res = true; + res &= load_lut_from_file(enc_to_pos_lut, fn1.c_str()); + res &= load_lut_from_file(pos_to_field_lut, fn2.c_str()); + if(res == false) + return false; + + servo_controller->set_enc_to_pos_lut(enc_to_pos_lut); + servo_controller->set_pos_to_field_lut(pos_to_field_lut); + + is_calibrated = true; + LOG_INFO("Joint-%i: Encoder lookup tables loaded (size=%i,%i)", + joint_idx, enc_to_pos_lut.size(), pos_to_field_lut.size()); + + return true; +} + +bool RobotJoint::store_calibration() { + bool res = true; + + res &= save_lut_to_file(servo_controller->get_enc_to_pos_lut(), + calib_data_filename("enc_to_pos_lut").c_str()); + res &= save_lut_to_file(servo_controller->get_pos_to_field_lut(), + calib_data_filename("pos_to_field_lut").c_str()); + + return res; +} + +std::string RobotJoint::calib_data_filename(std::string data_name) const { + return std::string("joint")+std::to_string(joint_idx)+"_"+data_name+".dat"; +} diff --git a/firmware/MotionControllerRP/src/robot_joint/robot_joint.h b/firmware/MotionControllerRP/src/robot_joint/robot_joint.h new file mode 100644 index 0000000..e5cf906 --- /dev/null +++ b/firmware/MotionControllerRP/src/robot_joint/robot_joint.h @@ -0,0 +1,60 @@ +// -------------------------------------------------------------------------------------- +// Project: MicroManipulatorStepper +// License: MIT (see LICENSE file for full description) +// All text in here must be included in any redistribution. +// Author: M. S. (diffraction limited) +// -------------------------------------------------------------------------------------- + +#pragma once + +#include "utilities/logging.h" +#include "utilities/frequency_counter.h" +#include "hardware/MT6701_encoder.h" +#include "hardware/MT6835_encoder.h" +#include "hardware/TB6612_motor_driver.h" +#include "servo_control/servo_controller.h" +#include "utilities/lookup_table.h" +#include "utilities/math_constants.h" + +#include "motion_control/path_planner.h" +#include "motion_control/motion_controller.h" +#include "command_parser/command_parser.h" +#include "robot_joint_interface.h" + +//*** CLASS ***************************************************************************** + +//--- RobotJoint ------------------------------------------------------------------------ + +// TODO: create abstract interface for RobotJoint (to support remote Joints) +// hide direct HW access + +class RobotJoint { + public: + RobotJoint(MT6835Encoder* encoder, TB6612MotorDriver* motor_driver, int pole_pairs); + ~RobotJoint(); + + void init(int joint_idx); + bool calibrate(bool print_measurements); + void update(float dt, float one_over_dt); + void update_target(float p, float v); + bool load_calibration(); + bool store_calibration(); + + + private: + std::string calib_data_filename(std::string data_name) const; + + public: + int joint_idx = 0; + bool is_homed = false; + bool is_calibrated = false; + + float position; + float velocity; + + MT6835Encoder* encoder; + ServoController* servo_controller; + + private: + TB6612MotorDriver* motor_driver; +}; diff --git a/firmware/MotionControllerRP/src/robot_joint/robot_joint_interface.h b/firmware/MotionControllerRP/src/robot_joint/robot_joint_interface.h new file mode 100644 index 0000000..f5fc8be --- /dev/null +++ b/firmware/MotionControllerRP/src/robot_joint/robot_joint_interface.h @@ -0,0 +1,28 @@ +// -------------------------------------------------------------------------------------- +// Project: MicroManipulatorStepper +// License: MIT (see LICENSE file for full description) +// All text in here must be included in any redistribution. +// Author: M. S. (diffraction limited) +// -------------------------------------------------------------------------------------- + +#pragma once + +//*** CLASS ***************************************************************************** + +//--- RobotJoint ------------------------------------------------------------------------ + +// TODO: create abstract interface for RobotJoint (to support remote Joints) +// hide direct HW access + +class IRobotJoint { + public: + virtual ~IRobotJoint() {}; + + void init(int joint_idx); + void update_target(float p, float v); + bool load_calibration(); + bool store_calibration(); + + virtual bool calibrate(bool print_measurements) = 0; + virtual void update(float dt, float one_over_dt) = 0; +}; diff --git a/firmware/MotionControllerRP/src/robot_tool/pwm_tool.cpp b/firmware/MotionControllerRP/src/robot_tool/pwm_tool.cpp new file mode 100644 index 0000000..a44ba25 --- /dev/null +++ b/firmware/MotionControllerRP/src/robot_tool/pwm_tool.cpp @@ -0,0 +1,131 @@ +#include "pwm_tool.h" +#include "hardware/clocks.h" +#include "hardware/pio.h" +#include "utilities/logging.h" + +//--- PIO ----------------------------------------------------------------------------------------- + +/* +.program pwm +.side_set 1 opt + + pull noblock ; Pull from FIFO to OSR if available, else copy X to OSR. + mov x, osr ; Copy most-recently-pulled value back to scratch X + mov y, isr ; ISR contains PWM period. Y used as counter. + + jmp x!=y set_output_off + jmp compare_end +set_output_off: + nop side 0 +compare_end: + +countloop: + jmp x!=y noset ; Set pin high if X == Y, keep the two paths length matched + jmp skip side 1 +noset: + nop ; Single dummy cycle to keep the two paths the same length +skip: + jmp y-- countloop ; Loop until Y hits 0, then pull a fresh PWM value from FIFO + +% c-sdk { +static inline void pwm_program_init(PIO pio, uint sm, uint offset, uint pin) { + pio_gpio_init(pio, pin); + pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true); + pio_sm_config c = pwm_program_get_default_config(offset); + sm_config_set_sideset_pins(&c, pin); + pio_sm_init(pio, sm, offset, &c); +} +%} +*/ + +#define pwm_wrap_target 0 +#define pwm_wrap 9 + +static const uint16_t pwm_program_instructions[] = { + // .wrap_target + 0x8080, // 0: pull noblock + 0xa027, // 1: mov x, osr + 0xa046, // 2: mov y, isr + 0x00a5, // 3: jmp x != y, 5 + 0x0006, // 4: jmp 6 + 0xb042, // 5: nop side 0 + 0x00a8, // 6: jmp x != y, 8 + 0x1809, // 7: jmp 9 side 1 + 0xa042, // 8: nop + 0x0086, // 9: jmp y--, 6 + // .wrap +}; + +static const struct pio_program pwm_program = { + .instructions = pwm_program_instructions, + .length = 10, + .origin = -1, +}; + +// Helper to set the PWM period (the 'resolution') via the ISR +void pio_pwm_set_period(PIO pio, uint sm, uint32_t period) { + pio_sm_set_enabled(pio, sm, false); + pio_sm_put_blocking(pio, sm, period); + // Pull the period from FIFO to OSR, then move OSR to ISR + pio_sm_exec(pio, sm, pio_encode_pull(false, false)); + pio_sm_exec(pio, sm, pio_encode_out(pio_isr, 32)); + pio_sm_set_enabled(pio, sm, true); +} + +static inline pio_sm_config pwm_program_get_default_config(uint offset) { + pio_sm_config c = pio_get_default_sm_config(); + sm_config_set_wrap(&c, offset + pwm_wrap_target, offset + pwm_wrap); + sm_config_set_sideset(&c, 2, true, false); + return c; +} + +static inline void pwm_program_init(PIO pio, uint sm, uint offset, uint pin, float clk_div) { + pio_gpio_init(pio, pin); + pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true); + pio_sm_config c = pwm_program_get_default_config(offset); + sm_config_set_sideset_pins(&c, pin); + sm_config_set_clkdiv(&c, clk_div); // added + pio_sm_init(pio, sm, offset, &c); +} + +//--- PwmTool ------------------------------------------------------------------------------------- + +void PwmTool::init(int output_pin, int frequency, int resolution_bits) { + PwmTool::pio = pio0; + + // calculate max value + max_pwm = (1u << resolution_bits) - 1; + this->output_pin = output_pin; + + // load program and claim state machine + uint offset = pio_add_program(pio, &pwm_program); + state_machine = pio_claim_unused_sm(pio, true); + if(state_machine < 0) + LOG_ERROR("PwmTool::init: No free PIO statemachine available"); + + // compute clock divisor + float sysclk = (float)clock_get_hz(clk_sys); + float clkdiv = sysclk / (frequency * (max_pwm + 1) * 2); + + // initialize program + pwm_program_init(pio, state_machine, offset, output_pin, clkdiv); + + // subtract -1 here since the PIO loop includes start value AND 0 + pio_pwm_set_period(pio, state_machine, max_pwm-1); + set_value(0.0f); +} + +void PwmTool::set_value(float v) { + if (v < 0.0f) v = 0.0f; + if (v > 1.0f) v = 1.0f; + + // Scale 0.0-1.0 to 0-max_pwm + uint32_t duty = (uint32_t)(v * max_pwm); + + // subtract -1 to match decresed period - the underflow results in correct + // contnuous off state for 0 duty cycle + duty--; + + // The PIO program pulls from the TX FIFO + pio_sm_put_blocking(pio, state_machine, duty); +} \ No newline at end of file diff --git a/firmware/MotionControllerRP/src/robot_tool/pwm_tool.h b/firmware/MotionControllerRP/src/robot_tool/pwm_tool.h new file mode 100644 index 0000000..6ee5898 --- /dev/null +++ b/firmware/MotionControllerRP/src/robot_tool/pwm_tool.h @@ -0,0 +1,32 @@ +// -------------------------------------------------------------------------------------- +// Project: MicroManipulatorStepper +// License: MIT (see LICENSE file for full description) +// All text in here must be included in any redistribution. +// Author: M. S. (diffraction limited) +// -------------------------------------------------------------------------------------- + +#pragma once + +#include "pico/stdlib.h" +#include "hardware/pio.h" +#include "hardware/clocks.h" +#include "robot_tool_interface.h" + +//*** CLASS ***************************************************************************** + +//--- PwmTool --------------------------------------------------------------------------- + +class PwmTool : public IRobotTool { + public: + ~PwmTool() {}; + + void init(int output_pin, int frequency, int resolution_bits); + void set_value(float v) override; + + private: + PIO pio = pio0; + int state_machine = 0; + int output_pin = 0; + + uint32_t max_pwm = 0; +}; \ No newline at end of file diff --git a/firmware/MotionControllerRP/src/robot_tool/robot_tool_interface.h b/firmware/MotionControllerRP/src/robot_tool/robot_tool_interface.h new file mode 100644 index 0000000..bb0d63b --- /dev/null +++ b/firmware/MotionControllerRP/src/robot_tool/robot_tool_interface.h @@ -0,0 +1,18 @@ +// -------------------------------------------------------------------------------------- +// Project: MicroManipulatorStepper +// License: MIT (see LICENSE file for full description) +// All text in here must be included in any redistribution. +// Author: M. S. (diffraction limited) +// -------------------------------------------------------------------------------------- + +#pragma once + +//*** CLASS ***************************************************************************** + +//--- IRobotTool ------------------------------------------------------------------------ + +class IRobotTool { + public: + virtual ~IRobotTool() {}; + virtual void set_value(float v) = 0; +}; \ No newline at end of file diff --git a/firmware/MotionControllerRP/src/servo_control/actuator_calibration.cpp b/firmware/MotionControllerRP/src/servo_control/actuator_calibration.cpp index 0f1d7a6..92a0d27 100644 --- a/firmware/MotionControllerRP/src/servo_control/actuator_calibration.cpp +++ b/firmware/MotionControllerRP/src/servo_control/actuator_calibration.cpp @@ -13,7 +13,6 @@ #include "actuator_calibration.h" - //*** FUNCTION ***********************************************************************************/ bool measure_calibration_data( @@ -25,6 +24,8 @@ bool measure_calibration_data( size_t table_size, bool print_measurements) { + const float max_rmse_rad = Constants::DEG2RAD * 0.5f; + LOG_INFO("Measuring motor to encoder angle lookup table..."); int sample_count = table_size*4; @@ -37,18 +38,27 @@ bool measure_calibration_data( float start_field_angle = motor_driver.get_field_angle(); float field_angle_step = calibration_range*pole_pair_count/(sample_count-1); - auto run_measurement = [&](int sample_count, float field_angle_step) { + auto& encoder = servo_controller.get_encoder(); + + encoder.get_crc_error_count(true); // reset crc error count + bool was_crc_enabled = encoder.is_crc_enabled(); + encoder.set_crc_enabled(true); + + auto run_measurement = [&](int sample_count, float field_angle_step, int& weak_field_measurements) { // Measure in increasing direction for (size_t i = 0; i < sample_count; ++i) { if(i>0) motor_driver.rotate_field(field_angle_step, field_velocity, nullptr); - float encoder_angle_raw = servo_controller.get_encoder().read_abs_angle_raw(); + float encoder_angle_raw = encoder.read_abs_angle_raw(); float field_angle = motor_driver.get_field_angle(); float motor_pos = (field_angle-start_field_angle)/pole_pair_count; // TODO: read motor_pos from precise reference encoder - - if(print_measurements) + + if(encoder.get_status() & MT6835_STATUS_WEAKFIELD) + weak_field_measurements++; + + if(true) LOG_RAW("%15.10f, %15.10f, %f", motor_pos, field_angle, encoder_angle_raw); encoder_angle_and_motor_pos.push_back({encoder_angle_raw, motor_pos}); @@ -57,31 +67,57 @@ bool measure_calibration_data( }; // Measure in increasing direction + int weak_field_measurements = 0; LOG_DEBUG("Running foreward pass..."); - run_measurement(sample_count, field_angle_step); + run_measurement(sample_count, field_angle_step, weak_field_measurements); LOG_DEBUG("Running backward pass..."); - run_measurement(sample_count, -field_angle_step); + run_measurement(sample_count, -field_angle_step, weak_field_measurements); // rotate back to start position motor_driver.rotate_field(start_field_angle-motor_driver.get_field_angle(), Constants::TWO_PI_F*40.0f, [&servo_controller]() { servo_controller.get_encoder().read_abs_angle_raw(); }); + + encoder.set_crc_enabled(was_crc_enabled); - // build lookup tables - bool ok = encoder_raw_to_motor_pos_lut.init_interpolating(encoder_angle_and_motor_pos, table_size, true); - encoder_raw_to_motor_pos_lut.optimize_lut(encoder_angle_and_motor_pos); - if(ok == false) { - LOG_ERROR("Creating lookup table encoder_raw_angle -> motor_pos failed."); + uint32_t encorder_crc_errors = encoder.get_crc_error_count(false); + if(encorder_crc_errors > 0) { + LOG_WARNING("Data error (CRC) in %i of %i measurements", encorder_crc_errors, sample_count); + // return false; + } + + if(weak_field_measurements > 0) { + LOG_ERROR("Magnetic field too weak for %i of %i measurements", weak_field_measurements, sample_count); return false; } - ok = motor_pos_to_field_angle_lut.init_interpolating(motor_pos_and_field_angle, table_size/2, true); - motor_pos_to_field_angle_lut.optimize_lut(motor_pos_and_field_angle); + // build lookup table 'encoder_raw_angle -> motor_pos' + float rmse = 0.0f; + bool ok = encoder_raw_to_motor_pos_lut.init_interpolating(encoder_angle_and_motor_pos, table_size, true); if(ok == false) { - LOG_ERROR("Creating lookup table motor_pos -> field_angle failed."); + LOG_ERROR("Creating lookup table 'encoder_raw_angle -> motor_pos' failed."); return false; } + encoder_raw_to_motor_pos_lut.optimize_lut(encoder_angle_and_motor_pos, rmse); + if(rmse > max_rmse_rad) { + LOG_WARNING("Fitting error of lookup table 'encoder_raw_angle -> motor_pos' unusually high (rms_error = %f deg)." + "Calibration might be invalid.", + Constants::RAD2DEG*rmse); + } + + // build lookup table 'motor_pos -> field_angle' + ok = motor_pos_to_field_angle_lut.init_interpolating(motor_pos_and_field_angle, table_size/2, true); + if(ok == false) { + LOG_ERROR("Creating lookup table 'motor_pos -> field_angle' failed."); + return false; + } + motor_pos_to_field_angle_lut.optimize_lut(motor_pos_and_field_angle, rmse); + if(rmse > max_rmse_rad) { + LOG_WARNING("Fitting error of lookup table 'motor_pos -> field_angle' is unusually high (rms_error = %f deg)." + "Calibration might be invalid.", + Constants::RAD2DEG*rmse); + } LOG_INFO("finished"); return true; diff --git a/firmware/MotionControllerRP/src/servo_control/homing_controller.cpp b/firmware/MotionControllerRP/src/servo_control/homing_controller.cpp index 7b56c27..52cf67c 100644 --- a/firmware/MotionControllerRP/src/servo_control/homing_controller.cpp +++ b/firmware/MotionControllerRP/src/servo_control/homing_controller.cpp @@ -36,7 +36,7 @@ void HomingController::start(ServoController* servo_controller, float pole_pair_count = servo_controller->get_pole_pair_count(); float field_angle_to_encoder_angle = 1.0f / pole_pair_count / encoder_angle_to_motor_angle; - if(retract_angle_rad >= 0.0f) + if(retract_angle_rad > 0.0f) HomingController::retract_field_angle = retract_angle_rad * pole_pair_count; // field_angle_to_rotor_angle = 1.0 / pole_pair_count @@ -136,7 +136,7 @@ void HomingController::on_endstop_detected() { void HomingController::finalize() { auto& motor_driver = servo_ctrl->get_motor_driver(); float pole_pair_count = servo_ctrl->get_pole_pair_count(); - + // back off from home position motor_driver.rotate_field(retract_field_angle * (field_velocity>0.0f ? -1.0f : 1.0f), retract_field_velocity, [this](){ diff --git a/firmware/MotionControllerRP/src/servo_control/servo_controller.cpp b/firmware/MotionControllerRP/src/servo_control/servo_controller.cpp index 39a6b82..d0d1119 100644 --- a/firmware/MotionControllerRP/src/servo_control/servo_controller.cpp +++ b/firmware/MotionControllerRP/src/servo_control/servo_controller.cpp @@ -12,6 +12,8 @@ #include "utilities/logging.h" #include "utilities/math_constants.h" +#include "hw_config.h" + #include ServoController::ServoController( @@ -44,9 +46,14 @@ void ServoController::init(float max_motor_amplitude) { motor_driver.enable(); motor_driver.set_field_angle(0.0f); - velocity_lowpass.set_time_constant(0.004f); - pos_controller.set_parameter(75.0f, 50000.0f, 0.0f, Constants::PI_F*2.0F, Constants::PI_F*0.5F); - velocity_controller.set_parameter(0.2f, 150.0f, 0.0f, Constants::PI_F*0.45f, Constants::PI_F*0.45f); + velocity_lowpass.set_time_constant(VEL_LOWPASS_TC); + + pos_controller.set_parameter(POS_KP, POS_KI, 0.0f, Constants::PI_F*2.0F, Constants::PI_F*0.5F); + velocity_controller.set_parameter(VEL_KP, VEL_KI, 0.0f, Constants::PI_F*0.45f, Constants::PI_F*0.45f); + + // large 0.9° steppers +// pos_controller.set_parameter(75.0f, 50000.0f, 0.0f, Constants::PI_F*2.0F, Constants::PI_F*0.5F); +// velocity_controller.set_parameter(0.2f, 150.0f, 0.0f, Constants::PI_F*0.45f, Constants::PI_F*0.45f); // pos_controller.set_parameter(75.0f, 2000.0f, 0.0f, Constants::PI_F*2.0F, Constants::PI_F*0.5F); // velocity_controller.set_parameter(0.2f, 0.0f, 0.0f, Constants::PI_F*0.45f, Constants::PI_F*0.45f); diff --git a/firmware/MotionControllerRP/src/utilities/lookup_table.cpp b/firmware/MotionControllerRP/src/utilities/lookup_table.cpp index 253cc5c..375b1c3 100644 --- a/firmware/MotionControllerRP/src/utilities/lookup_table.cpp +++ b/firmware/MotionControllerRP/src/utilities/lookup_table.cpp @@ -147,7 +147,7 @@ bool LookupTable::init_interpolating(std::vector> in_out return true; } -bool LookupTable::optimize_lut(std::vector> in_out_pairs) { +bool LookupTable::optimize_lut(std::vector> in_out_pairs, float& rms_error) { if (lookup_table.empty() || in_out_pairs.empty()) return false; @@ -198,7 +198,9 @@ bool LookupTable::optimize_lut(std::vector> in_out_pairs //if(iter%100 == 0) // LOG_DEBUG("iteration %04i: rms=%f", iter, sqrtf(total_loss)); } - LOG_DEBUG("Optimizing lookup table finished: rms=%f", total_loss); + + rms_error = sqrt(total_loss); + LOG_DEBUG("Optimizing lookup table finished: rms_error=%f", rms_error); return true; } diff --git a/firmware/MotionControllerRP/src/utilities/lookup_table.h b/firmware/MotionControllerRP/src/utilities/lookup_table.h index 456c4a1..5ea963b 100644 --- a/firmware/MotionControllerRP/src/utilities/lookup_table.h +++ b/firmware/MotionControllerRP/src/utilities/lookup_table.h @@ -27,7 +27,7 @@ class LookupTable { int table_size, bool sort_input); // optimizes the lookup table using gradient descen to minimize error to provided data - bool optimize_lut(std::vector> in_out_pairs); + bool optimize_lut(std::vector> in_out_pairs, float& rms_error); // clear the lookup table, use init to use it again void clear(); diff --git a/firmware/MotionControllerRP/src/version.h b/firmware/MotionControllerRP/src/version.h index 754176c..e6f4ba8 100644 --- a/firmware/MotionControllerRP/src/version.h +++ b/firmware/MotionControllerRP/src/version.h @@ -1 +1 @@ -static const char* FIRMWARE_VERSION = "v1.0.3"; +static const char* FIRMWARE_VERSION = "v1.0.5"; diff --git a/images/FreeCAD-Model.jpg b/images/FreeCAD-Model.jpg index 7034bf9..2f69065 100644 Binary files a/images/FreeCAD-Model.jpg and b/images/FreeCAD-Model.jpg differ diff --git a/images/Hardware-v4.0.jpg b/images/Hardware-v4.0.jpg new file mode 100644 index 0000000..d7935d2 Binary files /dev/null and b/images/Hardware-v4.0.jpg differ diff --git a/images/thumbnail.jpg b/images/video-thumbnails/01_MicroManipulator.jpg similarity index 100% rename from images/thumbnail.jpg rename to images/video-thumbnails/01_MicroManipulator.jpg diff --git a/images/video-thumbnails/02_BetterBallJoints.jpg b/images/video-thumbnails/02_BetterBallJoints.jpg new file mode 100644 index 0000000..e1686f5 Binary files /dev/null and b/images/video-thumbnails/02_BetterBallJoints.jpg differ diff --git a/software/PythonAPI/README.md b/software/PythonAPI/README.md new file mode 100644 index 0000000..ad855b0 --- /dev/null +++ b/software/PythonAPI/README.md @@ -0,0 +1,66 @@ +# Python API + +This folder contains a lightweight Python interface for the Open Micro-Manipulator serial protocol, plus two small example scripts: + +- `usage_example.py`: homes the device, performs a simple move, and prints device state information. +- `calibration_plotter.py`: runs joint calibration for the first three actuators and plots the returned data. + +## Requirements + +Install the Python dependencies with: + +```bash +python -m venv env +source env/bin/activate +pip install -r requirements.txt +``` + +The API itself is implemented in `open_micro_stage_api.py`. + +## Serial Port Selection + +Both scripts support: + +- `--list-ports`: list detected serial devices and exit +- `--port `: explicitly select a serial port + +If `--port` is not provided, the scripts try to choose a port automatically: + +1. If exactly one detected device contains `Pico` in its name, that port is used. +2. Otherwise, if there is exactly one detected serial device, that port is used. +3. Otherwise, the script lists the available ports and exits. + +## Running The Example Script + +From this folder: + +```bash +python usage_example.py --list-ports +python usage_example.py --port /dev/ttyACM0 +``` + +On Windows, a typical command looks like: + +```bash +python usage_example.py --port COM3 +``` + +## Running The Calibration Plotter + +From this folder: + +```bash +python calibration_plotter.py --list-ports +python calibration_plotter.py --port /dev/ttyACM0 +``` + +The calibration script opens a matplotlib window with the measured calibration curves. + +## Running From The Repository Root + +If you prefer to run the scripts from the repository root, use: + +```bash +python software/PythonAPI/usage_example.py --port /dev/ttyACM0 +python software/PythonAPI/calibration_plotter.py --port /dev/ttyACM0 +``` diff --git a/software/PythonAPI/calibration_plotter.py b/software/PythonAPI/calibration_plotter.py index c0e3f26..a6851de 100644 --- a/software/PythonAPI/calibration_plotter.py +++ b/software/PythonAPI/calibration_plotter.py @@ -1,7 +1,12 @@ -from open_micro_stage_api import OpenMicroStageInterface +import argparse + import matplotlib.pyplot as plt + +from open_micro_stage_api import OpenMicroStageInterface + plt.rcParams['figure.dpi'] = 200 + def plot_calibration_data(ax_encoder_counts, ax_field_angel, label, data): # Plot on the provided Axes object if ax_encoder_counts is not None: @@ -21,20 +26,92 @@ def plot_calibration_data(ax_encoder_counts, ax_field_angel, label, data): ax_field_angel.legend() ax_field_angel.grid(True) + +def list_available_ports(): + devices = OpenMicroStageInterface.enumerate_devices() + if not devices: + print('No serial devices detected.') + return devices + + print('Available serial devices:') + for device in devices: + print(f" {device['label']}") + + return devices + + +def resolve_port(port): + if port: + return port + + devices = OpenMicroStageInterface.enumerate_devices() + pico_devices = [device for device in devices if 'pico' in device['label'].lower()] + + if len(pico_devices) == 1: + print(f"Using detected Pico serial device: {pico_devices[0]['label']}") + return pico_devices[0]['port'] + + if len(pico_devices) > 1: + print('Multiple Pico serial devices detected. Pass --port to choose one:') + for device in pico_devices: + print(f" {device['label']}") + raise SystemExit(1) + + if len(devices) == 1: + print(f"Using detected serial device: {devices[0]['label']}") + return devices[0]['port'] + + if devices: + print('Multiple serial devices detected. Pass --port to choose one:') + for device in devices: + print(f" {device['label']}") + else: + print('No serial devices detected.') + + raise SystemExit(1) + + +def parse_args(): + parser = argparse.ArgumentParser( + description='Run joint calibration and plot the measured data.', + ) + parser.add_argument( + '--port', + help='Serial port to use (for example /dev/ttyACM0 or COM3).', + ) + parser.add_argument( + '--list-ports', + action='store_true', + help='List detected serial devices and exit.', + ) + return parser.parse_args() + + def main(): - # create interface and connect + args = parse_args() + if args.list_ports: + list_available_ports() + return + + port = resolve_port(args.port) oms = OpenMicroStageInterface(show_communication=True, show_log_messages=True) - oms.connect('/dev/ttyACM0') + if not oms.connect(port): + raise SystemExit(f'Could not connect to {port}.') - # Create subplots - fig, ax = plt.subplots(1, 1, figsize=(10, 7), sharex='all') + try: + # Create subplots + fig, ax = plt.subplots(1, 1, figsize=(10, 7), sharex='all') - for i in range(3): - res, data = oms.calibrate_joint(i, save_result=False) - plot_calibration_data(ax, None, f'Actuator {i}', data) + for i in range(3): + res, data = oms.calibrate_joint(i, save_result=False) + plot_calibration_data(ax, None, f'Actuator {i}', data) - # Adjust layout and show - plt.tight_layout() - plt.show() + # Adjust layout and show + plt.tight_layout() + plt.show() + finally: + oms.disconnect() -main() \ No newline at end of file + +if __name__ == '__main__': + main() diff --git a/software/PythonAPI/open_micro_stage_api.py b/software/PythonAPI/open_micro_stage_api.py index 3dc8835..c4d7268 100644 --- a/software/PythonAPI/open_micro_stage_api.py +++ b/software/PythonAPI/open_micro_stage_api.py @@ -1,3 +1,11 @@ +# -------------------------------------------------------------------------------------- +# Project: OpenMicroManipulator +# License: MIT (see LICENSE file for full description) +# All text in here must be included in any redistribution. +# Author: M. S. (diffraction limited) +# -------------------------------------------------------------------------------------- + +import os import threading import time import re @@ -6,6 +14,7 @@ from enum import Enum import serial import numpy as np from colorama import Fore, Style, init +from serial.tools import list_ports # --- SerialInterface -------------------------------------------------------------------------------------------------- @@ -59,18 +68,23 @@ class SerialInterface: self._response_string = "" self._response_status = None self._response_error_msg = None + self._stop_event = threading.Event() + self._reader_thread = None - self.connect(self.reconnect_timeout) - - # Start reader thread - self._reader_thread = threading.Thread(target=self._reader_loop, daemon=True) - self._reader_thread.start() + if self.connect(self.reconnect_timeout): + self._reader_thread = threading.Thread(target=self._reader_loop, daemon=True) + self._reader_thread.start() + while not self._reader_thread.is_alive(): + time.sleep(0.001) def connect(self, timeout): """ Try to open the serial port. Retry until timeout expires. """ + if self._stop_event.is_set(): + return False + deadline = time.time() + timeout print(Fore.MAGENTA, end='') print(f"[SerialInterface] Connecting to port '{self.port}'...", end='') @@ -81,6 +95,15 @@ class SerialInterface: print(Style.RESET_ALL, end='') return True except (serial.SerialException, OSError) as e: + if getattr(e, 'errno', None) == 13: # Permission denied + import os, sys + print(f"\n[SerialInterface] Permission denied on '{self.port}'.") + if sys.platform.startswith('linux'): + username = os.getenv('USER') or os.getenv('LOGNAME') or 'your_user' + print(f"[SerialInterface] Add your user to the dialout group and re-login: sudo usermod -aG dialout {username}") + print(Style.RESET_ALL, end='') + self.serial = None + return False print('.', end='') time.sleep(0.2) @@ -95,7 +118,7 @@ class SerialInterface: Asynchronous reader loop, collecting serial data into a buffer """ buffer = "" - while True: + while not self._stop_event.is_set(): try: if self.serial is not None and self.serial.in_waiting: char = self.serial.read(1).decode('ascii', errors='ignore') @@ -108,6 +131,9 @@ class SerialInterface: else: time.sleep(0.001) except (serial.SerialException, OSError) as e: + if self._stop_event.is_set(): + break + print(Fore.MAGENTA+f"[SerialInterface] Lost connection: {e}"+Style.RESET_ALL) try: if self.serial is not None and self.serial.is_open: @@ -195,8 +221,13 @@ class SerialInterface: def close(self): """Closes the serial port.""" + self._stop_event.set() if self.serial and self.serial.is_open: self.serial.close() + self.serial = None + + if self._reader_thread and self._reader_thread.is_alive(): + self._reader_thread.join(timeout=1.0) # --- OpenMicroStageInterface ------------------------------------------------------------------------------------------ @@ -212,19 +243,46 @@ class OpenMicroStageInterface: def __init__(self, show_communication=True, show_log_messages=True): self.serial = None self.workspace_transform = np.eye(4) + self.workspace_transform_inv = np.linalg.inv(self.workspace_transform) self.show_communication = show_communication self.show_log_messages = show_log_messages self.disable_message_callbacks = False + @staticmethod + def enumerate_devices(): + devices = [] + + for port in sorted(list_ports.comports(), key=lambda item: item.device): + description = (port.description or "").strip() + device_name = os.path.basename(port.device) + label = device_name + if description and description.lower() != "n/a" and description != port.device: + label = f"{device_name} - {description}" + + devices.append({ + "id": port.device, + "label": label, + "port": port.device, + }) + + return devices + def connect(self, port: str, baud_rate: int = 921600): def version_to_str(v): return f"v{v[0]}.{v[1]}.{v[2]}" - if self.serial is not None: self.disconnect() - self.serial = SerialInterface(port, baud_rate, - log_msg_callback=self.log_msg_callback, - command_msg_callback=self.command_msg_callback, - unsolicited_msg_callback=self.unsolicited_msg_callback) + if self.serial is not None: + self.disconnect() + + serial_interface = SerialInterface(port, baud_rate, + log_msg_callback=self.log_msg_callback, + command_msg_callback=self.command_msg_callback, + unsolicited_msg_callback=self.unsolicited_msg_callback) + if serial_interface.serial is None: + serial_interface.close() + return False + + self.serial = serial_interface self.disable_message_callbacks = True fw_version = self.read_firmware_version() @@ -233,15 +291,23 @@ class OpenMicroStageInterface: if fw_version < min_fw_version: print(Fore.MAGENTA + f"Firmware version {version_to_str(fw_version)} incompatible. " f"At least {version_to_str(min_fw_version)} required" + Style.RESET_ALL) + self.serial.close() self.serial = None + print('') + self.disable_message_callbacks = False + return False print('') self.disable_message_callbacks = False + return True def disconnect(self): if self.serial is not None: self.serial.close() self.serial = None + def is_connected(self): + return self.serial is not None + def log_msg_callback(self, log_level, msg): if not self.show_log_messages or self.disable_message_callbacks: return @@ -273,6 +339,7 @@ class OpenMicroStageInterface: def set_workspace_transform(self, transform): self.workspace_transform = transform + self.workspace_transform_inv = np.linalg.inv(self.workspace_transform) def get_workspace_transform(self): return self.workspace_transform @@ -282,7 +349,11 @@ class OpenMicroStageInterface: if ok != SerialInterface.ReplyStatus.OK or len(response) == 0: return 0, 0, 0 - major, minor, patch = map(int, re.match(r'v(\d+)\.(\d+)\.(\d+)', response).groups()) + match = re.match(r'v(\d+)\.(\d+)\.(\d+)', response) + if match is None: + return 0, 0, 0 + + major, minor, patch = map(int, match.groups()) return major,minor,patch def home(self, axis_list=None): @@ -370,11 +441,17 @@ class OpenMicroStageInterface: res, msg = self.serial.send_command("M53\n") if res != SerialInterface.ReplyStatus.OK: return res elif msg.strip() == "1": + self.disable_message_callbacks = disable_message_callbacks_prev return SerialInterface.ReplyStatus.OK + time.sleep(polling_interval_ms*0.001) self.disable_message_callbacks = disable_message_callbacks_prev - def read_current_position(self): + def read_current_position(self, apply_inv_workspace_transform): + """ + Reads the current position of the dives EXCLUDING the workspace transform. + If you want to use the result with a + """ ok, response = self.serial.send_command("M50") if ok != SerialInterface.ReplyStatus.OK or len(response) == 0: return None, None, None @@ -388,6 +465,10 @@ class OpenMicroStageInterface: raise ValueError(f"Invalid format: {response}") x, y, z = match.groups() + if apply_inv_workspace_transform: + transformed = self.workspace_transform_inv @ np.array([float(x), float(y), float(z), 1.0]) + x, y, z = transformed[:3] / transformed[3] + return float(x), float(y), float(z) def read_encoder_angles(self): @@ -398,19 +479,19 @@ class OpenMicroStageInterface: def read_device_state_info(self): res, msg = self.serial.send_command("M57") - return res + return res, msg def set_servo_parameter(self, pos_kp=150, pos_ki=50000, vel_kp=0.2, vel_ki=100, vel_filter_tc=0.0025): cmd = f"M55 A{pos_kp:.6f} B{pos_ki:.6f} C{vel_kp:.6f} D{vel_ki:.6f} F{vel_filter_tc:.6f}" res, msg = self.serial.send_command(cmd) return res - def enable_motors(self, enable): + def enable_motors(self, enable: bool): cmd = f"M17" if enable else "M18" res, msg = self.serial.send_command(cmd, timeout=5) return res - def set_pose(self, x, y, z): + def set_pose(self, x: float, y: float, z: float): # Convert to homogeneous vector transformed = self.workspace_transform @ np.array([x, y, z, 1.0]) x_t, y_t, z_t = transformed[:3] / transformed[3] @@ -419,6 +500,17 @@ class OpenMicroStageInterface: res, msg = self.serial.send_command(cmd) return res + def set_tool_output(self, tool_idx: int, output_value: float, immediate: bool = True): + # sets the output value for the specified tool + cmd = f"M3 T{tool_idx} S{output_value}" + res, msg = self.serial.send_command(cmd) + + # send dwell command to update tool value immediately + if immediate: + self.serial.send_command("G4 S0.001") + + return res + def send_command(self, cmd: str, timeout_s: float=5): res, msg = self.serial.send_command(cmd, timeout_s) return res, msg diff --git a/software/PythonAPI/requirements.txt b/software/PythonAPI/requirements.txt index 6e4d37a..bf33c24 100644 --- a/software/PythonAPI/requirements.txt +++ b/software/PythonAPI/requirements.txt @@ -1,3 +1,4 @@ numpy pyserial colorama +matplotlib diff --git a/software/PythonAPI/usage_example.py b/software/PythonAPI/usage_example.py index 212a305..1484b38 100644 --- a/software/PythonAPI/usage_example.py +++ b/software/PythonAPI/usage_example.py @@ -1,18 +1,95 @@ +import argparse + from open_micro_stage_api import OpenMicroStageInterface -# create interface and connect -oms = OpenMicroStageInterface(show_communication=True, show_log_messages=True) -oms.connect('/dev/ttyACM0') -# run this once to calibrate joints -# for i in range(3): oms.calibrate_joint(i, save_result=True) +def list_available_ports(): + devices = OpenMicroStageInterface.enumerate_devices() + if not devices: + print('No serial devices detected.') + return devices -# home device -oms.home() + print('Available serial devices:') + for device in devices: + print(f" {device['label']}") -# move and wait -oms.move_to(0, 0, 0, f=10) -oms.wait_for_stop() + return devices -# print some info -oms.read_device_state_info() \ No newline at end of file + +def resolve_port(port): + if port: + return port + + devices = OpenMicroStageInterface.enumerate_devices() + pico_devices = [device for device in devices if 'pico' in device['label'].lower()] + + if len(pico_devices) == 1: + print(f"Using detected Pico serial device: {pico_devices[0]['label']}") + return pico_devices[0]['port'] + + if len(pico_devices) > 1: + print('Multiple Pico serial devices detected. Pass --port to choose one:') + for device in pico_devices: + print(f" {device['label']}") + raise SystemExit(1) + + if len(devices) == 1: + print(f"Using detected serial device: {devices[0]['label']}") + return devices[0]['port'] + + if devices: + print('Multiple serial devices detected. Pass --port to choose one:') + for device in devices: + print(f" {device['label']}") + else: + print('No serial devices detected.') + + raise SystemExit(1) + + +def parse_args(): + parser = argparse.ArgumentParser( + description='Basic OpenMicroManipulator serial API example.', + ) + parser.add_argument( + '--port', + help='Serial port to use (for example /dev/ttyACM0 or COM3).', + ) + parser.add_argument( + '--list-ports', + action='store_true', + help='List detected serial devices and exit.', + ) + return parser.parse_args() + + +def main(): + args = parse_args() + if args.list_ports: + list_available_ports() + return + + port = resolve_port(args.port) + oms = OpenMicroStageInterface(show_communication=True, show_log_messages=True) + if not oms.connect(port): + raise SystemExit(f'Could not connect to {port}.') + + try: + # run this once to calibrate joints + # for i in range(3): oms.calibrate_joint(i, save_result=True) + + # home device + oms.home() + + # move and wait + oms.move_to(0, 0, 0, f=10) + oms.wait_for_stop() + + # print some info + oms.read_device_state_info() + finally: + oms.disconnect() + + +if __name__ == '__main__': + main()