mmbasic:backpack_tracker_curve_tracer

Backpack Tracker curve tracer

This article describes the design of a electronics debugging tool for electronic circuits. www.thebackshed.com_forum_uploads_volhout_2019-11-26_190124_20191125_194950.jpg

The main purpose of the tool is to give a graphical representation of the impedance at a node of the circuit, similar to a commercial product, the Huntron Tracker. The tool allows for very fast fault finding in electronic circuits, especially when a known good circuit is available, so graphs can be compared. You can find the faults in a circuit without taking components out. That is a great benefit.

Typically you have this tool on the test bench, and next to each other 2 boards, one known good, the other suspect of fault. The ground connection of the test tool is connected to the same pin on each board (typically the ground node). The test wire is used to alternatively probe the good board at node X, and the suspect board at the same node. When waveforms differ between boards, that points to the culprit. The tool has a memory button, so the waveform of the known good board can be checked more carefully.

If there is no “known good” circuit is available, still comparison can be made to similar nodes in the same circuit, and differences will point to the culprit. In example microprocessor pins are all similar, if one pin shows a different impedance, there is reason to doubt the microprocessor as being defect.

Creating an impedance graph is based on a very simple principle: apply a voltage to that pin, and measure the current that flows in the pin. By applying different voltage, the impedance at each voltage can be shown in a graph. A good description of the circuit can be found here: Octopus Curve Tracer
and this Using a Curve Tracer

Typical test voltages are +/- 15V at currents of a few mA, to avoid damage to the circuit under test.

As explained in the article, for resistors, Ohms law U=IxR will show a linear relation between voltage and current. A straight line. For a diode, at positive voltages the impedance will be low, and negative voltage will be high. Result will be a line with a bend. This kind of characteristics are visible on the screen of the Backpack Tracker.

The name “Backpack” is from the core building block of this tool: the Micromite Backpack. The Micromite Backpack is a design of Geoff Graham, and is based around a PIC32 processor that can be programmed in Basic. Information can be found here: Backpack

The Micromite Backpack is a 2 circuit board sandwich existing of a PIC32 board, and a commercial ILI9341 LCD touch color display 320×240 pixels. In this design the LCD will display the impedance curves, and will act as a very simple control panel with only 2 (touch) buttons. The PIC32 microcontroller will generate the voltage applied to the circuit under test, measure the current and convert the measurements to an impedance graph. The software is written in MMBasic, the native language of the Micromite Backpack.

Since the PIC32 processor can only output voltages in the range of 0V..3.3V, an additional amplifier is needed to achieve the +/- 15V. This amplifier, and it's power supply, are located on a third printed circuit board.

The amplifier schematics are shown here: Amplifier board

A short explanation of the circuit: The PIC32 processor does not have a DAC output that can be used to generate different voltages, therefore a PWM output is used, running at a rather high frequency of 120kHz. This frequency is an optimum between resolution (the higher the frequency - the lower the resolution, the lower the frequency - the slower the voltages can be varied, the lower the screen update rate). The PWM signal passes through a low pass filter, to convert it into an analog voltage, that can be amplified by a classical opamp circuit around an LM741.

The LM741 is powered from +/- 16.5V that is generated from 5V in an MC34063 switch mode convertor.

The circuitry fits on a small PCB, the size of the micromite backpack (could form a sandwich of 3). The circuit board layout is shown here: Board layout J1 is the connector that plugs into the micromite backpack.

Download PCB foil (solder side view) Download PCB foil (component side view)

To understand how the circuit works it is necessary to know that the current measurement, required to determine the impedance of the circuit under test, is done through a trick: the ADC inside the PIC32 measures the output voltage of the LM741 after it passed through a resistor R16, and subtracts the measured value from the theoretical output voltage of the LM741. result is the voltage across that resistor, and thus the current through the resistor. Since this principle (subtract 2 large values to get a small value) is in essence inaccurate, the software performs a calibration at powerup.

