The story so far - the ERM vibration motor arrived

Vibration haptics failed thoroughly back in Part 2. The actuator harvested from a Switch Pro Controller would not budge on an analog voltage, and it took a while to work out that it was an LRA, a completely different class of part. The conclusion that day was “match the actuator to the board” - we ordered an ERM vibration motor, which shakes in proportion to DC voltage, and closed Part 2 there.

That coin-sized 3V vibration motor has arrived. It waited in a drawer while Parts 3 and 4 plugged in blackjack and dressed up the screen. This chapter makes good on that promise, though it went a little differently than expected. It is the story of succeeding once, discovering the success was fake, and finally giving up on reasoning and measuring instead.

The ERM motor installed, and it buzzes

The ERM motor wiring was exactly as sketched in Part 2. The analog output board sends a voltage and the motor shakes accordingly. We adjusted the logic so the lever position converts straight into that voltage - most of it was already written back in Part 2, so there was barely anything to change

  • and started the game.

We pulled the lever. Buzz.

We had finally done what Part 2 could not. While beer flows, the lever trembles in your hand. You watch the glass fill with your eyes and feel it with your hand at the same time, the excessive feedback that arcade machines specialize in. We thought that was the end of it.

Vibration strength never changes - “is this just on and off?”

Vibration strength was what felt off after a few days of playing. Open the lever a little and it buzzes; pull it all the way and it buzzes - at the same strength. We had definitely built it “proportional to lever position,” and the proportion was not there.

At this point we chased two wrong theories. They are embarrassing, so we will keep them short.

The first theory was the dead zone. ERM motors have a start-up voltage; below it, static friction wins and the motor does not turn at all. So we assumed most of the lever’s travel sat below the start-up voltage and it only barely turned at the very end. Plausible, except that on retesting, it buzzed from the very start even with the lever barely open. Not a dead zone.

The second theory was the circuit. The motor is driven through a transistor, so if that stage were saturating like a switch rather than amplifying linearly, any input voltage would put the full supply across the motor. That was plausible too, and we got as far as sketching a rewiring - except that this circuit is perfectly capable of driving the motor directly from the analog output. Not the transistor’s fault.

Both were “plausible stories” and both were wrong. We were about to start a third theory when we stopped, because we realized we had never once looked at the actual values.

Stop reasoning, measure the lever value and output voltage

Standard communication is where the cabinet’s design pays off - the controller continuously publishes game state over it. The screen reads it to draw the glass, so we can read the same values.

So we attached a short diagnostic script. It starts the game automatically and logs the lever value alongside the vibration output while pouring. We swept the lever slowly from 0 to full a few times.

The result: while the lever value moved from 12% to 99%, the vibration output tracked it exactly. No flat sections, no spikes.

LeverOutput voltage
10~19%2.15V
40~49%2.57V
70~79%2.90V
90~99%3.21V

The software had been correct from the start. Perfectly proportional. The culprit the two theories were hunting had never existed.

The real cause: the output voltage range was wrong

The output voltage range shows its problem in the top row of that table. With the lever barely open, 2.15V was already going out. The output range we had written was 2.0V at lever zero and 3.3V at full - and this motor is rated for 3V. In other words, the whole game was swinging between “nearly rated” and “slightly over rated.” The bottom half was never used at all.

One more thing compounds it. ERM vibration strength is not proportional to voltage. The centrifugal force from the eccentric mass is proportional to the square of the rotation speed, and the speed is roughly proportional to voltage. So strength follows the square of the voltage. A floor of 2.0V is 61% of the 3.3V ceiling, but converted into strength it is already 37% of maximum.

From 37 to 100. A factor of 2.7. The numbers differ, but with a 3D-printed plastic lever wrapped in your hand, a factor of 2.7 reads as “it just keeps buzzing.” The weak end simply did not exist - that was the real cause.

Lowering the output floor to widen the vibration range

The output range was fixed with two numbers. We pulled the output floor far lower, and actually lowered the ceiling slightly to match the motor’s rating. Overall it gets weaker, and the gap between weak and strong gets much wider.

Perceived vibration strength against lever position - before and after

The vertical axis is relative perceived strength with maximum output as 100. The red line (before) starts at 37, so pulling all the way gains only a factor of 2.7. The green line (after) starts at 13 and spreads to a factor of 6.4, with a lower maximum strength.

Now opening the lever slightly produces a tremble you can barely feel at your fingertips, and pushing it up gets firmly stronger. Trickling beer and gushing beer feel different in your hand. That is what we wanted in the first place.

Bonus - fixing the bartender sprite alignment

The bartender sprite from Part 4 got a fix too. There was a bug where the character jumped upward when the expression changed on failure, and it had two causes. Each expression’s artwork had a different vertical height, and - more decisively - a wooden counter was drawn into the artwork itself. It doubled up with the bar counter in the background, so the character looked like it was floating in mid-air holding its own table.

Bartender alignment fix - before and after

On the left is the screen as it appeared in Part 4. A separate wooden plank floats below the bartender. On the right, the drawn table has been cropped away and the cut line placed exactly on the background counter. He now looks like a person standing behind the bar.

The mistake was cutting each expression out of the source sprite according to its own margins. Recutting all five to the same vertical range fixes the eye level even when the expression changes. We found the background counter’s position by reading pixels directly from the image.

Deploying to the touch panel made it a standalone cabinet

Deploying to the touch panel was the last outstanding item. Until now this cabinet needed a development PC connected to run. The touch panel attached to the cabinet still had the old screen from before blackjack existed, so pressing buttons did nothing.

We deployed the current screen to the touch panel and set it to launch automatically. Now power on brings up the title, you pick a game, and pulling the lever makes your hand tremble. No PC required.

When the series started, the goal was to replace the crank in the Playdate game Root Bear with a physical lever. Five chapters later it is a standalone arcade machine with two games in it. Our thanks once again for the idea in the original (© TEAM ROOT).

Recap: vibration tuning and sprite alignment lessons

  • “I made it proportional” and “it feels proportional” are different problems. Something - a square, a logarithm - always sits between physical quantity and human perception. Making the output linear is not the same as the user feeling the steps.
  • Half the battle is which part of the operating range you use. Check whether you are using the part’s full spec range. We were using a narrow band near the rating and wondering why nothing changed.
  • One measurement beats two plausible theories. Both hypotheses were logical and both were wrong. Reading the actual values once was far faster.
  • A cropped image carries the cropper’s mistakes. Cutting sprites to their individual margins breaks alignment. Cut them against a shared reference.

Measuring the actual values to see how much of a part’s operating range you are using beat every plausible theory.

Coming in Part 6: we plugged a joystick into the cabinet, and the documentation was wrong six times over.

Earlier chapters: Parts 1 through 4.

Contact