Posted on 9 Comments

Arduino Milliohm Meter Build

During the rebuild of the wheelchair motors for the support trolley, I found myself needing an accurate milliohm meter to test the armature windings with. Commercial instruments like these are expensive, but some Google searching found a milliohm meter project based around the Arduino from Circuit Cellar.

Circuit Diagram
Circuit Diagram

Here’s the original author’s circuit diagram, paralleling nearly all of the Arduino’s digital output pins together to source/sink the test current, an ADS1115 ADC to take more accurate readings, with the results displayed on a jellybean 128×64 OLED module. The most expensive part here is the 10Ω 0.1% 15ppm reference resistor, R9.
I decided to make some small adjustments to the power supply section of the project, to include a rechargeable lithium cell rather than a 9v PP3 battery. This required some small changes to the Arduino sketch, a DC-DC boost converter to supply 5v from the 3.7v of a lithium cell, a charger module for said cell, and with the battery voltage being within the input range of the analogue inputs, the voltage divider on A3 was removed. A new display icon was also added in to indicate when the battery is being charged, this uses another digital input pin for input voltage sensing.
I also made some basic changes to the way an unreadable resistance is displayed, showing “OL” instead of “—–“, and the meter sends the reading out over the I²C bus, for future expansion purposes. The address the data is directed to is set to 0x50.

I’ve not etched a PCB for this as I couldn’t be bothered with the messy etchant, so I built this on a matrix board instead.

Final Prototype
Final Prototype

Since I made some changes to both the software and the hardware components, I decided to prototype the changes on breadboard. The lithium cell is at the top of the image. with the charger module & DC-DC converter. The Arduino Nano is on the right, the ADC & reference resistor on the left, and the display at the bottom.
The Raspberry Pi & ESP8266 module are being used in this case to discharge the battery quicker to make sure the battery level calibration was correct, and to make sure the DC-DC converter would continue to function throughout the battery voltage range.

Matrix Board Passives
Matrix Board Passives

Here’s the final board with the passive components installed, along with the DC-DC converter. I used a Texas Instruments PTN04050 boost module for power as I had one spare.

Matrix Board Rear
Matrix Board Rear

The bottom of the board has most of the wire jumpers for the I²C bus, and power sensing.

Matrix Board Modules
Matrix Board Modules

Here’s both modules installed on the board. I used an Arduino Nano instead of the Arduino Pro Mini that the original used as these were the parts I had in stock. Routing the analogue pins is also easier on the Mini, as they’re brought out to pins in the DIP footprint, instead of requiring wire links to odd spots on the module. To secure the PCB into the case without having to drill any holes, I tapped the corner holes of the matrix board M2.5 & threaded cap head screws in. These are then spot glued to the bottom of the case to secure the finished board.

Lithium Charger
Lithium Charger

The lithium charger module is attached to the side of the enclosure, the third white wire is for input sensing – when the USB cable is plugged in a charge icon is shown on the OLED display.

Input Connections
Input Connections

The inputs on the side of the enclosure. I’ve used the same 6-pin round connector for the probes, power is applied to the Arduino when the probes are plugged in.

Module Installed
Module Installed

Everything installed in the enclosure – it’s a pretty tight fit especially with the lithium cell in place.

Meter Top Cover
Meter Top Cover

The top cover has the Measure button, and the OLED display panel, the latter secured to the case with M2.5 cap head screws.

Kelvin Clips
Kelvin Clips

Finally, the measurement loom, with Kelvin clips. These were an eBay buy, keeping things cheap. These clips seem to be fairly well built, even if the hinges are plastic. I doubt they’re actually gold-plated, more likely to be brass. I haven’t noticed any error introduced by these cheap clips so far.

The modified sketch is below:

// ---------------------------------------------------------------------------------------------
//  Simple, accurate milliohmeter
//
//  (c) Mark Driedger 2015
//
//  - Determines resistance using 4 wire measurement of voltage across a series connected
//  reference resistor (Rr, 10 ohm, 0.1%) and test resistor (Rx)
//  - range of accurate measurement is roughly 50 mohm to 10Kohm
//  - Uses Arduino digital I/O ports to deliver the test current, alternating polarity to cancel 
//  offset errors (synchronous detector)
//  - 4 I/O pins are used for each leg of the test current to increase test current
//  - Averages 2 cycles and 100 samples/cycle 
//  - Uses a 16 bit ADC ADS1115 with 16x PGA to improve accuracy
//
//  Version History
//    May 24/15    v1.0-v4.0
//      - initial development versions
//    May 27/15    v5.0
//      - changed display to I2C
//      - backed out low power module since it seemed to cause serial port upload problems
// ---------------------------------------------------------------------------------------------

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//#include <LowPower.h>

#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

// ---------------------------------------------------------------------------------------------
//  I/O port usage
// ---------------------------------------------------------------------------------------------
//    serial port (debug and s/w download)    0, 1
//    I²C interface to ADC & display          A4, A5
//    positive drive                          2, 3, 4, 5
//    push to test input                      8
//    unused                                  9, 10, 11, A0, A1, A2, A6, A7
//    negative drive                          6, 7, 8, 9
//    battery voltage monitor                 A3
//    debug output                            13

#define  P_PushToTest  10       // push button (measure), active low
#define  P_Debug       13
#define  CHG           12

//  ADS1115 mux and gain settings
#define  ADS1115_CH01  0x00    // p = AIN0, n = AIN1
#define  ADS1115_CH03  0x01    // ... etc
#define  ADS1115_CH13  0x02
#define  ADS1115_CH23  0x03
#define  ADS1115_CH0G  0x04    // p = AIN0, n = GND
#define  ADS1115_CH1G  0x05    // ... etc
#define  ADS1115_CH2G  0x06
#define  ADS1115_CH3G  0x07