A picture of the displayed waveform is shown here: Display waveform

There are 2 buttons: MEM: this button stores the current waveform, and displays it in red, as a reference. This would be the waveform of the “known good” circuit. ZOOM: this button zooms in at the center, to allow more detail if low voltage circuits are probed.

In the screen there is a waveform, characteristic for the impedance of the pin under test (yellow), and 2 markers (cyan). The markers show the voltage at the waveform extremes, and can be used to detect smaller changes between very similar impedance's. Very handy to check zener diodes.

When building the Backpack Tracker, some things are important to note. The LM741 was chosen because of it's supply voltage range. To reach an output of +/-15V (actually +/-14V at the test pins) the opamp needs a supply voltage of +/- 16.5V or more. Most opamps are specified up to +/- 15V supply voltage. The LM741 to +/-18V. Alternatives to the LM741 are: MC34071 and TLE2141IP (+/- 22V). The MC34063 switch mode convertor can be replaced by a MC33063. For the resistors preferably use 1% parts, since the gain and offset of the amplifier, and the centering of the ADC input at half 3.3V need to be fairly accurate.

The tool is powered from 5V (a phone charger) of from the USB power of a PC. Essential to it's performance is the calibration at powerup. It requires the test leads (J2/J3) to be disconnected from any object during powerup.

The software will also work on a ArmmiteF4 (commercial ARM based platform with LCD module, ported to MMBasic by Peter Mather). However, the hardware is not optimal for the Armmite. The Armmite processor is much faster, so the update rate is faster. The PWM low pass filter cannot settle fast enough, resulting in a more “jagged” waveform display. And the connector pinning (J1) is different so some flying wires are needed.

Some explanation of the software:

The voltage waveform is pre-calculated (a triangle waveform).

In a tight loop (main) the new voltage is sent to the PWM. While waiting for the settling of the PWM low pass filter the last line segment is erased (color=black), the memory line segment drawn(memcolor). Then the ADC is read, and the new value is drawn (yellow). If the memory line must be displayed, memcolor = red, if not , memcolor is black (so it is drawn for nothing…but that avoids another IF statement). This loop determines the screen update rate. With current settings (samples = 64) the screen updates every 110msec (8.5 frames/second).

Once every second a timer fires, and the markers are updated, and the screen border is re-drawn. Redrawing the screen border is needed since MMBasic on the micromite backpack only has one grapical layer, and the border can be corrupted by the impedance lines.

At powerup the system is calibrated at it's 10% and 90% points (the LM741 is used up to it's limits, and may become slightly non linear at 0% and 100% points).

Zooming in is partly done in hardware: only half the voltage (+/- 7V) is applied to the test pin. This gives full resolution to the PWM in only +/- 7V. The ADC (12 bits) has sufficient accuracy, even if only used at half scale.

Zoom and Memory are touch buttons. For robustness and ease of use, the touch location is set very wide.

The Basic code that runs the tracker:

'+-------------------------------------------------------------+
'|                                                             |
'|                         BACKPACK TRACKER                    |
'|                                                             |
'| 21-7-2021                         Volhout @ TheBackShed.com |
'+-------------------------------------------------------------+
' Curve tracer type huntron tracker
' For ILI9341 LCD backpack on 28 pin MX170
' Uses pin 24 as analog input
' Uses pin 4 as pwm output
' Uses pin 9 and 10 to set amplifier gain
' all values scaled to 'resolution'
' there are 'samples' measurements per period


'------------------------- Version History ------------------
' V00       Proof of concept with 640 samples 100 resolution
' V01       Increase resolution to 1000, decrease samples to 200
' V02       Implemented touch for REF and ZOOM buttons, REF added
' V03       Optimized main loop from 400msec to 300msec
' V04       Implemented support for HW zoom
' V05       Zoom implemented in SW
' V06       Restructure code to support samples and resolution as constants
' V07       Tune performance on MX170 ( 8 frames / second )
' V08       Improved code for readability, remove obsolete DIM's
' V09       Screen resolution independent (untested), added header
' V10       Add dynamic measurement values
' V11       Support for ArmiteF4 (untested with hardware)
' V12       Support for PicoMite (MMbasic 0.5.07 alpha48)

