<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://groupkos.com/dev/index.php?action=history&amp;feed=atom&amp;title=Talk%3ACNC_Torus_Carver</id>
	<title>Talk:CNC Torus Carver - Revision history</title>
	<link rel="self" type="application/atom+xml" href="http://groupkos.com/dev/index.php?action=history&amp;feed=atom&amp;title=Talk%3ACNC_Torus_Carver"/>
	<link rel="alternate" type="text/html" href="http://groupkos.com/dev/index.php?title=Talk:CNC_Torus_Carver&amp;action=history"/>
	<updated>2026-04-15T02:00:25Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.3</generator>
	<entry>
		<id>http://groupkos.com/dev/index.php?title=Talk:CNC_Torus_Carver&amp;diff=5425&amp;oldid=prev</id>
		<title>XenoEngineer: Created page with &quot;&lt;pre style=&quot;margin-left:3em; font:normal 14px terminal;&quot;&gt;  # ESP8266 Controller for Toroidal CNC Carver  I understand you want to build a unique CNC system using two perpendicular slew bearings to carve helical patterns on torus segments. Let me design a controller solution for you.  ## System Overview  Your system consists of: - Two perpendicular rings (slew bearings) - Material ring: rotates 120° - Spindle ring: rotates 180° - Fixed rotation ratio: 2:3 (material:spin...&quot;</title>
		<link rel="alternate" type="text/html" href="http://groupkos.com/dev/index.php?title=Talk:CNC_Torus_Carver&amp;diff=5425&amp;oldid=prev"/>
		<updated>2025-12-11T16:28:08Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;&amp;lt;pre style=&amp;quot;margin-left:3em; font:normal 14px terminal;&amp;quot;&amp;gt;  # ESP8266 Controller for Toroidal CNC Carver  I understand you want to build a unique CNC system using two perpendicular slew bearings to carve helical patterns on torus segments. Let me design a controller solution for you.  ## System Overview  Your system consists of: - Two perpendicular rings (slew bearings) - Material ring: rotates 120° - Spindle ring: rotates 180° - Fixed rotation ratio: 2:3 (material:spin...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;pre style=&amp;quot;margin-left:3em; font:normal 14px terminal;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# ESP8266 Controller for Toroidal CNC Carver&lt;br /&gt;