#define  ADS1115_6p144  0x00   // +/- 6.144 V full scale
#define  ADS1115_4p096  0x01   // +/- 4.096 V full scale
#define  ADS1115_2p048  0x02   // +/- 2.048 V full scale
#define  ADS1115_1p024  0x03   // +/- 1.024 V full scale
#define  ADS1115_0p512  0x04   // +/- 0.512 V full scale
#define  ADS1115_0p256  0x05   // +/- 0.256 V full scale
#define  ADS1115_0p256B 0x06   // same as ADS1115_0p256
#define  ADS1115_0p256C 0x07   // same as ADS1115_0p256

Adafruit_SSD1306   display(0);               // using I2C interface, no reset pin
static int         debug_mode = 0;           // true in debug mode

float ADS1115read(byte channel, byte gain)
//--------------------------------------------------------------------------------------
//  reads a single sample from the ADS1115 ADC at a given mux (channel) and gain setting
//  - channel is 3 bit channel number/mux setting (one of ADS1115_CHxx)
//  - gain is 3 bit PGA gain setting (one of ADS1115_xpxxx)
//  - returns voltage in volts
//  - uses single shot mode, polling for conversion complete, default I2C address
//  - conversion takes approximatly 9.25 msec
//--------------------------------------------------------------------------------------
  {  
  const int    address = 0x48;      // ADS1115 I2C address, A0=0, A1=0 
  byte         hiByte, loByte;
  int          r;
  float        x;

  channel &= 0x07;                  // constrain to 3 bits
  gain    &= 0x07;
 
  hiByte = B10000001 | (channel<<4) | (gain<<1);    // conversion start command
  loByte = B10000011;
  
  Wire.beginTransmission(address);  // send conversion start command
  Wire.write(0x01);                 // address the config register
  Wire.write(hiByte);               // ...and send config register value
  Wire.write(loByte);           
  Wire.endTransmission();

   do                               // loop until conversion complete
    {
    Wire.requestFrom(address, 2);   // config register is still addressed
    while(Wire.available())
      {
      hiByte = Wire.read();         // ... and read config register
      loByte = Wire.read();
      }
    }
  while ((hiByte & 0x80)==0);       // upper bit (OS) is conversion complete

  Wire.beginTransmission(address); 
  Wire.write(0x00);                 // address the conversion register
  Wire.endTransmission();

  Wire.requestFrom(address, 2);     // ... and get 2 byte result
  while(Wire.available())
    {
    hiByte = Wire.read();
    loByte = Wire.read();
    }

  r = loByte | hiByte<<8;           // convert to 16 bit int
  switch(gain)                      // ... and now convert to volts
    {
      case ADS1115_6p144:  x = r * 6.144 / 32768.0; break;
      case ADS1115_4p096:  x = r * 4.096 / 32768.0; break;
      case ADS1115_2p048:  x = r * 2.048 / 32768.0; break;
      case ADS1115_1p024:  x = r * 1.024 / 32768.0; break;
      case ADS1115_0p512:  x = r * 0.512 / 32768.0; break;
      case ADS1115_0p256:  
      case ADS1115_0p256B:  
      case ADS1115_0p256C: x = r * 0.256 / 32768.0; break;
    }
  return x;
  }

// ---------------------------------------------------------------------------------------------
//  Drive functions
//   - ports 4-7 and A0-A3 are used to differentially drive resistor under test
//   - the ports are resistively summed to increase current capability
//   - DriveOff() disables the drive, setting the bits to input
//   - DriveOn()  enables the drive,  setting the bits to output
//   - DriveP()   enables drive with positive current flow (from ports 4-7 to ports A0-A3)
//   - DriveN()   enables drive with negative current flow
// ---------------------------------------------------------------------------------------------
void DriveP()
  {
    DriveOff();
    digitalWrite( 2, HIGH);
    digitalWrite( 3, HIGH);    
    digitalWrite( 4, HIGH);    
    digitalWrite( 5, HIGH);
    digitalWrite( 6, LOW);
    digitalWrite( 7, LOW);
    digitalWrite( 8, LOW);
    digitalWrite( 9, LOW);  
    DriveOn();
  }

void DriveN()
  {
    DriveOff();
    digitalWrite( 2, LOW);
    digitalWrite( 3, LOW);    
    digitalWrite( 4, LOW);    
    digitalWrite( 5, LOW);
    digitalWrite( 6, HIGH);
    digitalWrite( 7, HIGH);
    digitalWrite( 8, HIGH);
    digitalWrite( 9, HIGH);   
    DriveOn();
  }

void DriveOn()
  {
    pinMode( 2, OUTPUT);      // enable source/sink in pairs
    pinMode( 6, OUTPUT);
    pinMode( 3, OUTPUT);
    pinMode( 7, OUTPUT);
    pinMode( 4, OUTPUT);
    pinMode( 8, OUTPUT);
    pinMode( 5, OUTPUT);
    pinMode( 9, OUTPUT);
    delayMicroseconds(5000);  // 5ms delay
  }
    
void DriveOff()
  {
    pinMode( 2, INPUT);       // disable source/sink in pairs
    pinMode( 6, INPUT);
    pinMode( 3, INPUT);
    pinMode( 7, INPUT);
    pinMode( 4, INPUT);
    pinMode( 8, INPUT);
    pinMode( 5, INPUT);
    pinMode( 9, INPUT);
  }

int CalcPGA(float x)  
// ---------------------------------------------------------------------------------------------
//   Calculate optimum PGA setting based on a sample voltage, x, read at lowest PGA gain
//     - returns the highest PGA gain that allows x to be read with 10% headroom
// ---------------------------------------------------------------------------------------------
  {
    x = abs(x);
    if (x>3.680) return ADS1115_6p144;
    if (x>1.840) return ADS1115_4p096;
    if (x>0.920) return ADS1115_2p048;
    if (x>0.460) return ADS1115_1p024;
    if (x>0.230) return ADS1115_0p512;
    else         return ADS1115_0p256;
  }

