In the distant past I was an experimental physicist and worked with some exciting hardware for interfacing detectors to data-acquisition computers like the Norsk Data Nord 10 and Nord 100 machines. Since the rise of the home PC, I have been interested in interfacing it to devices and sensors. This page shows some of the things I have done. If you want to know more, please do

USB25IO in box

In 2012 I saw the Mirrorbow USB25IO card selling at an excellent price, I could not resist buying one. This device is a small data input/output card that connects via USB to a computer. The image on the left shows it inside the small box I made to protect it. Its capabilities are configurable and are:

  • 24 Digital Input/outputs (three 8-bit ports) each individually programmed for direction
  • Up to 12 of the IOs may be configured as 10-bit ADC inputs (all 12 sampled with 1 command)
  • One 8-bit port can be turned into servo mode, providing control of up to 8 servos
  • An additional output provides programmable PWM (2.93KHz to 1MHz)

I was more interested in the ADCs than anything else, having worked in the past with nanosecond CAMAC ADCs made by LeCroy Corporation. The USB25IO devices are somewhat more modest, but still very interesting.

The first problem that I encountered was using the USB port to communicate with the USB25IO. Mirrorbow provided a Windows XP driver that emulates a serial port, and I started with that. However I wanted to write my applications in Java under NetBeans, and Sun have ceased support for serial ports under Windows. Fortunately there is a third-party library available called rxtx, and I was able to use that. This let me use it under both Windows and Linux.

Having tried a few simple things like cycling the LEDs that indicate the status of the first four bits on the USB25IO, it was time to do something more useful:

  • I started by measuring the internal resistance of some NiMH cells, to find the duds.
  • Then I measured the discharge curve of the cells, out of curiosity.
  • Then I measured some temperatures in my conservatory and garage, using a LM335 temperature sensor.
  • Finally I built a seismometer and have detected earthquakes around the world.

By the time I'd done all that, Mirrorbow had stopped marketing the USB25IO and the company folded in December 2016.

By then I had upgraded to a different data acquisition device for my seismometer.

This image shows how I built a good-quality analogue data-acquisition system for the PC at a relatively low cost. The small card on the right is a 'breakout board' containing an ADS1115 analogue-to-digital converter chip. This IC provides either two 16-bit fully differential inputs (i.e. positive or negative values) or four 15-bit single-ended inputs (positive only). However, there is only one ADC on the chip - a multiplexer selects which input is being read at any time. The chip uses the I2C interface as its output.

The other small card is a USB-I2C convertor. This itself contains a 10-bit ADC, but I am not using it. Instead, I have connected the card by I2C to the ADS1115 and am using two single-ended channels to read out my seismograph's sensors.

I bought both of these devices on eBay for a total of less than 20 pounds Sterling, and have mounted them in an ABS box with connectors for convenience. I can add further I2C devices on the same bus later, should I wish.

I had to write some simple software to handle these devices. I have them working under both Windows XP and Linux. My data acquisition application is written in Java and therefore runs under both those operating systems. Under Windows, I use the serial port emulator driver provided with the USB-I2C convertor, and the RXTX library to read the emulated port. Under Linux I use the usbserial driver to emulate a serial port (although this is not really a bulk device), and RXTX again.

I wrote some simple byte-handling routines that set the MUX on the ADS1115 and read out the ADC conversion register. I'm using two channels, and it requires three port commands per channel. My measurements show that this takes about 110 milliseconds. I suspect that this would not change much if I used a faster PC. It means that my sampling rate is limited to about 8 samples per second.

ADS1115 in box

Now we move to the present, more-or-less. A couple of years ago I bought a few Arduino 'nano' boards on eBay at prices which I consider absurdly low for the capabilities they have. At the time I played around using the basic 'blink' sketch that just flashes an LED. Now I have tried some more useful things.

I have a compact digital camera that uses AA cells for power, and I use NiMH rechargeable ones. Sometimes I find that having put in freshly-charged ones, after a short time the camera says that new batteries are needed. I suspect that this means that one or more of the cells has developed sufficient internal resistance that the high current demand of the camera results in excessive voltage drop.

cell resistance measurement board

I therefore have used the Arduino to check the cell internal resistance. I built a small circuit card following the schematic shown. This is basically five 10 ohm load resistors switched across the cell by power MOSFETs (wonderful devices in my view) under control of the Arduino. The 1M5 resistor stops the analogue input from "floating up" when no cell is present and all loads are off. The LEDs show which loads are switched in, just for human understanding :-).

cell resistance measurement board

This image shows the hardware: my homebrew board linked to the Arduino, which is on a small breadboard. The USB cable goes to my desktop PC.

Two pieces of software are used to automate the internal resistance measurement:

  • Firstly, a simple Arduino sketch loads the cell by switching on each of the MOSFETs in turn, using the digital outputs. After each switch, it waits a second and then reads the cell voltage on the analogue ADC input before switching in the next load. It transmits the ADC value on the serial link (USB). Once all MOSFETs are on, it turns them all off and repeats. It does not load the cell if the voltage drops below a critical value.
  • A Java/NetBeans/Swing application running on the PC receives the ADC values over the serial link. It is interrupt-driven using RXTX. It stores each value until it has all six (no-load plus all five loads) when it calculates the internal resistance using a least-squares fit of the reciprocal of the voltage versus the reciprocal of the load resistance, and plots the results.

The rationale for this is that the theoretical equation for the cell voltage under load Rext is
where E is the 'perfect' internal cell voltage, Vext is the measured external voltage, and Rint and Rext are the internal and external resistances. Vext plotted against Rext is a hyperbola. However, by inverting both sides we obtain:
which shows that if we plot the reciprocal of the Vext against the reciprocal of Rext, it should be a straight line.

cell resistance measurement graph This screenshot shows a typical result for a good cell. The points do indeed lie on a decent straight line (beware the suppressed zero) resulting in a good fit and an internal resistance of 0.1 Ohms. In my view that's about the acceptable limit, if your camera has several cells in series all with a higher internal resistance than that then the battery's voltage will drop considerably when the camera requires a high current.

The same board can be used to check a cell's capacity, using a slightly different Arduino sketch and Java display program.

  • The sketch just turns on two resistors, giving a load of 5 Ohms, which draws about 240 mA from the cell. It then measures the voltage at 1 minute intervals and sends the ADC value out on the serial port. If the cell voltage drops below 0.9 volts the sketch turns off the load and stops (obviously one must beware that the cell voltage will rise when the load is removed, naive programming might consequently turn the load back on, and then off again, and then on ...).
  • The Java program accumulates and displays the data. It also calculates the milliamp-hours discharged, using the cell voltage and the known load.

This image shows the result for a good 2100 mAh cell. The measured capacity was 1757 mAh. Previous tests using the Mirrorbow showed that the cell capacity varies depending on the current drawn by the load. I'm not concerned about the discrepancy, in fact cell manufacturers usually say the capacity is quoted at C/10h which means 210 mA in this case. As I'm drawing more current, I would expect the measured capacity to be less than nominal.

cell capacity measurement graph

Valid XHTML 1.0 Strict