
N20 Encoder Gear Motor Library for Proteus V1.0 (Hall Encoder, PID)

Hello friends, I hope you all are doing great. Today, I am going to share the new N20 Encoder Gear Motor Library for Proteus V1.0. The N20 is the tiny metal gear motor of line followers, small robot arms and balancing toys: a motor no bigger than a sugar cube with a gearbox in front and, in the version everybody wants for projects, a small encoder board on its back. That encoder is what turns a plain motor into something your Arduino can steer to an exact angle or hold at an exact speed, and it is the part that matters most in this library.
N20 Encoder Gear Motor Library for Proteus
Latest version: V1.0 (October 2026, this tutorial)
Helping Tools
- Serial Monitor Advance: a serial terminal window for the UART of your board
- Serial Monitor Expert: the serial monitor with extra debugging tools
- LCD Library for Proteus V3.0: 16x2, 20x4 and I2C LCDs to show your readings
The motor is analog: it takes real current from any driver, speeds up, slows down under load and stalls like the real one. The encoder is digital: it sends its two square waves on C1 and C2, and every edge comes at the moment the shaft really reaches it, so interrupts, encoder libraries and PID loops see exactly what they would see on the bench. The demo runs on our Arduino UNO V4.0, drives the motor through our separate L9110S library and turns the shaft to the angle of a potentiometer.
NOTICE: an encoder motor in a simulator is only useful if its pulses come at the right moments. So we did not fake a pulse train, we built the motor and worked out the time of every single edge from the shaft's real motion. It took our team a lot of hard work. Your feedback is the fuel that keeps us going, so please tell us what you think in the comments below or in the Motor Driver board of our forum. And if our free libraries help you, you can buy us a coffee. So, let's get started with the N20 Encoder Gear Motor Library for Proteus V1.0:
What is the N20 Encoder Gear Motor?
The N20 is a family of micro metal gear motors. The motor itself is a small brushed DC motor, 12 mm wide and 10 mm high, and in front of it sits a metal spur gearbox that trades its speed for torque. Gear ratios run from about 1:30 to 1:298 and the windings are made for 3, 6 or 12 V, so one N20 can turn at a thousand RPM while another creeps along at thirty. The one in this library is the common 6 V, 1:100 motor: about 300 RPM with no load.
The encoder version adds a small round board on the motor's rear shaft. A magnet disc spins with the motor, and two Hall sensors on the board see its poles go by. Each sensor gives a square wave, and the two waves are a quarter of a period apart. That is a quadrature encoder, the same idea as the KY-040 knob of our Rotary Encoder Library for Proteus, only on a motor that turns by itself. Six wires leave the back: two for the motor, two for the encoder's supply and two for its outputs, C1 and C2.
| N20 6 V 1:100 with a Hall encoder (the model) | |
|---|---|
| Motor | brushed DC, 8 ohm winding, M+ and M- |
| Gearbox | 1:100 metal spur gears, D-shaft |
| No load | about 300 RPM and 50 mA at 6 V, 140 RPM at 3 V |
| Stall | about 0.75 A and 0.75 kg.cm at 6 V |
| Encoder | 7 pulses per motor turn on C1 and on C2, 90 degrees apart, 3.3 - 5 V |
| Counts per output turn | 700 pulses per channel, 2800 counts with x4 decoding |
| Wires | M+ red, M- white, VCC blue, GND black, C1 yellow, C2 green |
Counting a Quadrature Encoder
The encoder sits on the motor shaft, before the gearbox. It gives 7 pulses per motor turn, and the gearbox turns the motor 100 times for one turn of the output shaft, so each channel gives 700 pulses per output turn. A sketch can count those pulses in three ways, and each way gives a finer position than the last:
| Decoding | What the sketch counts | Counts per output turn | One count is |
|---|---|---|---|
| x1 | the rising edges of C1 | 700 | 0.51 degrees |
| x2 | both edges of C1 | 1400 | 0.26 degrees |
| x4 | both edges of C1 and of C2 | 2800 | 0.13 degrees |
The direction comes from the order of the edges. While the shaft turns clockwise (M+ positive), C1 rises before C2: C1 leads. Turn it the other way and C2 leads. So a sketch that watches both channels knows not only how far the shaft has turned but also which way, with no extra wire. The demo uses x4 decoding: 2800 counts per turn.
What's New in N20 Encoder Gear Motor Library for Proteus V1.0
- A real encoder: C1 and C2 are digital outputs with 2800 counts per output turn, C1 leading clockwise and C2 leading counterclockwise.
- Every edge on time: the model works out when the shaft reaches each count and puts the edge there, even between two analog steps of the simulation.
- An analog motor: the winding, the back-EMF, the gearbox's friction and losses, the inertia and the load, driven by any driver, PWM or DC, either way.
- A dial that turns: the white dial on the D-shaft shows the simulated shaft angle, and the C1 / C2 LEDs show the two channels.
- Loads and stalls: a LOAD property, load buttons on the pop-up and a finger when you click the dial.
- A pop-up window with four pages - Motor, Graphs, Event log and Check - and a live chart of C1 and C2.
- It names the problems: a stall, an over-voltage, a reversal at speed and an encoder without its supply.
- A closed-loop demo on our Arduino UNO V4.0: a PD position loop on the pot, a PI speed loop and open-loop PWM, with no library at all.
The N20 in Proteus
Search N20 in Pick Devices; the device N20MOTORTEP is in TEPN20.LIB (category Electromechanical, DC Motors) and its model is TEPN20.DLL. It shows the motor from its shaft end at 4.5 times its real size: the 12 x 10 mm silver gearbox face with its two M1.6 mounting holes and the bearing boss, and a white dial on the D-shaft with a red pointer. While the simulation runs, the dial turns to the simulated angle of the output shaft, so a held position, a slow creep and a fast spin all look the way they are.
The six wires run from the motor to the pins on the left in their usual colours. Two LEDs on the plate light with C1 (yellow) and C2 (green); while the shaft turns fast they flicker together, and when it stands still they show which state the encoder stopped in. Under the plate is the strip with three readouts - the speed with its direction, the angle and the encoder count - and the OPEN PANEL button. The plate, the dial, the LEDs and the strip are TEP additions; the real motor has none of them.
| Pin | Wire | What the model does with it |
|---|---|---|
| M+ | red | the motor, analog: positive on M+ turns the shaft clockwise |
| M- | white | the motor's other terminal |
| VCC | blue | the encoder's supply, read as logic: low or open and C1 / C2 float |
| GND | black | the encoder's ground |
| C1 | yellow | encoder channel 1, a digital output (leads while turning clockwise) |
| C2 | green | encoder channel 2, a digital output (leads while turning counterclockwise) |
A Finger on the Dial
Click the dial while the simulation runs and you press a finger on the shaft: 0.3 kg.cm of friction. The motor slows and draws more current; in the demo's speed mode you can watch the loop push harder to keep its speed. Click again to lift the finger. The property LOAD adds a constant load in kg.cm for the whole run, and the pop-up has load buttons from 0.1 to 0.5 kg.cm. Enough load and the motor stalls.
Download N20 Encoder Gear Motor Library for Proteus
The download link of N20-Encoder-Gear-Motor-Library-for-Proteus-v1.0.zip (without the source code) will be added here soon. The zip file will contain:
- README.txt: installation, the demo, the wiring, the encoder, real hardware, troubleshooting and the limits.
- Proteus Library Files:
TEPN20.LIBandArduinoV4TEP.LIBfrom our Arduino Library for Proteus V4.0. - Proteus Model Files:
TEPN20.DLLandTEPARDUINO.DLL. - Proteus Simulation:
N20-Encoder-Motor-L9110S-ArduinoUnoV4.pdsprj,N20_Encoder_Demo.hexand copies of the two DLLs. - Arduino Code:
N20_Encoder_Demo.ino(no library needed).
The driver is a separate library: this package holds only the motor and the UNO. The demo drives the N20 through our L9110S motor driver, which has its own download - get it from our L9110S Motor Driver Library for Proteus and install it first, or the demo opens without its driver.
No Proteus yet? Read How to Download and Install Proteus 7 and 8. New to libraries? Follow How to Install a New Library in Proteus.
How to Install N20 Encoder Gear Motor Library for Proteus
- Close Proteus and extract the whole zip file, for example to your Desktop.
- Copy
TEPN20.LIBandArduinoV4TEP.LIBfrom Proteus Library Files into the LIBRARY folder of Proteus (usuallyC:\Program Files (x86)\Labcenter Electronics\Proteus 8 Professional\LIBRARY). - Copy
TEPN20.DLLandTEPARDUINO.DLLfrom Proteus Model Files into the MODELS folder. The two Arduino files are the ones of our Arduino Library V4.0; if you have it, they are the same. - Install our L9110S Motor Driver library the same way from its own zip:
TEPL9110S.LIBinto LIBRARY andTEPL9110S.DLLinto MODELS. - Delete
TEPN20.IDXfrom the LIBRARY folder if it is there. - Start Proteus, press P and search for N20.
Tip: keep the Proteus Simulation folder together, because the project needs its .hex file and the DLLs beside it. The library is tested in Proteus 8.5; Proteus 7 is not supported.
The Demo Circuit
Open N20-Encoder-Motor-L9110S-ArduinoUnoV4.pdsprj. ARD1 is an Arduino UNO V4.0 from our Arduino UNO Library for Proteus V4.0, running N20_Encoder_Demo.hex with its serial monitor built in. DRV1 is the L9110S driver in its pop-up version. M1 is the N20 on the driver's MOTOR A terminal. RV1 is a 10k potentiometer on A0 that sets the target angle from 0 to 360 degrees. The sheet is A3: the UNO, the driver and the motor with its six labelled wires do not fit an A4 sheet legibly.
| From | To | Note |
|---|---|---|
| L9110S A-IA | D5 | PWM, 980 Hz |
| L9110S A-IB | D6 | PWM, 980 Hz |
| L9110S VCC / GND | 5V / GND | on a real robot: the battery, 2.5 - 12 V |
| N20 M+ / M- | L9110S A-OA / A-OB | MOTOR A |
| N20 VCC / GND | 5V / GND | the encoder's supply |
| N20 C1 | D2 | interrupt 0 |
| N20 C2 | D3 | interrupt 1 |
| RV1 wiper | A0 | the target angle |
The encoder goes to D2 and D3 because those are the UNO's two external interrupt pins: every edge on either channel calls the sketch at once, wherever it is. In Proteus the pins meet through net labels, while the motor wires run straight from the driver's terminal to M+ and M-, so you can follow the current. The serial monitor needs no wires, because it is built into the UNO V4.0.
The Arduino Code
The demo needs no library, which makes it a good place to see how an encoder loop works. New to Arduino? Start with Arduino Tutorial for Beginners and Introduction to Arduino UNO. The pins and the counts per turn come first:
const byte IA = 5, IB = 6, ENC_A = 2, ENC_B = 3, POT = A0;
const long CPR = 2800; // counts per output turn (x4)
The heart of the sketch is the interrupt routine. It reads both channels, makes a two-bit state of them and looks up the step from the old state and the new one: +1, -1 or 0. That one table does x4 decoding and the direction at the same time:
volatile long count = 0;
volatile byte lastAB = 0;
// x4 decoding: the previous and the new state of (C1, C2) -> -1, 0, +1 (C1 leading = +)
const int8_t STEP[16] = {0, 1, -1, 0, -1, 0, 0, 1, 1, 0, 0, -1, 0, -1, 1, 0};
void encISR() {
byte ab = (digitalRead(ENC_A) ? 1 : 0) | (digitalRead(ENC_B) ? 2 : 0);
count += STEP[(lastAB << 2) | ab];
lastAB = ab;
}
Both channels call the same routine on every change, rising and falling:
attachInterrupt(digitalPinToInterrupt(ENC_A), encISR, CHANGE);
attachInterrupt(digitalPinToInterrupt(ENC_B), encISR, CHANGE);
The count is a long, four bytes, and the interrupt can change it halfway through a read. So the main loop copies it with interrupts off for a moment:
long readCount() { noInterrupts(); long c = count; interrupts(); return c; }
The motor is driven the way the L9110S wants it: PWM on one input and the other one LOW, so a positive number turns it forward and a negative one backward:
void drive(int p) { // L9110S: PWM on one input, the other LOW
pwmNow = constrain(p, -255, 255);
if (pwmNow >= 0) { analogWrite(IB, 0); analogWrite(IA, pwmNow); }
else { analogWrite(IA, 0); analogWrite(IB, -pwmNow); }
}
The control loop runs every 5 ms. It takes the count, works out how many counts went by since the last pass and turns that into a smoothed speed in RPM:
if (now - loopAt < 5) return; // the control loop: every 5 ms
loopAt = now;
long c = readCount();
long dc = c - lastCount; lastCount = c;
rpmNow += (dc * 60000.0 / 5 / CPR - rpmNow) * 0.2; // counts per 5 ms -> RPM, smoothed
To hold an angle, the sketch uses a PD loop. The P part pushes in proportion to the error in counts; the D part brakes in proportion to the speed, so the shaft does not overshoot. A dead band of 3 counts stops the loop from buzzing around the target, and a minimum drive of 40 gets the motor over its friction for the last few counts:
if (mode == KNOB || mode == POSITION) { // PD: the error in counts, the speed in counts per 5 ms
long e = target - c;
int p = 0;
if (labs(e) > 3) { p = (int)constrain(2.0 * e - 4.0 * dc, -255, 255); if (abs(p) < 40) p = p > 0 ? 40 : -40; }
drive(p);
To hold a speed, it switches to a PI loop with a feed-forward: the expected PWM for the target speed, plus a correction for the present error, plus an integral that slowly removes what is left - the part that keeps the speed when you press a finger on the dial:
} else if (mode == SPEED) { // PI on the RPM, with a feed-forward
float err = rpmTarget - rpmNow;
iTerm = constrain(iTerm + 0.02 * err, -120, 120);
drive((int)(rpmTarget * 255.0 / 250 + 0.8 * err + iTerm));
If you have never controlled a motor's speed from an Arduino before, our older DC Motor Speed Control using Arduino tutorial shows the open-loop side. The HEX file is in the package. To change the sketch, open it in the Arduino IDE and export the compiled binary, as in How to get the HEX file from Arduino. It needs 9,996 bytes of flash (30 % of the UNO) and 323 bytes of RAM.
Running the Demo
Press Run. The UNO's serial monitor and the two pop-ups - the motor's and the L9110S's - open over the schematic; move them aside. RV1 starts at 40 %, so the sketch asks for 1121 counts:
N20 Encoder Gear Motor demo - The Engineering Projects
L9110S A-IA D5, A-IB D6; encoder C1 D2, C2 D3 (x4: 2800 counts per turn). The shaft follows the pot on A0.
Commands: a 90 | s 2800 | rpm 120 | pwm 50 | stop | zero | knob | help
Pot 410 -> target 1121 counts = 144.1 deg
The shaft swings round and stops at 144.3 degrees, count 1122 - one count from the target, inside the loop's dead band. Click RV1's arrows and the dial follows the pot. Then try the commands in the monitor:
| Type | What it does | What the run showed |
|---|---|---|
| a 90 | go to 90 degrees and stay | a 270: 269.9 degrees, count 2099 |
| s 2800 | 2800 counts from here: one turn (- = the other way) | one turn and stop |
| rpm 120 | hold 120 RPM with the encoder as the speed sensor | 116 - 125 RPM CW while the loop settles |
| rpm -200 | the same counterclockwise | 202 RPM CCW, C2 leading |
| pwm 100 | open loop, full drive | 243 RPM at 4.89 V, 52 mA |
| stop / zero | both inputs LOW / the count = 0 here | |
| knob | follow the pot again | back to 144 degrees |
The end of the run is a good story in numbers. With full drive and a heavy load the motor stalls: the speed reads 0 or 1 RPM, yet the count still creeps up by a few counts each half second, because a stalled N20 is not quite stopped. Then the load comes off, the motor runs up to 248 RPM, and knob sends it back to the pot:
Count 10365, 1 RPM, PWM 255
Count 10368, 0 RPM, PWM 255
Count 10373, 0 RPM, PWM 255
Count 10382, 0 RPM, PWM 255
Count 10444, 36 RPM, PWM 255
Count 15738, 248 RPM, PWM 255
knob
Following the pot on A0
Pot 410 -> target 1121 counts = 144.1 deg
Pot 417 -> target 1140 counts = 146.6 deg
Pot 412 -> target 1127 counts = 144.9 deg
At 1124 counts = 144.5 deg - holding
The loop reverses the motor at full speed, winds the shaft back and settles at 1124 counts, 144.5 degrees - within its 3-count dead band of the last target. That reversal is also the hardest moment for a driver, as the pop-up will tell you.
The Pop-Up Window
At Run the motor opens TEP N20 Encoder Gear Motor, a window in the look of our TEP Serial Monitor Advance for Proteus. It has four tabs - Motor, Graphs, Event log and Check - plus Settings and Help behind the gear and question mark icons, and the palette icon that switches the theme. If you close it, the OPEN PANEL button on the strip brings it back.
Motor
The banner says what the motor is doing: RUNNING CW or CCW with the speed and the drive, STOPPED, STALLED or OVER-VOLTAGE. The gauge runs from 300 RPM counterclockwise on the left to 300 RPM clockwise on the right, with the rated band marked in orange, and shows the frequency on C1 under the needle. The live values are the speed, the direction, the average voltage, the current, the drive, the power, the load and the encoder count in counts and turns. The toolbar puts a load on the shaft - None, 0.1, 0.2, 0.3 or 0.5 kg.cm - or the finger.
The Encoder Chart
The bottom of the Motor page is the picture this library was built for: C1 and C2 over the last 5 ms as two logic traces, with the drive across M+ / M- under them. At 123 RPM the output shaft turns about twice a second and C1 runs at 1433 Hz: 123 RPM times 700 pulses per turn, divided by 60. Look at any rising edge of C1 and you find C2 rising a quarter of a period later. That is clockwise.
Reverse the motor and the same chart shows the other order: C2 leads, the count runs down, and the sketch's STEP table subtracts instead of adding. In the speed loop the Drive tile may show a PWM frequency, because the drive that reaches M+ / M- moves while the loop corrects it; with a fixed drive it reads STEADY, as explained further down.
Graphs
Graphs draws the speed, the current and the average voltage across the motor over the last 1, 3 or 6 seconds, as 50 ms averages. Here the motor runs at full speed counterclockwise until the loop takes over: the drive flips, the current jumps, the speed crosses zero, swings a little past it and settles. Tuning a PID loop is much easier when you can see this.
Event Log and Check
The Event log keeps the story of the run: every steady speed, for example "steady 243 RPM CW (2830 Hz on C1) at 4.89 V average, 0.05 A", every direction change, every stop, the loads and the warnings. Filter it by drive and speed or by warnings, pause it or clear it. The Check page puts the drive, the PWM, the current against the common drivers (an L9110S, an L293D, an L298N), the speed with the encoder rate, the load, the encoder's supply and count and the peaks in rows with a green, amber or red verdict.
Stalls and Reversals
Type pwm 100, pick 0.5 kg.cm on the toolbar and click the dial. The 0.8 kg.cm on the shaft is more than the motor can give through the L9110S, and it stops. The banner turns red: "STALLED - 0.49 A at 0 RPM: the load is too much". The Event log adds "STALLED - 0.49 A at 0.4 RPM", and the encoder chart goes flat. The L9110S leaves 3.97 V across the motor at that current, so the stall current is lower than the 0.75 A a stiff 6 V supply would give.
The other classic is the reversal. When knob sends the motor back while it runs at 223 RPM, the loop reverses the drive at once. For a moment the back-EMF of the spinning motor adds to the supply, and the Event log warns: "reversed at 223 RPM: 0.90 A peak - stop (or brake) first, the driver sees about twice the stall current". The model warns because a real driver deserves it.
How the Model Works
Proteus solves the analog part of a circuit in steps and runs the digital part between them. The motor is analog: its speed is an internal node solved together with the driver, with the winding resistance, the back-EMF, the friction and losses of the gearbox, the inertia and the load. The angle is the speed added up over time. The encoder is digital, and here is the trick: after each analog step the model knows the angle and the speed, so it works out when the shaft will reach the next count and schedules the edge on C1 or C2 at that exact time. The edges come evenly spaced at a steady speed and bunch up or spread out as the motor speeds up or slows down, as they do on the real motor.
That is also why the simulation does not slow down at high speed: about 0.2 x real time on a desktop PC, holding still or at 240 RPM, which is about 11,000 encoder edges a second. We checked the model on a PC with 26 automatic tests: 303 RPM and 53 mA at 6 V, 90 % of the speed in 0.10 s, 140 RPM at 3 V, a reversal at 5 V peaking at 1.17 A, 1.0 kg.cm stalling at 0.75 A, 0.4 kg.cm still turning at 143 RPM, and 2800 evenly spaced counts per turn in the right order both ways.
About the L9110S in the Demo
The demo's driver is our L9110S Motor Driver Library for Proteus. Its model does not switch the motor on and off a thousand times a second; it hands the motor the average of its PWM in each analog step. The speed is exactly what the PWM would give and the simulation runs much faster. So at a fixed duty the motor's Drive tile reads STEADY, "DC, or a driver that averages its PWM". The L9110S's own pop-up is the place to see the UNO's 980 Hz PWM on its inputs. Drive the N20 from a driver that really switches and its pop-up shows the PWM frequency and duty.
Troubleshooting
- The shaft never turns and the pop-up says NO DRIVE: the driver's inputs (both LOW = stop), its VCC, or the motor wires on the wrong outputs.
- No driver in the project: install our L9110S library (
TEPL9110S.LIB/TEPL9110S.DLL) - it is not in this package. - The count stays at 0 while it turns: the encoder's VCC or GND, or C1 / C2 on pins the sketch does not read; the Check page says "no supply" when VCC is not HIGH.
- The count runs backwards: swap C1 and C2, or M+ and M-.
- It oscillates around the target: lower the P gain or raise the D gain in the sketch (2.0 and 4.0 in the demo).
- STALLED: less load, or more drive.
- No dial, no UNO or no monitor:
TEPN20.DLLorTEPARDUINO.DLLis missing from MODELS and the project folder; a closed monitor opens again with a click on the UNO's USB port.
Things to Know Before Using a Real N20
- Power: feed the driver from a battery, for example two 18650 cells or four AA cells, with GND common to the Arduino. A stalled N20 takes about 0.75 A at 6 V.
- The encoder's supply: 3.3 - 5 V. Many encoder boards need no pull-ups; some do, 10k from C1 and C2 to VCC.
- Direction: swap M+ and M- and both the direction and the sign of the count change; swap C1 and C2 in the sketch or on the wires if the count runs the wrong way.
- Know your motor: N20s come with 1:30 to 1:298 gearboxes and 3, 6 or 12 V windings. This one is the 6 V 1:100 with 2800 counts per turn; for another, change CPR in the sketch.
- Interrupts: on an UNO only D2 and D3 have external interrupts; for two encoder motors, give each motor one interrupt pin and count x2, or use a board with more interrupt pins.
Limitations of the Simulation
- Not modelled: the winding inductance, the gear backlash (a real encoder on the motor shaft counts the backlash too), the encoder's duty and phase errors, heating, and the differences between real motors.
- The motor is the 6 V 1:100 N20 with a 7-pulse Hall encoder; other ratios and windings are not selectable.
- The plate, the dial, the LEDs, the strip and the finger are TEP additions.
- The model is our own, written from the typical data of the 6 V 1:100 N20 gear motor with a Hall encoder; this library is not made or endorsed by Arduino or Labcenter.
- Licences: the demo needs no Arduino library; the HEX file contains the Arduino AVR core 1.8.6 with LGPL-licensed code, and the sketch is included. The potentiometer is Proteus's own POT-HG. The L9110S driver is our separate library.
- Tested in Proteus 8.5 in October 2026 with the demo as shipped: the knob, the angles, the speed loop both ways, open loop, the stall, the reversal and all four pages of the pop-up. Proteus 7 is not supported.
So, that was all about the N20 Encoder Gear Motor Library for Proteus V1.0. I hope it helps you write and tune your encoder code - the interrupts, the quadrature, the PD and PI loops - before the first N20 is glued to your robot. If you have any questions, ask in the comments and I will help you out. Till the next tutorial, take care and have fun!
























Comments
0