void BatteryIcon(float charge)
// ---------------------------------------------------------------------------------------------
//   Draw a battery charge icon into the display buffer without refreshing the display
//     - charge ranges from 0.0 (empty) to 1.0 (full)
// ---------------------------------------------------------------------------------------------
  {
    static const unsigned char PROGMEM chg[] =     // Battery Charge Icon
    { 0x1c, 0x18, 0x38, 0x3c, 0x18, 0x10, 0x20, 0x00 };
    
    int w = constrain(charge, 0.0, 1.0)*16;  // 0 to 16 pixels wide depending on charge
    display.drawRect(100, 0, 16, 7, WHITE);  // outline
    display.drawRect(116, 2,  3, 3, WHITE);  // nib
    display.fillRect(100, 0,  w, 7, WHITE);  // charge indication

    //battery charging indication
    pinMode(CHG, INPUT);
    if (digitalRead(CHG) == HIGH)
      display.drawBitmap(91, 0, chg, 8, 8, WHITE);
  }

void f2str(float x, int N, char *c)
// ---------------------------------------------------------------------------------------------
//    Converts a floating point number x to a string c with N digits of precision
//     - *c must be a string array of length at least N+3 (N + '-', '.', '\0')
//     - x must be have than N leading digits (before decimal) or "#\0" is returned
// ---------------------------------------------------------------------------------------------
  {
  int     j, k, r;
  float   y;

  if (x<0.0)                    // handle negative numbers
    {
      *c++ = '-';
      x = -x;
    }
  for (j=0; x>=1.0; j++)        // j digits before decimal point
    x /= 10.0;                  // .. and scale x to be < 1.0

  if (j>N)                      // return error string if too many digits
    {
      *c++ = '#';
      *c++ = '\0';
      return;
    }

  y = pow(10, (float) N);       // round to N digits
  x = round(x * y) / y;
  if (x>1.0)                    // if 1st digit rounded up ...
    {
      x /= 10.0;                // then normalize back down 1 digit
      j++;
    }

  for (k=0; k<N; k++)
    {
      r = (int) (x*10.0);        // leading digit as int
      x = x*10-r;                // remove leading digit and shift 1 digit
      
      *c++ = r + '0';            // add leading digit to string
      if (k==j-1 && k!=N-1)      // add decimal point after j digits
        *c++ = '.';              // ... unless there are N digits before decimal
    }
  *c++ = '\0';
  }

void DisplayResistance(float x)
// ---------------------------------------------------------------------------------------------
//    Adds the resistance value, x, to the display buffer without refreshing the display
//      - converts to kohm, milliohm or microohm if necessary
// --------------------------------------------------------------------------------------------- 
  {
    static const unsigned char PROGMEM omega_bmp[] =     // omega (ohm) symbol
    { B00000011, B11000000,
      B00001100, B00110000,
      B00110000, B00001100,
      B01000000, B00000010,
      B01000000, B00000010,
      B10000000, B00000001,
      B10000000, B00000001,
      B10000000, B00000001,
      B10000000, B00000001,
      B10000000, B00000001,
      B01000000, B00000010,
      B01000000, B00000010,
      B01000000, B00000010,
      B00100000, B00000100,
      B00010000, B00001000,
      B11111000, B00011111 };

    char  s[8];
    char  prefix;
    
    if (x>=1000.0)          // display in killo ohms
      {
        x /= 1000.0;
        prefix = 'k';
      }
    else if (x<0.001)       // display in micro ohms
      {
        x *= 1000000.0;
        prefix = 0xe5;    // mu
      }
    else if (x<1.0)         // display in milli ohms
      {
        x *= 1000.0;
        prefix = 'm';
      }
    else
      prefix = ' ';         // display in ohms
  
    f2str(x, 5, s);
       
    // display computed resistance
    display.setTextSize(2);
    display.setTextColor(WHITE);
    display.setCursor(0,20);
    display.print(s);

    // display prefix
    display.setCursor(85,20);
    display.print(prefix);
    
    // display omega (ohms) symbol
    display.drawBitmap(103, 18, omega_bmp, 16, 16, WHITE);
  }

void DisplayDebug(int a, int b, float x, float y, float Vbat)
// ---------------------------------------------------------------------------------------------
//    Adds debug info to the display buffer without showing the updated display
//      - Adds 2 ints (a, b) and a float(Vbat) to the top line and 2 floats (x, y) 
//      to the bottom line+, all in small (size 1) text
// ---------------------------------------------------------------------------------------------
  {
    // display x, y in lower left, small font
    display.setTextSize(1);
    display.setCursor(0,45);
    display.print(x,3);
    display.print("  ");
    display.print(y,3);

    // display a, b in upper left, small font
    display.setTextSize(1);
    display.setCursor(0,0);
    display.print(a);
    display.print("  ");
    display.print(b);

    // display Vbat in upper middle, small font
    display.setTextSize(1);
    display.setCursor(60,0);
    display.print(Vbat,1);
  }

void DisplayStr(char *s)
// ---------------------------------------------------------------------------------------------
//    Adds a string, s, to the display buffer without refreshing the display @ (0,20)
// --------------------------------------------------------------------------------------------- 
  {
    display.setTextSize(2);              
    display.setTextColor(WHITE);
    display.setCursor(8,20);
    display.print(s);
  }

#ifdef TESTMODE
void loop()
  {
    while (digitalRead(P_PushToTest))
      ;
    DriveP();
    display.clearDisplay();
    DisplayStr("Drive: +");
    display.display();
    delay(250);

    while (digitalRead(P_PushToTest))
      ; 
    DriveN();
    display.clearDisplay();
    DisplayStr("Drive: -");
    display.display();
    delay(250);

    while (digitalRead(P_PushToTest))
      ; 
    DriveOff();
    display.clearDisplay();
    DisplayStr("Drive: Off");
    display.display();
    delay(250);
  }
#endif
  
void setup() 
// ---------------------------------------------------------------------------------------------
//    - initializae display and I/O ports
// --------------------------------------------------------------------------------------------- 
  {
    DriveOff();                                    // disable current drive
    Wire.begin();                                  // join I2C bus
    display.begin(SSD1306_SWITCHCAPVCC, 0x3c, 0);  // initialize display @ address 0x3c, no reset
    pinMode(P_PushToTest, INPUT_PULLUP);           // measure push button switch, active low
    debug_mode = !digitalRead(P_PushToTest);       // if pushed during power on, then debug mode
    pinMode(P_Debug, OUTPUT);                      // debug port
  }
  