'------------------------------ init ------------------------
Option explicit

init:
 If MM.Device$ = "ARMmite F407" Then
   'STM32F407VET6 initialisation
   'OPTION LCDPANEL ILI9341_16, LANDSCAPE
   'TOUCH PB12, PC5
   Const ADC_PIN = 15             ' 15/PC0 for F4
   Const HI_GAIN_HI = 1          ' switch to high gain, PE2/pin1 for F4
   Const HI_GAIN_LO = 5          ' switch to high gain, PE6/pin5 for F4
   GUI interrupt Touch_Int
 ElseIf MM.Device$="RP2040 PicoMite" Then
   'PicoMite initialisation
   'option system spi gp2,gp3,gp4
   'option lcdpanel ili9341,landscape,gp7,gp6,gp5
   'option touch cs,irq,beep - not tested
   Const ADC_PIN = 31 'GP26
   Const HI_GAIN_HI = 32 'GP27
   Const HI_GAIN_LO = 34 'GP28
   SetPin 24,PWM1A 'GP18
 Else
   'PIC32MX170 initialisation
   'OPTION LCDPANEL ILI9341, L, 2, 23, 6
   'OPTION TOUCH 7, 15
   CPU 48                          ' max speed - not needed in ARM F4
   Const ADC_PIN = 24              ' 24 for MX170
   Const HI_GAIN_HI = 10           ' switch to high gain, 10 for MX
   Const HI_GAIN_LO = 9            ' switch to high gain, 9 for MX
   ' enable touch
   SetPin 15, INTL, Touch_Int
 EndIf

 'start board
 SetPin ADC_PIN,ain              ' voltage input ADC1-ch10 (at pin 15)
 PWM 1,120000,50                 ' set PWM to 50% (0Vdc amplifier out)
                                 ' pin 31/PA6 on F4, pin 4 on MX170
 amp_high_gain                   ' set amplifier gain

 ' Define samples each scan
 Const samples = 64
 Const resolution = 1000

 ' external ADC divider (R15=47k into R10=12k//R11=15k)
 Const R10_R11 = 12000*15000/(12000+15000)
 Const resistor_divider = (47000 + R10_R11)/R10_R11


 ' Declare variables -------------------------------------------------

 ' Declare defaults for scaling ADC to 'resolution', these values
 ' are fine tuned in calibration (at powerup)
 Dim integer lowgain=resolution/3.3, highgain=2*lowgain
 Dim gain=lowgain
 Dim integer lowoffset=0, highoffset=-resolution/2
 Dim offset=lowoffset

 ' for user interface, xt/yt are touch coordinates
 Dim integer xt,yt

 ' generic i,j,h are counters, ADC is scaled adc value, adc10 and adc90
 ' are used in calibration
 Dim integer i,j,h,ADCV
 Dim float adc10,adc90

 ' display waveform, x/y are measured waveform, xr/yr are memory reference
 Dim integer x0,y0,x(samples),y(samples),xr(samples),yr(samples)
 ' init coordinates with values that fit the screen
 For i=1 To samples
   xr(i)=MM.HRes-3:yr(i)=MM.VRes/2:x(i)=MM.HRes-3:y(i)=MM.VRes/2
 Next i
 x0=MM.HRes-3:y0=MM.VRes/2

 ' display numerics, xnl/ynl for left side, xnr/ynr for right side
 Dim integer xnr=100,xnl=100,ynr=100,ynl=100,yor=0,yol=0
 Dim float vr,ir,vl,il

 ' generate waveform, pw = pwm value, pc = pwm value scaled to 'resolution'
 Dim pw(samples), pc(samples)
 ' fill waveform with triange wave 0...100%
 For i=1 To samples / 2
   pw(i) = 100 - ( 200 / samples ) * i
   pc(i) = resolution * pw(i) / 100
   pw(i + samples / 2) = ( 200 / samples ) * i
   pc(i + samples / 2) = resolution * pw(i + samples / 2) / 100
 Next

 ' graphics scaling to resolution
 Dim float Vstep = MM.VRes / resolution, Hstep = MM.HRes / resolution
 Dim center = resolution / 2

 ' buttons and line colors
 Dim integer membuttoncolor = RGB(blue), zoombuttoncolor = RGB(blue)
 Dim integer memcolor = RGB(black), linecolor = RGB(yellow)

 'debug
 Memory

 ' initialize screen
 draw_window

 ' timed interrupts
 SetTick 1000, Time_Int, 1

 ' calibrate analog circuits
 calibrate


