My little rover project switched away from modified servos with unpredictable motor drivers to pure DC gear motors. The good news is that this switch allows me to take control of the motor driver. The bad news is that... well, now I have to control motor drivers myself.

For this exploration, I'll start with a classic the L298. These are featured in countless tutorials for turning digital logic into physical motion with motors and solenoids. It is not the latest technology, it is not compact, it is not efficient, but I expect L298 (or clones) to be available anywhere maker electronics are available. It's such a classic that in the official ST Electronics datasheet PDF, diagrams are blurry as if scanned from paper instead of generated directly. At least the text is clear, but it is also amusingly dated "Jenuary 2000" so maybe we're looking at a document with OCR-enhanced text (with OCR errors) and old scanned diagrams.

When used to control DC motors like my current project, a L298 is usually put to work running two motors. There are two sides "A" and "B" each with its own control signals and output pins, though both share common power supply and ground pins. Motor can be driven at up to 45V with occasional spikes are allowed up to 50V. Electrical current is up to 2A with occasional peaks of 3A. Steady state, that multiplies out to 45V * 2A * 2 motors = 180 Watts, a respectable chunk of power which explains why there is a big metal tab for heat dissipation and datasheet says operating temperature may rise to as high as 130°C.

The chip itself requires 5V input for internal logic, separate from the motor power supply. For digital logic purposes, anything under 1.5V is treated as logic low. This is relatively high threshold and is intentionally done to to mitigate electrical noise coming from motors next door. Fortunately that should not present problems for newer 3.3V microcontrollers like ESP32, Teensy and newer Arduinos. Data pins draw up to 100uA which shouldn't be a problem to pair it with modern chips with far less amperage capacity than old school 8-bit chips.

Figure 6 explains how our microcontroller controls motor behavior. Direction is commanded by raising one input high and pulling other low. If they are equal, we get motor brake which we are warned must still not exceed 2A. If enable is low, the motor coasts independent of input values. Reading this chart, I understand that proportional motor speed control is accomplished by putting a PWM signal into the enable pin, alternating between applying power and coasting. However, I don't see a recommendation on what my PWM frequency should be.

A web search found this electronics StackExchange answer that claims single-digit kilohertz would be sufficient. However, there's also a contradiction in an answer that first claims PWM is done on the control input lines and enable is simply tied to high (always enable), but then links to the Arduino motor shield with L298N where the schematic clearly has PWM input lines going to the enable pins. Strange! I'll follow Arduino precedent and send PWM control to the enable pin.

Another use for the enable pin is in the power up/down sequence. Enable pin should be pulled low before motor supply is turned on, and should be low before motor supply is turned off. Speaking of power, when driving inductive loads (and motors certainly are) a 4-diode network is required to dissipate power that might feed back to the circuit from these coils.

I saw several mentions of a current sensing resistor, and I see a "Rs" in all the schematics, but there's no specification for resistance value or any other information beyond that they should be grounded as close to L298's GND pin as possible. No reference for how L298 interprets current as a function of ohms resistance. Eventually I figured it out: the current sensing pin is only a provision for those that want to add a current sensing circuit to their design elsewhere. The L298 itself doesn't care, and that's why ohms are not specified in this datasheet. It's going to be implementation-dependent so time for me to get my hands on an implementation.