void loop() 
// ---------------------------------------------------------------------------------------------
//    main measurement loop
// --------------------------------------------------------------------------------------------- 
  {
    const float      Rr = 10.0;             // reference resistor value, ohms
    const float      Rcal = 1.002419;       // calibration factor
    const int        N = 2;                 // number of cycles to average
    const int        M = 50;                // samples per half cycle
    static long      Toff;
    double           Rx;                    // calculated resistor under test, ohms
    byte             PGAr, PGAx;            // PGA gains (r = reference, x = test resistors)
    float            Vr, Vx, Wx, Wr;        // voltages in V
    float            Rn;                    // calculated resistor under test, ohms, single sample
    double           Avgr, Avgx;            // average ADC readings in mV
    int              j, k, n;
    float            Vbat;                  // battery voltage in V (from 2:1 divider)
    char             serialbuff[10];        // Buffer for sending the reading over I²C

    display.clearDisplay();
    DisplayStr("measuring"); 
    display.display();

    // determine PGA gains      
    DriveP(); 
    Wr =  ADS1115read(ADS1115_CH01, ADS1115_6p144);
    Wx =  ADS1115read(ADS1115_CH23, ADS1115_6p144);    
    DriveN();
    Vr = -ADS1115read(ADS1115_CH01, ADS1115_6p144);
    Vx = -ADS1115read(ADS1115_CH23, ADS1115_6p144);

    //  measure battery voltage ... while drive is on so there is a load
    Vbat = analogRead(A3)*5.0/1024.0;    // 2:1 divider (5V FS) on 4.2v lithium battery

    DriveOff();

    PGAr = CalcPGA(max(Vr, Wr));           // determine optimum PGA gains
    PGAx = CalcPGA(max(Vx, Wx));

    // measure resistance using synchronous detection
    Avgr = Avgx = 0.0;                     // clear averages
    Rx = 0.0;
    n = 0;
    for (j=0; j<N; j++)                    // for each cycle
      {
        DriveP();                          // turn on drive, positive
        for (k=0; k<M; k++)
          {
            digitalWrite(P_Debug, 1);
            Vx = ADS1115read(ADS1115_CH23, PGAx);
            digitalWrite(P_Debug, 0);
            Vr = ADS1115read(ADS1115_CH01, PGAr);
            Avgx += Vx;
            Avgr += Vr;
            Rn = Vx/Vr;
            if (Rn>0.0 && Rn<10000.0)
              {
              Rx += Rn;
              n++;
              }
          }

        DriveN();                          // turn on drive, negative
        for (k=0; k<M; k++)
          {
            digitalWrite(P_Debug, 1);
            Vx = ADS1115read(ADS1115_CH23, PGAx);
            digitalWrite(P_Debug, 0);
            Vr = ADS1115read(ADS1115_CH01, PGAr);
            Avgx -= Vx;
            Avgr -= Vr;
            Rn = Vx/Vr;
            if (Rn>0.0 && Rn<10000.0)
              {
              Rx += Rn;
              n++;
              }
          }
      }
    
    DriveOff();
    Rx   *= Rr * Rcal / n;                 // apply calibration factor and compute average
    Avgr *= 1000.0 / (2.0*N*M);            // average in mV
    Avgx *= 1000.0 / (2.0*N*M);   

    // display the results ... battery icon, Rx measurement, debug info if requested
    display.clearDisplay();                // ... and display result
    BatteryIcon((Vbat-3.0)/(4.2-3.0));     // 7.5V = 0%, 9V = 100%
    //display.drawLine(0, 8, 127, 8, WHITE); //Draw separator line under icons
    if (n==0){                              // no measurement taken ...
      display.setTextSize(2);
      display.setCursor(51,20);
      display.print(F("OL"));
    }
      //DisplayStr("-----");
    else
      DisplayResistance(Rx);
    //Send Reading via I²C
      Wire.beginTransmission(0x50);
      Wire.write(dtostrf(Rx, 5, 5, serialbuff));
      Wire.endTransmission();
    if (debug_mode) 
      DisplayDebug(PGAr, PGAx, Avgr, Avgx, Vbat);
    display.display();                     // show the display
    
    // and then wait for next measurement request
    Toff = millis()+60000L;
    while(digitalRead(P_PushToTest))       // loop until measure button pressed
      {
        // Enter power down state for 120ms with ADC and BOD module disabled
        //LowPower.powerDown(SLEEP_120MS, ADC_OFF, BOD_OFF);  
        if (millis()>Toff)                 // after 7 seconds ...
          {
            display.clearDisplay();        // clear display
            display.display(); 
          }
      }
  }

 

Posted on 5 Comments

EpEver Tracer 4210A MPPT Solar Charge Controller Teardown

Tracer 4210A MPPT Solar Controller
Tracer 4210A MPPT Solar Controller

Here’s the solar charge controller to go with the MT50 from the last post. This is the 40A version of the EpEver Tracer A series, the 4210A. This unit is large, and very heavy. Most of this weight comes from the enormous heatsink which doubles as the mounting plate for all the other components, and the large inductors that are going to be required for the DC-DC conversion that MPPT requires.

Front Panel
Front Panel

The front panel has a basic LCD, which shows various stats, such as PV Volts & Amps, and battery bank Volts & Amps. The pair of buttons are used to navigate the basic menu to configure some options, along with switching the load terminals ON/OFF.

Specifications
Specifications

There’s a specs label on the top, with a slight difference here vs the manual, which states the max. PV volts as 92v.

Main PCB Overview
Main PCB Overview

Removing 4 machine screws from the bottom of the unit allows the top to come off. Like the MT50 remote panel, this unit also has moulded-in brass thread inserts in the plastic parts. The PCB in here is heavily comformal coated, which stops me from reading the laser-etched numbers on the semiconductor devices, so there will be few details there.

