jes notes .

# 2023-10-16

< 2023-10-15 2023-10-17 >

## Stepper motor ratios

I reckon it's converging towards 10.24 seconds/rev exactly. So far, after nearly 23 hours, the average rate is 10.23977 seconds/rev. That is a difference from 10.24 of under 2 seconds per day.

I will leave it running for longer, but on the basis that it is exactly 10.24 seconds/rev, what are the best ratios to use to get hours and minutes?

I want to use a "Geneva drive" on the output of the stepper motor to drive the train, both because it will result in large pauses between intermittent motion, which I think is fun, and because it makes for an easy place to put the "anti-reverse" feature: make an asymmetrical slot in the Geneva drive, with something that can catch the pin if it tries to turn backwards.

Actually you could do that with Involute gears too, if you angle the back surfaces of the gear so that they won't turn past each other, I think. Let's have a quick look in FreeCAD.

Something like this?

Anyway. The gear ratios.

We get one turn every 10.24 seconds at the motor, and we want one turn every 3600 seconds for the minute hand. So it needs to be slowed down by a factor of 5625/16.

If we assume a Geneva drive on the stepper motor, with 1 driving pin, then we get one tooth every 10.24 seconds at the start of the train.

One option is 1:20, 8:45, 8:25. The stepper turns once every 10.24 seconds. The first wheel turns once every 204.8 seconds. The second wheel turns once every 1152 seconds. The third wheel turns once every 3600 seconds.

Another options is 1:25, 6:25, 8:27. Needs a slightly-larger driven wheel on the Geneva drive, but does not need the big 45-tooth gear.

Can you do it with fewer wheels?

What about 1:75, 16:75? First wheel turns once every 768 seconds, second wheel turns once every 3600 seconds. Needs a monster 75-tooth Geneva driven wheel though.

What about 1:45, 16:125? A 125-tooth gear is even more monster, but at least the Geneva-driven one is smaller.

Also I found that after having been running for a day it takes much less torque to stall the motor. Is that just because it's got hot and the resistance has increased? I've ordered a 6v transformer.

And let's just use 3 wheels. Less trouble that way.

## Metal escapement

I resumed yesterday's task and completed steps 7 and 8, fitting the pins into the pallet fork and the balance wheel, using Loctite. Next up is to assemble it and see if it all lines up any better than before.

Hmm, it looks like the location of the pallet fork is incorrect:

Probably because the pivot is too eccentric so it couldn't get pushed all the way into its hole in the die block.

I forced it along a bit with the tweezers and managed to assemble everything:

However the pallet pins seem to have got bent. Maybe they need a "boss" in the fork to fit in, so there is more than 0.5mm depth of engagement. In fact maybe that would be a good idea for everything that has to fit a pin/shaft. Or maybe the issue is that the router doesn't drill straight holes.

From working it by hand, it seems like at the point of one pallet pin unlocking, the other pallet pin lands on the impulse face of its next tooth, instead of on the locking face. This is not what happens in CAD, or in the bigger model, so this is an error in making the parts. In fact, there is a point where the escape wheel can spin almost freely, hardly touching the pallet pins at all.

So given that it worked correctly on the big model, and it looks correct in CAD, but it doesn't work in reality, I think I should dismantle this again and measure all the important dimensions as accurately as I can and see what is actually wrong.

## Measurements

Measured value in bold, CAD value in brackets.

All length measurements were taken with Vernier calipers, angle measurements with photographs and Gimp.

Before I take it apart:

• Maximum amplitude: 90 deg (87 deg)

And then with it taken apart...

### Escape wheel

• Thickness: 0.65 mm (0.5 mm)
• Outside diameter: 13.4 mm (13.5 mm)
• Shaft length: 9.9 mm (excluding pivots) (9.5 mm)
• Axial distance from front of shaft: 1.3 mm (1.0 mm)
• Length of impulse face: 1.0 mm (1.0 mm)
• Depth of locking face: 1.0 mm (measured from a line touching two impulse face tips, perpendicularly to the root) (1.0 mm)

### Pallet fork

