Notes on Adafruit AS7341 Arduino Library Example Code

I’ve purchased an AS7341 breakout board from Adafruit (#4698) and read through their guide (single-page view) on the board. It’s nice to see their library takes care of the complexity of this chip’s internals such as SMUX configuration. Examples that come bundled with a library is always a good overview of capabilities, and this is what I see from its examples directory:

  • basic_counts: “Basic Counts” is a concept described in the AS7341 calibration application note. A bit of math that takes raw sensor counts and compensates for gain and integration time. AMS recommends application logic work with “Basic Counts”. This lets us change gain and integration based on environment and still keep the rest of the application logic unchanged.
  • flicker_detection: Prime concern of flicker detection is with household AC power frequencies of 50Hz or 60Hz however this sensor is not limited to those rates. The datasheet says it can detect flicker frequencies up to 2kHz. This capability feels like a potential project all by itself, I’ll have to think more about it.
  • get_channel: Performs a read of all channels then iterates through 10 spectral sensing channels of 8 visible spectrum + clear + infrared to print their raw counts. (Flicker detection channel is ignored.)
  • gpio_example: Using the “GPIO” pin as a digital output. High for 3 seconds and low for half a second and repeat. Important note: according to board schematic published by Adafruit, the GPIO pin is brought out directly to the headers. There is no voltage level shifting or protection on this pin so be sure to consult datasheet and be nice to this 1.8V part.
  • gpio_input_example: Using the “GPIO” pin as digital input. Samples every half second and prints either “high” or “low” to serial console.
  • led_test: The canonical “blink a LED” test implemented with the LED Adafruit installed on the breakout board connected to AS7341’s LDR pin. Lights up at 4mA for 1/10th of a second, dark for half a second, light up to 100mA for 1/10th of a second, dark for another half a second, and repeat. Note while the AS7341 constant current control register goes up to 258mA, we shouldn’t go that far. According to board schematic published by Adafruit, the onboard LED is an EAHC2835WD6 with recommended ceiling of 150mA and absolute maximum of 180mA.
  • plotter_example: A clever variation on get_channel designed to work with Arduino IDE’s Serial Plotter feature. Five comma-separated sensor values are printed on a line so that when we turn on Serial Plotter, the plotter line drawing colors are close to the color wavelength of that sensor.
  • read_all_channels: This is almost identical to get_channel. The only difference is this sketch passes an array into the call to readAllChannels() and prints from sketch’s own array. get_channel does the exact same thing using the array stored in Adafruit library object.
  • reading_while_looping: Most of these examples call readAllChannels(), which is a blocking call that waits for sensor integration to complete before returning with results. Depending on integration time configuration, delay caused by waiting can be problematic. This sketch illustrates a way to initiate AS7341 integration and yield control so other things can happen until integration is complete. Note: the I2C operations involved are still blocking calls via Arduino’s Wire library.
  • smux_test: I didn’t understand this sketch. It has an empty loop() and I don’t see how setup() tests SMUX in any way.
  • spectral_interrupts: By its name I hoped to see a demonstration of using AS7341 INT pin to generate a hardware interrupt signal for Arduino microcontroller, triggering an ISR (interrupt service routine) for sensor read. I was wrong, the “interrupt” for this sketch is merely a register flag that we read from within loop().
  • synd_mode: By its name I hoped to see a demonstration of using GPIO pin to trigger start of AS7341 sensor integration. This time I think I got my wish! Unlike all of the other examples, this sketch doesn’t use Adafruit’s AS7341 library and was not written by anyone at Adafruit. It uses the Wire library directly and was written by an AMS application support engineer.

Despite mysteries like smux_test, I see a good set of examples here to help me become familiar with AS7341 capabilities. A sensible person would start their exploration with simple modifications to one of these sample sketches. I did not go down that path of sensibility.

Adafruit AS7341 Board (4698)

I wanted to play with the AMS AS7341 11-channel spectral color sensor and the easiest way is to buy a breakout board making it easier to work with that tiny little 1.8V surface-mount chip. DFRobot has reasonable looking products but I ended up going with Adafruit’s AS7341 board, item #4698.

Compared with DFRobot’s offering, the Adafruit board has only a single LED instead of two. Neither of them brought out LDR pin for controlling external illumination. They both include all the voltage level handling necessary to allow 3.3V and 5V microcontrollers to talk to this 1.8V chip. DFRobot offered two products: one with their solderless Gravity connector system and a different offering compatible with 0.1″ pitch headers. Physically, Adafruit’s #4698 is slightly larger, but it has both 0.1″ pitch headers and their STEMMA QT connector. These are also known as JST-SH connectors, and I’ve already purchased a set (*) originally intended for use with BeagleBone Blue. Having both options for connectivity down the line is appealing to me, and I’ve been a longtime Adafruit customer. Which meant there were other things I wanted to buy from Adafruit anyway. It was minimal additional effort and cost to add AS7341 to an order and wait for it to show up.

Once the sensor arrived (UPS required a few extra days beyond original estimated delivery) I connected it to an ATmega328P Arduino Nano on a breadboard. As is typical of Adafruit, they have developed an Arduino library to communicate with this sensor, and I could load up the led_test example sketch as a quick test to see if it worked.

Yes, it works! I will now look over Adafruit’s full set of examples.

(*) Disclosure: As an Amazon Associate I earn from qualifying purchases.

Window Shopping DFRobot AS7341 Board

I’m intrigued by the AMS AS7341 11-channel spectral color sensor, and I’ve reached the limits of what I can learn from its (somewhat disappointing) datasheet and application note documentation. It’s time to get some hands-on experience with the device, which hopefully would help me understand more of the documentation in a positive feedback cycle. Plus I just want to start playing with it.

I could buy the sensor chip itself from Digi-Key, which has published a product page highlighting AS7341. Cost is reasonable for single quantities ($11.42 at time of writing) but at 3.1mm x 2mm x 1mm it is far too small for me to handle directly. I need a breakout board. The most obvious choice is AMS’ own evaluation kit, but that is priced far too high ($189.38) for me to stomach. Thankfully there are other companies providing AS7341 breakout boards for electronics hobbyists like myself.

DFRobot is one of these companies, and it has not one but two AS7341 offerings that differ by physical interface. Product SEN0364 has connectivity via DFRobot’s “Gravity” connector. Its sibling product SEN0365 has generic 0.1″ pitch breadboard-compatible headers. They both have mounting holes and voltage level shifters/converters for both signal and power interface with 3.3V and 5V parts. (AS7341 itself is a 1.8V part.) The Gravity port only has I2C communication, but the 0.1″ header version also break out INT (optional signal for “reading complete”) and GPIO (optional signal for “start reading”). Both include a pair of white LEDs for illumination controlled by AS7341 LDR pin, but that also meant LDR was not brought out so we can’t use it to control external lights.

On the software front, DFRobot provides an Arduino library and several example projects. I thought their household lights comparison test was very interesting, using an AS7341 to show difference in emission spectra of various household lights. I understood the spectral plots, but they lost me when the math started going into CIE color spaces like the AMS calibration data sheet did. The biggest problem with this example project is that its online listing is incomplete: the Arduino sketch for interfacing with AS7341 is listed, but the Processing sketch was missing. It plots results on a desktop computer screen and screenshots were included in the project writeup. Without it we’d just have a bunch of numbers in a serial terminal. It shouldn’t be too hard to recreate using Processing’s Serial library if one felt motivated to do so. Still, its absence was annoying.

Interesting but incomplete example projects won’t change the fact DFRobot SEN0364 and SEN0365 seem like reasonable options for AS7341 breakout boards. Another option for AS7341 breakout board is Adafruit product #4698, which is what I eventually bought for myself.

AMS AS7341 Calibration Application Note

I’m learning the ropes of using an AMS AS7341 11-channel spectral color sensor, figuring out what I absolutely need and what I will wait to explore later. So far, I have found AMS product datasheet to be lacking. The topmost irritation was missing information on configuring the sensor multiplexor, a critical component inside the chip. It was also missing information on higher-level concepts for a color sensor and how the AS7341 implements them. I found some of this information in the document titled Spectral Sensor Calibration Methods which is listed as an Application Note Calibration Methods AS7341 EVKs.

This document taught me how an ideal spectral detector would activate on a specific wavelength, but real-world implementation is sensitive to a range of wavelengths near that target. This is why its documented response curve is a series of bell curves and not a set of spikes. Furthermore, there may be responses far from the target wavelength due to a variety of other factors.

This foundation led to an explanation of why, in addition to 8 different wavelengths within the visible spectrum, the sensor also had three additional sensors: A “Clear” sensor with no color filter, a near-infrared sensor, and a flicker detection system. Originally I had thought they were just thrown in for the sake of more features, but this application note explains they support the 8 color sensors by detecting problems that throw off readings.

I have to admit I did not understand much of the discussion about plotting sensor readings into CIE color space. Color science is a field with a long history and reading Wikipedia pages only taught me that there is a lot I don’t know. Clearly this application note is aimed at an audience who is already familiar with the topic.

But even if I was familiar with CIE color spaces, this document left a lot of gaps in information. This application note referenced a piece of software called “AS7341 Software GUI, running on a Windows personal computer” but that software is nowhere to be found on AMS website. It appears to be something I can obtain by contacting my AMS account representative, which I don’t have. There are also snippets of a large Excel spreadsheet, with the disclaimer “Tables were interrupted. See the full tables in the original MS Excel File.” And is this MS Excel file on the website? Apparently not: “Ask the ams support team for the original XLS file” And there was a section that ended with “For more details, please refer to the Sensor ECGs manual.” What is ECG? That was not explained. And so on.

I learned a lot from AMS documentation for AS7341 but I felt there were significant room for improvement. Nevertheless, I am confident enough in my understanding to get hands-on with AS7341 sensor.

Additional AMS AS7341 Sensor Functionality

I’m starting to get a handle on the basics of an AMS AS7341 11-channel spectral color sensor. I know how to control sensitivity and exposure time, and I know I lack information on configuring the sensor multiplexor (SMUX) within the device. These are critical parameters for taking any readings and I need to understand them up front. For the moment I’ll postpone the following auxiliary functions that I (hope) are not crucial to sensor operation.

Given this chip only has 8 pins to the outside world, I was surprised that one pin (LDR) was allocated to the task of sinking current for a LED. But it made sense once I thought about it: a source of illumination is a common need for spectral sensor applications. According to figure 37 describing the LED register, it is a constant-current sink that defaults to 12mA which is more than enough to illuminate a single LED. The register implies quite a range of current handling: we can set it to go as low as 4mA and as high as 258mA. A quarter of an amp is quite a lot for a single LED so I guess this is for driving multiple LEDs in parallel. For example, if we want to surround the sensor with a ring of lights. Even then, at a quarter of an amp I’d start to worry about thermal issues.

And heat is definitely a concern for this sensor, judging by its built-in capability to compensate for device temperature. This “autozero” capability takes about 15ms to perform and we can configure its frequency in the AZ_CONFIG register 0xD6. By default, autozero runs once before taking first reading and never again. We can configure it to run more frequently, in terms of once every X readings. I don’t know how important temperature compensation is for this sensor. There’s a chance it is only important for those who need absolute precision, but it is important enough to run at least once. (Datasheet recommends against setting register to zero.)

Back to pins on the chip: INT can be configured to signal that a sensor reading is complete, intended to be connected to a microcontroller pin that signals an interrupt. This is not required as we can optionally poll the STATUS2 register via I2C for a bit indicating sensor reading is complete. And finally, a pin can be used to start a sensor reading but can also be used for general input/output hence it is labeled GPIO. This is also optional: we can start a sensor reading via I2C by setting a bit in the ENABLE register.

These features and others are neat but are not required for taking spectral color sensor readings. Either because they’re not required at all (LED), or their default values are good enough to start (autozero) or we have alternatives (INT and GPIO.) I can come back to play with these later. For now, I want to learn some higher-level concepts about this sensor via its color calibration application note.

AMS AS7341 SMUX Configuration is Critical Yet Absent from Datasheet

I want to understand the capabilities of the AMS AS7341 11-channel spectral color sensor and started orienting myself with its datasheet. The sensor seems quite capable but also quite complex to operate. The biggest barrier on the critical path (I must understand it to do anything with the sensor) is SMUX or sensor multiplexor. The onboard ADC (analog to digital converter) only has 6 channels to serve 11 sensor channels, the SMUX decides which subset of 6 is read at any given time.

Given their importance, I was quite baffled to find no documentation in the datasheet describing SMUX configuration registers. The closest thing I found was in section 8.4:”ams provides reference code and an application note on how to configure the SMUX.” First of all, sample code is not a substitute for proper documentation. Second, I see neither sample code nor SMUX configuration application note on the product’s supporting documents section. This is… unsatisfactory.

I hope I can resolve that “WTF?” item later, so I set that aside and continued learning about sensor parameters. I started thinking of this sensor as a small digital camera and I could use photography analogies to understand AS7341 parameters. A digital camera has three important variables in every shot:

  1. Aperture size
  2. Shutter speed controlling duration of exposure
  3. Film ISO equivalent controlling sensor sensitivity.

For an AS7341:

  1. It is a point sensor, so its aperture size is a pinhole camera and not adjustable.
  2. Integration time parameters control duration of exposure, equivalent to shutter speed.
  3. Gain parameter control sensor sensitivity, equivalent to ISO.

Integration time is controlled via parameters ATIME and ASTEP. ATIME is a single register at 0x81, and the entire range of 8-bit values (0-255) are valid. ASTEP is a 16-bit value split across two registers: 0xCA (low byte) and 0xCB (high byte.) 65535 is a reserved value for ASTEP, but 0-65534 are valid. Together they control the ADCfullscale parameter, which is defined as (ATIME+1)*(ASTEP+1) and has this footnote:

The maximum ADC count is 65535. Any ATIME/ASTEP field setting resulting in higher ADCfullscale values would result in a full-scale of 65535

This I found curious: if the maximum is 65535, the maximum possible representation in 16-bits, why do we need ATIME at all? ASTEP can cover the entire 16 range all by itself rendering ATIME superfluous. There’s a story here missing from the datasheet.

As a starting point for exploration, the datasheet listed 50ms (ATIME 29 ASTEP 599) as the typical integration time. I’ll start there and go higher or lower as needed. And as I’m just starting out, I hope I can safely ignore some of the auxiliary features until later.

Notes on AMS AS7341 Core Features

I have some grand dreams about what I might do with an AS7341 spectral color sensor, but things are always easier in the fantasy world than in the real world. To turn ideas into reality (or to see if it’s realistic at all) I need to learn the nuts and bolts of the sensor. Which means starting with its datasheet downloadable from AS7341 product page on AMS website. It answered some questions but opened many more.

The first and most important data point is its I2C address: 0x39 and I found no way to change it. (Datasheet section 9.1) It means this sensor is not designed to work in conjunction with others of its kind on the same I2C bus, there can be only one. The sensor is still responsive to I2C traffic when in sleep mode, which might be useful. (Datasheet 8) Also useful is a device identification register to verify I2C communication is working properly. (Datasheet 10.2.4)

The next important note was the chip’s internal architecture (Datasheet 8.1): there are 11 different sensors that could be read, but onboard ADC (analog-to-digital converter) has only 6 channels and a sensor multiplexor (SMUX) which controls which sensor is connected to which ADC and which are left disconnected. In order to read all 11 sensors, we need to make one read operation with 6 sensors then reconfigure SMUX to read the remaining 5. This architecture hints at the challenges ahead.

Each of these ADC channels have 16-bit resolution, and some configuration parameters are 16-bit values as well. This chip organized its registers such that the low order byte comes first, immediately followed by the high order byte. Read operations latch these registers, so the value does not change between reading the low byte and reading the high byte. (Datasheet 9)

With this information, I think I have enough basics to understand how to take a reading with AS7341.

Capacitor Replacement on Insignia 100W Powered Subwoofer (NS-RSW211)

My home theater had a small powered subwoofer, an Insignia NS-RSW211 Rocketboost 6-1/2″ 70W Wired/Wireless-Ready Subwoofer. After several years of use, it started exhibiting some strange effects and I disconnected it. Since I’m not a huge home theater buff and it was a modest unit to begin with, I didn’t really miss its absence. It sat forgotten in a corner until I saw Monoprice held a sale on their item #8248, a similar-sized powered subwoofer that would be a great replacement. Before I hit “Buy” on the Monoprice item, though, I thought I should make an effort to fix the one I have.

The failing symptoms indicate an intermittent connection somewhere in the system. When I turn on the subwoofer, it is fine for the first few minutes. After that initial period, sound would start cutting in and out at irregular periods. Every time it cuts out, the low bass sounds disappear. When it cuts back in, a deep “thump” announces return of low frequencies. This would start out tolerably infrequent, like hearing a distant firework show. Interruptions then become increasingly frequent. Eventually it will sound like automatic weapons fire in the background even when we’re not watching an action film, at which point I would turn it off. After a few hours of rest, I could repeat the cycle. Intermittent issues are always annoying to diagnose (part of why I’ve been putting it off) but I should at least take a look. On to the workbench it goes!

There are a lot of fasteners visible on this back plate. This is not a huge surprise: a subwoofer’s job is to push those low frequency thumps. Each thump will rattle anything not securely fastened, and every thump will be trying to loosen every fastener. In fact, the large numbers of fasteners are quite welcome: if it had been glued together, opening it up would be a destructive act making a successful repair unlikely.

But it wasn’t glued, so I could get to work. Removing the outermost eight fasteners allowed me to remove the rear module. I was a little surprised to see all electronics were sealed inside an airtight box. This might be good for acoustics but bad for air cooling circulation. The only thing poking into the acoustic chamber are the pair of speaker wires going to the driver itself. They used commodity spade connectors and were easy to disconnect so I could focus on the electronics box.

Removing the next outermost set of six fasteners allowed me to open up the electronics box. I was greeted with the thick stench of fried electronics. Something definitely died in here and, if it smelled this strong, I should be able to see it.

Yep, there it is. Capacitor C28 is toast. Finding this dead capacitor is good news, much easier than diagnosing an intermittent issue. The bad news is I’m not familiar enough with power supply theory of operation to explain why this absolutely and completely dead capacitor would cause an intermittent failure.

One end has completely blackened and appears to have broken open as well.

The yellow circuit board appears to be the power supply subsystem. 120V AC power cable (black & white wires) goes to the power switch, then into one corner of this yellow board near the dead capacitor. Diagonally opposite them is this connector delivering +24V to the rest of the subwoofer.

Unplugging AC input and DC output wires, then removing four screws, allowed removal of this power supply board so I could unsolder the dead capacitor easily. It came off in two separate pieces, very dead.

Reading markings on the charred capacitor carcass was a challenge. After playing with lighting, camera settings, and photo editing, I could make it out as:


I’m not familiar with this type of capacitor and didn’t know how to interpret those numbers. Looking around online, I found this page which said “105” meant 10 * 105 pF = 1000000 pF = 1000 nF = 1 uF and the “K” meant +/- 10% tolerance. The voltage rating portion didn’t line up with anything on that page, though. I’m inferring that “250KC” means something that can handle up to at least 250V, as this device can take up to 230V AC input.

Looking around my various assortment trays of capacitors, I didn’t find anything +/- 10% of 1uF. I then looked through my pile of teardown remnants for capacitors to salvage. The closest candidate was a 0.68uF 450V capacitor from the Antec power supply that caught on fire.

It even had the same footprint as the original toasted capacitor, making for an easy fit in the available space. However, 0.68uF is still short of the capacitance of the original so I continued looking.

I found a 0.22uF 250V capacitor inside the surprisingly complex evaporator fan. There was a clear conformal coating over everything that made removal a bit of a pain (and the result looking messy.) But they gave me a theoretical 0.68uF + 0.22uF = 0.90uF and my multimeter says they’re actually a tiny bit above rated value. Bringing me within 10% of 1uF, good enough for a test run.

Since the original capacitor slot was already occupied by the 0.68uF capacitor, the second parallel capacitor had to sit on the back.

I buttoned everything back up and preliminary test looks promising. After playing through a two-hour movie, I have yet to hear the thumping “fireworks” to “gunfire” failure sequence. Still unknown: what killed the original capacitor, and whether the same will happen to these replacements. Time will tell. In the meantime, I’ve managed to keep something out of landfill and resisted the temptation to buy a Monoprice powered subwoofer on sale. I’m thankful the design & engineering team built this device in a repairable way.

Resistors Negotiate 5V Power in USB Type C

Thanks to prompting by a comment, I am picking up where I left off trying to supply power over a USB-C cable. I love the idea of USB Power Delivery, the latest version covers transferring up to 240W over a USB Type-C cable. But that power also comes with complexity, and I didn’t want to figure out how to establish a power delivery contract when my project really just wanted five volts. Fortunately, the specification also describes a low-complexity way to manage 5V power over USB Type-C. But I had to be confident I was dealing with the correct wires, so I probed wiring with a small breakout board. (*) I confirmed that the four red wires were VBUS, the green and white wires were indeed the differential data pairs, and the mystery yellow wire is the VCONN or CC (cable configuration) wire on the same side.

Ah, yes, that “same side” was an interesting find. USB Type-C is physically shaped so there’s no “upside-down” way to insert the plug, with symmetric wires. However, that also means each side has a set of D+/D-/CC wires, and a USB Type-A to Type-C adapter only connects to one side. It is up to the Type-C device to check both sides.

In my previous experiment I learned that just connecting +5V to red and ground to black was enough to be recognized as a power source by some Type-C device but not my Pixel 3a phone. I found multiple guides that said to connect a 56kΩ pull-up resistor between CC and VBUS, but I wanted to know a little bit more without diving into the deep end of USB specifications. I found a very accessible post on Digi-Key forums describing the details of 5V @ 3A = 15W power over Type-C. Which is itself a simplified version of a much more complex Digi-Key overview of USB power.

Like several other guides, it mentioned the resistors on both ends of the Type-C cable, but it also had this phrase: “Together they form a voltage divider” which was my “A-ha!” moment. It allowed components to negotiate 5V power delivery without a digital communication protocol. We just need a resistor on either side: one for the provider to indicate the amount available, and the other by the consumer to indicate its desired consumption. Then we just need an ADC to measure voltage value of the resulting voltage divider, and we’ll know the safe power level.

When I added the 56kΩ pull-up resistor to my circuit, my Pixel 3a lit up with “Charging slowly”. I thought it was successfully charging at 500mA, but it wasn’t. Over the next half hour, its battery level actually dropped! I put the circuit under a USB power meter(*) and found it was only drawing a feeble 40mA. That meter also told me why: my circuit had supplied only 4.3V because I had a transistor in the circuit for power control and it dropped 0.7V from collector to emitter. This was why the power level was so low: a pull-up resistor to 4.3V was below the voltage threshold for 500mA power.

In order to create a microcontroller-switchable 5V (not 4.3V) power supply, I went with my most expedient option of using another voltage regulator with an enable pin connected to what used to be the transistor base. This raised the divided voltage within 500mA range, and finally the Pixel 3a started charging at that rate as confirmed by the USB power meter. And as an experiment to confirm my understanding, I dropped pull-up resistance down to 22kΩ. This raised the resulting voltage at the divider, and USB power meter reported that my Pixel 3a started drawing 1.5A. My buck converter is rated to handle this output and this way the phone charges faster.

[UPDATE: Hackaday has post describing USB-C power for the electronic hobbyist audience.]

(*) Disclosure: As an Amazon Associate I earn from qualifying purchases.

Notes on “Open Circuits” by Eric Schlaepfer and Windell H. Oskay

I am interested in electronics, in teardowns, and in electronics teardowns. Thus I was the exact audience for a book coming out soon: Open Circuits by Eric Schlaepfer and Windell H. Oskay. I preordered directly from publisher No Starch Press, which also granted me access to an early access eBook. I’ve finished browsing through that PDF and loved every page of it. I look forward to having the print book in my hand.

I first became aware of these cutaways from Twitter, where author Eric Schlaepfer tweeted a few cross sections shot with a cell phone camera via @TubeTimeUS. Feedback was positive, encouraging Eric to repeat the same treatment for more components, improving the techniques as he went. Things got popular enough that a vocal subset of his new Twitter following got grumpy when he went back to his regular programming. (Paraphrasing his reply: “Come on, guys, this account isn’t @CrossSectionTimeUS.”) Still, people loved the cross-sections and some said “I would love to have these pictures in a coffee-table book.” Thus this book Open Circuits.

Every component cross-sectioned in the book is accompanied by a brief explanation of the component. Knowing what a component does and how its internals accomplish the objective helps give us context to understand what we see in the pictures. Sometimes there’s a diagram with subcomponents called out as a visual explanation augmenting the text description. I knew roughly what some of these components did, but most of them were new information for me. But even if I had known of a component, usually I hadn’t known what it looked like inside! Every page is a new discovery. Occasionally, I even recognized something that I’ve seen before. For example, I recognized a thermal switch as something I took out of a retired coffee maker but I wasn’t sure what it was until I saw one explained and cross-sectioned.

This book is aimed at people who want to know more about what happens behind the scenes, so naturally the book covered that as well: the afterword section describes the techniques that went into this book’s photography. From cutting and polishing of components, to cleaning and mounting, to the photography process. Starting with cameras and lenses, to macro photography, and finally focus stacking to compose the sharp pictures in the book.

If you’ve read this far, you will enjoy the book as well.

I earn nothing from endorsing this book, I just love it.

Arduino Nano Failed to Power Backlight via USB

It was fun to look at a revived LED backlight module, salvaged from a LG laptop display panel model LP133WF2(SP)(A1). It was controlled from a breadboard Arduino, and powered by my bench power supply. I’m still unsure what input voltage it was originally designed for, but it seemed to run well at 5V. When I turned brightness up to maximum, the bench power supply reported 1A of current draw. As a 5W LED light, it does feel approximately in the same ballpark as the 7W LED bulbs serving as 60W incandescent bulb replacements. But with the key and very valuable difference of the fact its light is evenly distributed across a much large area for a softer more diffuse light.

While I’m at it, I measured the electrical behavior of these LED strings. This is mostly for reference since the TPS61187 chip handles adjusting these voltage values to keep electricity flowing at the target current. When it sees a very minimal PWM signal, I measure the voltage drop from anode to ground to be roughly 15V and the panel is not visibly illuminated at this low level. When I turn the duty cycle up high enough to see just a little bit of visible illumination, the voltage differential has climbed to 24V. At max power, I measured about 28V. This was all generated by the onboard boost converter from a 5V input signal. In my experience white LEDs drop roughly 2.7-3V at full power, so these values are consistent with parallel LED strings of either nine or ten LEDs per string.,

Since this circuit seemed to run at 5V, I thought it would be fun to convert this to run on USB. The Arduino Nano was designed to run on 5V and already had a handy USB jack, and most portable USB power banks can supply 5V@1A or at least they claim to. When I hooked up the wires, it was able to illuminate up to a certain level. But beyond that level (roughly 1/4 to 1/3 brightness) the lights started flickering in a classic sign of power instability. Oops. What went wrong?

Whenever I see potential sign of power instability, my first reaction is always to perform the Big Honkin’ Capacitor test. Find the biggest capacitor I have handy, connect it across the power input terminals, and see if that solves the problem. In this case, the big capacitor failed to soothe the system.

Digging into schematics for an official Arduino Nano, I see that the VUSB line is not directly connected to the +5V output pin. There are a few components in the way, relating to power control and regulation. The Arduino Nano could be powered via its VIN pin. Following Arduino Uno barrel jack precedence, the input voltage is usually recommended to be 9V. When this happens, there’s a diode presumably to make sure that 9V does not feed back into the USB +V line. There are also several capacitors in parallel with VUSB but they should help rather than interfere with any instability.

Mystified as to why I couldn’t power the backlight via this Arduino Nano’s USB jack, I wanted to isolate the problem. See if the problem lies within the Arduino Nano or with my USB power bank. I took a USB cable and cut off its a damaged micro-B connector. Splaying out the wires, I found VUSB and GND wires, and I connected that to the Arduino Nano circuit. With this arrangement, my backlight module is happy all the way up to full brightness with no flickering problem.

Something about this particular (non-genuine) Arduino Nano module is causing interference, and I don’t understand why, but at least I have a workaround. That’s enough for me to ignore this weirdness today and proceed with my backlight project, even if there was a temporary setback.

A Closer Look at LED Backlight Panel

I’ve successfully interfaced with the existing TPS61187 driver chip on the circuit board of a LG laptop display panel LP133WF2(SP)(A1), and brought the backlight module back to life. Given all the new territory I had to explore to get this far, I was very excited by a successful initial test. After I was able to calm down, I settled down to take a closer look at its physical/optical behavior.

Since I tested it face-down, the easiest thing to look at first are the backsides of the LED strip. Most of it is hidden by the sheet metal frame from this side, but from earlier examination I knew there was even less to see from the front. Once illuminated, we can see the structure inside the light strip. The yellow flexible segment that connects to the green circuit board isn’t a separate piece like I thought earlier, it is actually all a single sheet of flexible circuit. All the LEDs are mounted on it, and they are located at the very bottom edges of the screen. I knew the lights themselves had to be very thin and well hidden right up against the bottom edge, but I couldn’t figure out where the wiring would go. Now we can see all electrical wiring runs above the LEDs, and when we look at it from the front we can see it as a thin strip of light gray along the bottom.

I had been worried that the illumination would be compromised because it is working without some of the friends it had earlier. The backside used to have a laptop lid that would have helped reflect and diffuse light. And the front used to be up against the LCD pixel array, which was backed by a mirror finish that would have also helped reflect light around.

I need not have worried. It was quite evenly illuminated and, as seen in the wire shadow picture above, there are no distinct spotlights marking location of individual LEDs.

I also wondered if the surprisingly complex four-layer diffuser required precise alignment with the LEDs in order to do their light distribution magic. They are no longer pressed by the LCD pixel array into a tight space, but happily they still worked quite well. While they worked visibly best at certain positions, the falloff is graceful. Not like aiming a laser at precision optics. Now I’m even more impressed by this stuff performing magic with light in ways I don’t understand.

But one thing I do understand is that they look thin and quite fragile. Designed to sit behind a LCD panel of multiple glass layers and without that, these layers of magical optical sheets flap around. I looked around and found a piece of 3mm clear acrylic that is nearly the perfect size and taped it to the metal backing chassis. The acrylic is far thicker than the LCD glass sandwich used to be, but it is also more rigid, so that’s a good tradeoff.

The final comparison I wanted to make before moving on is: how bright is the backlight alone compared to the full backlight plus LCD screen? I placed this backlight, turned brightness all the way up high, and set it side-by-side with the intact replacement screen still serving display duty in the Chromebook. I then turned on the Chromebook and increased its screen brightness to maximum setting.

I don’t have light level measurement instruments to obtain an objective number, but this picture makes it quite clear there is a dramatic difference in brightness. I knew some light would have been lost within the layers of a LCD panel, but it’s fun to see firsthand it’s far more than I had expected. This really drove home why alternate display technologies with self-illuminating pixels (OLED, micro-LED, etc.) can offer much brighter pictures than a backlit LCD could. My salvaged backlight is plenty bright running on just 5V, but running it on USB took more effort than expected.

Arduino Nano PWM Signal for TPS61187 LED Driver

Trying to revive the LED backlight from a LG Lp133WF2(SP)(A1) laptop display panel, I am focused on a TPS61187 LED driver chip on its integrated circuit board. After studying its datasheet, I soldered a few wires to key parts of the circuit and applied power, checking the circuit as I went. Nothing has gone obviously wrong yet, so the final step is to give that driver chip a PWM signal to dictate brightness.

This is where I am happy I’ve added Arduino to my toolbox, because I was able to whip up a controllable PWM signal generator in minutes. Putting an Arduino Nano onto a breadboard, I wired up a potentiometer to act as interactive input. 5V power and ground were shared with the panel, and one of the PWM-capable output pins was connected to the TPS61187 PWM input line via a 10 kΩ resistor as per datasheet. I found that my enable line already had a 1 kΩ resistor on board, so now I wired enable directly to the 5V line.

Since I wanted some confidence in my circuit before plugging the panel into the circuit, I also wired a test LED in parallel with the PWM signal line. I had originally thought I could use the LED already on board the Arduino, but that is hard-wired to pin 13 which is not one of the PWM-capable pins, so the external LED was necessary for me to run my PWM-generating test code, which thanks to the Arduino framework was as easy as:

int sensorPin = A0;    // select the input pin for the potentiometer
int ledPin = 3;        // select the pin for the LED
int sensorValue = 0;   // variable to store the value coming from the sensor

void setup() {
  // declare the ledPin as an OUTPUT:
  pinMode(ledPin, OUTPUT);

void loop() {
  // read potentiometer position
  sensorValue = analogRead(sensorPin);

  // map analogRead() range to analogWrite() range
  sensorValue = map(sensorValue, 0, 1023, 0, 255);

  analogWrite(ledPin, sensorValue);

My external test LED brightened and dimmed in response to potentiometer knob turns, so that looked good. My heart started racing as I connected the panel to my Arduino breadboard, which is then connected to my benchtop power supply. Even though I’m powering this system with 5V, I used a bench power supply instead of a USB port. Because I didn’t know how much the panel drew and didn’t want to risk damaging my computer. Also, by using a benchtop power supply I could monitor the current draw and also set a limit of 120mA (20mA spread across 6 strings) for the first test.

I powered up the system with the potentiometer set to minimum, then slowly started turning the knob clockwise…

It lit up! It lit up! Woohoo!

I was very excited at this success, jumping and running down the hallway. It was a wild few minutes before I could settle down and calmly take a closer look.

Finding TPS61187 LED Driver Interfaces

I want to reuse the TPS61187 LED Driver IC already on board the display circuit board of a LG LP133WF2(SP)(A1) laptop LCD panel. Driving the backlight that used to shine from behind the now-cracked LCD screen. After studying the datasheet and probed around the circuit board to understand how the chip is configured, I am now probing to see where I can solder wires to interface with the chip.

There are two major concerns here. The first is that I’m learning to work with modern consumer electronics, with circuit boards populated by very small surface mount components. Most of the resistors and capacitors I probed earlier are barely larger than the tip of my soldering iron’s finest tip. The “normal” tip is comically large next to these things. If I continue with experiments like this I will need to buy my own hot air station and learn to use it well.

The second concern are the other components on this control board. If I supply voltage and ground to the TPS61187, the rest of the circuit will probably come alive in some way I don’t understand. I’m not worried about them draining a bit of battery, that’s the best case scenario. I’m more worried about them interfering with the backlight control signals for enable (EN) and brightness (PWM).

First target is to find a place to inject power. The datasheet told me where the power pins are on this chip, but it’s far too small for me to hand solder myself. I’m not saying it’s impossible to hand solder to them, I’m just saying it’s very difficult and unlikely to succeed with my current skill level. So I went poking around nearby components looking for a decoupling capacitor. Because this driver IC uses a boost converter circuit to raise the voltage to drive the backlight LEDs, I expect to find a sizable decoupling capacitor nearby to isolate the rest of this board from the electrical noise of boost conversion. I found one adjacent to the inductor. For a surface-mounted component, it is large and thankfully big enough for me to feel confident I could solder to its two ends for VIN and GND.

I found a resistor and capacitor nearby connected to the enable pin. But even though they are larger than the corresponding TPS61187 pin I couldn’t solder to them. I was able to connect to one side of the small capacitor, but an intended-to-be-gentle test tug ripped off the wire taking a corner chunk of the capacitor with it. Oops, not so gentle after all.

I had even less luck finding a PWM signal connection near the TPS61187. I could see its pin connection on the circuit board, but it instantly sank out of sight to one of the other layers of the board and I found no place nearby where it surfaced.

After some thought, I decided to look for these signals near the largest chip sitting on the other end of the board, labelled “LG Display ANX2804”. I reasoned that EN and PWM are probably controlled from this chip and perhaps I could find something. There was nothing obvious near the chip itself, but I struck gold on the backside of the board. Sitting effectively under the ANX2804 are several labelled and accessible test points, and I was happy to see “LED_EN” next to one pad and “PWM” next to another. (There’s also VLED visible further left I didn’t notice until later, which should be better than soldering to the VIN end of a surface mount decoupling capacitor.)

Continuity test confirmed these do connect all the way across this thin strip of circuit board to the TPS61187, I think we are in business! Time to do some soldering.

Probing TPS61187 LED Driver Configuration

I’ve read through the datasheet for a TI TPS61187 LED driver chip and I think I have a fair (if not perfect) grasp of how to use it. Specifically I want to use one I found on the integrated driver board of a LG laptop LCD panel I’ve taken apart, there to drive the backlight module I wanted to salvage as a LED light. Armed with the datasheet and a multimeter, I started poking at the driver board to understand how it uses the chip. Since most of the chip’s configuration are done via resistors connected to certain pins, I could use the ohmmeter to decipher configuration. I enlarged and printed out my picture of that area of the circuit board so I could scribble down notes as I went.

Here’s what I found on this board, listed in order of their corresponding datasheet sections:

7.3.1 Supply Voltage

For applications that are always-on, it is valid for the enable (EN) pin to be connected to the chip’s internal regulator output pin VDDIO. Since a laptop would want to put a screen to sleep, I did not expect EN to be tied to VDDIO and my meter confirmed it was not. Which means I’ll have to go hunting for my own connection to EN later.

7.3.2 Boost Regulator and Programmable Switch Frequency (FSCLT)

The internal boost converter can operate at a range of frequencies, giving the designer an option to tradeoff between efficiency, inductor component size, etc. I probed the selection resistor on this board to be 822 kΩ. Plugging this into datasheet formula I arrive at a switching frequency of 608 kHz. Table 1 lists a few recommended values, and 833 kΩ is one of the recommendations for 600 kHz. I suspect this was indeed the intent and this 822 kΩ resistor is pretty good at less than 2% off nominal value.

7.3.3 LED Current Sinks

This is arguably the core parameter of driving LEDs. I traced the circuit and found two resistors in series. ~20 kΩ and ~31 kΩ but they added up to about 58 kΩ so there’s obviously something else I missed. Nevertheless, plugging 58 kΩ into datasheet formula says it’ll sets the target at 20mA. Typical for driving LEDs.

7.4.2 Adjustable PWM Dimming Frequency and Mode Selection (R_FPWM/MODE)

There are two ways to control brightness of the backlight. Either they can be blinked directly by an external PWM signal, or they can be blinked with an internal signal generator. One advantage of using the internal signal is that the phase for each of six strings are offset, so they blink in turn instead of simultaneously, which I expect to give smoother dimming. Another advantage of separating the two signals is that the external PWM can run at a far slower frequency, even one that would otherwise cause visible flicker, but it wouldn’t matter. Because once its duty cycle is read, it is copied for use by the internal generator running at a far faster flicker-free rate.

Probing the configuration resistors proved this board uses the internal high speed PWM signal. The resistor is 3.9 kΩ which works out to about 46.6 kHz. This is not one of the Table 2 recommendations, in fact it is over twice the speed of the highest recommended value. at 9.09 kΩ / 20 kHz. Higher switching frequency usually mean smoother behavior but lower power efficiency, I wonder what design meeting decisions at LG led to this value. Though of course it’s possible I’ve misread the value somehow.

7.4.4 Overvoltage Clamp and Voltage Feedback (OVC/FB)

These resistors configure how the boost converter works, and there’s an ideal formula in the datasheet mapping input voltage to LED output voltage. I was able to measure Rdown as 20 kΩ, but Rupper did not converge. My ohmmeter’s initial reading was in the 370-400 kΩ range, but the value continued to increase as I kept the probes in place. Eventually it would read as off-scale high. I think this means there’s a capacitor in parallel?

Out of all the configurations I had hoped to read, this was the one I really wanted to get because it would inform me as to the best voltage level to feed into this system. With this ambiguous reading, I’m sadly no wiser.

But at least I have some idea of how this chip has been configured to run, so I could continue probing this circuit board looking for places where I can interface with this LED driving circuit.

My TPS61187 LED Driver Startup Plan

I wanted to see if I could power up just the LED backlight portion of a broken LG LCD laptop screen, model LP133WF2(SP)(A1). It was cracked and couldn’t display images, but the backlight still worked before I took it apart. Does it still work? I wanted to find out and I still had the screen’s integrated driver circuit board and will try that first. The biggest question mark here is how the rest of the circuit board will react if I try to power up the TI TPS61187 LED driver chip in-place on the circuit board. My fallback position is to bypass the chip and power the LED strings directly, but that wouldn’t be as energy-efficient and I lose out on cool features. The one most novel to me is the phase-shifted PWM dimming control, where the six LED strings are dimmed round-robin instead of all at once for a smoother display. It’s not something I would likely do if I had to power the LEDs directly with my own cricuit.

To see if I could get the original circuit running, I plan to do it in steps based on this excerpt from the datasheet:

7.3.4 Enable and Start-up

The internal regulator which provides VDDIO wakes up as soon as VIN is applied even when EN is low. This allows the device to start when EN is tied to the VDDIO pin. VDDIO does not come to full regulation until EN is high. The TPS61187 checks the status of all current feedback channels and shuts down any unused feedback channels. It is recommended to short the unused channels to ground for faster start-up.

After the device is enabled, if the PWM pin is left floating, the output voltage of the TPS61187 regulates to the minimum output voltage. Once the device detects a voltage on the PWM pin, the TPS61187 begins to regulate the IFB pin current, as pre-set per the ISETH pin resistor, according to the duty cycle of the signal on the PWM pin.

This translated to the following plan:

  1. Put minimal voltage across VIN and GND. If it doesn’t go up in smoke, probe VDDIO to see if it has some voltage.
  2. If that works, check the Enable pin. If I am to drive the chip, I will need to control the state of the Enable pin. This is where an interaction with existing components might cause headaches: something else on the board might be trying to keep it high or keep it low, and if I put voltage on that pin the opposite state, I might damage that component unless I cut a trace somewhere to disconnect it.
  3. I might also have to find and cut a trace for the PWM pin for the same reason.
  4. Send the Enable signal, and check the voltage level across a LED string for the “minimum output voltage” mentioned by the datasheet.
  5. If all of the above works, then I’ll work on how to generate the PWM dimming signal.

Plans rarely survive intact upon their first contact with reality, but I wanted to have one before I got started. It will guide me as I probe the circuit board to understand how it uses a TPS61187.

TI TPS61187 Circuit’s Boost Converter

I had a broken LG laptop screen, model LP133WF2(SP)(A1), which I’ve disassembled and now I’m digging into its backlight module. I want to see if it I could make it work as a standalone diffuse light panel. I could probably wire up the LEDs directly with a voltage source and current-limiting resistor, but I also have its original integrated driver circuit board which still worked as far as I knew. I’m sure most of it were concerned with moving pixels which are no longer relevant, but there is also a TI TPS61187 chip on the board to drive the backlight section.

The PWM control signal is 3.3V friendly with a logic high threshold of 2.1V, so I could use either a 5V ATmega328 Arduino or a 3.3V ESP32. The part I didn’t understand was the power input. The datasheet says input voltage can range anywhere from 4.5V to 24V, and that it has a built-in boost converter to send up to 38V to the LED strings. I had expected to see a separate output pin for this higher voltage, but in the Typical Application schematic, the LED’s common anode is connected to the input voltage plane via a diode and an inductor. This combined with the following quote in the datasheet confused me:

there must be enough white LEDs in series to ensure the output voltage stays above the input voltage range

With the common anode seemingly tied to voltage input, I didn’t understand how the anode voltage could be higher than the input voltage. The next hypothesis is that instead of different voltage supply planes, perhaps there are separate ground planes at different levels. I saw there was a PGND pin for logic that is separate from AGND pin for the LED strings so the hypothesis had potential. But when I probed the circuit board, my meter said PGND and AGND pins are tied together on my board, eliminating the “separate ground levels” idea.

With a distinct sense that I have misunderstood something, I went to Wikipedia to learn more about boost converters and how they work. As soon as the diagrams came onscreen for that page, I realized that inductor and diode I saw earlier WAS the boost converter. I just didn’t recognize it as I was only aware of a block diagram representation and didn’t know it when the core components of a boost converter were staring at me in the schematic. Now it all makes sense how the LED string common anode voltage will be higher than the input voltage, and I feel confident enough to devise a plan.

Notes on Commodity DRV8833 Breakout Board

Having read through the datasheet for DRV8833 DC motor driver IC, I was optimistic that they would be a good choice to control DC motors on the TT gearmotors I have installed on Micro Sawppy Beta 3 (MSB3) rover. DRV8833 operating voltage range of up to 10V is a much better fit for these 3-6V motors. Compared to the classic L298N motor controller with its 4 to 45V range. The lower voltage handling requirements, as well as being a much newer design using modern power management techniques, means a DRV8833 breakout board is far more compact than a L298N breakout board. Something clearly visible in this side-by-side picture. Physical volume is an important consideration when fitting electronics inside a little rover.

Side by side size comparison of L298N and DRV8833 motor control IC breakout boards.

For my first round of experiments, I bought a batch of 5 DRV8833 breakout boards from the lowest bidder of the day on Amazon (*) I’m sure a different day will have a different lowest vendor when we issue a query for DRV8833(*), because these breakout boards seem to be commodities offered by many different vendors. We also see this particular design from many vendors on AliExpress. I noticed two or three very popular designs for a DRV8833 breakout board. I have no idea where this particular design came from. If the same factory is supplying all of these vendors, or if the design has been cloned by multiple manufacturers. Whatever the history, I see enough quantity to give me confidence these boards won’t disappear overnight. We’ll see if I’m right!

Incorrect instructions shown on some DRV8833 product listings.

In this particular product listing, one of the pictures serve as a rudimentary reference manual for the board. I was suspicious of these instructions so I probed this board to determine the circuit for myself as I did for the L298N board. I’m glad I did! The instructions had swapped the “FAULT” and “SLEEP” pins for reasons unknown. Fortunately, those pins are optional so most users (including my intended use) won’t be affected.

There are only a few supporting components on this board. From the DRV8833 datasheet I expected three capacitors and they are clearly visible. I also see two resistors and a LED. The LED was not on the datasheet, it was a bonus feature to indicate power supply is present, along with its 4.7kOhm current-limiting resistor. The final resistor is a 47kOhm pull-up resistor for the SLEEP pin, by default pulling it high to enable the board and giving us the option to leave the breakout board’s (SL)EEP pin unconnected.

Back side view of a DRV8833 breakout board, showing the J1 trace that can be cut to disconnect pull-up resistor and allow control over sleep functionality.

For applications that want to assert control over sleep/enable themselves, there is a provision on the back side of this breakout board. Cutting the trace on J1 will disconnect SLEEP from the pull-up resistor, opening up the pin to external control. If we should change our minds afterwards, we can solder across J1 pads to reconnect the pull-up resistor.

No such provisions exist for current chopping control. DRV8833 offers the option to limit maximum current by putting current-sensing resistors on the AISEN and BISEN pins, but this particular breakout board design connected those pins directly to ground without any provisions to add current-sensing resistors back in. Applications that want current chopping will have to go elsewhere.

Remainder of the board was fairly straightforward, once we figure out the pin rename mapping. This board labelled its pins IN1-4 and OUT1-4 following precedent of L298N, instead of the names in the DRV8833 datasheet of pins 1 and 2 for channels A and B. For those that prefer this information in schematic form, here’s what I drew up after my probing session for this board to guide my first experiment putting one to use:

Schematic diagram for a popular type of DRV8833 breakout board.

(*) Disclosure: As an Amazon Associate I earn from qualifying purchases.

Window Shopping DRV8833 DC Motor Control IC

It was a pure accident that I stumbled across the DRV8833 DC motor control IC. After a quick comparison against my original candidate TB6612 I think some DRV8833 modules might actually the better choice for my micro Sawppy rover project. Its required control signals are an ideal fit for the MCPWM peripheral on the ESP32 I planned as my rover brain. Though note not all models of the ESP32 line has MCPWM peripherals, for example it appears to be absent from the ESP32-S2.

The DRV8833 is less capable than the TB6612 in some ways. For example, the maximum voltage is listed as 10.8V which is lower than the 15V listed for TB6612, and far short of the 45V listed for a L298. But TT gearmotors are typically listed with a maximum voltage of 6V, so I should be fine. I was surprised that the amperage rating isn’t much lower, with 1.5A typical and 2A peak that should suffice for TT gearmotors. And if I need additional current carrying capacity, the DRV8833 is explicitly stated to be capable of both output stages working in parallel to double the maximum current. The L298 datasheet also explicitly listed parallel operation as an option, but the TB6612 did not.

Like the L298, the DRV8833 has provisions for current-sensing resistors between AISEN and BISEN pins to ground. But unlike the L298, the DRV8833 will actually read their voltage to limit maximum current output. The current-sensing resistors are a whole world into themselves. They work best when placed close to the IC because that minimizes variation introduced by PCB traces. But if they are close, they will be in close proximity to heat generated by the IC, which will change their resistance. Quite a few variables need to be juggled for it to work right, so I’ll probably choose to opt out of current limiting and connect those pins to ground. Fortunately the chip’s own overcurrent protection circuit works independently and will activate with or without external current-sensing resistors.

All four control pins, two for each stage, have internal pull-down resistors. Thus this chip is always in a defined state and we don’t have to worry about any particular startup sequence. Whether power arrives first or control signals arrive first, the chip will work in a known way. There are two more input pins, one to control sleep and another to signify fault. The fault signal is open-drain which would make it compatible with a lot of different circuits, but I might not have ESP32 input pins to spare for detecting fault conditions. I won’t worry about low-power sleep (at least not yet) for micro Sawppy, and in that case the recommended procedure is to pull it up with a 25-75kOhm resistor.

In addition to that optional resistor, there are three required capacitors, but no external diodes are required. Looks like the diodes to handle back-EMF from inductive loads are built in which is great news. It makes for a pretty short list of external support components, but I still don’t plan to use the chip directly. The first reason is that I have many options for breakout boards. From high quality Adafruit #3297 to the lowest bidder of the day on Amazon.(*) For low quantities it’s worth a few extra bucks to pay for an already-assembled breakout board.

The second reason is that I can’t meet proper installation requirements for the more capable DRV8833 variants. As is typical, the DRV8833 is available in several chip package formats. I was surprised to see that one of them had a much lower rating for typical amperage, a third of the others. However, peak rating stayed the same, so I suspected it’s not a limitation of the chip itself. Further reading (section 10.3.1) confirmed that maximum current of a DRV8833 is a direct function of heat dissipation and the lower-rated chip package lacked a heat conduction pad present in the others. (TI calls it PowerPAD.) Thus soldering a DRV8833 correctly requires reflow soldering. I would have to pay someone else to handle it, or buy my own reflow setup, but that’s a concern for the future. Right now I can start with some cheap breakout boards.

(*) Disclosure: As an Amazon Associate I earn from qualifying purchases.

TB6612 Vs. DRV8833 DC Motor Driver ICs for ESP32 Micro Sawppy

While researching TB6612 DC motor driver IC breakout boards on Amazon, my results list actually had more breakout boards built around the DRV8833 (and claiming TB6612 compatibility) than actual TB6612 boards. So I tried performing an Amazon query for DRV8833(*) and saw I had far more options in that category. This may change in the future as worldwide silicon supply & demand varies, but that’s the situation as I type this. I didn’t explicitly set out to find yet another candidate to replace my L298 motor driver, but since I stumbled across it, I decided to spend a bit of time to take a closer look at the DRV8833 by Texas Instruments.

First things first: the claim of TB6612 control logic compatibility is wrong. Well, technically they are compatible for applications that are only interested in powering their motors only in full forward or full reverse, but that is not realistic. Such applications would not bother with a motor control IC and would directly use some MOSFETs or even relays instead. For real motor control applications, I’ve seen two different methods to interface with the classic L298 motor control IC. TB6612 is logic compatible with one method, DRV8833 is compatible with the other method, and they are not compatible with each other.

TB6612 requires three pins: two digital pins to control behavior (forward, backward, brake, or coast) and a PWM pin to control magnitude of that behavior. DRV8833 only accepts two pins to control behavior and modulation is done by rapidly pulsing one of those pins to switch between states. Partial throttle forward, for example, is done by rapidly switching between forward and coast states. DRV8833 does not have a dedicated PWM pin like the TB6612, and the closest counterpart to a L298’s ENABLE pin is the nSLEEP pin on a DRV8833 but that pin is unsuitable for modulating velocity. The first problem is that there’s only a single nSLEEP pin for both motors, and secondly waking up from sleep requires ~1ms making smooth motion difficult if not impossible.

In general, using two pins instead of three is an advantage when we are constrained by the number of pins available, and the ESP32 certainly has that problem. However, the tradeoff is that DRV8833 requires two pins capable of generating PWM signals per motor, whereas TB6612 only requires one. This would be a concern for microcontrollers with limited PWM peripherals, but the ESP32 literally has more PWM peripheral outputs than it has usable pins.

Looking specifically at my micro Sawppy rover application, the picture of pin allocation is not quite that straightforward as (2 pins * 6 wheels = 12 pins) versus (3 pins * 6 wheels = 18 pins). In typical operation, all the wheels on one side of the rover will be traveling in the same direction, so it is possible to share the direction control pins across three wheels on the same side of the rover, cutting it down to 10 pins instead of 18. Plus if I make the rover front-back symmetric I have an additional option to share the PWM control signal across front and rear wheels, which cuts pin count down to 8. But while DRV8833 can’t share pins across wheels on the same side, it can also benefit from front-back symmetry cutting its requirements down to 8 pins as well. A tie!

Clearly there are many tradeoffs I can make with motor driver arrangement and control, depending on how many PWM peripherals are on a particular microcontroller and how many pins it has to spare. For my first iteration I like the idea of having independent control over each wheel, even though right now I’m not sure how it would be useful. Once I get that working (or learn why I can’t) I’ll look into trading off independent control for reduced pin count. So the current plan of record is to use two PWM pins for each of six wheels, driving DRV8833 DC motor control ICs.

(*) Disclosure: As an Amazon Associate I earn from qualifying purchases.