Main PCB Lower
Main PCB Lower

Here’s the bottom section of the main PCB, with the enormous screw terminals, which will easily take cables up to about 16mm². The RJ-45 jack which hosts the unit’s RS-485 bus is to the right, and a smaller 2-pin connector on the left sorts out the battery temperature sensor.
The DC output MOSFET switches are hiding just behind the right-hand terminals, there’s a pair of them in this unit to handle the output current. Some beefy diodes polarity-protect both the battery & PV inputs.

Board Centre
Board Centre

Moving up the board shows two 35A automotive blade fuses soldered into the board – these would be a real pain to replace if they ever blew, however with the electronic load current protection built into this unit, it’s an unlikely situation, unless something went hideously wrong. The main switching devices for the DC-DC converter are hidden – they’re clamped to the heatsink with the bars at right angles in the photo, I’m not going to dig any deeper into this just for those though – they’re just TO220 devices.
Under a load of thermal gunk on the right are 4 current shunt resistors, and the amplifiers for reading their values. These 1206-size SMD resistors looked a bit small for the power rating to me, but they’re heatsinked in operation to a small heatsink mounted in the top cover.

Board Upper
Board Upper

The upper section of the PCB hosts the main microcontroller, and the connections over to the front panel LCD & buttons. Couldn’t really get much info from these chips, due to the conformal coating.

Toroidal Inductors
Toroidal Inductors

Right at the top of the unit are these toroidal inductors, potted into aluminium housings. The copper windings of these is very heavy – at least 2.5mm². They’re electrically in parallel, the 20A version would only have a single inductor.

Current Shunt Heatsink
Current Shunt Heatsink

This small heatsink sits inside the top cover, and provides some cooling to the current shunts.

Display Board
Display Board

Not much to say for the display board, there’s going to be nothing here apart from an I²C LCD driver & the pair of front panel buttons, so I won’t bother removing this from the case.

Posted on Leave a comment

LG Flatron 22EA53VQ-P Power Issue

I was recently given a pretty nice LED backlit 1080p LG monitor, with the instruction that it wouldn’t power on correctly. The monitor would power on as far as the standby light, but when fully powered on, would flash the backlight momentarily then shut down. A power supply issue was immediately suspected.

LCD Logic Board
LCD Logic Board

I popped the covers off the monitor itself first, thinking that it was an electrolytic gone bad in the backlight DC-DC converter. Not to mention the fact that cracking into a wall-wart type of PSU is only occasionally possible without the use of anger & large hammers. (Cracking the glue with the handle of a screwdriver doesn’t work so well when the factory went a bit nuts with the glue/ultrasonic welder). As can be seen in the photo, there’s not much inside these monitors, the logic is a single-chip solution, the rest of the PCB is dedicated to supplying the power rails for the various circuits. On the left is the power input & the DC-DC converter for the backlight, along with the DC-DC converter supplying the logic circuits. None of the capacitors here are damaged, everything looks good.
I then measured the output of the PSU, which under no load was the correct 19v DC. However applying any load caused the output voltage to drop like a proverbial brick. Applying a full load of 1.3A saw the output voltage drop so severely that the PSU tripped on it’s UVLO.

200mA Load
200mA Load

At 200mA of load the factory PSU is already dropping to 18v, with a 5.3kHz switching frequency appearing.

500mA Load
500mA Load

At higher load the frequency increases to 11.5kHz & the output voltage has dropped to 11.86v!

750mA Load
750mA Load

750mA was as high as I could make the supply go without it tripping itself out – the UVLO circuit trips at 9v. 12.6kHz is now riding on the severely low DC at this point.

PSU Ratings
PSU Ratings

The power supply is supposed to be rated at 1.3A at 19v, however with this fault it’s getting nowhere near that. The LG brand is on this PSU but it’s contracted out to Shenzen Honor Electric Co. Ltd.

Output Electrolytic
Output Electrolytic

Here’s the problem with this PSU. The output electrolytic has ballooned. I don’t have an ESR tester, but this cap has gone way past it’s sell-by date. It’s position right next to the heatsink with the output rectifier diodes has probably cooked it. The PSU isn’t that badly built for a Chinese one – there’s plenty of creepage distance on the PCB & even a couple of isolation slots.

Posted on 1 Comment

Sony Watchman FD-280 Teardown

Sony FD-280
Sony FD-280

Here’s another Sony Flat CRT TV, the FD0280. This one was apparently the last to use CRT technology, later devices were LCD based. This one certainly doesn’t feel as well made as the last one, with no metal parts at all in the frame, just moulded plastic.

CRT Screen
CRT Screen

Being a later model, this one has a much larger screen.

Autotuning
Autotuning

Instead of the manual tuner of the last Watchman, this one has automatic tuning control, to find the local stations.

Spec Label
Spec Label

The spec puts the power consumption a little higher than the older TV, this isn’t surprising as the CRT screen is bigger & will require higher voltages on the electrodes.

Certification Label
Certification Label

The certification label dates this model to May 1992.

External Inputs
External Inputs

Still not much in the way of inputs on this TV. There’s an external power input, external antenna input & a headphone jack. No composite from the factory. (Hack incoming ;)).

Power / Band
Power / Band

The UHF/VHF & power switches are on the top of this model.

Back Cover Removed
Back Cover Removed

Removing some very tiny screws allows the back to be removed. There’s significant difference in this model to the last, more of the electronics are integrated into ICs, nearly everything is SMD.

RF Section
RF Section

There’s the usual RF tuner section & IF, in this case the VIF/SIF is a Mitsubishi M51348AFP.

Tuner Controller
Tuner Controller

The digital control of the tuner is perfomed by this Panasonic AN5707NS.

Deflection / Sync
Deflection / Sync

The deflection & sync functions appear to be controlled by a single Sony branded custom IC, the CX20157. Similar to many other custom Sony ICs, a datasheet for this wasn’t forthcoming.

PCB Top
PCB Top