• Thickness: 0.5 mm (0.5 mm)
• Shaft length: 9.5 mm (9.5 mm)
• Axial distance from front of shaft: 3.0 mm (2.5 mm)
• Total length: 10.7 mm (end to end) (10.5 mm)
• Angle (pin, shaft, pin): 125 deg (122 deg)
• Radius to pin 1: 3.85 mm (3.9 mm)
• Radius to pin 2: 4.2 mm (4.4 mm)
• Pin 1 stick-out: 1.8 mm (2.0 mm)
• Pin 2 stick-out: 2.3 mm (2.0 mm)
• Slot total length: 1.5 mm (1.6 mm)
• Slot radius: 0.35 mm (0.3 mm)
• Slot width at big end: 0.8 mm (0.9 mm)

### Balance wheel

• Thickness: 2.5 mm (2.5 mm)
• Outside diameter: 13.5 mm (13.5 mm)
• Shaft length: 9.35 mm (9.5 mm)
• Axial distance from front of shaft: 4.0 mm (4.0 mm)
• Inside diameter: 10.0 mm (10.0 mm)
• Spoke thickness: 1.0 mm (1.0 mm)
• Radius to pin: 1.7 mm (2.0 mm)
• Pin stick-out: 2.1 mm (2.0 mm)

### Frame plates

• Escape wheel to pallet fork: 7.5 mm (7.5 mm)
• Pallet fork to balance wheel: 8.0 mm (8.0 mm)
• Plate separation: 9.9 to 10.0 mm (9.6 mm)

## Errors

The angle discrepancies are both 3 degrees, which is probably within the margin of error of measurement.

Also, probably the worst errors are in the perpendicularity of shafts/pins, and the concentricity of the parts with the pivots. I should work out sensible ways to measure those. Maybe I want some sort of microscope measuring jig.

The largest length errors, in descending order of absolute difference (is that the best metric?) are:

• Pallet fork axial position (0.5 mm)
• Escape wheel shaft length (0.4 mm)
• Frame plate separation (0.3 to 0.4 mm)
• Escape wheel axial position (0.3 mm)
• Pallet pin 2 stick-out (0.3 mm)
• Balance wheel radius to pin (0.3 mm)
• Pallet fork total length (0.2 mm)
• Pallet fork radius to pin 2 (0.2 mm)
• Pallet pin 1 stick-out (0.2 mm)
• Escape wheel thickness (0.15 mm)
• Balance wheel shaft length (0.15 mm)

It is possible that some of these are measurement errors rather than actual errors, so must re-check them before attempting to correct.

Let's go over those errors and speculate on the causes and remedies.

### Pallet fork axial position

Cause: I think this was caused by the pivot being so far out of concentric that it couldn't seat in the hole in the die block, so it was initially fitted to its shaft about 1mm out of place, and when I subsequently shifted it with tweezers during assembly I didn't push it far enough.

Remedy: Widen the pivot hole in the die block. Make a better shaft.

### Escape wheel shaft length

Cause: Shaft blank was cut too long before turning pivots.

Remedy: Make the shaft exactly 11.5mm before cutting pivots on it. Measure it after cutting pivots to check it is acceptable.

### Frame plate separation

Cause: Standoffs are too long.

Remedy: Turn the standoffs down so that the shoulders are 9.6mm apart.

### Escape wheel axial position

Cause: Shaft is too long, so when it is placed in the die block the "front" end of the shaft sticks up further than it should. Also the escape wheel is too thick.

Remedy: Make a shorter shaft. Turn the escape wheel down to 0.5mm thickness.

### Pallet pin 2 stick-out

Cause: Pallet pin too long.

Remedy: Make the pin shorter. Measure it.

### Balance wheel radius to pin

Cause: Measurement error. I re-checked it by putting the caliper across the shaft and the pin, which measured at 2.75 mm, and then subtracting out the radii of the shaft and pin, it comes to 2.0 mm as intended.

Remedy: none.

### Pallet fork total length

Cause: Measurement error? I re-checked it several times and got various values between 10.5 and 10.7mm. In any event this is really not a critical dimension, as long as it clears everything it needs to clear.

Remedy: none.

