How to calculate the length of cable on a winch given the rotations of the drum I have a cable winch system that I would like to know how much cable is left given the number of rotations that have occurred and vice versa. This system will run on a low-cost microcontroller with low computational resources and should be able to update quickly, long for/while loop iterations are not ideal.
The inputs are cable diameter, inner drum diameter, inner drum width, and drum rotations. The output should be the length of the cable on the drum.
At first, I was calculating the maximum number of wraps of cable per layer based on cable diameter and inner drum width, I could then use this to calculate the length of cable per layer. The issue comes when I calculate the total length as I have to loop through each layer, a costly operation (could be 100's of layers).
My next approach was to precalculate a table with each layer, then perform a 3-5 degree polynomial regression down to an easy to calculate formula.
This appears to work for the most part, however, there are slight inaccuracies at the low and high end (0 rotations could be + or - a few units of cable length). The real issue comes when I try and reverse the function to get the current rotations of the drum given the length. So far, my reversed formula does not seem to equal the forward formula (I am reversing X and Y before calculating the polynomial).
I have looked high and low and cannot seem to find any formulas for cable length to rotations that do not use recursion or loops. I can't figure out how to reverse my polynomial function to get the reverse value without losing precision. If anyone happens to have an insight/ideas or can help guide me in the right direction that would be most helpful. Please see my attempts below.
// Units are not important

CableLength = 15000
CableDiameter = 5
DrumWidth = 50
DrumDiameter = 5

CurrentRotations = 0
CurrentLength = 0
CurrentLayer = 0

PolyRotations = Array
PolyLengths = Array
PolyLayers = Array

WrapsPerLayer = DrumWidth / CableDiameter

While CurrentLength < CableLength // Calcuate layer length for each layer up to cable length
  CableStackHeight = CableDiameter * CurrentLayer
  DrumDiameterAtLayer = DrumDiameter + (CableStackHeight * 2) // Assumes cables stack vertically
  WrapDiameter = DrumDiameterAtLayer + CableDiameter // Center point of cable
  WrapLength = WrapDiameter * PI
  LayerLength = WrapLength * WrapsPerLayer
  
  CurrentRotations += WrapsPerLayer // 1 Rotation per wrap
  CurrentLength += LayerLength
  CurrentLayer++
  
  PolyRotations.Push(CurrentRotations)
  PolyLengths.Push(CurrentLength)
  PolyLayers.Push(CurrentLayer)

End


// Using 5 degree polynomials, any lower = very low precision

PolyLengthToRotation = CreatePolynomial(PolyLengths, PolyRotations, 5) // 5 Degrees
PolyRotationToLength = CreatePolynomial(PolyRotations, PolyLengths, 5) // 5 Degrees

// 40 Rotations should equal about 3141.593 units
RealRotation = 40
RealLength = 3141.593
CalculatedLength = EvaluatePolynomial(RealRotation,PolyRotationToLength)
CalculatedRotations = EvaluatePolynomial(RealLength,PolyLengthToRotation)

// CalculatedLength = 3141.593 // Good
// CalculatedRotations = 41.069 // No good
// CalculatedRotations != RealRotation // These should equal


// 0 Rotations should equal 0 length
RealRotation = 0
RealLength = 0
CalculatedLength = EvaluatePolynomial(RealRotation,PolyRotationToLength)
CalculatedRotations = EvaluatePolynomial(RealLength,PolyLengthToRotation)

// CalculatedLength = 1.172421e-9 // Very close
// CalculatedRotations = 1.947, // No good
// CalculatedRotations != RealRotation // These should equal

Side note: I have a "spool factor" parameter to calibrate for the actual cable spooling efficiency that is not shown here. (cable is not guaranteed to lay mathematically perfect)
 A: The (long) answer I suggested is at least somewhat complicated, and involves a bunch of unverified assumptions. I want to propose an alternative, and this is really an answer about modelling rather than algebra or anything like that.
Your drum is going to be able to hold a certain amount of cable. Maybe it'll be 3 layers, maybe 30. I don't recall ever seeing anything drum-like with more layers than that, including substantial industrial cranes, etc. I suppose 100 layers is possible. By the time you get to 1000, you're really talking about "spools" rather than drums -- things like cones of thread. Those seldom use parallel cable layers, instead winding the thread along fairly steep diagonals, etc.
With an upper limit of, say, 100 layers, you can just measure. Wind up one layer of  cable, measure how much you've pulled in, and write it down:
layer[1] = 37.05

Then wind up a second layer, and write down the total pulled in so far:
layer[2] = 81.33

and keep doing that. Now you don't need to model layer-compaction or anything. You just use those numbers. Knowing that you get $w$ turns per layer, you say that the amount consumed by a turn after the first layer is laid down is (layer[2] - layer[1])/w. So if your length is 62, for instance, you say

Hmm. 62 is bigger than 37.05, but less than 81.33; so $n$ is $1$. That leaves me $62 - 37.05 = 24.95$ units of cable that's in layer-2 wraps. The number of additional turns is therefore $\frac{24.95}{81.33 - 37.05} w$.

And you're done. Now to find out which layer you're in might seem to require testing each layer[i] against the total length, but because the values in the layer array form an increasing sequence, you can actually use bisection. In a 100-element array, bisection should take no more than 8 steps to find the largest $i$ with layer[i] < s. Even on an Arduino, that's not an excessive burden. (After all, the prior method required extracting a square root!)
It's less fun math, but it's probably a lot closer to what you need to get the job done. And I say this as someone who loves math, but has also spent a lot of time modeling real systems, and knows enough to know that simpler is often better than "elegant".