'------------------------------ MAIN ------------------------

main:
 ' all comments removed from main loop to speed it up
 ' cycle through all pwm values using pointers i (actual) and j (last)
 ' erase last segment
 ' allways draw memory line, but color decides if it is visible
 ' draw memory line first so actual overwrites memory
 ' measure input value
 ' recalculate new segment (huntron method)
 ' draw new segement

 Do
   Timer = 0

   For i = 1 To samples
     j = i - 1 : If j = 0 Then j = samples
     PWM 1,120000,pw(i)
     Line x0,y0,x(i),y(i),1,0
     Line xr(j),yr(j),xr(i),yr(i),1,memcolor
     x0 = x(i) : y0 = y(i)
     ADCV = (Pin(ADC_PIN) * gain) + offset
     y(i)=(ADCV - pc(i) + center) * Vstep
     x(i)= ADCV * Hstep
     Line x(j),y(j),x(i),y(i),1,linecolor
   Next i

   Print Timer
 Loop




'--------------------------- SUBS ---------------------------

Sub Touch_Int
 xt = Touch(x) : yt = Touch(y)

 'check for MEM button if we should display memory
 If xt < ( MM.HRes / 4 ) And yt < ( MM.VRes / 4 ) Then
   If memcolor = RGB(black) Then
     For h = 1 To samples          'copy live to REF line
       yr(h) = y(h)
       xr(h) = x(h)
     Next
     memcolor = RGB(red)
     membuttoncolor = RGB(red)
   Else
     memcolor = RGB(black)
     membuttoncolor = RGB(Blue)
   EndIf
   RBox 10,10,60,30,2,RGB(white),membuttoncolor
   Text 30,18,"MEM",,,,RGB(white),membuttoncolor
 EndIf

 'check for ZOOM button to see if we should zoom in
 If xt > (3 * MM.HRes / 4 ) And yt > (3 * MM.VRes / 4) Then
   If zoombuttoncolor = RGB(blue) Then
     zoombuttoncolor = RGB(red)
     adc_high_gain
     amp_low_gain
   Else
     zoombuttoncolor = RGB(Blue)
     adc_low_gain
     amp_high_gain
   EndIf
     RBox MM.HRes-70,MM.VRes-40,60,30,2,RGB(white),zoombuttoncolor
     Text MM.HRes-55,MM.VRes-32,"ZOOM",,,,RGB(white),zoombuttoncolor
 EndIf

 draw_frame

 Pause 300                 'prevent double touch
End Sub


Sub amp_high_gain
     SetPin HI_GAIN_LO,dout : Pin(HI_GAIN_LO)=0
     SetPin HI_GAIN_HI,dout : Pin(HI_GAIN_HI)=1
End Sub


Sub amp_low_gain
     SetPin HI_GAIN_LO,din
     SetPin HI_GAIN_HI,din
End Sub


Sub adc_high_gain
     gain = highgain
     offset = highoffset
End Sub