There’s very little on the top side of the board, the RF section is on the left, there’s a DC-DC converter bottom centre next to the battery contacts. This DC-DC converter has a very unusual inductor, completely encased in a metal can. This is probably done to prevent the magnetic field from interfering with the CRT.

CRT
CRT

Here’s the CRT itself, the Sony 03-JM. The back of this CRT is uncoated at the bottom, the tuning scale was taped to the back so it lined up with the tuning bar displayed on the screen.

Electronics
Electronics

Here’s the electronics completely removed from the shell. There’s much more integration in this model, everything is on a single PCB.

Phosphor Screen
Phosphor Screen

The curve in the phosphor screen can clearly be seen here. This CRT seems to have been cost-reduced as well, with the rough edges on the glass components having been left unfinished.

Electron Gun
Electron Gun

Here’s the electron gun end of the tube. There isn’t a separate final anode connection to the bell of the tube unlike the previous model. Instead the final anode voltage is on a pin of the electron gun itself. This keeps all the wiring to the tube at one end & shortens the high voltage cable.

Electron Gun
Electron Gun

Here’s the gun in the neck of the tube. Again this is pretty much standard fare for CRT guns. It’s more similar to a viewfinder tube in that the anode connection is running from the pins at the back. (It’s the line running up the right side of the tube). I’m guessing the anode voltage is pretty low for this to work without the HV flashing over, probably in the 2-4kV range.

Posted on 14 Comments

Dyson DC16 Handheld Teardown

DC16
DC16

The Dyson DC16 is one of the older handheld vacuums, before the introduction of the “Digital Motor”. (Marketing obviously didn’t think “Switched Reluctance Motor” sounded quite as good).

These vacuums have a very large DC brush motor driving the suction turbine instead, the same as would be found in a cordless power tool.

Control PCB
Control PCB

Popping the front cap off with the ID label, reveals the brains of the vacuum. The two large terminals at the right are for charging, which is only done at 550mA (0.5C). There are two PIC microcontrollers in here, along with a large choke, DC-DC converter for supplying the logic most likely. The larger of the MCUs, a PIC16HV785, is probably doing the soft-start PWM on the main motor, the smaller of the two, a PIC16F684 I’m sure is doing battery charging & power management. The motor has a PCB on it’s tail end, with a very large MOSFET, a pair of heavy leads connect directly from the battery connector to the motor.
Just out of sight on the bottom left edge of the board is a Hall Effect Sensor, this detects the presence of the filter by means of a small magnet, the vacuum will not start without a filter fitted.

Battery Pack
Battery Pack

The battery pack is a large custom job, obviously. 4 terminals mean there’s slightly more in here than just the cells.

Battery Cracked
Battery Cracked

Luckily, instead of ultrasonic or solvent welding the case, these Dyson batteries are just snapped together. Some mild attack with a pair of screwdrivers allows the end cap to be removed with minimal damage.

Cells
Cells

The cells were lightly hot-glued into the shell, but that can easily be solved with a drop of Isopropanol to dissolve the glue bond. The pack itself is made up of 6 Sony US18650VT High-Drain 18650 Li-Ion cells in series for 21.6v nominal. These are rated at a max of 20A discharge current, 10A charge current, and 1.3Ah capacity nominal.
There’s no intelligence in this battery pack, the extra pair of terminals are for a thermistor, so the PIC in the main body knows what temperature the pack is at – it certainly gets warm while in use due to the high current draw.

Motor
Motor

Hidden in the back side of the main body is the motor. Unfortunately I wasn’t able to get this out without doing some damage, as the wiring isn’t long enough to free the unit without some surgery.

Turbine
Turbine

The suction is generated by a smaller version of the centrifugal high-speed blowers used in full size vacuums. Not much to see here.

Unofficial Charger
Unofficial Charger

Since I got this without a charger, I had to improvise. The factory power supply is just a 28v power brick, all the charging logic is in the vacuum itself, so I didn’t have to worry about such nasties as over-charging. I have since fitted the battery pack with a standard Li-Po balance cable, so it can be used with my ProCell charger, which will charge the pack in 35 minutes, instead of the 3 hours of the original charger.

Posted on Leave a comment

De La Rue Coin Counting Machine Followup – PSU Oddness

I did a little more digging into the PSU circuitry of the small coin counting machine, and it’s even more strange than I thought!
The part I originally thought was a transformer on the PSU board is in fact a DC-DC converter module!

DC-DC Converter
DC-DC Converter

Here’s the device after desoldering it from the PCB. It turns out that instead of a transformer, it’s an inductor.

Hiding Control Electronics
Hiding Control Electronics

Underneath is the controller electronics, with an COB controller & the switching transistors are under a protective covering of silicone.

Mains Transformer
Mains Transformer

Driving this whole lot of PSU randomness is the mains transformer, with a secondary voltage of 35v.

The only reason I can think of that the manufacturer went to this much expense with the power supply is stability – a coin counting machine that miscounts due to power supply surges, sags & spikes wouldn’t be very much use. It’s not likely I’ll see anything similar again, unless I manage to get hold of something like medical grade equipment.

Posted on Leave a comment

Turnigy Accucell 6 Multi-Chemistry Charger

Accucell 6
Accucell 6

A lot of the electronics I use & projects I construct use batteries, mainly of the lithium variety. As charging this chemistry can be a little explosive if not done correctly, I decided a proper charger was required. This charger is capable of handling packs up to 6 cells for Lithium, and up to 20v for lead-acids.

External Connections
External Connections

The usual DC input barrel jack on the left, with an external temp sensor for fast charging NiCd/NiMH chemistry batteries. The µUSB port registers under Linux as USB HID, probably so drivers aren’t required. Unfortunately the software is Windows only, but it doesn’t provide anything handy like charging graphs or stats. Just a way to alter settings & control charging from a PC. On other versions of this charger there’s a setting to change the temp sensor port into a TTL serial output, which would be much handier.

Output & Balance
Output & Balance

The other side of the charger has the main DC output jacks & the pack balancing connections.

Cover Removed
Cover Removed

