diff --git a/readme.md b/readme.md
index e0ceb16..efc4af4 100644
--- a/readme.md
+++ b/readme.md
@@ -24,24 +24,24 @@ A list of changes classified as breaking, additions or fixes is maintained in [C
Axials | Jack | Rails | Box | Annotation | BOM |
Ball_bearings | KP_pillow_blocks | Ring_terminals | Butt_box | Bezier | Clip |
Batteries | LDRs | Rockers | Cable_grommets | Catenary | Global |
- Belts | LED_meters | Rod | Camera_housing | Dogbones | Polyholes |
- Blowers | LEDs | SCS_bearing_blocks | Carriers | Fillet | Rounded_rectangle |
- Bulldogs | Leadnuts | SK_brackets | Corner_block | Gears | Sphere |
- Buttons | Light_strips | SMDs | Door_hinge | Hanging_hole | Teardrops |
- Cable_strips | Linear_bearings | SSRs | Door_latch | Horiholes | |
- Cameras | Magnets | Screws | Drag_chain | Layout | |
- Circlips | Mains_sockets | Sealing_strip | Fan_guard | Maths | |
- Components | Microswitches | Shaft_couplings | Fixing_block | Offset | |
- DIP | Microview | Sheets | Flat_hinge | Quadrant | |
- D_connectors | Modules | Spades | Foot | Round | |
- Displays | Nuts | Spools | Handle | Rounded_cylinder | |
- Extrusion_brackets | O_ring | Springs | PCB_mount | Rounded_polygon | |
- Extrusions | Opengrab | Stepper_motors | PSU_shroud | Rounded_right_triangle | |
- Fans | PCB | Swiss_clips | Pocket_handle | Sector | |
- Fuseholder | PCBs | Toggles | Press_fit | Sweep | |
- Geared_steppers | PSUs | Transformers | Printed_box | Thread | |
- Green_terminals | Panel_meters | Tubings | Printed_pulleys | Tube | |
- Hot_ends | Pillars | Variacs | Ribbon_clamp | | |
+ Belts | LED_meters | Rod | Camera_housing | Core_xy | Polyholes |
+ Blowers | LEDs | SCS_bearing_blocks | Carriers | Dogbones | Rounded_rectangle |
+ Bulldogs | Leadnuts | SK_brackets | Corner_block | Fillet | Sphere |
+ Buttons | Light_strips | SMDs | Door_hinge | Gears | Teardrops |
+ Cable_strips | Linear_bearings | SSRs | Door_latch | Hanging_hole | |
+ Cameras | Magnets | Screws | Drag_chain | Horiholes | |
+ Circlips | Mains_sockets | Sealing_strip | Fan_guard | Layout | |
+ Components | Microswitches | Shaft_couplings | Fixing_block | Maths | |
+ DIP | Microview | Sheets | Flat_hinge | Offset | |
+ D_connectors | Modules | Spades | Foot | Quadrant | |
+ Displays | Nuts | Spools | Handle | Round | |
+ Extrusion_brackets | O_ring | Springs | PCB_mount | Rounded_cylinder | |
+ Extrusions | Opengrab | Stepper_motors | PSU_shroud | Rounded_polygon | |
+ Fans | PCB | Swiss_clips | Pocket_handle | Rounded_right_triangle | |
+ Fuseholder | PCBs | Toggles | Press_fit | Sector | |
+ Geared_steppers | PSUs | Transformers | Printed_box | Sweep | |
+ Green_terminals | Panel_meters | Tubings | Printed_pulleys | Thread | |
+ Hot_ends | Pillars | Variacs | Ribbon_clamp | Tube | |
Hygrometer | Pin_headers | Veroboard | SSR_shroud | | |
IECs | Pulleys | Washers | Screw_knob | | |
Inserts | | Wire | Socket_box | | |
@@ -5574,6 +5574,65 @@ The coordinates of the lowest point on the curve can be retrieved by calling `ca
![catenary](tests/png/catenary.png)
+Top
+
+---
+
+## Core_xy
+Parameterised Core XY implementation. Draws the belts and provides utilities for positioning the pulleys.
+
+The belts are positioned according the bottom left "anchor" pulley and the top right drive pulley.
+Implementation has the following features:
+1. The drive and idler pulleys may be different sizes.
+2. The belt separation is parameterised.
+3. The separation of the plain and toothed pulleys on the Y carriages is parameterised, in both the X and the Y direction.
+4. The drive pulleys may be offset in the X and Y directions. If this is done, extra idler pulleys are added. This
+allows flexible positioning of the motors.
+
+[utils/core_xy.scad](utils/core_xy.scad) Implementation.
+
+[tests/core_xy.scad](tests/core_xy.scad) Code for this example.
+
+### Properties
+| Function | Description |
+|:--- |:--- |
+| `coreXY_belt(type)` | Belt type |
+| `coreXY_drive_pulley(type)` | Drive pulley type |
+| `coreXY_lower_belt_colour(type)` | Colour of the lower belt |
+| `coreXY_lower_tooth_colour(type)` | Colour of the lower belt's teeth |
+| `coreXY_plain_idler(type)` | Plain idler type |
+| `coreXY_toothed_idler(type)` | Toothed idler type |
+| `coreXY_upper_belt_colour(type)` | Colour of the upper belt |
+| `coreXY_upper_tooth_colour(type)` | Colour of the upper belt's teeth |
+
+### Functions
+| Function | Description |
+|:--- |:--- |
+| `coreXY_coincident_separation(type)` | Value of x, y separation to make y-carriage pulleys coincident |
+| `coreXY_drive_plain_idler_offset(type)` | Offset of plain drive idler pulley |
+| `coreXY_drive_pulley_x_alignment(type)` | Belt alignment offset of the drive pulley relative to the anchor pulley |
+| `coreXY_drive_toothed_idler_offset(type)` | Offset of toothed drive idler pulley |
+| `coreXY_plain_idler_offset(type)` | Offset of y-carriage plain idler |
+| `coreXY_toothed_idler_offset(type)` | offset of y-carriage toothed idler |
+
+### Modules
+| Module | Description |
+|:--- |:--- |
+| `coreXY(type, size, pos, separation, x_gap, plain_idler_offset = 0, upper_drive_pulley_offset, lower_drive_pulley_offset, show_pulleys = false)` | Wrapper module to draw both belts of a coreXY setup |
+| `coreXY_belts(type, carriagePosition, coreXYPosBL, coreXYPosTR, separation, x_gap = 20, upper_drive_pulley_offset = [0, 0], lower_drive_pulley_offset = [0, 0], show_pulleys = false)` | Draw the coreXY belts |
+| `coreXY_half(type, size, pos, separation_y = 0, x_gap = 0, plain_idler_offset = 0, drive_pulley_offset = [0, 0], show_pulleys = false, lower_belt = false, hflip = false)` | Draw one belt of a coreXY setup |
+
+![core_xy](tests/png/core_xy.png)
+
+### Vitamins
+| Qty | Module call | BOM entry |
+| ---:|:--- |:---|
+| 1 | `belt(GT2x6, [ ... ], [10.0078, 11.69], [0, -24.686])` | Belt GT2 x 6mm x 742mm |
+| 1 | `belt(GT2x6, [ ... ], [10.0078, 11.69], [0, -24.686])` | Belt GT2 x 6mm x 852mm |
+| 8 | `screw(M3_cap_screw, 20)` | Screw M3 cap x 20mm |
+| 2 | `NEMA(NEMA17M)` | Stepper motor NEMA17 x 40mm |
+
+
Top
---
diff --git a/tests/core_xy.scad b/tests/core_xy.scad
index 8fdd5ff..ca549e0 100644
--- a/tests/core_xy.scad
+++ b/tests/core_xy.scad
@@ -23,7 +23,7 @@ include <../vitamins/screws.scad>
include <../vitamins/stepper_motors.scad>
include <../vitamins/washers.scad>
-include <../utils/core_xy_belts.scad>
+include <../utils/core_xy.scad>
module coreXY_belts_test() {
diff --git a/tests/png/core_xy.png b/tests/png/core_xy.png
new file mode 100644
index 0000000..17dd067
Binary files /dev/null and b/tests/png/core_xy.png differ