Sub adc_low_gain
     gain = lowgain
     offset = lowoffset
End Sub


Sub draw_window
 'clear screen
 CLS

 'draw outside lines
 draw_frame

 'draw buttons
 RBox 10,10,60,30,2,RGB(white),membuttoncolor
 Text 30,18,"MEM",,,,RGB(white),membuttoncolor
 RBox MM.HRes-70,MM.VRes-40,60,30,2,RGB(white),zoombuttoncolor
 Text MM.HRes-55,MM.VRes-32,"ZOOM",,,,RGB(white),zoombuttoncolor
End Sub


Sub calibrate
 'calibrate standard mode ------------
 amp_high_gain
 adc_low_gain

 'measure 10% and 90% points
 PWM 1,120000,10
 Pause 1
 adc10 = Pin(ADC_PIN)
 PWM 1,120000,90
 Pause 1
 adc90 = Pin(ADC_PIN)

 'calculate ADC low gain and offset
 lowgain = 80 * resolution / (100 * (adc90 - adc10))
 lowoffset = - lowgain * (adc10 - ((adc90 - adc10)/8))
 Print adc10, adc90, lowgain , lowoffset

 'calibrate zoom mode --------------
 amp_low_gain
 adc_high_gain

 'measure 10% and 90% values
 PWM 1,120000,10
 Pause 1
 adc10 = Pin(ADC_PIN)
 PWM 1,120000,90
 Pause 1
 adc90 = Pin(ADC_PIN)

 'calculate ADC high gain and offset
 highgain = 80 * resolution / (100 * (adc90 - adc10))
 highoffset = - highgain * (adc10 - ((adc90 - adc10)/8))
 Print adc10, adc90, highgain , highoffset

 'back to standard mode
 amp_high_gain
 adc_low_gain
End Sub


Sub draw_frame
 'draw outside lines
 Line 1,1,1,MM.VRes-2,2,RGB(white)
 Line 1,MM.VRes-2,MM.HRes-2,MM.VRes-2,2,RGB(white)
 Line MM.HRes-2,MM.VRes-2,MM.HRes-2,1,2,RGB(white)
 Line MM.HRes-2,1,1,1,2,RGB(white)
End Sub



Sub Time_Int

 'check if left marker needs update
 If ynl <> y(samples/2) Then

   'erase old text
   Text xnl+12,ynl+yol,"       ",l,,,0,0

   'write markers
   Box xnl-5,ynl-5,10,10,,0

   ' calculate voltage
   xnl = x(samples/2): ynl = y(samples/2)
   vl = resistor_divider * ((xnl - MM.HRes / 2) / Hstep) / gain

   ' repair corrupted frame
   draw_frame

   'write markers
   Box xnl-5,ynl-5,10,10,,RGB(cyan)

   'get new coordinates for writing text, and write
   If ynl > MM.VRes-30 Then yol=-20 Else yol=5
   Text xnl+12,ynl+yol,Str$(vl,0,2)+"V",l,,,RGB(white),0

 EndIf

 ' check if right marker needs an update
 If ynr <> y(samples) Then

   'erase old text
   Text xnr-12,ynr+yor,"       ",r,,,0,0

   'write markers
   Box xnr-5,ynr-5,10,10,,0

   ' calculate voltage
   xnr = x(samples): ynr = y(samples)
   vr = resistor_divider * ((xnr - MM.HRes / 2) / Hstep) / gain

   ' repair corrupted frame
   draw_frame

   'write markers
   Box xnr-5,ynr-5,10,10,,RGB(cyan)

   'get new coordinates for writing text, and write
   If ynr < 30 Then yor=5 Else yor=-20
   Text xnr-12,ynr+yor,Str$(vr,0,2)+"V",r,,,RGB(white),0

 EndIf

End Sub
mmbasic/backpack_tracker_curve_tracer.txt · Last modified: 2024/07/19 21:04 by gerry