Here’s the top cover removed from the charger, showing most of the internals. A standard HD44780 LCD provides the user interface, the CPU & it’s associated logic is hidden under there somewhere.
The PCB has nice heavy tracks to handle the 6A of current this charger is capable of.

Balancing Network
Balancing Network

The output side of the board. Here the resistive pack balancing network can be seen behind the vertical daughter board holding the connectors, along with the output current shunt between the DC output banana jacks & the last tactile button.

Main Logic
Main Logic

Unfortunately the LCD is soldered directly to the board, and my desoldering tool couldn’t quite get all the solder out, so time to get a bit violent. I’ve gently bent the header so I could see the brains of the charger. The main CPU is a Megwin MA84G564AD48, which is an Intel 8081 clone with USB support. Unfortunately I was unable to find a datasheet for this part, and the page on Megwin’s site is Chinese only.

I was hoping it was an ATMega328, as I have seen in other versions of this charger, as there are custom firmwares available to increase the feature set of the charger, but no dice on this one. I do think the µUSB port is unique to this version though, so avoiding models with that port probably would get a hackable version.
There’s some glue logic for controlling the resistor taps on the balancing network, and a few op-amps for voltage & current readings.

Power Switching Devices
Power Switching Devices

All the power diodes & switching FETs for the DC-DC converter are mounted on the bottom of the PCB, and clamped against the aluminium casing when the PCB is screwed down. Not the best way to ensure great contact, but Chinese tech, so m’eh.

Posted on Leave a comment

ViewSonic VA2232W-LED Monitor 12v Conversion

ID Label
ID Label

On the quest to get things on board replaced that are heavy users of power, the monitor in the main cabin was next. The original CCFL-backlit monitor was very heavy on 12v power, at 5A. This meant falling asleep watching TV would result in severely flattened batteries.

Replacement with a suitable LED-backlit monitor was definitely required. The cheapest on eBay was a ViewSonic VA2232W-LED, so I took to work converting it from 240v to 12v operation.

Back Cover Removed
Back Cover Removed

There are no screws holding these monitors together, so a spudger & frequent swearing got the back off. The shield holding the circuitry is also not screwed down, only attached to the back of the LCD panel with aluminium shielding tape.

Power PCB Trackside
Power PCB Trackside

Once the tape has been cut, the main power board is accessible. The large IC on the left is the main backlight LED driver.

In this case the monitor requires a pair of rails from the supply, 18.5v for the backlight circuitry & 5v for the logic.

DC-DC Regulators
DC-DC Regulators

A pair of DC-DC converters has been fitted in the small space between the power & control boards.

PCB Connection Points
PCB Connection Points

To save me some work & keep maximum compatibility, I’ve not modified the existing supply, just attached the new DC-DC converter outputs onto the corresponding outputs of the factory PSU. The 12v input leads are routed out of the same gap as the mains IEC connector, with some hot glue over the mains input solder points to provide some more insulation.

Wiring Tidied
Wiring Tidied

The wiring is tidied up with hot glue so the back cover will go back on.

Total current draw at 12v is 1.4A.

Posted on Leave a comment

Rigol DS1054Z 12v Power Supply Project – Completion

All of the parts I required to complete the supply arrived this morning. After several hours of building, here’s what I came up with:

12v Power Supply
12v Power Supply

I’ve mounted everything on a piece of FR4 PCB, with it’s copper plane grounded to the case. This backing board is the same size as the original PSU PCB to allow it to be screwed into the same location in the scope.

The power comes in via the converter on the right, which outputs a single 24v rail for the rest of the supplies. The other 6 supplies then generate the individual voltage rails that the scope requires. The use of a single input supply allows this system to operate at voltages up to 30v DC, so it’s good for both 12v & 24v systems.

Scope Ripple
Scope Ripple

At present the only issue is with some ripple on one of the supplies, this is showing up on the scope display with no input connected at the lowest volts/division. Parts are on order from Farnell to build some common mode filters to remove this from the DC output.

On a 13.8v supply, the scope draws about 1.5A total from the supply, giving a total power consumption of 20.7W. This is with all 4 channels enabled.

My wiring assignments & DC-DC converter ratings are in the table below

Connector PinPCB PinSignalMainboardDC-DC RatingWire Colour
110GNDGNDN/ABLACK
22+9v_GNDFAN --NABLACK
38+7.5V6.3V6AORANGE
414-7.5V-7.5V2AGREEN
51NOT USEDAC_TRIGN/ANOT USED
64+5V5V5A6ARED
76GNDGNDN/ABLACK
87GNDGNDN/ABLACK
912-17.5V-17.5V3APURPLE
109+7.5V6.3V6AORANGE
113+9VFAN +1AGREY
121117.5V17.5V3ABLUE
135+5V5V5A6ARED
1413GNDGNDN/ABLACK

Stay tuned for the final section of this build with the power supply filtering & main DC input connections!

73s for now 🙂

Posted on 1 Comment

12v Temperature Controlled Soldering Iron

In my shack, 99% of my gear is all 12v powered, which is good for a few reasons:

  • Single Power Supply – This increases efficiency, as I’m only getting the losses of a single supply.
  • Safety – Mains voltages are dangerous, I’m not fond of working on such equipment.
  • Portability – I can power everything pretty much no matter were I am from a convenient car battery.
  • Convenience – Since everything is single supply, with all the same plugs, I don’t have to think about what goes where. This is more important due to my forgetfulness ;).

The one piece of equipment I regularly use that isn’t 12v is my soldering station. This is a Maplin A55KJ digital unit, which uses a 24v heating element.
While the soldering wand works OK when hooked direct to a 12v power supply (only at half power though), this removes the convenience of having temperature control.

The circuitry inside the unit is PIC microcontroller based, and doesn’t even bother rectifying the AC from the supply transformer before it’s sent to the heater. Because of this there are several reasons why I can’t just hook a DC-DC converter up to it to give it 24v.

It’s sensing the zero-crossing for the triac switch, to reduce heat dissipation, so it refuses to work at all with DC.

