https://github.com/luni64/encsim
Quadrature signal generator for testing encoder software. Requires a PJRC Teensy board. Generates quadrature signals with adjustable frequency, phase and bouncing
https://github.com/luni64/encsim
arduino bounce chatter encoder index-signal quadrature teensy
Last synced: about 2 months ago
JSON representation
Quadrature signal generator for testing encoder software. Requires a PJRC Teensy board. Generates quadrature signals with adjustable frequency, phase and bouncing
- Host: GitHub
- URL: https://github.com/luni64/encsim
- Owner: luni64
- License: mit
- Created: 2017-06-07T19:48:09.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2022-05-16T15:36:55.000Z (over 3 years ago)
- Last Synced: 2025-10-09T19:25:33.595Z (3 months ago)
- Topics: arduino, bounce, chatter, encoder, index-signal, quadrature, teensy
- Language: C++
- Homepage:
- Size: 815 KB
- Stars: 18
- Watchers: 4
- Forks: 6
- Open Issues: 2
-
Metadata Files:
- Readme: readme.md
Awesome Lists containing this project
README
# EncSim
- [Library Description](#library-description)
- [Serial Interface](#serial-interface)
- [API](#api)
## Library Description
EncSim is a library for the PJRC Teensy ARM boards (T3.0 - T3.6, T4.0, T4.1). It can be used for testing the performance of encoder libraries and/or hardware in a manual or automated test environment. It generates a quadrature signal which simulates optical or mechanical incremental [encoders](https://en.wikipedia.org/wiki/Rotary_encoder#Incremental_rotary_encoder). You can adjust the **direction**, **count rate** and the **phase** of the generated signal. For simulating mechanical encoders you can add random [**contact bouncing**](https://en.wikipedia.org/wiki/Switch#Contact_bounce) (aka chatter) peaks to the signal. EncSym uses the [TeensyTimerTool](https://github.com/luni64/TeensyTimerTool) for generation of the quadrature signal and the random bounce peaks.
### Key Features
- Easy to use interface to control signal generation with a serial terminal.
- Count frequency adjustable.
- Signal phase adjustable from 90° (standard) to 10°.
- Generates index pulses with settable distance for e.g., simulating rotary encoders with index signal.
- Bouncing:
- Total bounce time adjustable.
- Minimum width of random bounce peaks adjustable.
- Maximum width of random bouce peaks adjustable.
- Programming API for use in own sketches, automated tests or simular applications.
**Precompiled Firmware**
If you just want to use EncSym for testing your encoder library you do not need to install EncSim. You can download precompiled hex files for various Teensy boards instead. Just upload the firmware, open a serial terminal (arduinos serial monitor, [TyCommander](https://github.com/Koromix/tytools), [PuTTY](http://www.putty.org/), ...) and start testing. Precompiled firmware for various boards can be downloaded from [here](https://github.com/luni64/EncSim/tree/master/examples/SerialControl/precompiled_binaries).
### Examples of generated signals
**Bouncing:**
The follwing two images show the simulation of a mechanical encoder. The pulse rate was set to 50Hz and a total bounce time of 5 ms was choosen. The min and max duration of the bounce pulses was set to 20µs and 500µs respectively. The first image shows an overview, the second show the same data zoomed in.


**Phase Adjustment:**
Below the generated signal for a pulse rate of 100kHz and a signal phase of 45° is shown.

**Maximum Pulse Rate:**
The last example shows a signal with the maximum possible pulsrate of 1.4 MHz. You'll need a T3.6 @240MHz with F_BUS=120MHz to be able to get such high pulse rates.

***
# Serial Interface
The signal generation can be controlled by an easy to use [serial interface](https://github.com/luni64/EncSim/tree/master/examples/SerialControl). You can use the Aduino serial monitor, [TyCommander](https://github.com/Koromix/tytools) or any other serial terminal to send commands to the library. Internally the serial inteface uses Kroimons [SerialCommand](https://github.com/kroimon/Arduino-SerialCommand) lib for communication with the terminal.
**Commands:**
Typing in *help* or *?* in the terminal shows a list of all available commands:

**Command description**
- The *up* and *down* commands generate a continous quadrature signal until you send the *stop* command. The current counter value is printed during the 'movement'.
- *mva* and *mvr* 'move' to a given absolute or relative position respectively. Current counter value is printed during amd after the move.
- Each move command can be intercepted by *stop* or other move commands. E.g., sending *up* followed by *down* will change the direction of the signal immediately. Sending *up* followed by *mva 0* will change direction and move back to position 0.
- *getpos* and *setpos* get and set the current counter value
- *freq*, *phase*, *btot*, *bmin*, *bmax* and period set pulse rate, phase, total bounce time, minimal and maximal bounce pulse width and index pulse period respectively.
- *print* shows the current settings. Please note: the library clips the frequency and phase settings if the requested signal can not be generated with the given board. It is a good idea to check the actual settings with *print* if you use high frequencies and/or small phases settings.
# API
Using EncSim from your sketches without the serial interface is easy:
```c++
#include
#include
EncSim<0,1> simulator; // use pin 0 and pin 1 as output (any two digital pins can be used)
void setup() {
simulator.begin();
simulator // settings can be done by a "fluent interface"
.setFrequency(150) // 150Hz count rate
.setPhase(90) // normal 90° phase shift
.setTotalBounceDuration(0); // no bouncing
simulator.moveRel(100); // generate 100 counts
}
```
The following settings are available
```c++
setFrequency(Hz) // pulse rate in Hz (1-f_max), f_max depends on board and F_BUS settings
setPhase(deg) // signal phase in deg (10-90)
setTotalBounceDuration(µs) // total duration of bouncing phase in µs
setBounceDurationMin(µs) // minimum peak width of a bouncing peak
setBounceDurationMax(µs) // maximum peak width of a bouncing peak
setPeriod(steps) // distance in steps between the index pulses (-1 disables index pulses)
```
The following commands handle signal generation
```c++
moveAbsAsync(pos) // moves (generates pulses) to absolute position, returns after starting the move
moveRelAsync(delta) // moves relative to current position
moveAbs(pos) // moves to absolute position, blocks until movement is done
moveRes(delta) // moves relative to current position, blocks until movement is done
stop() // stops movement immediately
bool isRunning() // true if simulator is currently moving
```