BUS PIRATE: Voltage measurement on every pin

Bus Pirate Ultra v1a follows the same pinout as previous Bus Pirates. 5 I/O pins (MOSI, CLOCK, MISO, CS, AUX), a voltage probe (ADC), a voltage source for the on-board pull-up resistors (Vpu), two power supplies (3.3, 5.0volts) and ground. While we were building the prototype it became obvious that a few tweaks could make a much more useful tool.

  1. MOSI
  2. CLOCK
  3. MISO
  4. CS
  5. AUX
  6. ADC
  7. Vpu
  8. 3.3V
  9. 5.0V
  10. GND

This is the starting pinout. In this post we’ll update the voltage/ADC probe to measure voltage on every IO pin, and free up a pin for general purpose use.

Measuring voltage with the Bus Pirate ADC pin.

The voltage probe (ADC pin) is useful for checking the output of a digital to analog converter (DAC), verifying a supply voltage, or almost anything you’d do with a multimeter. The d command takes a single voltage measurement, while the D command takes continuous measurements.

Problems with the resistor voltage divider approach

The Bus Pirate runs at 3.3volts, but we still want to measure within the most common 0-5.0volt range used in hobby electronics. To bring the voltage into range, the Bus Pirate uses two 10K resistors to divide the measured voltage in half. Now we can safely measure a voltage in the range of 0-6.6volts using an analog digital converter with a maximum input of 3.3volts.

This is a super effective and simple approach, but it adds a 20K resistive load to the pin at all times. This load makes the pin less useful for digital IO, so the ADC has always been a dedicated pin without any other functions.

Adding a unity gain op-amp buffer

Input from IO_PIN is buffered by the op-amp and then divided in half for ADC1.

One obvious way to eliminate the load on the ADC pin is to buffer the voltage divider with an op-amp. The op-amp input is extremely low impedance and has negligible impact on the signal we’re measuring.

An MCP6001 is a cheap general purpose op-amp (U15) with common mode voltage that extends 0.25volts beyond the power and ground rails. Using it in a unity gain configuration buffers the input voltage (IO_PIN), which then goes through the voltage divider (RN3D, RN3C) to be measured by the ADC (ADC1). A few current limiting resistors and protection diodes suggested in the datasheet help ruggadize the op-amp for abuse during hacking.

Voltage measurement on every IO pin

A 74HCT4051 analog multiplexer selects which IO pin connects to the op-amp.

Without that nasty 20K load the ADC pin can be a general purpose digital IO. While we could dedicate an op-amp and ADC to measure each IO pin, that’s a lot of routing and resources. Instead, each IO pin connects to a 74HCT4051 8:1 analog multiplexer that selects which IO pin to measure with a single op-amp and ADC.

Three FPGA pins select one of the 8 analog inputs to measure. The FPGA is in control, rather than the MCU, so that we are ready to add an external high-speed ADC in the future.

Updated pinout

  1. MOSI
  2. CLOCK
  3. MISO
  4. CS
  5. AUX
  6. AUX2 (formerly ADC)
  7. Vpullup
  8. 3.3volts
  9. 5.0volts
  10. GND

Using a single analog mux and op-amp we can measure the voltage on every Bus Pirate IO pin. The dedicated ADC pin is cast into the dustbin of history, and we gain a new digital pin that we’ll call AUX2 for now.

Taking it further

1 x 10P connector on v1a (1)

6 IO pins is definitely better than 5. Wouldn’t it be great to have even more? Our goal is to get to 8 digital IO pins. That’s enough to interface nearly any serial bus, and it’s the logical number of channels for a proper logic analyzer.

At the same time, we’d like to stick with the 2.54mm 10 pin IO header (1) we’ve been using in recent prototypes. It fits common jumper cables we have in the parts box, but could also accept a nice keyed custom cable.

Next we’ll rethink the function of the on-board power supplies and pull-up resistors. To skip the wait, see our most recent progress in the forum.

Leave a Reply

Your email address will not be published. Required fields are marked *