On looking at the Great Google, I found a project on Dangerous Prototypes, an Arduino based PID controller for soldering irons.

This requires that the soldering wand itself contains a thermocouple sensor – as the Maplin one I have is a cheap copy of the Atten 938D, it doesn’t actually use a thermocouple for temperature sensing. It appears to read the resistance of the element itself – Nichrome heating elements change resistance significantly depending on temperature.

I’ve managed to find a source of cheap irons on eBay, with built in thermocouples, so I’ve got a couple on order to do some testing with. While I wait for those to arrive, I’ve prototyped up the circuit on breadboard for testing:

Prototype
Prototype

I’ve remapped some of the Arduino pins, to make PCB layout less of a headache, but the system is working OK so far, with manual input for the sensed temperature.
I’m using an IRL520N logic-level HEXFET for the power switching, rated at 10A. As the irons only draw a max of 4.5A, this is plenty beefy enough.
To come up with the +24v supply for the heater, a small DC-DC converter will be used.

More to come when the components for the thermocouple amplifier arrive, and the soldering irons themselves!

Posted on Leave a comment

Upcoming Project – Monster DC-DC Converter

Here’s a sneak preview of my next upcoming project. The target is building a monster DC-DC converter, capable of 70A continuous output, 100A surge.

DC-DC Converter Modules
DC-DC Converter Modules

Here’s the 10 modules, each rated at up to 7A continuous & 10A surge. I ordered so many that they turned up still panelised!

Closeup
Closeup
Posted on Leave a comment

Precision 10v & 5v Reference

After watching a video over at Scullcom Hobby Electronics on YouTube, I figured I’d build one of these precision references to calibrate my multimeters.

It’s based around a REF102P 10v precision reference & an INA105P precision unity gain differential amplifier.

For full information, check out the video, I won’t go into the details here, just my particular circuit & PCB layout.

In the video, Veroboard is used. I’m not too fond of the stuff personally. I find it far too easy to make mistakes & it never quite looks good enough. To this end I have spun a board in Eagle, as usual.

Precision Ref SCH
Precision Ref SCH – Click to Embiggen

Here’s the schematic layout, the same as is in the video.

Precision Ref BRD
Precision Ref BRD

As usual, the Eagle CAD layout files can be found at the bottom of the post.

And the associated PCB layout. I have added the option to be able to tweak the output, to get a more accurate calibration, which can be added by connecting JP1 on the PCB.

As in the original build, this unit uses pre-built DC-DC converter & Li-Ion charger modules. A handy Eagle library can be found online for these parts.
I have however left off the battery monitor section of the circuit, since I plan to use a protected lithium cell for power. This also allowed me to keep the board size down, & use a single sided layout.

Toner Transfer Paper
Toner Transfer Paper

Here’s the track layout ready to iron onto the copper clad board. I use the popular toner transfer system with special paper from eBay, this stuff has a coating that allows the toner to easily be transferred to the PCB without having to mess about with soaking in water & scraping paper off.

Ironed On
Ironed On

Here’s the paper having just been ironed onto the copper. After waiting for the board to cool off the paper is peeled off, leaving just the toner on the PCB.

Etched PCB
Etched PCB

PCB just out of the etch tank, drilled & with the solder pins for the modules installed. Only one issue with the transfer, in the bottom left corner of the board is visible, a very small section of copper was over etched.
This is easily fixed with a small piece of wire.

Components Populated
Components Populated

Main components populated. The DC-DC converter is set at 24v output, which the linear regulator then drops down to the +15v rail for the reference IC. The linear section of the regulator, along with the LC filter on the output of the switching regulator produce a low-ripple supply.

SMPS Ripple
SMPS Ripple

Here’s the scope reading the AC ripple on the output of the DC-DC converter. Scale is 100mV/Div. Roughly 150mV of ripple is riding on top of the DC rail.

Linear PSU Ripple
Linear PSU Ripple

And here’s the output from the linear regulator, scale of 50mV/Div. Ripple has been reduced to ~15mV for the reference IC.
In total the circuit as built has a power consumption of ~0.5W, most of which is being dissipated as heat in the linear part of the PSU.

[download id=”5583″]

Posted on Leave a comment

Raspberry Pi Timelapse Setup

Here is the setup used to create the previous videos, the PiCE from Elson Designs makes the Pi water resistant, the only slight modification being to install a 2.5mm DC Barrel Jack into one of the grommet holes in the rear coupled with a custom DC-DC converter to power the setup.

CamPi_1

CamPi_2

CamPi_3

Posted on Leave a comment

Mobile Power Pack Upgrade

New Regulators
New Regulators

The original LM2577 based regulators I designed into my mobile battery pack turned out to be insufficient for requirements, therefore they have been replaced with higher capacity regulators.

The 12v regulator (left) is a muRata UQQ-12/8-Q12P-C SEPIC converter, providing a max of 8A at 12.1v DC. The 12v rail is also now independently switchable to save power when not in use.

The 5v regulator (right) is a Texas Instruments PTN78020WAZ switching regulator, rated at 6A. The pair of resistors on the back of the regulator set the output voltage to 5.1v.

Also a new addition is a pair of banana sockets & a 2.1mm DC jack, wired into the 12v DC bus, for powering various accessories.

New Additions
New Additions

Below the USB sockets is now a built in eCig charger, to save on USB ports while charging these devices.

IWA National Festival 2013
IWA National Festival 2013

These changes were made after much field testing of the unit at Cassiobury Park, Watford, for the IWA National Waterways Festival.

Posted on Leave a comment

2600 Farad Ultra Capacitors

Ultracap Bank
Ultracap Bank

Just a quickie to note down the current progress of another project – Ultracapacitors.
Pictured right is a bank of 6 2.5v 2600F Maxwell Boostcaps, for a total of 15v at 433.333F. A total energy storage of  48.7kJ.

Coming soon will be the inclusion of charge balancing, using Zener diodes & integrating a DC-DC converter on the output to hold the bank voltage at 12v when being used.