### Pallet fork radius to pin 2

Cause: Measurement error. I re-checked it with the "across shaft and pin" technique and got 4.45mm, which is within measurement error of the intended value.

Remedy: none

### Pallet pin 1 stick-out

Cause: Pallet pin too short.

Remedy: Make a longer pin. Measure it.

### Escape wheel thickness

Cause: I didn't face the escape wheel down far enough on the lathe.

Remedy: Put it back on the lathe and face it down a bit more.

### Balance wheel shaft length

Cause: Shaft blank was cut too long before turning pivots.

Remedy: Make the shaft exactly 11.5mm before cutting pivots on it. Measure it after cutting pivots to check it is acceptable.

So tasks to do before re-assembling:

• Widen the pivot holes in the die block
• Make 3 new shafts, at correct length, and with nice concentric pivots
• Shorten the standoffs to 9.6mm
• Turn escape wheel down to 0.5mm thickness
• Make new pallet pins at 2.5mm and impulse pin at 3mm, with bluing polished off before cutting to length
• Work out how to fit the pins perpendicular

I wondered if it might help to make a 0.5mm diameter hole in the die block, 2mm deep, to aid fitting of pins. I can fit the pallet fork pins before fitting its shaft. Just need to make the 0.5mm hole close enough to the edge that the 1st pin can clear the block when fitting the 2nd one.

Not sure about the balance wheel pin.

## const for SLANG

I want to make SLANG support a `const` keyword, to make it more time- and space-efficient to look up constants.

I'm prepared to accept the following caveats:

• no & operator
• no `const` outside global scope
• no arithmetic on `const`s
• `const` values must be numbers, not strings or functions or asm's
• we need to provide a separate file of constants for the library blob

Plan:

1. make `const` an alias for `var`, in perl compiler, slang-in-slang compiler, and interpreter
2. change all the constants to use `const`
3. make `const`s lookup the value at compile-time instead of runtime
4. output a file for `const`s like the one for `extern`s
5. read the file in `slangc`

Wish me luck!

Step 1 took a long time because I forgot about the optimisation in slang-in-slang that checks the next char is 'v' before calling `Declaration`, but https://github.com/jes/scamp-cpu/commit/c014d95c1626461ee0bca5ad1f9bb91495bbcef6

Making most of the constants use `const` was pretty easy: https://github.com/jes/scamp-cpu/commit/b2c2d4a2ec03ec29e03fa9817bae10e64c74941c

Now the good part: make `const` lookup the value at compile-time. I'll probably let `slangi` keep it as an alias for `var` for the time being. There would probably be a performance gain for doing it differently, but really the use case for `slangi` is that most of your runtime is spent in the library blob, so it's not worth it. If a significant enough part of runtime is spent in interpreted code that you care about having `const` implemented well, then compile the program instead of using the interpreter.

https://github.com/jes/scamp-cpu/commit/250020515903ed7509792c3895cf05334984718a

Comes with a bonus of moving the kernel up from 0xd200 to 0xd400! That might be critical for Advent of Code!

Steps 4 and 5 in one go: https://github.com/jes/scamp-cpu/commit/e1f5b66086255cf40d03d3f242c2f1e99ab8b4e2

And a bonus of not needing the "--slang-header" file any more: https://github.com/jes/scamp-cpu/commit/983101a0553a1e5fe82b981162403c0bb829ab2d

So what improvement has this made?

Kernel size: 11206 -> 10948 (-2.3%) Library blob size: 9540 -> 9450 (-0.95%) Disk usage: 4181 blocks -> 4171 blocks (-0.25%) `kilo` binary size: 15377 -> 15127 (-1.6%) Startup cycles: 2679316 -> 2634249 (-1.7%)

So maybe overall a 1 to 2 percent improvement to memory usage and CPU time. Not world-changing but I've definitely had less productive evenings working on SCAMP!

I should make sure to do some more thorough testing to make sure I haven't broken anything.

## Tomorrow

• Carry out the "Next tasks" for the watch project.
• Motorcycle maintenance
• SCAMP testing
< 2023-10-15 2023-10-17 >