Available patterns
Simple Stroke
Simple Stroke
Creates a trapezoidal stroke profile with 1/3 acceleration, 1/3 coasting, and 1/3 deceleration.
The sensation parameter has no effect on this pattern.
Teasing or Pounding
Teasing or Pounding
Adjusts the speed ratio between in and out movements using the sensation value:
- Positive sensation (> 0): Makes the in-move faster (up to 5x) for a hard pounding sensation
- Negative sensation (< 0): Makes the out-move faster for a more teasing sensation
Robo Stroke
Robo Stroke
Controls stroke acceleration through the sensation value:
- Positive values: Increase acceleration until motion becomes constant speed (feels robotic)
- Neutral (0): Equal to Simple Stroke (1/3, 1/3, 1/3 profile)
- Negative values: Reduce acceleration into a triangle profile
Half'n'Half
Half'n'Half
Similar to Teasing or Pounding, but every second stroke reaches only half the depth.
- Positive sensation (> 0): Makes the in-move faster (up to 5x) for a hard pounding sensation
- Negative sensation (< 0): Makes the out-move faster for a more teasing sensation
Deeper
Deeper
Gradually ramps up the insertion depth with each stroke until reaching maximum, then resets and restarts.The sensation value controls how many strokes complete one ramp cycle.
Stop'n'Go
Stop'n'Go
Inserts pauses between a series of strokes. The number of strokes ramps from 1 to 5 and back.The sensation value controls the pause duration between stroke series.
Insist
Insist
Reduces the effective stroke length while keeping stroke speed constant. This creates vibrational patterns at higher sensation values.
- Positive sensation: Strokes wander towards the front
- Negative sensation: Strokes wander towards the back
Jack Hammer
Jack Hammer
Creates a vibrational pattern that vibrates on the way in and pulls out smoothly in one motion.The sensation value sets the vibration amplitude from 3mm to 25mm.
Stroke Nibbler
Stroke Nibbler
Adds a vibrational overlay to strokes, vibrating on both the way in and out.The sensation value sets the vibration amplitude from 3mm to 25mm.
Creating custom patterns
You can create your own patterns by subclassing thePattern class in the header-only pattern.h file.
1
Subclass the Pattern class
Create a new class that extends The constructor stores the pattern’s display name string.
Pattern. See SimpleStroke for a minimal implementation:pattern.h
2
Override set-functions if needed
Reimplement set-functions when you need custom calculations:
pattern.h
3
Implement the nextTarget function
This is the core function that StrokeEngine calls after each stroke to get the next motion parameters.
pattern.h
The
index parameter starts at 0 when the pattern is first called and increments by 1 after each stroke. Use this to create patterns that vary over time.4
Add debugging output
Encapsulate
Serial.print() statements with preprocessor directives so they can be toggled:pattern.h
5
Register the pattern
Add an instance of your pattern class to the
patternTable[] array at the bottom of the file:pattern.h
Pattern requirements
Depth and stroke boundaries
Depth and stroke values set in StrokeEngine are axiomatic boundaries. Your pattern defines the envelope it uses within these limits. The same safety constraints apply to speed viatimeOfStroke.
Graceful parameter changes
Your pattern must handle parameter changes gracefully. When depth or stroke values change mid-operation, the pattern must:- Stay within the interval
[depth, depth - stroke]at all times - Execute transfer moves at the same speed as regular moves
- Avoid erratic behavior
Using the index parameter
Theindex parameter provides important state information:
- Resets to 0 when
StrokeEngine.setPattern(int)orStrokeEngine.startMotion()is called - Increments after each successfully executed move
- Comparing
index == _indexdetermines if this is an update to the current stroke rather than a new stroke
_index before returning to track stroke state in time-varying patterns.
Implementing pauses
Patterns can insert pauses between strokes. When the target position is reached, StrokeEngine polls for new motion commands every few milliseconds. To implement a pause, return_nextMove.skip = true from your nextTarget() function. StrokeEngine will poll again later instead of starting a new motion.
The Pattern base class provides three helper functions for pause management:
| Function | Description |
|---|---|
_startDelay() | Starts the delay timer |
_updateDelay(int delayInMillis) | Sets the pause duration in milliseconds (can be updated anytime) |
_isStillDelayed() | Returns true if the scheduled time hasn’t been reached |
If a stroke becomes overdue, it executes immediately. See the Stop’n’Go pattern for an example implementation.

