I've been spectating on this thread

for a while, having nothing very useful to add up until now. But a few thoughts have occurred...
Assuming you could tell from logged data that things have gone wrong, is there any need to risk a workpiece, tool or the lathe itself by actually cutting metal?
Is the use of USB serial a complete no-no, or it is only during triggering and/or cutting that it causes issues? I was wondering if you could just log to PSRAM during sync / trigger / "cut", and dump data during the Z return time, possibly prolonged in order to complete the dump prior to the next pass.
With PSRAM, you can store a
lot of data. Say you create a log record every spindle tick, i.e. at 400/60*4096 ~= 27,307Hz - that's not a huge data rate into memory. If you log at every tick for every turn of a 20-turn thread, plus a few extra at each end, for say a total of 32 turns, you need 4096*32=131,072 records, which with 8MB of PSRAM allows each record to be up to 64 bytes, or 16x 32-bit values. You'd presumably want a timestamp, spindle count, and Z position (possibly with its own timestamp), which is only 12 or 16 of your available 64 bytes/record.
Some completely untested code to show the principle:
C++:
// Modify this record structure to your requirements,
// adjusting the logging and dumping code accordingly:
struct logRecord
{
uint32_t timeStampS;
uint32_t spindleCount;
uint32_t timeStampZ;
int32_t zPosition;
};
#define LOG_RECORD_COUNT (int)(8*1024*1024/sizeof(logRecord))
bool logging;
int logIndex;
EXTMEM logRecord logRecords[LOG_RECORD_COUNT]; // fill PSRAM
// Placeholder for your Z-encoder stuff
int32_t zPosition;
uint32_t zTimeStamp;
volatile bool directionPos;
void zISR(void)
{
if (directionPos)
zPosition++;
else
zPosition--;
zTimeStamp = micros();
}
// Placeholder for your spindle encoder stuff
uint32_t spindleCount;
void spindleISR(void)
{
spindleCount++; // wrap at 4096? can it decrement?
if (logging)
{
logRecords[logIndex] = {micros(),spindleCount,zTimeStamp,zPosition};
logIndex++;
if (logIndex >= LOG_RECORD_COUNT)
logIndex=0; // wrap - or you could stop
}
}
void dumpLog(void)
{
for (int i=0;i<logIndex;i++)
Serial.printf("%u,%u,%u,%d\n", // or use Serial5 if you need to
logRecords[i].timeStampS,
logRecords[i].spindleCount,
logRecords[i].timeStampZ,
logRecords[i].zPosition);
}
void stopLog(void) { logging = false; }
void startLog(void) { logIndex = 0; logging = true; }
Final thought ... if this is implemented, then you should easily be able to see any lost encoder counts, because they will have an unexpected timestamp. The spindle should have timestamps every 36.62µs (so, 36 or 37 in reality).