A few years ago, I made a PCB to aid in measuring a bunch of thermistors for some thermal testing on battery modules. I’m finally getting around to creating some documentation for it so it can be helpful for others as well. I previously showed this board in the JLC PCB Assembly post.
The purpose of the board was to measure a bunch of thermistors. The battery module we were measuring had 50 cells in it, so 64 measurement channels seemed to be a good number to target. The first version was to be created with a perfboard, so all the ICs used had to be available on breakout boards. I’ve used the ADS1115 in the past for other projects. With 4 channels, 16-bit measurement, and an internal reference, it fits the use case perfectly. Adding a CD4067 16-channel multiplexer to each of the 4 inputs, we have the capability to measure analog voltages on 64 channels. Each thermistor needs another resistor for a voltage divider, and a capacitor for an RC filter on the board.
The board has the capability for digital I/O, as well as analog input on every channel. An analog output is not available as this would require a DAC at each channel since it is not possible to easily multiplex a DAC.
The full schematic for the board is available here: (link).
The input structure for each channel was designed specifically to require no external components to connect a thermistor. Digital I/O is handled by the TCA9539 I/O expanders, which are set up with a 3.3k resistor in series with the I/O expander going to the screw terminal. This means that any digital I/O channels have a 3.3k series resistance on its line. All channels share a common ground point, available at every channel’s screw terminals.
The screw terminals are 2.54mm pitch, best used with 22AWG solid core wire. Stranded wire with ferrules are difficult to get small enough to fit the opening. Each channel has a GND terminal directly beside it for easy connection of a thermistor.
Board dimensions are 97.6mm x 149.8mm. 4x M3 holes on the board for mounting are located 4mm from the corners of the board. The upper left screw near the USB connector is located 20.5mm from the top edge of the board. A 3D printed board mount is available here.
The board requires only a 5V power source, and can be powered entirely from the Micro USB port. The onboard LDO converts the USB input voltage to 3V3. An external 5V power input port is available via the screw terminals, and can be plugged in at the same time as the USB since it is diode-or’ed on the board. This means the higher voltage of the USB port or the external power port will provide the current for the board, and neither source will be back-fed from the other.
How to Connect To:
Analog Input (ADC)
This board can measure analog signals in the 0-3.3V range, with 16-bit resolution using the ADS1115 ADC. The 64 channels are in groups of 16 channels which pass through a CD4067 16:1 multiplexer and are passed to one of the 4 inputs of the ADS1115. These 4 inputs are multiplexed internally in the ADS1115 to a single 16-bit ADC. The multiplexer control lines are connected together, so if selecting channel 0 on the multiplexers, then channels 16, 32, and 48 are also available at the ADS1115.
There is a 1k and 100nF low pass filter before the multiplexer, and then a 100Ohm and 10nF low pass filter after the multiplexer. When switching which channel to measure, ensure to wait for the 100Ohm and 10nF filter to settle before reading. This should take 5 time constants, or 5*100*10e-9 s = 5us. The I2C command to trigger a conversion likely takes longer than this to start the conversion, so an explicit delay may not be required, but it is good to note.
Thermistor (Analog input extension)
The 3.3k resistor in series with the digital IO lines may have seemed like a weird choice, until you see that thermistors can be connected to this board without any extra components. Simply connect the thermistor across the channel’s screw terminal and the adjacent ground screw terminal. Set the TCA9539 to output a digital 1, which pulls up the 3.3k resistor to 3.3V and acts as the top resistor in a voltage divider with the thermistor across the screw terminals. A 3.3k resistor was chosen in this location to give the best resolution at the ADC in the range of temperatures that are often seen in electronics (room temperature and up to about 70C) when used with a 10K NTC thermistor. The recommended thermistor is an NXRT15XV103 as it gives good resolution when paired with the 3.3k pullup for the 20-70C temperature range.
Analog Output (DAC)
Not available on this board.
Digital input, with 0 to 3.3V logic, is available through the TCA9539 I/O Expander. Note there is a 3.3k resistor in series with the signal before the input is read, which may affect the output.
Digital output, 0 or 3.3V, is available through the TCA9539 I/O Expander. There is a 3.3k resistor in series with the signal before the output. This may be good for a MOSFET’s gate drive if you want it to be pretty slow, but make sure to not create unintentional voltage dividers with this resistor which will affect the output.
The firmware controls the IO expanders, ADC, and multiplexers on the board. An A2D DAQ class was created which creates instances of the classes for the ADC, IO expanders, and multiplexers. The examples in the class provide a SCPI control interface, which uses to A2D DAQ class to provide communicate to the low-level communication with the ICs on the board.
Software / Interfacing
There are instructions in the readme of the repository linked above about how to read voltages and temperatures of many different inputs, and log to a CSV file.
In the lab_equipment/A2D_DAQ_control.py file, there are SCPI commands to communicate with the DAQ. Digital I/O, as well as analog input is available through the SCPI interface.
When first connecting to the DAQ, you will need to provide a config file to tell it how all the inputs are set up. This config file should be in the same format as provided example config files in the lab_equipment directory. The ‘configure_from_dict’ function in lab_equipment/A2D_DAQ_control.py defines what happens for the available input types. If you will use any analog input functions for a channel, the Voltage_Scaling header must be present, and if any thermistors will be used to measure temperature, you must provide their Steinhart-Hart constants. To get the Steinhart-Hart constants from a lookup table or Beta model, this site is very useful: https://www.thinksrs.com/downloads/programs/Therm%20Calc/NTCCalibrator/NTCcalculator.htm