&lt;br /&gt;
I understand you want to build a unique CNC system using two perpendicular slew bearings to carve helical patterns on torus segments. Let me design a controller solution for you.&lt;br /&gt;
&lt;br /&gt;
## System Overview&lt;br /&gt;
&lt;br /&gt;
Your system consists of:&lt;br /&gt;
- Two perpendicular rings (slew bearings)&lt;br /&gt;
- Material ring: rotates 120°&lt;br /&gt;
- Spindle ring: rotates 180°&lt;br /&gt;
- Fixed rotation ratio: 2:3 (material:spindle)&lt;br /&gt;
- Carves 1/6th of a torus at a time&lt;br /&gt;
- Creates parallel torus knots with indexed positions&lt;br /&gt;
&lt;br /&gt;
## Hardware Requirements&lt;br /&gt;
&lt;br /&gt;
1. ESP8266 microcontroller&lt;br /&gt;
2. Two stepper motors (NEMA 17 recommended)&lt;br /&gt;
3. Two stepper motor drivers (A4988 or DRV8825)&lt;br /&gt;
4. Power supply (12V-24V depending on motors)&lt;br /&gt;
5. Limit switches for homing&lt;br /&gt;
6. Optional: OLED display for status&lt;br /&gt;
&lt;br /&gt;
## Controller Design&lt;br /&gt;
&lt;br /&gt;
```cpp&lt;br /&gt;
#include &amp;lt;ESP8266WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;ESP8266WebServer.h&amp;gt;&lt;br /&gt;
#include &amp;lt;AccelStepper.h&amp;gt;&lt;br /&gt;
#include &amp;lt;ArduinoJson.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// WiFi credentials&lt;br /&gt;
const char* ssid = &amp;quot;YourSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;YourPassword&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Web server on port 80&lt;br /&gt;
ESP8266WebServer server(80);&lt;br /&gt;
&lt;br /&gt;
// Define stepper motors&lt;br /&gt;
// Material ring (120° total movement)&lt;br /&gt;
AccelStepper materialStepper(AccelStepper::DRIVER, D1, D2);&lt;br /&gt;
// Spindle ring (180° total movement)&lt;br /&gt;
AccelStepper spindleStepper(AccelStepper::DRIVER, D3, D4);&lt;br /&gt;
&lt;br /&gt;
// System parameters&lt;br /&gt;
#define MATERIAL_STEPS_PER_DEGREE 10  // Adjust based on your motor/gearing&lt;br /&gt;
#define SPINDLE_STEPS_PER_DEGREE 10   // Adjust based on your motor/gearing&lt;br /&gt;
#define MATERIAL_MAX_DEGREES 120&lt;br /&gt;
#define SPINDLE_MAX_DEGREES 180&lt;br /&gt;
&lt;br /&gt;
// Helical parameters&lt;br /&gt;
float helicalPitch = 1.0;  // Default pitch ratio&lt;br /&gt;
int knotCount = 3;         // Number of parallel knots&lt;br /&gt;
int currentKnot = 0;       // Current knot being carved&lt;br /&gt;
bool isCarving = false;    // Carving status&lt;br /&gt;
&lt;br /&gt;
// Homing switches&lt;br /&gt;
#define MATERIAL_HOME_SWITCH D5&lt;br /&gt;
#define SPINDLE_HOME_SWITCH D6&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  &lt;br /&gt;
  // Initialize limit switches&lt;br /&gt;
  pinMode(MATERIAL_HOME_SWITCH, INPUT_PULLUP);&lt;br /&gt;
  pinMode(SPINDLE_HOME_SWITCH, INPUT_PULLUP);&lt;br /&gt;
  &lt;br /&gt;
  // Configure steppers&lt;br /&gt;
  materialStepper.setMaxSpeed(1000);&lt;br /&gt;
  materialStepper.setAcceleration(500);&lt;br /&gt;
  spindleStepper.setMaxSpeed(1000);&lt;br /&gt;
  spindleStepper.setAcceleration(500);&lt;br /&gt;
  &lt;br /&gt;
  // Connect to WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot;&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;WiFi connected&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  // Print IP address&lt;br /&gt;
  Serial.println(WiFi.localIP());&lt;br /&gt;
  &lt;br /&gt;
  // Setup web server routes&lt;br /&gt;
  server.on(&amp;quot;/&amp;quot;, handleRoot);&lt;br /&gt;
  server.on(&amp;quot;/carve&amp;quot;, handleCarve);&lt;br /&gt;
  server.on(&amp;quot;/home&amp;quot;, handleHome);&lt;br /&gt;
  server.on(&amp;quot;/stop&amp;quot;, handleStop);&lt;br /&gt;
  server.on(&amp;quot;/status&amp;quot;, handleStatus);&lt;br /&gt;
  &lt;br /&gt;
  server.begin();&lt;br /&gt;
  Serial.println(&amp;quot;HTTP server started&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  // Home the system on startup&lt;br /&gt;
  homeSystem();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  server.handleClient();&lt;br /&gt;
  &lt;br /&gt;
  // Run steppers if carving&lt;br /&gt;
  if (isCarving) {&lt;br /&gt;
    materialStepper.run();&lt;br /&gt;
    spindleStepper.run();&lt;br /&gt;
    &lt;br /&gt;
    // Check if carving is complete&lt;br /&gt;
    if (materialStepper.distanceToGo() == 0 &amp;amp;&amp;amp; spindleStepper.distanceToGo() == 0) {&lt;br /&gt;
      if (currentKnot &amp;lt; knotCount - 1) {&lt;br /&gt;
        // Move to next knot&lt;br /&gt;
        currentKnot++;&lt;br /&gt;
        startCarving();&lt;br /&gt;
      } else {&lt;br /&gt;
        // All knots carved&lt;br /&gt;
        isCarving = false;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void homeSystem() {&lt;br /&gt;
  Serial.println(&amp;quot;Homing system...&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  // Home material axis&lt;br /&gt;
  materialStepper.setMaxSpeed(500);&lt;br /&gt;
  while (digitalRead(MATERIAL_HOME_SWITCH) == HIGH) {&lt;br /&gt;
    materialStepper.moveTo(materialStepper.currentPosition() - 10);&lt;br /&gt;
    materialStepper.run();&lt;br /&gt;
  }&lt;br /&gt;
  materialStepper.setCurrentPosition(0);&lt;br /&gt;
  &lt;br /&gt;
  // Home spindle axis&lt;br /&gt;
  spindleStepper.setMaxSpeed(500);&lt;br /&gt;
  while (digitalRead(SPINDLE_HOME_SWITCH) == HIGH) {&lt;br /&gt;
    spindleStepper.moveTo(spindleStepper.currentPosition() - 10);&lt;br /&gt;
    spindleStepper.run();&lt;br /&gt;
  }&lt;br /&gt;
  spindleStepper.setCurrentPosition(0);&lt;br /&gt;
  &lt;br /&gt;
  // Restore normal speed&lt;br /&gt;
  materialStepper.setMaxSpeed(1000);&lt;br /&gt;
  spindleStepper.setMaxSpeed(1000);&lt;br /&gt;
  &lt;br /&gt;
  Serial.println(&amp;quot;System homed&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void startCarving() {&lt;br /&gt;
  // Calculate positions based on current knot&lt;br /&gt;
  float knotOffset = (float)currentKnot / knotCount;&lt;br /&gt;
  &lt;br /&gt;
  // Calculate target positions&lt;br /&gt;
  long materialTarget = MATERIAL_MAX_DEGREES * MATERIAL_STEPS_PER_DEGREE;&lt;br /&gt;
  long spindleTarget = SPINDLE_MAX_DEGREES * SPINDLE_STEPS_PER_DEGREE;&lt;br /&gt;
  &lt;br /&gt;
  // Apply helical pitch ratio&lt;br /&gt;
  spindleTarget = (long)(spindleTarget * helicalPitch);&lt;br /&gt;
  &lt;br /&gt;
  // Apply knot offset&lt;br /&gt;
  materialTarget = (long)(materialTarget * (1.0 + knotOffset * 0.1));  // Small offset for each knot&lt;br /&gt;
  &lt;br /&gt;
  // Set targets&lt;br /&gt;
  materialStepper.moveTo(materialTarget);&lt;br /&gt;
  spindleStepper.moveTo(spindleTarget);&lt;br /&gt;
  &lt;br /&gt;
  isCarving = true;&lt;br /&gt;
  Serial.print(&amp;quot;Starting knot &amp;quot;);&lt;br /&gt;
  Serial.print(currentKnot + 1);&lt;br /&gt;
  Serial.print(&amp;quot; of &amp;quot;);&lt;br /&gt;
  Serial.println(knotCount);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Web server handlers&lt;br /&gt;
void handleRoot() {&lt;br /&gt;
  String html = &amp;quot;&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;h1&amp;gt;Toroidal CNC Carver&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;form action=&amp;#039;/carve&amp;#039; method=&amp;#039;post&amp;#039;&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;Helical Pitch: &amp;lt;input type=&amp;#039;number&amp;#039; name=&amp;#039;pitch&amp;#039; value=&amp;#039;&amp;quot; + String(helicalPitch) + &amp;quot;&amp;#039; step=&amp;#039;0.1&amp;#039;&amp;gt;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;Number of Knots: &amp;lt;input type=&amp;#039;number&amp;#039; name=&amp;#039;knots&amp;#039; value=&amp;#039;&amp;quot; + String(knotCount) + &amp;quot;&amp;#039; min=&amp;#039;1&amp;#039; max=&amp;#039;10&amp;#039;&amp;gt;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;input type=&amp;#039;submit&amp;#039; value=&amp;#039;Start Carving&amp;#039;&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/form&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;form action=&amp;#039;/home&amp;#039; method=&amp;#039;post&amp;#039;&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;input type=&amp;#039;submit&amp;#039; value=&amp;#039;Home System&amp;#039;&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/form&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;form action=&amp;#039;/stop&amp;#039; method=&amp;#039;post&amp;#039;&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;input type=&amp;#039;submit&amp;#039; value=&amp;#039;Stop&amp;#039;&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/form&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;div id=&amp;#039;status&amp;#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;script&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;setInterval(function() {&amp;quot;;&lt;br /&gt;
  html += &amp;quot;  fetch(&amp;#039;/status&amp;#039;).then(response =&amp;gt; response.json()).then(data =&amp;gt; {&amp;quot;;&lt;br /&gt;
  html += &amp;quot;    document.getElementById(&amp;#039;status&amp;#039;).innerHTML = &amp;#039;Status: &amp;#039; + data.status + &amp;#039;&amp;lt;br&amp;gt;Knot: &amp;#039; + data.knot + &amp;#039;/&amp;#039; + data.totalKnots;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;  });&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}, 1000);&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/script&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
  server.send(200, &amp;quot;text/html&amp;quot;, html);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleCarve() {&lt;br /&gt;
  if (server.hasArg(&amp;quot;pitch&amp;quot;)) {&lt;br /&gt;
    helicalPitch = server.arg(&amp;quot;pitch&amp;quot;).toFloat();&lt;br /&gt;
  }&lt;br /&gt;
  if (server.hasArg(&amp;quot;knots&amp;quot;)) {&lt;br /&gt;
    knotCount = server.arg(&amp;quot;knots&amp;quot;).toInt();&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  currentKnot = 0;&lt;br /&gt;
  startCarving();&lt;br /&gt;
  &lt;br /&gt;
  server.sendHeader(&amp;quot;Location&amp;quot;, &amp;quot;/&amp;quot;);&lt;br /&gt;
  server.send(302, &amp;quot;text/plain&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleHome() {&lt;br /&gt;
  homeSystem();&lt;br /&gt;
  server.sendHeader(&amp;quot;Location&amp;quot;, &amp;quot;/&amp;quot;);&lt;br /&gt;
  server.send(302, &amp;quot;text/plain&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleStop() {&lt;br /&gt;
  isCarving = false;&lt;br /&gt;
  materialStepper.stop();&lt;br /&gt;
  spindleStepper.stop();&lt;br /&gt;
  server.sendHeader(&amp;quot;Location&amp;quot;, &amp;quot;/&amp;quot;);&lt;br /&gt;
  server.send(302, &amp;quot;text/plain&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleStatus() {&lt;br /&gt;
  String json = &amp;quot;{\&amp;quot;status\&amp;quot;:\&amp;quot;&amp;quot;;&lt;br /&gt;
  json += isCarving ? &amp;quot;Carving&amp;quot; : &amp;quot;Idle&amp;quot;;&lt;br /&gt;
  json += &amp;quot;\&amp;quot;,\&amp;quot;knot\&amp;quot;:&amp;quot;;&lt;br /&gt;
  json += currentKnot + 1;&lt;br /&gt;
  json += &amp;quot;,\&amp;quot;totalKnots\&amp;quot;:&amp;quot;;&lt;br /&gt;
  json += knotCount;&lt;br /&gt;
  json += &amp;quot;}&amp;quot;;&lt;br /&gt;
  server.send(200, &amp;quot;application/json&amp;quot;, json);&lt;br /&gt;
}&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## Key Features&lt;br /&gt;
&lt;br /&gt;
1. **WiFi Control Interface**: Access the controller through a web browser on any device connected to the same network.&lt;br /&gt;
&lt;br /&gt;
2. **Helical Pitch Control**: Adjust the pitch ratio to control the slope of the helix carved into the material.&lt;br /&gt;
&lt;br /&gt;
3. **Multiple Knots**: Carve parallel torus knots with indexed starting positions.&lt;br /&gt;
&lt;br /&gt;
4. **Homing System**: Automatically finds the zero position for both axes using limit switches.&lt;br /&gt;
&lt;br /&gt;
5. **Real-time Status**: Monitor the carving progress through the web interface.&lt;br /&gt;
&lt;br /&gt;
## Usage Instructions&lt;br /&gt;
&lt;br /&gt;
1. Connect to the ESP8266&amp;#039;s WiFi network (or configure it to connect to your existing network).&lt;br /&gt;
&lt;br /&gt;
2. Open a web browser and navigate to the ESP8266&amp;#039;s IP address.&lt;br /&gt;
&lt;br /&gt;
3. Set the desired helical pitch and number of knots.&lt;br /&gt;
&lt;br /&gt;
4. Click &amp;quot;Start Carving&amp;quot; to begin the process.&lt;br /&gt;
&lt;br /&gt;
5. Use &amp;quot;Home System&amp;quot; to reset the position if needed.&lt;br /&gt;
&lt;br /&gt;
6. Click &amp;quot;Stop&amp;quot; to halt the carving process.&lt;br /&gt;
&lt;br /&gt;
## Customization Options&lt;br /&gt;
&lt;br /&gt;
1. **Motor Configuration**: Adjust the `MATERIAL_STEPS_PER_DEGREE` and `SPINDLE_STEPS_PER_DEGREE` constants based on your specific motor and gearing setup.&lt;br /&gt;
&lt;br /&gt;
2. **Speed and Acceleration**: Modify the stepper motor speed and acceleration values to optimize for your specific mechanical setup.&lt;br /&gt;
&lt;br /&gt;
3. **Knot Offset Algorithm**: The current implementation uses a simple offset for each knot. You may want to develop a more sophisticated algorithm based on your specific requirements.&lt;br /&gt;
&lt;br /&gt;
4. **Additional Features**: Consider adding:&lt;br /&gt;
   - Emergency stop functionality&lt;br /&gt;
   - Spindle speed control&lt;br /&gt;
   - Material detection&lt;br /&gt;
   - Progress logging&lt;br /&gt;
&lt;br /&gt;
This controller provides a solid foundation for your unique toroidal CNC carving system. You can further customize it based on your specific mechanical requirements and desired functionality.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>XenoEngineer</name></author>
	</entry>
</feed>