Diff
checker
Text
Text
Bilder
Dokumente
Excel
Ordner
Legal
Enterprise
Desktop-App
Preise
Einloggen
Diffchecker Desktop herunterladen
Texte vergleichen
Finde den Unterschied zwischen zwei Textdateien
Werkzeuge
Verlauf
Live-Editor
Gleiches ausblenden
Zeilenumbruch aus
Ansicht
Zweispaltig
Einspaltig
Vergleichsgenauigkeit
Intelligent
Wort
Zeichen
Syntaxhervorhebung
Syntax auswählen
Ignorieren
Text umwandeln
Zur ersten Änderung
Eingabe bearbeiten
Diffchecker Desktop
Der sicherste Weg, Diffchecker zu nutzen. Hol dir die Desktop-App: Deine Diffs verlassen nie deinen Computer!
Desktop holen
main.c
Erstellt
vor 5 Jahren
Diff läuft nie ab
Löschen
Exportieren
Teilen
Erklären
0 Entfernungen
Zeilen
Gesamt
Entfernt
Zeichen
Gesamt
Entfernt
Um diese Funktion weiterhin zu nutzen, aktualisiere auf
Diff
checker
Pro
Preise anzeigen
981 Zeilen
Kopieren
0 Hinzufügungen
Zeilen
Gesamt
Hinzugefügt
Zeichen
Gesamt
Hinzugefügt
Um diese Funktion weiterhin zu nutzen, aktualisiere auf
Diff
checker
Pro
Preise anzeigen
981 Zeilen
Kopieren
/* ************************************************************************
/* ************************************************************************
*
*
* main part
* main part
*
*
* (c) 2012-2020 by Markus Reschke
* (c) 2012-2020 by Markus Reschke
* based on code from Markus Frejek and Karl-Heinz Kübbeler
* based on code from Markus Frejek and Karl-Heinz Kübbeler
*
*
* ************************************************************************ */
* ************************************************************************ */
/*
/*
* local constants
* local constants
*/
*/
/* source management */
/* source management */
#define MAIN_C
#define MAIN_C
/*
/*
* include header files
* include header files
*/
*/
/* local includes */
/* local includes */
#include "config.h" /* global configuration */
#include "config.h" /* global configuration */
#include "common.h" /* common header file */
#include "common.h" /* common header file */
#include "variables.h" /* global variables */
#include "variables.h" /* global variables */
#include "functions.h" /* external functions */
#include "functions.h" /* external functions */
#include "colors.h" /* color definitions */
#include "colors.h" /* color definitions */
/*
/*
* local variables
* local variables
*/
*/
/* program control */
/* program control */
#if CYCLE_MAX < 255
#if CYCLE_MAX < 255
uint8_t MissedParts; /* counter for failed/missed components */
uint8_t MissedParts; /* counter for failed/missed components */
#endif
#endif
/* ************************************************************************
/* ************************************************************************
* output components and errors
* output components and errors
* ************************************************************************ */
* ************************************************************************ */
/*
/*
* show pinout for semiconductors
* show pinout for semiconductors
*
*
* required:
* required:
* - character for pin A
* - character for pin A
* - character for pin B
* - character for pin B
* - character for pin C
* - character for pin C
*/
*/
void Show_SemiPinout(uint8_t A, uint8_t B, uint8_t C)
void Show_SemiPinout(uint8_t A, uint8_t B, uint8_t C)
{
{
uint8_t n; /* counter */
uint8_t n; /* counter */
uint8_t Char; /* character */
uint8_t Char; /* character */
#ifdef SW_PROBE_COLORS
#ifdef SW_PROBE_COLORS
uint16_t Color; /* color value */
uint16_t Color; /* color value */
Color = UI.PenColor; /* save current color */
Color = UI.PenColor; /* save current color */
#endif
#endif
/* display: 123 */
/* display: 123 */
for (n = 0; n <= 2; n++)
for (n = 0; n <= 2; n++)
{
{
Display_ProbeNumber(n);
Display_ProbeNumber(n);
}
}
/* display: = */
/* display: = */
Display_Char('=');
Display_Char('=');
/* display pin IDs */
/* display pin IDs */
for (n = 0; n <= 2; n++) /* loop through probe pins */
for (n = 0; n <= 2; n++) /* loop through probe pins */
{
{
#ifdef SW_PROBE_COLORS
#ifdef SW_PROBE_COLORS
UI.PenColor = ProbeColors[n]; /* set probe color */
UI.PenColor = ProbeColors[n]; /* set probe color */
#endif
#endif
if (n == Semi.A) Char = A; /* probe A - ID A */
if (n == Semi.A) Char = A; /* probe A - ID A */
else if (n == Semi.B) Char = B; /* probe B - ID B */
else if (n == Semi.B) Char = B; /* probe B - ID B */
else Char = C; /* - ID C */
else Char = C; /* - ID C */
Display_Char(Char); /* display ID */
Display_Char(Char); /* display ID */
}
}
#ifdef SW_PROBE_COLORS
#ifdef SW_PROBE_COLORS
UI.PenColor = Color; /* restore old color */
UI.PenColor = Color; /* restore old color */
#endif
#endif
}
}
/*
/*
* show simple pinout
* show simple pinout
*
*
* required:
* required:
* - ID: characters for probes 1, 2 and 3
* - ID: characters for probes 1, 2 and 3
* 0 -> not displayed
* 0 -> not displayed
*/
*/
void Show_SimplePinout(uint8_t ID_1, uint8_t ID_2, uint8_t ID_3)
void Show_SimplePinout(uint8_t ID_1, uint8_t ID_2, uint8_t ID_3)
{
{
uint8_t n; /* counter */
uint8_t n; /* counter */
unsigned char ID[3]; /* component pin IDs */
unsigned char ID[3]; /* component pin IDs */
#ifdef SW_PROBE_COLORS
#ifdef SW_PROBE_COLORS
uint16_t Color; /* color value */
uint16_t Color; /* color value */
Color = UI.PenColor; /* save current color */
Color = UI.PenColor; /* save current color */
#endif
#endif
/* copy probe pin characters/IDs */
/* copy probe pin characters/IDs */
ID[0] = ID_1;
ID[0] = ID_1;
ID[1] = ID_2;
ID[1] = ID_2;
ID[2] = ID_3;
ID[2] = ID_3;
for (n = 0; n <= 2; n++) /* loop through probe pins */
for (n = 0; n <= 2; n++) /* loop through probe pins */
{
{
if (ID[n] != 0) /* display this one */
if (ID[n] != 0) /* display this one */
{
{
Display_ProbeNumber(n);
Display_ProbeNumber(n);
Display_Char(':');
Display_Char(':');
#ifdef SW_PROBE_COLORS
#ifdef SW_PROBE_COLORS
UI.PenColor = ProbeColors[n]; /* set probe color */
UI.PenColor = ProbeColors[n]; /* set probe color */
#endif
#endif
Display_Char(ID[n]);
Display_Char(ID[n]);
#ifdef SW_PROBE_COLORS
#ifdef SW_PROBE_COLORS
UI.PenColor = Color; /* restore old color */
UI.PenColor = Color; /* restore old color */
#endif
#endif
Display_Space();
Display_Space();
}
}
}
}
}
}
#ifdef FUNC_EVALUE
#ifdef FUNC_EVALUE
/*
/*
* show E series norm values
* show E series norm values
*
*
* requires:
* requires:
* - Value: unsigned value
* - Value: unsigned value
* - Scale: exponent/multiplier (* 10^n)
* - Scale: exponent/multiplier (* 10^n)
* - ESeries: E6-192
* - ESeries: E6-192
* - Tolerance: in 0.1%
* - Tolerance: in 0.1%
* - Unit: unit character
* - Unit: unit character
*/
*/
void Show_ENormValues(uint32_t Value, int8_t Scale, uint8_t ESeries, uint8_t Tolerance, unsigned char Unit)
void Show_ENormValues(uint32_t Value, int8_t Scale, uint8_t ESeries, uint8_t Tolerance, unsigned char Unit)
{
{
uint8_t n; /* number of norm values (1 or 2) */
uint8_t n; /* number of norm values (1 or 2) */
uint8_t Pos; /* char x position */
uint8_t Pos; /* char x position */
uint8_t Temp; /* temporary value */
uint8_t Temp; /* temporary value */
/*
/*
* get E series norm values
* get E series norm values
* - 1st: Semi.I_value, Semi.I_scale
* - 1st: Semi.I_value, Semi.I_scale
* - 2nd: Semi.C_value, Semi.C_scale
* - 2nd: Semi.C_value, Semi.C_scale
*/
*/
n = GetENormValue(Value, Scale, ESeries, Tolerance);
n = GetENormValue(Value, Scale, ESeries, Tolerance);
/*
/*
* show E series and tolerance
* show E series and tolerance
*/
*/
Display_NextLine(); /* move to next line */
Display_NextLine(); /* move to next line */
/* display E series */
/* display E series */
Display_Char('E'); /* display: E */
Display_Char('E'); /* display: E */
Display_FullValue(ESeries, 0 , 0); /* display E series */
Display_FullValue(ESeries, 0 , 0); /* display E series */
Display_Space(); /* display: " " */
Display_Space(); /* display: " " */
/* display tolerance */
/* display tolerance */
Temp = Tolerance; /* copy tolerance */
Temp = Tolerance; /* copy tolerance */
Pos = 0; /* reset decimal places */
Pos = 0; /* reset decimal places */
if (Temp < 10) /* < 1% */
if (Temp < 10) /* < 1% */
{
{
Pos = 1; /* one decimal place */
Pos = 1; /* one decimal place */
}
}
Temp /= 10; /* scale to 1 */
Temp /= 10; /* scale to 1 */
Display_FullValue(Temp, Pos, '%'); /* display tolerance */
Display_FullValue(Temp, Pos, '%'); /* display tolerance */
Display_Space(); /* display: " " */
Display_Space(); /* display: " " */
/*
/*
* show norm values
* show norm values
*/
*/
if (n) /* got norm value(s) */
if (n) /* got norm value(s) */
{
{
Pos = UI.CharPos_X; /* get current char position */
Pos = UI.CharPos_X; /* get current char position */
/* display first norm value */
/* display first norm value */
Display_EValue(Semi.I_value, Semi.I_scale, Unit);
Display_EValue(Semi.I_value, Semi.I_scale, Unit);
if (n == 2) /* got two norm values */
if (n == 2) /* got two norm values */
{
{
/* move to next line at same position (after E series) */
/* move to next line at same position (after E series) */
Display_NextLine();
Display_NextLine();
LCD_CharPos(Pos, UI.CharPos_Y);
LCD_CharPos(Pos, UI.CharPos_Y);
/* display second norm value */
/* display second norm value */
Display_EValue(Semi.C_value, Semi.C_scale, Unit);
Display_EValue(Semi.C_value, Semi.C_scale, Unit);
}
}
}
}
else /* no norm value */
else /* no norm value */
{
{
Display_Char('-'); /* display: - */
Display_Char('-'); /* display: - */
}
}
}
}
#endif
#endif
#ifdef FUNC_COLORCODE
#ifdef FUNC_COLORCODE
/*
/*
* show E series norm value color-codes
* show E series norm value color-codes
*
*
* requires:
* requires:
* - Value: unsigned value
* - Value: unsigned value
* - Scale: exponent/multiplier (* 10^n)
* - Scale: exponent/multiplier (* 10^n)
* - ESeries: E6-192
* - ESeries: E6-192
* - Tolerance: in 0.1%
* - Tolerance: in 0.1%
* - TolBand: color of tolerance band
* - TolBand: color of tolerance band
*/
*/
void Show_ENormCodes(uint32_t Value, int8_t Scale, uint8_t ESeries, uint8_t Tolerance, uint16_t TolBand)
void Show_ENormCodes(uint32_t Value, int8_t Scale, uint8_t ESeries, uint8_t Tolerance, uint16_t TolBand)
{
{
uint8_t n; /* number of norm values (1 or 2) */
uint8_t n; /* number of norm values (1 or 2) */
uint8_t Pos; /* char x position */
uint8_t Pos; /* char x position */
/*
/*
* tolerance band
* tolerance band
* - resistor
* - resistor
* 20% 10% 5% 2% 1% 0.5% 0.25% 0.1% 0.05%
* 20% 10% 5% 2% 1% 0.5% 0.25% 0.1% 0.05%
* none silver gold red brown green blue violet grey
* none silver gold red brown green blue violet grey
* - inductor
* - inductor
* 20% 10% 5% 4% 3% 2% 1% 0.5% 0.25% 0.1% 0.05%
* 20% 10% 5% 4% 3% 2% 1% 0.5% 0.25% 0.1% 0.05%
* black silver gold yellow orange red brown green blue violet grey
* black silver gold yellow orange red brown green blue violet grey
* - caps: many different schemas
* - caps: many different schemas
*
*
* multiplier reference
* multiplier reference
* - R: 0 (10^0) -> 1 Ohms
* - R: 0 (10^0) -> 1 Ohms
* C: -12 (10^-12) -> 1 pF
* C: -12 (10^-12) -> 1 pF
* L: -6 (10^-6) -> 1 µH
* L: -6 (10^-6) -> 1 µH
* - ref_scale as function argument?
* - ref_scale as function argument?
* scale = scale - ref_scale
* scale = scale - ref_scale
*/
*/
/*
/*
* get E series norm values
* get E series norm values
* - 1st: Semi.I_value, Semi.I_scale
* - 1st: Semi.I_value, Semi.I_scale
* - 2nd: Semi.C_value, Semi.C_scale
* - 2nd: Semi.C_value, Semi.C_scale
*/
*/
n = GetENormValue(Value, Scale, ESeries, Tolerance);
n = GetENormValue(Value, Scale, ESeries, Tolerance);
/*
/*
* show E series
* show E series
*/
*/
Display_NextLine(); /* move to next line */
Display_NextLine(); /* move to next line */
/* display E series */
/* display E series */
Display_Char('E'); /* display: E */
Display_Char('E'); /* display: E */
Display_FullValue(ESeries, 0 , 0); /* display E series */
Display_FullValue(ESeries, 0 , 0); /* display E series */
Display_Space(); /* display: " " */
Display_Space(); /* display: " " */
/*
/*
* show color-codes of norm values
* show color-codes of norm values
*/
*/
if (n) /* got norm value(s) */
if (n) /* got norm value(s) */
{
{
Pos = UI.CharPos_X; /* get current char position */
Pos = UI.CharPos_X; /* get current char position */
/* display color-code of first norm value */
/* display color-code of first norm value */
Display_ColorCode(Semi.I_value, Semi.I_scale, TolBand);
Display_ColorCode(Semi.I_value, Semi.I_scale, TolBand);
if (n == 2) /* got two norm values */
if (n == 2) /* got two norm values */
{
{
/* move to next line at same position (after E series) */
/* move to next line at same position (after E series) */
Display_NextLine();
Display_NextLine();
LCD_CharPos(Pos, UI.CharPos_Y);
LCD_CharPos(Pos, UI.CharPos_Y);
/* display color-code of second norm value */
/* display color-code of second norm value */
Display_ColorCode(Semi.C_value, Semi.C_scale, TolBand);
Display_ColorCode(Semi.C_value, Semi.C_scale, TolBand);
}
}
}
}
#if 0
#if 0
/*
/*
* color testing
* color testing
*/
*/
uint16_t Color;
uint16_t Color;
Display_NextLine();
Display_NextLine();
/* first 5 colors plus gold */
/* first 5 colors plus gold */
n = 0;
n = 0;
while (n < 5)
while (n < 5)
{
{
Color = DATA_read_word((uint16_t *)&ColorCode_table[n]);
Color = DATA_read_word((uint16_t *)&ColorCode_table[n]);
LCD_Band(Color, ALIGN_LEFT);
LCD_Band(Color, ALIGN_LEFT);
n++;
n++;
}
}
LCD_Band(COLOR_CODE_GOLD, ALIGN_RIGHT);
LCD_Band(COLOR_CODE_GOLD, ALIGN_RIGHT);
Display_NextLine();
Display_NextLine();
/* last 5 colors plus silver */
/* last 5 colors plus silver */
while (n < 10)
while (n < 10)
{
{
Color = DATA_read_word((uint16_t *)&ColorCode_table[n]);
Color = DATA_read_word((uint16_t *)&ColorCode_table[n]);
LCD_Band(Color, ALIGN_LEFT);
LCD_Band(Color, ALIGN_LEFT);
n++;
n++;
}
}
LCD_Band(COLOR_CODE_SILVER, ALIGN_RIGHT);
LCD_Band(COLOR_CODE_SILVER, ALIGN_RIGHT);
TestKey(0, CURSOR_BLINK);
TestKey(0, CURSOR_BLINK);
#endif
#endif
}
}
#endif
#endif
/*
/*
* show failed test
* show failed test
*/
*/
void Show_Fail(void)
void Show_Fail(void)
{
{
/* display info */
/* display info */
Display_EEString(Failed1_str); /* display: No component */
Display_EEString(Failed1_str); /* display: No component */
Display_NL_EEString(Failed2_str); /* display: found! */
Display_NL_EEString(Failed2_str); /* display: found! */
#if CYCLE_MAX < 255
#if CYCLE_MAX < 255
MissedParts++; /* increase counter */
MissedParts++; /* increase counter */
#endif
#endif
}
}
/*
/*
* show error
* show error
*/
*/
void Show_Error()
void Show_Error()
{
{
if (Check.Type == TYPE_DISCHARGE) /* discharge failed */
if (Check.Type == TYPE_DISCHARGE) /* discharge failed */
{
{
Display_EEString(DischargeFailed_str); /* display: Battery? */
Display_EEString(DischargeFailed_str); /* display: Battery? */
/* display probe number and remaining voltage */
/* display probe number and remaining voltage */
Display_NextLine();
Display_NextLine();
Display_ProbeNumber(Check.Probe);
Display_ProbeNumber(Check.Probe);
Display_Char(':');
Display_Char(':');
Display_Space();
Display_Space();
Display_Value(Check.U, -3, 'V');
Display_Value(Check.U, -3, 'V');
}
}
else if (Check.Type == TYPE_DETECTION) /* detection error */
else if (Check.Type == TYPE_DETECTION) /* detection error */
{
{
/* simply display: No component found! */
/* simply display: No component found! */
Show_Fail();
Show_Fail();
}
}
}
}
/*
/*
* show single (first) resistor
* show single (first) resistor
*
*
* requires:
* requires:
* - ID1: pin ID #1 character
* - ID1: pin ID #1 character
* - ID2: pin ID #2 character
* - ID2: pin ID #2 character
*/
*/
void Show_SingleResistor(uint8_t ID1, uint8_t ID2)
void Show_SingleResistor(uint8_t ID1, uint8_t ID2)
{
{
Resistor_Type *Resistor; /* pointer to resistor */
Resistor_Type *Resistor; /* pointer to resistor */
Resistor = &Resistors[0]; /* pointer to first resistor */
Resistor = &Resistors[0]; /* pointer to first resistor */
/* show pinout */
/* show pinout */
Display_Char(ID1);
Display_Char(ID1);
Display_EEString(Resistor_str);
Display_EEString(Resistor_str);
Display_Char(ID2);
Display_Char(ID2);
/* show resistance value */
/* show resistance value */
Display_Space();
Display_Space();
Display_Value(Resistor->Value, Resistor->Scale, LCD_CHAR_OMEGA);
Display_Value(Resistor->Value, Resistor->Scale, LCD_CHAR_OMEGA);
}
}
/*
/*
* show resistor(s)
* show resistor(s)
*/
*/
void Show_Resistor(void)
void Show_Resistor(void)
{
{
Resistor_Type *R1; /* pointer to resistor #1 */
Resistor_Type *R1; /* pointer to resistor #1 */
Resistor_Type *R2; /* pointer to resistor #2 */
Resistor_Type *R2; /* pointer to resistor #2 */
uint8_t Pin; /* ID of common pin */
uint8_t Pin; /* ID of common pin */
R1 = &Resistors[0]; /* pointer to first resistor */
R1 = &Resistors[0]; /* pointer to first resistor */
if (Check.Resistors == 1) /* single resistor */
if (Check.Resistors == 1) /* single resistor */
{
{
R2 = NULL; /* disable second resistor */
R2 = NULL; /* disable second resistor */
Pin = R1->A; /* make B the first pin */
Pin = R1->A; /* make B the first pin */
}
}
else /* multiple resistors */
else /* multiple resistors */
{
{
R2 = R1;
R2 = R1;
R2++; /* pointer to second resistor */
R2++; /* pointer to second resistor */
#ifdef UI_SERIAL_COMMANDS
#ifdef UI_SERIAL_COMMANDS
/* set data for remote commands */
/* set data for remote commands */
Info.Quantity = 2; /* got two */
Info.Quantity = 2; /* got two */
#endif
#endif
if (Check.Resistors == 3) /* three resistors */
if (Check.Resistors == 3) /* three resistors */
{
{
Resistor_Type *Rmax; /* pointer to largest resistor */
Resistor_Type *Rmax; /* pointer to largest resistor */
/*
/*
* 3 resistors mean 2 single resistors and both resistors in series.
* 3 resistors mean 2 single resistors and both resistors in series.
* So we have to single out that series resistor by finding the
* So we have to single out that series resistor by finding the
* largest resistor.
* largest resistor.
*/
*/
Rmax = R1; /* starting point */
Rmax = R1; /* starting point */
for (Pin = 1; Pin <= 2; Pin++)
for (Pin = 1; Pin <= 2; Pin++)
{
{
if (CmpValue(R2->Value, R2->Scale, Rmax->Value, Rmax->Scale) == 1)
if (CmpValue(R2->Value, R2->Scale, Rmax->Value, Rmax->Scale) == 1)
{
{
Rmax = R2; /* update largest one */
Rmax = R2; /* update largest one */
}
}
R2++; /* next one */
R2++; /* next one */
}
}
/* get the two smaller resistors */
/* get the two smaller resistors */
if (R1 == Rmax) R1++;
if (R1 == Rmax) R1++;
R2 = R1;
R2 = R1;
R2++;
R2++;
if (R2 == Rmax) R2++;
if (R2 == Rmax) R2++;
}
}
/* find common pin of both resistors */
/* find common pin of both resistors */
if ((R1->A == R2->A) || (R1->A == R2->B))
if ((R1->A == R2->A) || (R1->A == R2->B))
{
{
Pin = R1->A; /* pin A */
Pin = R1->A; /* pin A */
}
}
else
else
{
{
Pin = R1->B; /* pin B */
Pin = R1->B; /* pin B */
}
}
}
}
#ifdef UI_SERIAL_COMMANDS
#ifdef UI_SERIAL_COMMANDS
/* set data for remote commands */
/* set data for remote commands */
Info.Comp1 = (void *)R1; /* link first resistor */
Info.Comp1 = (void *)R1; /* link first resistor */
Info.Comp2 = (void *)R2; /* link second resistor */
Info.Comp2 = (void *)R2; /* link second resistor */
#endif
#endif
/*
/*
* display the pins
* display the pins
*/
*/
/* first resistor */
/* first resistor */
if (R1->A != Pin) /* A is not common pin */
if (R1->A != Pin) /* A is not common pin */
{
{
Display_ProbeNumber(R1->A); /* display pin A */
Display_ProbeNumber(R1->A); /* display pin A */
}
}
else /* single resistor or A is common pin */
else /* single resistor or A is common pin */
{
{
Display_ProbeNumber(R1->B); /* display pin B */
Display_ProbeNumber(R1->B); /* display pin B */
}
}
Display_EEString(Resistor_str);
Display_EEString(Resistor_str);
Display_ProbeNumber(Pin); /* display common pin */
Display_ProbeNumber(Pin); /* display common pin */
if (R2) /* second resistor */
if (R2) /* second resistor */
{
{
Display_EEString(Resistor_str);
Display_EEString(Resistor_str);
if (R2->A != Pin) /* A is not common pin */
if (R2->A != Pin) /* A is not common pin */
{
{
Display_ProbeNumber(R2->A); /* display pin A */
Display_ProbeNumber(R2->A); /* display pin A */
}
}
else /* A is common pin */
else /* A is common pin */
{
{
Display_ProbeNumber(R2->B); /* display pin B */
Display_ProbeNumber(R2->B); /* display pin B */
}
}
}
}
/*
/*
* display the values
* display the values
*/
*/
/* first resistor */
/* first resistor */
Display_NextLine();
Display_NextLine();
Display_Value(R1->Value, R1->Scale, LCD_CHAR_OMEGA);
Display_Value(R1->Value, R1->Scale, LCD_CHAR_OMEGA);
if (R2) /* second resistor */
if (R2) /* second resistor */
{
{
Display_Space();
Display_Space();
Display_Value(R2->Value, R2->Scale, LCD_CHAR_OMEGA);
Display_Value(R2->Value, R2->Scale, LCD_CHAR_OMEGA);
}
}
#ifdef SW_INDUCTOR
#ifdef SW_INDUCTOR
else /* single resistor */
else /* single resistor */
{
{
/* get inductance and display if relevant */
/* get inductance and display if relevant */
if (MeasureInductor(R1) == 1) /* inductor */
if (MeasureInductor(R1) == 1) /* inductor */
{
{
Display_Space();
Display_Space();
Display_Value(Inductor.Value, Inductor.Scale, 'H');
Display_Value(Inductor.Value, Inductor.Scale, 'H');
#ifdef UI_SERIAL_COMMANDS
#ifdef UI_SERIAL_COMMANDS
/* set data for remote commands */
/* set data for remote commands */
Info.Flags |= INFO_R_L; /* inductance measured */
Info.Flags |= INFO_R_L; /* inductance measured */
#endif
#endif
#ifdef SW_L_E6_T
#ifdef SW_L_E6_T
/* show E series norm values for E6 20% */
/* show E series norm values for E6 20% */
Show_ENormValues(Inductor.Value, Inductor.Scale, E6, 200, 'H');
Show_ENormValues(Inductor.Value, Inductor.Scale, E6, 200, 'H');
#endif
#endif
#ifdef SW_L_E12_T
#ifdef SW_L_E12_T
/* show E series norm values for E12 10% */
/* show E series norm values for E12 10% */
Show_ENormValues(Inductor.Value, Inductor.Scale, E12, 100, 'H');
Show_ENormValues(Inductor.Value, Inductor.Scale, E12, 100, 'H');
#endif
#endif
}
}
#ifdef SW_R_EXX
#ifdef SW_R_EXX
else /* no inductance */
else /* no inductance */
{
{
#ifdef SW_R_E24_5_T
#ifdef SW_R_E24_5_T
/* show E series norm values for E24 5% */
/* show E series norm values for E24 5% */
Show_ENormValues(R1->Value, R1->Scale, E24, 50, LCD_CHAR_OMEGA);
Show_ENormValues(R1->Value, R1->Scale, E24, 50, LCD_CHAR_OMEGA);
#endif
#endif
#ifdef SW_R_E24_5_CC
#ifdef SW_R_E24_5_CC
/* show E series norm value color-codes for E24 5% */
/* show E series norm value color-codes for E24 5% */
Show_ENormCodes(R1->Value, R1->Scale, E24, 50, COLOR_CODE_GOLD);
Show_ENormCodes(R1->Value, R1->Scale, E24, 50, COLOR_CODE_GOLD);
#endif
#endif
#ifdef SW_R_E24_1_T
#ifdef SW_R_E24_1_T
/* show E series norm values for E24 1% */
/* show E series norm values for E24 1% */
Show_ENormValues(R1->Value, R1->Scale, E24, 10, LCD_CHAR_OMEGA);
Show_ENormValues(R1->Value, R1->Scale, E24, 10, LCD_CHAR_OMEGA);
#endif
#endif
#ifdef SW_R_E24_1_CC
#ifdef SW_R_E24_1_CC
/* show E series norm value color-codes for E24 1% */
/* show E series norm value color-codes for E24 1% */
Show_ENormCodes(R1->Value, R1->Scale, E24, 10, COLOR_CODE_BROWN);
Show_ENormCodes(R1->Value, R1->Scale, E24, 10, COLOR_CODE_BROWN);
#endif
#endif
#ifdef SW_R_E96_T
#ifdef SW_R_E96_T
/* show E series norm values for E96 1% */
/* show E series norm values for E96 1% */
Show_ENormValues(R1->Value, R1->Scale, E96, 10, LCD_CHAR_OMEGA);
Show_ENormValues(R1->Value, R1->Scale, E96, 10, LCD_CHAR_OMEGA);
#endif
#endif
#ifdef SW_R_E96_CC
#ifdef SW_R_E96_CC
/* show E series norm value color-codes for E96 1% */
/* show E series norm value color-codes for E96 1% */
Show_ENormCodes(R1->Value, R1->Scale, E96, 10, COLOR_CODE_BROWN);
Show_ENormCodes(R1->Value, R1->Scale, E96, 10, COLOR_CODE_BROWN);
#endif
#endif
}
}
#endif
#endif
}
}
#elif defined (SW_R_EXX)
#elif defined (SW_R_EXX)
else /* single resistor */
else /* single resistor */
{
{
#ifdef SW_R_E24_5_T
#ifdef SW_R_E24_5_T
/* show E series norm values for E24 5% */
/* show E series norm values for E24 5% */
Show_ENormValues(R1->Value, R1->Scale, E24, 50, LCD_CHAR_OMEGA);
Show_ENormValues(R1->Value, R1->Scale, E24, 50, LCD_CHAR_OMEGA);
#endif
#endif
#ifdef SW_R_E24_5_CC
#ifdef SW_R_E24_5_CC
/* show E series norm value color-codes for E24 5% */
/* show E series norm value color-codes for E24 5% */
Show_ENormCodes(R1->Value, R1->Scale, E24, 50, COLOR_CODE_GOLD);
Show_ENormCodes(R1->Value, R1->Scale, E24, 50, COLOR_CODE_GOLD);
#endif
#endif
#ifdef SW_R_E24_1_T
#ifdef SW_R_E24_1_T
/* show E series norm values for E24 1% */
/* show E series norm values for E24 1% */
Show_ENormValues(R1->Value, R1->Scale, E24, 10, LCD_CHAR_OMEGA);
Show_ENormValues(R1->Value, R1->Scale, E24, 10, LCD_CHAR_OMEGA);
#endif
#endif
#ifdef SW_R_E24_1_CC
#ifdef SW_R_E24_1_CC
/* show E series norm value color-codes for E24 1% */
/* show E series norm value color-codes for E24 1% */
Show_ENormCodes(R1->Value, R1->Scale, E24, 10, COLOR_CODE_BROWN);
Show_ENormCodes(R1->Value, R1->Scale, E24, 10, COLOR_CODE_BROWN);
#endif
#endif
#ifdef SW_R_E96_T
#ifdef SW_R_E96_T
/* show E series norm values for E96 1% */
/* show E series norm values for E96 1% */
Show_ENormValues(R1->Value, R1->Scale, E96, 10, LCD_CHAR_OMEGA);
Show_ENormValues(R1->Value, R1->Scale, E96, 10, LCD_CHAR_OMEGA);
#endif
#endif
#ifdef SW_R_E96_CC
#ifdef SW_R_E96_CC
/* show E series norm value color-codes for E96 1% */
/* show E series norm value color-codes for E96 1% */
Show_ENormCodes(R1->Value, R1->Scale, E96, 10, COLOR_CODE_BROWN);
Show_ENormCodes(R1->Value, R1->Scale, E96, 10, COLOR_CODE_BROWN);
#endif
#endif
}
}
#endif
#endif
}
}
/*
/*
* show capacitor
* show capacitor
*/
*/
void Show_Capacitor(void)
void Show_Capacitor(void)
{
{
Capacitor_Type *MaxCap; /* pointer to largest cap */
Capacitor_Type *MaxCap; /* pointer to largest cap */
Capacitor_Type *Cap; /* pointer to cap */
Capacitor_Type *Cap; /* pointer to cap */
#if defined (SW_ESR) || defined (SW_OLD_ESR)
#if defined (SW_ESR) || defined (SW_OLD_ESR)
uint16_t ESR; /* ESR (in 0.01 Ohms) */
uint16_t ESR; /* ESR (in 0.01 Ohms) */
#endif
#endif
uint8_t Counter; /* loop counter */
uint8_t Counter; /* loop counter */
/* find largest cap */
/* find largest cap */
MaxCap = &Caps[0]; /* pointer to first cap */
MaxCap = &Caps[0]; /* pointer to first cap */
Cap = MaxCap;
Cap = MaxCap;
for (Counter = 1; Counter <= 2; Counter++)
for (Counter = 1; Counter <= 2; Counter++)
{
{
Cap++; /* next cap */
Cap++; /* next cap */
if (CmpValue(Cap->Value, Cap->Scale, MaxCap->Value, MaxCap->Scale) == 1)
if (CmpValue(Cap->Value, Cap->Scale, MaxCap->Value, MaxCap->Scale) == 1)
{
{
MaxCap = Cap;
MaxCap = Cap;
}
}
}
}
#ifdef UI_SERIAL_COMMANDS
#ifdef UI_SERIAL_COMMANDS
/* set data for remote commands */
/* set data for remote commands */
Info.Comp1 = (void *)MaxCap; /* link largest cap */
Info.Comp1 = (void *)MaxCap; /* link largest cap */
#endif
#endif
/* display pinout */
/* display pinout */
Display_ProbeNumber(MaxCap->A); /* display pin #1 */
Display_ProbeNumber(MaxCap->A); /* display pin #1 */
Display_EEString(Cap_str); /* display capacitor symbol */
Display_EEString(Cap_str); /* display capacitor symbol */
Display_ProbeNumber(MaxCap->B); /* display pin #2 */
Display_ProbeNumber(MaxCap->B); /* display pin #2 */
/* show capacitance */
/* show capacitance */
Display_NextLine(); /* move to next line */
Display_NextLine(); /* move to next line */
Display_Value(MaxCap->Value, MaxCap->Scale, 'F');
Display_Value(MaxCap->Value, MaxCap->Scale, 'F');
#if defined (SW_ESR) || defined (SW_OLD_ESR)
#if defined (SW_ESR) || defined (SW_OLD_ESR)
/* show ESR */
/* show ESR */
ESR = MeasureESR(MaxCap); /* measure ESR */
ESR = MeasureESR(MaxCap); /* measure ESR */
if (ESR < UINT16_MAX) /* if successfull */
if (ESR < UINT16_MAX) /* if successfull */
{
{
Display_Space();
Display_Space();
Display_Value(ESR, -2, LCD_CHAR_OMEGA); /* display ESR */
Display_Value(ESR, -2, LCD_CHAR_OMEGA); /* display ESR */
}
}
#ifdef UI_SERIAL_COMMANDS
#ifdef UI_SERIAL_COMMANDS
/* set data for remote commands */
/* set data for remote commands */
Info.Val1 = ESR; /* copy ESR */
Info.Val1 = ESR; /* copy ESR */
#endif
#endif
#endif
#endif
/* show discharge leakage current */
/* show discharge leakage current */
if (MaxCap->I_leak > 0)
if (MaxCap->I_leak > 0)
{
{
Display_NL_EEString_Space(I_leak_str);
Display_NL_EEString_Space(I_leak_str);
Display_Value(MaxCap->I_leak, -8, 'A'); /* in 10nA */
Display_Value(MaxCap->I_leak, -8, 'A'); /* in 10nA */
}
}
#ifdef SW_C_E6_T
#ifdef SW_C_E6_T
/* show E series norm values for E6 20% */
/* show E series norm values for E6 20% */
Show_ENormValues(MaxCap->Value, MaxCap->Scale, E6, 200, 'F');
Show_ENormValues(MaxCap->Value, MaxCap->Scale, E6, 200, 'F');
#endif
#endif
#ifdef SW_C_E12_T
#ifdef SW_C_E12_T
/* show E series norm values for E12 10% */
/* show E series norm values for E12 10% */
Show_ENormValues(MaxCap->Value, MaxCap->Scale, E12, 100, 'F');
Show_ENormValues(MaxCap->Value, MaxCap->Scale, E12, 100, 'F');
#endif
#endif
}
}
/*
/*
* show current (leakage or whatever) of semiconductor
* show current (leakage or whatever) of semiconductor
*
*
* Mapping for Semi structure:
* Mapping for Semi structure:
* - I_value - current
* - I_value - current
* - I_scale - scale for current (10^x)
* - I_scale - scale for current (10^x)
*/
*/
void Show_SemiCurrent(const unsigned char *String)
void Show_SemiCurrent(const unsigned char *String)
{
{
if (CmpValue(Semi.I_value, Semi.I_scale, 50, -9) >= 0) /* show if >=50nA */
if (CmpValue(Semi.I_value, Semi.I_scale, 50, -9) >= 0) /* show if >=50nA */
{
{
Display_NL_EEString_Space(String); /* display: <string> */
Display_NL_EEString_Space(String); /* display: <string> */
Display_Value(Semi.I_value, Semi.I_scale, 'A'); /* display current */
Display_Value(Semi.I_value, Semi.I_scale, 'A'); /* display current */
}
}
}
}
#ifndef UI_SERIAL_COMMANDS
#ifndef UI_SERIAL_COMMANDS
/*
/*
* display capacitance of a diode
* display capacitance of a diode
*
*
* requires:
* requires:
* - pointer to diode structure
* - pointer to diode structure
*/
*/
void Show_Diode_Cap(Diode_Type *Diode)
void Show_Diode_Cap(Diode_Type *Diode)
{
{
/* get capacitance (reversed direction) */
/* get capacitance (reversed direction) */
MeasureCap(Diode->C, Diode->A, 0);
MeasureCap(Diode->C, Diode->A, 0);
/* and show capacitance */
/* and show capacitance */
Display_Value(Caps[0].Value, Caps[0].Scale, 'F');
Display_Value(Caps[0].Value, Caps[0].Scale, 'F');
}
}
#endif
#endif
/*
/*
* show diode
* show diode
*/
*/
void Show_Diode(void)
void Show_Diode(void)
{
{
Diode_Type *D1; /* pointer to diode #1 */
Diode_Type *D1; /* pointer to diode #1 */
Diode_Type *D2 = NULL; /* pointer to diode #2 */
Diode_Type *D2 = NULL; /* pointer to diode #2 */
uint8_t CapFlag = 1; /* flag for capacitance output */
uint8_t CapFlag = 1; /* flag for capacitance output */
uint8_t A = 5; /* ID of common anode */
uint8_t A = 5; /* ID of common anode */
uint8_t C = 5; /* ID of common cothode */
uint8_t C = 5; /* ID of common cothode */
uint8_t R_Pin1 = 5; /* B_E resistor's pin #1 */
uint8_t R_Pin1 = 5; /* B_E resistor's pin #1 */
uint8_t R_Pin2 = 5; /* B_E resistor's pin #2 */
uint8_t R_Pin2 = 5; /* B_E resistor's pin #2 */
uint8_t n; /* counter */
uint8_t n; /* counter */
uint8_t m; /* counter */
uint8_t m; /* counter */
D1 = &Diodes[0]; /* pointer to first diode */
D1 = &Diodes[0]; /* pointer to first diode */
/*
/*
* figure out which diodes to display
* figure out which diodes to display
*/
*/
if (Check.Diodes == 1) /* single diode */
if (Check.Diodes == 1) /* single diode */
{
{
C = D1->C; /* make cathode first pin */
C = D1->C; /* make cathode first pin */
}
}
else if (Check.Diodes == 2) /* two diodes */
else if (Check.Diodes == 2) /* two diodes */
{
{
D2 = D1;
D2 = D1;
D2++; /* pointer to second diode */
D2++; /* pointer to second diode */
if (D1->A == D2->A) /* common anode */
if (D1->A == D2->A) /* common anode */
{
{
A = D1->A; /* save common anode */
A = D1->A; /* save common anode */
/* possible PNP BJT with low value B-E resistor and flyback diode */
/* possible PNP BJT with low value B-E resistor and flyback diode */
R_Pin1 = D1->C;
R_Pin1 = D1->C;
R_Pin2 = D2->C;
R_Pin2 = D2->C;
}
}
else if (D1->C == D2->C) /* common cathode */
else if (D1->C == D2->C) /* common cathode */
{
{
C = D1->C; /* save common cathode */
C = D1->C; /* save common cathode */
/* possible NPN BJT with low value B-E resistor and flyback diode */
/* possible NPN BJT with low value B-E resistor and flyback diode */
R_Pin1 = D1->A;
R_Pin1 = D1->A;
R_Pin2 = D2->A;
R_Pin2 = D2->A;
}
}
else if ((D1->A == D2->C) && (D1->C == D2->A)) /* anti-parallel */
else if ((D1->A == D2->C) && (D1->C == D2->A)) /* anti-parallel */
{
{
A = D1->A; /* anode and cathode */
A = D1->A; /* anode and cathode */
C = A; /* are the same */
C = A; /* are the same */
CapFlag = 0; /* skip capacitance */
CapFlag = 0; /* skip capacitance */
}
}
}
}
else if (Check.Diodes == 3) /* three diodes */
else if (Check.Diodes == 3) /* three diodes */
{
{
/*
/*
* Two diodes in series are detected as a virtual third diode:
* Two diodes in series are detected as a virtual third diode:
* - Check for any possible way the 2 diodes could be connected in series.
* - Check for any possible way the 2 diodes could be connected in series.
* - Only once the cathode of diode #1 matches the anode of diode #2.
* - Only once the cathode of diode #1 matches the anode of diode #2.
*/
*/
for (n = 0; n <= 2; n++) /* loop for first diode */
for (n = 0; n <= 2; n++) /* loop for first diode */
{
{
D1 = &Diodes[n]; /* get pointer of first diode */
D1 = &Diodes[n]; /* get pointer of first diode */
for (m = 0; m <= 2; m++) /* loop for second diode */
for (m = 0; m <= 2; m++) /* loop for second diode */
{
{
D2 = &Diodes[m]; /* get pointer of second diode */
D2 = &Diodes[m]; /* get pointer of second diode */
if (n != m) /* don't check same diode :-) */
if (n != m) /* don't check same diode :-) */
{
{
if (D1->C == D2->A) /* got match */
if (D1->C == D2->A) /* got match */
{
{
n = 5; /* end loops */
n = 5; /* end loops */
m = 5;
m = 5;
}
}
}
}
}
}
}
}
if (n < 5) D2 = NULL; /* no match found */
if (n < 5) D2 = NULL; /* no match found */
C = D1->C; /* cathode of first diode */
C = D1->C; /* cathode of first diode */
A = 3; /* in series mode */
A = 3; /* in series mode */
}
}
else /* too much diodes */
else /* too much diodes */
{
{
Display_EEString(Diode_AC_str); /* display: -|>|- */
Display_EEString(Diode_AC_str); /* display: -|>|- */
Display_Space(); /* display space */
Display_Space(); /* display space */
Display_Char(Check.Diodes + '0'); /* display number of diodes found */
Display_Char(Check.Diodes + '0'); /* display number of diodes found */
#ifdef UI_SERIAL_COMMANDS
#ifdef UI_SERIAL_COMMANDS
/* set data for remote commands */
/* set data for remote commands */
Info.Quantity = Check.Diodes; /* set quantity */
Info.Quantity = Check.Diodes; /* set quantity */
#endif
#endif
return;
return;
}
}
#ifdef UI_SERIAL_COMMANDS
#ifdef UI_SERIAL_COMMANDS
/* set data for remote commands */
/* set data for remote commands */
Info.Comp1 = (void *)D1; /* link first diode */
Info.Comp1 = (void *)D1; /* link first diode */
Info.Comp2 = (void *)D2; /* link second diode */
Info.Comp2 = (void *)D2; /* link second diode */
#endif
#endif
/*
/*
* display pins
* display pins
*/
*/
/* first diode */
/* first diode */
if (A < 3) /* common anode: show C first */
if (A < 3) /* common anode: show C first */
{
{
Display_ProbeNumber(D1->C); /* show C */
Display_ProbeNumber(D1->C); /* show C */
Display_EEString(Diode_CA_str); /* show -|<- */
Display_EEString(Diode_CA_str); /* show -|<- */
Display_ProbeNumber(A); /* show A */
Display_ProbeNumber(A); /* show A */
}
}
else /* common cathode: show A first */
else /* common cathode: show A first */
{
{
Display_ProbeNumber(D1->A); /* show A */
Display_ProbeNumber(D1->A); /* show A */
Display_EEString(Diode_AC_str); /* show ->|- */
Display_EEString(Diode_AC_str); /* show ->|- */
Display_ProbeNumber(C); /* show C */
Display_ProbeNumber(C); /* show C */
}
}
if (D2) /* second diode */
if (D2) /* second diode */
{
{
if (A <= 3) /* common anode or in-series */
if (A <= 3) /* common anode or in-series */
{
{
Display_EEString(Diode_AC_str); /* show ->|- */
Display_EEString(Diode_AC_str); /* show ->|- */
}
}
else /* common cathode */
else /* common cathode */
{
{
Display_EEString(Diode_CA_str); /* show -|<- */
Display_EEString(Diode_CA_str); /* show -|<- */
}
}
if (A == C) /* anti parallel */
if (A == C) /* anti parallel */
{
{
n = D2->A; /* get anode */
n = D2->A; /* get anode */
}
}
else if (A <= 3) /* common anode or in-series */
else if (A <= 3) /* common anode or in-series */
{
{
n = D2->C; /* get cathode */
n = D2->C; /* get cathode */
}
}
else /* common cathode */
else /* common cathode */
{
{
n = D2->A; /* get anode */
n = D2->A; /* get anode */
}
}
Display_ProbeNumber(n); /* display pin */
Display_ProbeNumber(n); /* display pin */
#ifdef UI_SERIAL_COMMANDS
#ifdef UI_SERIAL_COMMANDS
/* set data for remote commands */
/* set data for remote commands */
Info.Quantity = 2; /* got two */
Info.Quantity = 2; /* got two */
#endif
#endif
}
}
/* check for B-E resistor of possible BJT */
/* check for B-E resistor of possible BJT */
if (R_Pin1 < 5) /* possible BJT */
if (R_Pin1 < 5) /* possible BJT */
{
{
/* B-E resistor below 25kOhms */
/* B-E resistor below 25kOhms */
if (CheckSingleResistor(R_Pin1, R_Pin2, 25) == 1)
if (CheckSingleResistor(R_Pin1, R_Pin2, 25) == 1)
{
{
/* show: PNP/NPN? */
/* show: PNP/NPN? */
Display_Space();
Display_Space();
if (A < 3) /* PNP */
if (A < 3) /* PNP */
{
{
Display_EEString(PNP_str);
Display_EEString(PNP_str);
#ifdef UI_SERIAL_COMMANDS
#ifdef UI_SERIAL_COMMANDS
/* set data for remote commands */
/* set data for remote commands */
Info.Flags |= INFO_D_R_BE | INFO_D_BJT_PNP; /* R_BE & PNP */
Info.Flags |= INFO_D_R_BE | INFO_D_BJT_PNP; /* R_BE & PNP */
#endif
#endif
}
}
else /* NPN */
else /* NPN */
{
{
Display_EEString(NPN_str);
Display_EEString(NPN_str);
#ifdef UI_SERIAL_COMMANDS
#ifdef UI_SERIAL_COMMANDS
/* set data for remote commands */
/* set data for remote commands */
Info.Flags |= INFO_D_R_BE | INFO_D_BJT_NPN; /* R_BE & NPN */
Info.Flags |= INFO_D_R_BE | INFO_D_BJT_NPN; /* R_BE & NPN */
#endif
#endif
}
}
Display_Char('?');
Display_Char('?');
Display_NextLine(); /* move to line #2 */
Display_NextLine(); /* move to line #2 */
R_Pin1 += '1'; /* convert pin ID to character */
R_Pin1 += '1'; /* convert pin ID to character */
R_Pin2 += '1';
R_Pin2 += '1';
Show_SingleResistor(R_Pin1, R_Pin2); /* show resistor */
Show_SingleResistor(R_Pin1, R_Pin2); /* show resistor */
CapFlag = 0; /* skip capacitance */
CapFlag = 0; /* skip capacitance */
}
}
}
}
/*
/*
* display:
* display:
* - Uf (forward voltage)
* - Uf (forward voltage)
* - reverse leakage current (for single diodes)
* - reverse leakage current (for single diodes)
* - capacitance (not for anti-parallel diodes)
* - capacitance (not for anti-parallel diodes)
*/
*/
/* display Uf */
/* display Uf */
Display_NL_EEString_Space(Vf_str); /* display: Vf */
Display_NL_EEString_Space(Vf_str); /* display: Vf */
/* first diode */
/* first diode */
Display_Value(D1->V_f, -3, 'V'); /* in mV */
Display_Value(D1->V_f, -3, 'V'); /* in mV */
Display_Space();
Display_Space();
/* display low current Uf and reverse leakage current for a single diode */
/* display low current Uf and reverse leakage current for a single diode */
if (D2 == NULL) /* single diode */
if (D2 == NULL) /* single diode */
{
{
/* display low current Uf if it's quite low (Ge/Schottky diode) */
/* display low current Uf if it's quite low (Ge/Schottky diode) */
if (D1->V_f2 < 250) /* < 250mV */
if (D1->V_f2 < 250) /* < 250mV */
{
{
Display_Char('(');
Display_Char('(');
Display_Value(D1->V_f2, 0, 0); /* no unit */
Display_Value(D1->V_f2, 0, 0); /* no unit */
Display_Char(')');
Display_Char(')');
}
}
/* reverse leakage current */
/* reverse leakage current */
UpdateProbes(D1->C, D1->A, 0); /* reverse diode */
UpdateProbes(D1->C, D1->A, 0); /* reverse diode */
GetLeakageCurrent(1); /* get current */
GetLeakageCurrent(1); /* get current */
Show_SemiCurrent(I_R_str); /* display I_R */
Show_SemiCurrent(I_R_str); /* display I_R */
#ifdef UI_SERIAL_COMMANDS
#ifdef UI_SERIAL_COMMANDS
/* set data for remote commands */
/* set data for remote commands */
Info.Flags |= INFO_D_I_R; /* measured I_R */
Info.Flags |= INFO_D_I_R; /* measured I_R */
#endif
#endif
}
}
else /* two diodes */
else /* two diodes */
{
{
/* show Uf of second diode */
/* show Uf of second diode */
Display_Value(D2->V_f, -3, 'V');
Display_Value(D2->V_f, -3, 'V');
}
}
/* display capacitance */
/* display capacitance */
if (CapFlag == 1) /* if feasable */
if (CapFlag == 1) /* if feasable */
{
{
Display_NL_EEString_Space(DiodeCap_s
Display_NL_EEString_Space(DiodeCap_s
Gespeicherte Diffs
Originaltext
Datei öffnen
/* ************************************************************************ * * main part * * (c) 2012-2020 by Markus Reschke * based on code from Markus Frejek and Karl-Heinz Kübbeler * * ************************************************************************ */ /* * local constants */ /* source management */ #define MAIN_C /* * include header files */ /* local includes */ #include "config.h" /* global configuration */ #include "common.h" /* common header file */ #include "variables.h" /* global variables */ #include "functions.h" /* external functions */ #include "colors.h" /* color definitions */ /* * local variables */ /* program control */ #if CYCLE_MAX < 255 uint8_t MissedParts; /* counter for failed/missed components */ #endif /* ************************************************************************ * output components and errors * ************************************************************************ */ /* * show pinout for semiconductors * * required: * - character for pin A * - character for pin B * - character for pin C */ void Show_SemiPinout(uint8_t A, uint8_t B, uint8_t C) { uint8_t n; /* counter */ uint8_t Char; /* character */ #ifdef SW_PROBE_COLORS uint16_t Color; /* color value */ Color = UI.PenColor; /* save current color */ #endif /* display: 123 */ for (n = 0; n <= 2; n++) { Display_ProbeNumber(n); } /* display: = */ Display_Char('='); /* display pin IDs */ for (n = 0; n <= 2; n++) /* loop through probe pins */ { #ifdef SW_PROBE_COLORS UI.PenColor = ProbeColors[n]; /* set probe color */ #endif if (n == Semi.A) Char = A; /* probe A - ID A */ else if (n == Semi.B) Char = B; /* probe B - ID B */ else Char = C; /* - ID C */ Display_Char(Char); /* display ID */ } #ifdef SW_PROBE_COLORS UI.PenColor = Color; /* restore old color */ #endif } /* * show simple pinout * * required: * - ID: characters for probes 1, 2 and 3 * 0 -> not displayed */ void Show_SimplePinout(uint8_t ID_1, uint8_t ID_2, uint8_t ID_3) { uint8_t n; /* counter */ unsigned char ID[3]; /* component pin IDs */ #ifdef SW_PROBE_COLORS uint16_t Color; /* color value */ Color = UI.PenColor; /* save current color */ #endif /* copy probe pin characters/IDs */ ID[0] = ID_1; ID[1] = ID_2; ID[2] = ID_3; for (n = 0; n <= 2; n++) /* loop through probe pins */ { if (ID[n] != 0) /* display this one */ { Display_ProbeNumber(n); Display_Char(':'); #ifdef SW_PROBE_COLORS UI.PenColor = ProbeColors[n]; /* set probe color */ #endif Display_Char(ID[n]); #ifdef SW_PROBE_COLORS UI.PenColor = Color; /* restore old color */ #endif Display_Space(); } } } #ifdef FUNC_EVALUE /* * show E series norm values * * requires: * - Value: unsigned value * - Scale: exponent/multiplier (* 10^n) * - ESeries: E6-192 * - Tolerance: in 0.1% * - Unit: unit character */ void Show_ENormValues(uint32_t Value, int8_t Scale, uint8_t ESeries, uint8_t Tolerance, unsigned char Unit) { uint8_t n; /* number of norm values (1 or 2) */ uint8_t Pos; /* char x position */ uint8_t Temp; /* temporary value */ /* * get E series norm values * - 1st: Semi.I_value, Semi.I_scale * - 2nd: Semi.C_value, Semi.C_scale */ n = GetENormValue(Value, Scale, ESeries, Tolerance); /* * show E series and tolerance */ Display_NextLine(); /* move to next line */ /* display E series */ Display_Char('E'); /* display: E */ Display_FullValue(ESeries, 0 , 0); /* display E series */ Display_Space(); /* display: " " */ /* display tolerance */ Temp = Tolerance; /* copy tolerance */ Pos = 0; /* reset decimal places */ if (Temp < 10) /* < 1% */ { Pos = 1; /* one decimal place */ } Temp /= 10; /* scale to 1 */ Display_FullValue(Temp, Pos, '%'); /* display tolerance */ Display_Space(); /* display: " " */ /* * show norm values */ if (n) /* got norm value(s) */ { Pos = UI.CharPos_X; /* get current char position */ /* display first norm value */ Display_EValue(Semi.I_value, Semi.I_scale, Unit); if (n == 2) /* got two norm values */ { /* move to next line at same position (after E series) */ Display_NextLine(); LCD_CharPos(Pos, UI.CharPos_Y); /* display second norm value */ Display_EValue(Semi.C_value, Semi.C_scale, Unit); } } else /* no norm value */ { Display_Char('-'); /* display: - */ } } #endif #ifdef FUNC_COLORCODE /* * show E series norm value color-codes * * requires: * - Value: unsigned value * - Scale: exponent/multiplier (* 10^n) * - ESeries: E6-192 * - Tolerance: in 0.1% * - TolBand: color of tolerance band */ void Show_ENormCodes(uint32_t Value, int8_t Scale, uint8_t ESeries, uint8_t Tolerance, uint16_t TolBand) { uint8_t n; /* number of norm values (1 or 2) */ uint8_t Pos; /* char x position */ /* * tolerance band * - resistor * 20% 10% 5% 2% 1% 0.5% 0.25% 0.1% 0.05% * none silver gold red brown green blue violet grey * - inductor * 20% 10% 5% 4% 3% 2% 1% 0.5% 0.25% 0.1% 0.05% * black silver gold yellow orange red brown green blue violet grey * - caps: many different schemas * * multiplier reference * - R: 0 (10^0) -> 1 Ohms * C: -12 (10^-12) -> 1 pF * L: -6 (10^-6) -> 1 µH * - ref_scale as function argument? * scale = scale - ref_scale */ /* * get E series norm values * - 1st: Semi.I_value, Semi.I_scale * - 2nd: Semi.C_value, Semi.C_scale */ n = GetENormValue(Value, Scale, ESeries, Tolerance); /* * show E series */ Display_NextLine(); /* move to next line */ /* display E series */ Display_Char('E'); /* display: E */ Display_FullValue(ESeries, 0 , 0); /* display E series */ Display_Space(); /* display: " " */ /* * show color-codes of norm values */ if (n) /* got norm value(s) */ { Pos = UI.CharPos_X; /* get current char position */ /* display color-code of first norm value */ Display_ColorCode(Semi.I_value, Semi.I_scale, TolBand); if (n == 2) /* got two norm values */ { /* move to next line at same position (after E series) */ Display_NextLine(); LCD_CharPos(Pos, UI.CharPos_Y); /* display color-code of second norm value */ Display_ColorCode(Semi.C_value, Semi.C_scale, TolBand); } } #if 0 /* * color testing */ uint16_t Color; Display_NextLine(); /* first 5 colors plus gold */ n = 0; while (n < 5) { Color = DATA_read_word((uint16_t *)&ColorCode_table[n]); LCD_Band(Color, ALIGN_LEFT); n++; } LCD_Band(COLOR_CODE_GOLD, ALIGN_RIGHT); Display_NextLine(); /* last 5 colors plus silver */ while (n < 10) { Color = DATA_read_word((uint16_t *)&ColorCode_table[n]); LCD_Band(Color, ALIGN_LEFT); n++; } LCD_Band(COLOR_CODE_SILVER, ALIGN_RIGHT); TestKey(0, CURSOR_BLINK); #endif } #endif /* * show failed test */ void Show_Fail(void) { /* display info */ Display_EEString(Failed1_str); /* display: No component */ Display_NL_EEString(Failed2_str); /* display: found! */ #if CYCLE_MAX < 255 MissedParts++; /* increase counter */ #endif } /* * show error */ void Show_Error() { if (Check.Type == TYPE_DISCHARGE) /* discharge failed */ { Display_EEString(DischargeFailed_str); /* display: Battery? */ /* display probe number and remaining voltage */ Display_NextLine(); Display_ProbeNumber(Check.Probe); Display_Char(':'); Display_Space(); Display_Value(Check.U, -3, 'V'); } else if (Check.Type == TYPE_DETECTION) /* detection error */ { /* simply display: No component found! */ Show_Fail(); } } /* * show single (first) resistor * * requires: * - ID1: pin ID #1 character * - ID2: pin ID #2 character */ void Show_SingleResistor(uint8_t ID1, uint8_t ID2) { Resistor_Type *Resistor; /* pointer to resistor */ Resistor = &Resistors[0]; /* pointer to first resistor */ /* show pinout */ Display_Char(ID1); Display_EEString(Resistor_str); Display_Char(ID2); /* show resistance value */ Display_Space(); Display_Value(Resistor->Value, Resistor->Scale, LCD_CHAR_OMEGA); } /* * show resistor(s) */ void Show_Resistor(void) { Resistor_Type *R1; /* pointer to resistor #1 */ Resistor_Type *R2; /* pointer to resistor #2 */ uint8_t Pin; /* ID of common pin */ R1 = &Resistors[0]; /* pointer to first resistor */ if (Check.Resistors == 1) /* single resistor */ { R2 = NULL; /* disable second resistor */ Pin = R1->A; /* make B the first pin */ } else /* multiple resistors */ { R2 = R1; R2++; /* pointer to second resistor */ #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Quantity = 2; /* got two */ #endif if (Check.Resistors == 3) /* three resistors */ { Resistor_Type *Rmax; /* pointer to largest resistor */ /* * 3 resistors mean 2 single resistors and both resistors in series. * So we have to single out that series resistor by finding the * largest resistor. */ Rmax = R1; /* starting point */ for (Pin = 1; Pin <= 2; Pin++) { if (CmpValue(R2->Value, R2->Scale, Rmax->Value, Rmax->Scale) == 1) { Rmax = R2; /* update largest one */ } R2++; /* next one */ } /* get the two smaller resistors */ if (R1 == Rmax) R1++; R2 = R1; R2++; if (R2 == Rmax) R2++; } /* find common pin of both resistors */ if ((R1->A == R2->A) || (R1->A == R2->B)) { Pin = R1->A; /* pin A */ } else { Pin = R1->B; /* pin B */ } } #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Comp1 = (void *)R1; /* link first resistor */ Info.Comp2 = (void *)R2; /* link second resistor */ #endif /* * display the pins */ /* first resistor */ if (R1->A != Pin) /* A is not common pin */ { Display_ProbeNumber(R1->A); /* display pin A */ } else /* single resistor or A is common pin */ { Display_ProbeNumber(R1->B); /* display pin B */ } Display_EEString(Resistor_str); Display_ProbeNumber(Pin); /* display common pin */ if (R2) /* second resistor */ { Display_EEString(Resistor_str); if (R2->A != Pin) /* A is not common pin */ { Display_ProbeNumber(R2->A); /* display pin A */ } else /* A is common pin */ { Display_ProbeNumber(R2->B); /* display pin B */ } } /* * display the values */ /* first resistor */ Display_NextLine(); Display_Value(R1->Value, R1->Scale, LCD_CHAR_OMEGA); if (R2) /* second resistor */ { Display_Space(); Display_Value(R2->Value, R2->Scale, LCD_CHAR_OMEGA); } #ifdef SW_INDUCTOR else /* single resistor */ { /* get inductance and display if relevant */ if (MeasureInductor(R1) == 1) /* inductor */ { Display_Space(); Display_Value(Inductor.Value, Inductor.Scale, 'H'); #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Flags |= INFO_R_L; /* inductance measured */ #endif #ifdef SW_L_E6_T /* show E series norm values for E6 20% */ Show_ENormValues(Inductor.Value, Inductor.Scale, E6, 200, 'H'); #endif #ifdef SW_L_E12_T /* show E series norm values for E12 10% */ Show_ENormValues(Inductor.Value, Inductor.Scale, E12, 100, 'H'); #endif } #ifdef SW_R_EXX else /* no inductance */ { #ifdef SW_R_E24_5_T /* show E series norm values for E24 5% */ Show_ENormValues(R1->Value, R1->Scale, E24, 50, LCD_CHAR_OMEGA); #endif #ifdef SW_R_E24_5_CC /* show E series norm value color-codes for E24 5% */ Show_ENormCodes(R1->Value, R1->Scale, E24, 50, COLOR_CODE_GOLD); #endif #ifdef SW_R_E24_1_T /* show E series norm values for E24 1% */ Show_ENormValues(R1->Value, R1->Scale, E24, 10, LCD_CHAR_OMEGA); #endif #ifdef SW_R_E24_1_CC /* show E series norm value color-codes for E24 1% */ Show_ENormCodes(R1->Value, R1->Scale, E24, 10, COLOR_CODE_BROWN); #endif #ifdef SW_R_E96_T /* show E series norm values for E96 1% */ Show_ENormValues(R1->Value, R1->Scale, E96, 10, LCD_CHAR_OMEGA); #endif #ifdef SW_R_E96_CC /* show E series norm value color-codes for E96 1% */ Show_ENormCodes(R1->Value, R1->Scale, E96, 10, COLOR_CODE_BROWN); #endif } #endif } #elif defined (SW_R_EXX) else /* single resistor */ { #ifdef SW_R_E24_5_T /* show E series norm values for E24 5% */ Show_ENormValues(R1->Value, R1->Scale, E24, 50, LCD_CHAR_OMEGA); #endif #ifdef SW_R_E24_5_CC /* show E series norm value color-codes for E24 5% */ Show_ENormCodes(R1->Value, R1->Scale, E24, 50, COLOR_CODE_GOLD); #endif #ifdef SW_R_E24_1_T /* show E series norm values for E24 1% */ Show_ENormValues(R1->Value, R1->Scale, E24, 10, LCD_CHAR_OMEGA); #endif #ifdef SW_R_E24_1_CC /* show E series norm value color-codes for E24 1% */ Show_ENormCodes(R1->Value, R1->Scale, E24, 10, COLOR_CODE_BROWN); #endif #ifdef SW_R_E96_T /* show E series norm values for E96 1% */ Show_ENormValues(R1->Value, R1->Scale, E96, 10, LCD_CHAR_OMEGA); #endif #ifdef SW_R_E96_CC /* show E series norm value color-codes for E96 1% */ Show_ENormCodes(R1->Value, R1->Scale, E96, 10, COLOR_CODE_BROWN); #endif } #endif } /* * show capacitor */ void Show_Capacitor(void) { Capacitor_Type *MaxCap; /* pointer to largest cap */ Capacitor_Type *Cap; /* pointer to cap */ #if defined (SW_ESR) || defined (SW_OLD_ESR) uint16_t ESR; /* ESR (in 0.01 Ohms) */ #endif uint8_t Counter; /* loop counter */ /* find largest cap */ MaxCap = &Caps[0]; /* pointer to first cap */ Cap = MaxCap; for (Counter = 1; Counter <= 2; Counter++) { Cap++; /* next cap */ if (CmpValue(Cap->Value, Cap->Scale, MaxCap->Value, MaxCap->Scale) == 1) { MaxCap = Cap; } } #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Comp1 = (void *)MaxCap; /* link largest cap */ #endif /* display pinout */ Display_ProbeNumber(MaxCap->A); /* display pin #1 */ Display_EEString(Cap_str); /* display capacitor symbol */ Display_ProbeNumber(MaxCap->B); /* display pin #2 */ /* show capacitance */ Display_NextLine(); /* move to next line */ Display_Value(MaxCap->Value, MaxCap->Scale, 'F'); #if defined (SW_ESR) || defined (SW_OLD_ESR) /* show ESR */ ESR = MeasureESR(MaxCap); /* measure ESR */ if (ESR < UINT16_MAX) /* if successfull */ { Display_Space(); Display_Value(ESR, -2, LCD_CHAR_OMEGA); /* display ESR */ } #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Val1 = ESR; /* copy ESR */ #endif #endif /* show discharge leakage current */ if (MaxCap->I_leak > 0) { Display_NL_EEString_Space(I_leak_str); Display_Value(MaxCap->I_leak, -8, 'A'); /* in 10nA */ } #ifdef SW_C_E6_T /* show E series norm values for E6 20% */ Show_ENormValues(MaxCap->Value, MaxCap->Scale, E6, 200, 'F'); #endif #ifdef SW_C_E12_T /* show E series norm values for E12 10% */ Show_ENormValues(MaxCap->Value, MaxCap->Scale, E12, 100, 'F'); #endif } /* * show current (leakage or whatever) of semiconductor * * Mapping for Semi structure: * - I_value - current * - I_scale - scale for current (10^x) */ void Show_SemiCurrent(const unsigned char *String) { if (CmpValue(Semi.I_value, Semi.I_scale, 50, -9) >= 0) /* show if >=50nA */ { Display_NL_EEString_Space(String); /* display: <string> */ Display_Value(Semi.I_value, Semi.I_scale, 'A'); /* display current */ } } #ifndef UI_SERIAL_COMMANDS /* * display capacitance of a diode * * requires: * - pointer to diode structure */ void Show_Diode_Cap(Diode_Type *Diode) { /* get capacitance (reversed direction) */ MeasureCap(Diode->C, Diode->A, 0); /* and show capacitance */ Display_Value(Caps[0].Value, Caps[0].Scale, 'F'); } #endif /* * show diode */ void Show_Diode(void) { Diode_Type *D1; /* pointer to diode #1 */ Diode_Type *D2 = NULL; /* pointer to diode #2 */ uint8_t CapFlag = 1; /* flag for capacitance output */ uint8_t A = 5; /* ID of common anode */ uint8_t C = 5; /* ID of common cothode */ uint8_t R_Pin1 = 5; /* B_E resistor's pin #1 */ uint8_t R_Pin2 = 5; /* B_E resistor's pin #2 */ uint8_t n; /* counter */ uint8_t m; /* counter */ D1 = &Diodes[0]; /* pointer to first diode */ /* * figure out which diodes to display */ if (Check.Diodes == 1) /* single diode */ { C = D1->C; /* make cathode first pin */ } else if (Check.Diodes == 2) /* two diodes */ { D2 = D1; D2++; /* pointer to second diode */ if (D1->A == D2->A) /* common anode */ { A = D1->A; /* save common anode */ /* possible PNP BJT with low value B-E resistor and flyback diode */ R_Pin1 = D1->C; R_Pin2 = D2->C; } else if (D1->C == D2->C) /* common cathode */ { C = D1->C; /* save common cathode */ /* possible NPN BJT with low value B-E resistor and flyback diode */ R_Pin1 = D1->A; R_Pin2 = D2->A; } else if ((D1->A == D2->C) && (D1->C == D2->A)) /* anti-parallel */ { A = D1->A; /* anode and cathode */ C = A; /* are the same */ CapFlag = 0; /* skip capacitance */ } } else if (Check.Diodes == 3) /* three diodes */ { /* * Two diodes in series are detected as a virtual third diode: * - Check for any possible way the 2 diodes could be connected in series. * - Only once the cathode of diode #1 matches the anode of diode #2. */ for (n = 0; n <= 2; n++) /* loop for first diode */ { D1 = &Diodes[n]; /* get pointer of first diode */ for (m = 0; m <= 2; m++) /* loop for second diode */ { D2 = &Diodes[m]; /* get pointer of second diode */ if (n != m) /* don't check same diode :-) */ { if (D1->C == D2->A) /* got match */ { n = 5; /* end loops */ m = 5; } } } } if (n < 5) D2 = NULL; /* no match found */ C = D1->C; /* cathode of first diode */ A = 3; /* in series mode */ } else /* too much diodes */ { Display_EEString(Diode_AC_str); /* display: -|>|- */ Display_Space(); /* display space */ Display_Char(Check.Diodes + '0'); /* display number of diodes found */ #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Quantity = Check.Diodes; /* set quantity */ #endif return; } #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Comp1 = (void *)D1; /* link first diode */ Info.Comp2 = (void *)D2; /* link second diode */ #endif /* * display pins */ /* first diode */ if (A < 3) /* common anode: show C first */ { Display_ProbeNumber(D1->C); /* show C */ Display_EEString(Diode_CA_str); /* show -|<- */ Display_ProbeNumber(A); /* show A */ } else /* common cathode: show A first */ { Display_ProbeNumber(D1->A); /* show A */ Display_EEString(Diode_AC_str); /* show ->|- */ Display_ProbeNumber(C); /* show C */ } if (D2) /* second diode */ { if (A <= 3) /* common anode or in-series */ { Display_EEString(Diode_AC_str); /* show ->|- */ } else /* common cathode */ { Display_EEString(Diode_CA_str); /* show -|<- */ } if (A == C) /* anti parallel */ { n = D2->A; /* get anode */ } else if (A <= 3) /* common anode or in-series */ { n = D2->C; /* get cathode */ } else /* common cathode */ { n = D2->A; /* get anode */ } Display_ProbeNumber(n); /* display pin */ #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Quantity = 2; /* got two */ #endif } /* check for B-E resistor of possible BJT */ if (R_Pin1 < 5) /* possible BJT */ { /* B-E resistor below 25kOhms */ if (CheckSingleResistor(R_Pin1, R_Pin2, 25) == 1) { /* show: PNP/NPN? */ Display_Space(); if (A < 3) /* PNP */ { Display_EEString(PNP_str); #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Flags |= INFO_D_R_BE | INFO_D_BJT_PNP; /* R_BE & PNP */ #endif } else /* NPN */ { Display_EEString(NPN_str); #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Flags |= INFO_D_R_BE | INFO_D_BJT_NPN; /* R_BE & NPN */ #endif } Display_Char('?'); Display_NextLine(); /* move to line #2 */ R_Pin1 += '1'; /* convert pin ID to character */ R_Pin2 += '1'; Show_SingleResistor(R_Pin1, R_Pin2); /* show resistor */ CapFlag = 0; /* skip capacitance */ } } /* * display: * - Uf (forward voltage) * - reverse leakage current (for single diodes) * - capacitance (not for anti-parallel diodes) */ /* display Uf */ Display_NL_EEString_Space(Vf_str); /* display: Vf */ /* first diode */ Display_Value(D1->V_f, -3, 'V'); /* in mV */ Display_Space(); /* display low current Uf and reverse leakage current for a single diode */ if (D2 == NULL) /* single diode */ { /* display low current Uf if it's quite low (Ge/Schottky diode) */ if (D1->V_f2 < 250) /* < 250mV */ { Display_Char('('); Display_Value(D1->V_f2, 0, 0); /* no unit */ Display_Char(')'); } /* reverse leakage current */ UpdateProbes(D1->C, D1->A, 0); /* reverse diode */ GetLeakageCurrent(1); /* get current */ Show_SemiCurrent(I_R_str); /* display I_R */ #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Flags |= INFO_D_I_R; /* measured I_R */ #endif } else /* two diodes */ { /* show Uf of second diode */ Display_Value(D2->V_f, -3, 'V'); } /* display capacitance */ if (CapFlag == 1) /* if feasable */ { Display_NL_EEString_Space(DiodeCap_str); /* display: C */ #ifndef UI_SERIAL_COMMANDS /* first diode */ Show_Diode_Cap(D1); /* measure & show capacitance */ if (D2) /* second diode */ { Display_Space(); Show_Diode_Cap(D2); /* measure & show capacitance */ } #endif #ifdef UI_SERIAL_COMMANDS /* first diode */ MeasureCap(D1->C, D1->A, 0); /* get capacitance (reversed direction) */ Display_Value(Caps[0].Value, Caps[0].Scale, 'F'); if (D2) /* second diode */ { Display_Space(); MeasureCap(D2->C, D2->A, 1); /* get capacitance (reversed direction) */ Display_Value(Caps[1].Value, Caps[1].Scale, 'F'); } #endif } } /* * show BJT */ void Show_BJT(void) { Diode_Type *Diode; /* pointer to diode */ unsigned char *String; /* string pointer (EEPROM) */ uint8_t BE_A; /* V_BE: pin acting as anode */ uint8_t BE_C; /* V_BE: pin acting as cathode */ uint8_t CE_A; /* flyback diode: pin acting as anode */ uint8_t CE_C; /* flyback diode: pin acting as cathode */ uint8_t CE_Char; /* character */ #ifdef SW_SCHOTTKY_BJT uint8_t BC_A; /* clamping diode: pin acting as anode */ uint8_t BC_C; /* clamping diode: pin acting as cathode */ uint8_t BC_Char; /* character */ #endif uint16_t V_BE = 0; /* V_BE */ int16_t Slope; /* slope of forward voltage */ /* * Mapping for Semi structure: * A - Base pin * B - Collector pin * C - Emitter pin * U_1 - U_BE (mV) (not implemented yet) * U_3 - I_C/I_E (µA) * F_1 - hFE * F_2 - reverse hFE * I_value/I_scale - I_CEO */ /* * preset stuff based on BJT type */ if (Check.Type & TYPE_NPN) /* NPN */ { String = (unsigned char *)NPN_str; /* "NPN" */ /* direction of B-E diode: B -> E */ BE_A = Semi.A; /* anode at base */ BE_C = Semi.C; /* cathode at emitter */ /* direction of optional flyback diode */ CE_A = Semi.C; /* anode at emitter */ CE_C = Semi.B; /* cathode at collector */ CE_Char = LCD_CHAR_DIODE_CA; /* |<| */ #ifdef SW_SCHOTTKY_BJT /* direction of B-C diode: B -> C */ BC_A = Semi.A; /* anode at base */ BC_C = Semi.B; /* cathode at collector */ BC_Char = LCD_CHAR_DIODE_AC; /* |>| */ #endif } else /* PNP */ { String = (unsigned char *)PNP_str; /* "PNP" */ /* direction of B-E diode: E -> B */ BE_A = Semi.C; /* anode at emitter */ BE_C = Semi.A; /* cathode at base */ /* direction of optional flyback diode */ CE_A = Semi.B; /* anode at collector */ CE_C = Semi.C; /* cathode at emitter */ CE_Char = LCD_CHAR_DIODE_AC; /* |>| */ #ifdef SW_SCHOTTKY_BJT /* direction of B-C diode: C -> B */ BC_A = Semi.B; /* anode at collector */ BC_C = Semi.A; /* cathode at base */ BC_Char = LCD_CHAR_DIODE_CA; /* |<| */ #endif } /* * display type */ Display_EEString_Space(BJT_str); /* display: BJT */ Display_EEString(String); /* display: NPN / PNP */ /* parasitic BJT (freewheeling diode on same substrate) */ if (Check.Type & TYPE_PARASITIC) { Display_Char('+'); /* display: + */ } Display_NextLine(); /* next line (#2) */ /* * display pinout */ Show_SemiPinout('B', 'C', 'E'); /* optional freewheeling diode */ Diode = SearchDiode(CE_A, CE_C); /* search for matching diode */ if (Diode != NULL) /* got it */ { Display_Space(); /* display space */ Display_Char('C'); /* display: collector */ Display_Char(CE_Char); /* display diode symbol */ Display_Char('E'); /* display: emitter */ #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Flags |= INFO_BJT_D_FB; /* found flyback diode */ Info.Comp1 = Diode; /* link diode */ #endif } /* * display B-E resistor if detected */ /* check for B-E resistor below 25kOhms */ if (CheckSingleResistor(BE_C, BE_A, 25) == 1) /* found B-E resistor */ { Display_NextLine(); /* next line (#3) */ Show_SingleResistor('B', 'E'); /* B-E resistor renders hFE and V_BE measurements useless */ #ifdef SW_SYMBOLS UI.SymbolLine = 4; /* display fancy pinout in line #4 */ #endif #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Flags |= INFO_BJT_R_BE; /* R_BE */ #endif } /* * display h_FE */ /* display h_FE */ Display_NL_EEString_Space(h_FE_str); /* display: hFE */ Display_Value(Semi.F_1, 0, 0); /* display h_FE */ /* display hFE test circuit type */ Display_Space(); if (Semi.Flags & HFE_COMMON_EMITTER) /* common emitter */ { /* common emitter circuit */ Display_Char('e'); /* display: e */ } else if (Semi.Flags & HFE_COMMON_COLLECTOR) /* common collector */ { /* common collector circuit */ Display_Char('c'); /* display: c */ } #ifdef SW_HFE_CURRENT /* display test current for hFE measurement */ Display_NL_EEString(I_str); /* display: I_ */ if (Semi.Flags & HFE_COMMON_EMITTER) /* common emitter */ { /* I_C */ Display_Char('C'); /* display: C */ } else if (Semi.Flags & HFE_COMMON_COLLECTOR) /* common collector */ { /* I_E */ Display_Char('E'); /* display: E */ } Display_Space(); Display_SignedValue(Semi.U_3, -6, 'A'); /* display I_C/I_E */ #endif #ifdef SW_REVERSE_HFE /* display reverse hFE */ if (Diode == NULL) /* no freewheeling diode */ { if (Semi.F_2 > 0) /* valid value */ { Display_NL_EEString_Space(h_FE_r_str); /* display: hFEr */ Display_Value(Semi.F_2, 0, 0); /* display reverse h_FE */ } } #endif /* * display V_BE * (taken from diode's forward voltage) */ Diode = SearchDiode(BE_A, BE_C); /* search for matching B-E diode */ if (Diode != NULL) /* found diode */ { Display_NL_EEString_Space(V_BE_str); /* display: Vbe */ /* * V_f is quite linear for a logarithmicly scaled I_b. * So we may interpolate the V_f values of low and high test current * measurements for a virtual test current. Low test current is 10µA * and high test current is 7mA. That's a logarithmic scale of * 3 decades. */ /* calculate slope for one decade */ Slope = Diode->V_f - Diode->V_f2; Slope /= 3; /* select V_BE based on hFE */ if (Semi.F_1 < 100) /* low h_FE */ { /* * BJTs with low hFE are power transistors and need a large I_b * to drive the load. So we simply take Vf of the high test current * measurement (7mA). */ V_BE = Diode->V_f; } else if (Semi.F_1 < 250) /* mid-range h_FE */ { /* * BJTs with a mid-range hFE are signal transistors and need * a small I_b to drive the load. So we interpolate Vf for * a virtual test current of about 1mA. */ V_BE = Diode->V_f - Slope; } else /* high h_FE */ { /* * BJTs with a high hFE are small signal transistors and need * only a very small I_b to drive the load. So we interpolate Vf * for a virtual test current of about 0.1mA. */ V_BE = Diode->V_f2 + Slope; } Display_Value(V_BE, -3, 'V'); /* in mV */ #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Val1 = V_BE; /* copy V_BE */ #endif } /* I_CEO: collector emitter open current (leakage) */ Show_SemiCurrent(I_CEO_str); /* display I_CEO */ #ifdef SW_SCHOTTKY_BJT /* * Schottky transistor / Schottky-clamped BJT * - V_BC of a Germanium BJT is as low as V_f of a Schottky diode. * So we check only Silicon BJTs. */ /* check for Si BJT */ if (V_BE > 500) /* V_BE > 500mV */ { Diode = SearchDiode(BC_A, BC_C); /* search for matching diode */ if (Diode != NULL) /* found diode */ { /* check for Schottky diode */ if (Diode->V_f < 450) /* V_f < 450mV */ { Display_NextLine(); /* next line */ /* display diode */ Display_Char('B'); /* display: base */ Display_Char(BC_Char); /* display diode symbol */ Display_Char('C'); /* display: collector */ /* display diode's V_f */ Display_Space(); /* display space */ Display_Value(Diode->V_f, -3, 'V'); /* display V_f */ #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Flags |= INFO_BJT_SCHOTTKY; /* Schottky-clamped BJT */ // Info.Comp2 = Diode; /* link diode */ #endif } } } #endif } /* * show MOSFET/IGBT extras * - diode * - V_th * - Cgs */ void Show_FET_Extras(void) { Diode_Type *Diode; /* pointer to diode */ uint8_t Anode; /* anode of diode */ uint8_t Cathode; /* cathode of diode */ uint8_t Char_1; /* pin name */ uint8_t Char_2; /* pin name */ uint8_t Symbol; /* diode symbol */ /* * Mapping for Semi structure: * A - Gate pin * B - Drain pin * C - Source pin * U_1 - R_DS_on (0.01 Ohms) * U_2 - V_th (mV) */ /* * show instrinsic/freewheeling diode */ if (Check.Type & TYPE_N_CHANNEL) /* n-channel/NPN */ { Anode = Semi.C; /* source/emitter */ Cathode = Semi.B; /* drain/collector */ Symbol = LCD_CHAR_DIODE_CA; /* |<| */ } else /* p-channel/PNP */ { Anode = Semi.B; /* drain/collector */ Cathode = Semi.C; /* source/emitter */ Symbol = LCD_CHAR_DIODE_AC; /* |>| */ } if (Check.Found == COMP_FET) /* FET */ { Char_1 = 'D'; Char_2 = 'S'; } else /* IGBT */ { Char_1 = 'C'; Char_2 = 'E'; } /* search for matching diode */ Diode = SearchDiode(Anode, Cathode); if (Diode != NULL) /* got it */ { /* show diode */ Display_Space(); /* space */ Display_Char(Char_1); /* left pin name */ Display_Char(Symbol); /* diode symbol */ Display_Char(Char_2); /* right pin name */ #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Flags |= INFO_FET_D_FB; /* found flyback diode */ Info.Comp1 = Diode; /* link diode */ #endif } /* skip remaining stuff for depletion-mode FETs/IGBTs */ if (Check.Type & TYPE_DEPLETION) return; /* gate threshold voltage V_th */ if (Semi.U_2 != 0) { Display_NL_EEString_Space(Vth_str); /* display: Vth */ Display_SignedValue(Semi.U_2, -3, 'V'); /* display V_th in mV */ #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Flags |= INFO_FET_V_TH; /* measured Vth */ #endif } /* display gate-source capacitance C_GS */ /* todo: display "Cge" for IGBT? */ Display_NL_EEString_Space(Cgs_str); /* display: Cgs */ Display_Value(Semi.C_value, Semi.C_scale, 'F'); /* display value and unit */ #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Flags |= INFO_FET_C_GS; /* measured C_GS */ #endif /* display R_DS_on, if available */ if (Semi.U_1 > 0) { Display_NL_EEString_Space(R_DS_str); /* display: Rds */ Display_Value(Semi.U_1, -2, LCD_CHAR_OMEGA); /* display value */ #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Flags |= INFO_FET_R_DS; /* measured R_DS */ #endif } /* display V_f of diode, if available */ if (Diode != NULL) { Display_NL_EEString_Space(Vf_str); /* display: Vf */ Display_Value(Diode->V_f, -3, 'V'); /* display value */ } } /* * show FET/IGBT channel type */ void Show_FET_Channel(void) { Display_Space(); /* display space */ /* channel type */ if (Check.Type & TYPE_N_CHANNEL) /* n-channel */ { Display_Char('N'); /* display: N */ } else /* p-channel */ { Display_Char('P'); /* display: P */ } Display_EEString(Channel_str); /* display: -ch */ } /* * show FET/IGBT mode */ void Show_FET_Mode(void) { Display_Space(); /* display space */ if (Check.Type & TYPE_ENHANCEMENT) /* enhancement mode */ { Display_EEString(Enhancement_str); /* display: enh. */ } else /* depletion mode */ { Display_EEString(Depletion_str); /* display: dep. */ } } /* * show FET (MOSFET & JFET) */ void Show_FET(void) { /* * Mapping for Semi structure: * A - Gate pin * B - Drain pin * C - Source pin * U_1 - R_DS_on (0.01 Ohms) * U_2 - V_th (mV) * U_3 - V_GS(off) (mV) */ /* display type */ if (Check.Type & TYPE_MOSFET) /* MOSFET */ { Display_EEString(MOS_str); /* display: MOS */ } else /* JFET */ { Display_Char('J'); /* display: J */ } Display_EEString(FET_str); /* display: FET */ /* display channel type */ Show_FET_Channel(); /* display mode for MOSFETs*/ if (Check.Type & TYPE_MOSFET) Show_FET_Mode(); /* pinout */ Display_NextLine(); /* next line (#2) */ if (Check.Type & TYPE_SYMMETRICAL) /* symmetrical Drain and Source */ { /* we can't distinguish D and S */ Show_SemiPinout('G', 'x', 'x'); /* show pinout */ } else /* unsymmetrical Drain and Source */ { Show_SemiPinout('G', 'D', 'S'); /* show pinout */ } /* show body diode, V_th and Cgs for MOSFETs */ if (Check.Type & TYPE_MOSFET) Show_FET_Extras(); /* show I_DSS and V_GS(off) for depletion mode FET */ if (Check.Type & TYPE_DEPLETION) { /* I_DSS */ Show_SemiCurrent(I_DSS_str); /* display Idss */ /* V_GS(off) */ if (Semi.U_3 != 0) /* valid value */ { Display_NL_EEString_Space(V_GSoff_str); /* display: V_GS(off) */ #ifdef SW_SYMBOLS /* we need some space for the symbol: move value to next line */ Display_NextLine(); Display_Space(); #endif Display_SignedValue(Semi.U_3, -3, 'V'); /* display V_GS(off) in mV */ } } } /* * show IGBT */ void Show_IGBT(void) { /* * Mapping for Semi structure: * A - Gate pin * B - Collector pin * C - Emitter pin * U_2 - V_th (mV) */ Display_EEString(IGBT_str); /* display: IGBT */ Show_FET_Channel(); /* display channel type */ Show_FET_Mode(); /* display mode */ Display_NextLine(); /* next line (#2) */ Show_SemiPinout('G', 'C', 'E'); /* show pinout */ Show_FET_Extras(); /* show diode, V_th and C_GE */ } /* * show Thyristor and TRIAC */ void Show_ThyristorTriac(void) { /* * Mapping for Semi structure: * SCR TRIAC * A - Gate Gate * B - Anode MT2 * C - Cathode MT1 * U_1 - V_GT (mV) */ /* display component type any pinout */ if (Check.Found == COMP_THYRISTOR) /* SCR */ { Display_EEString(Thyristor_str); /* display: thyristor */ Display_NextLine(); /* next line (#2) */ Show_SemiPinout('G', 'A', 'C'); /* display pinout */ } else /* TRIAC */ { Display_EEString(Triac_str); /* display: TRIAC */ Display_NextLine(); /* next line (#2) */ Show_SemiPinout('G', '2', '1'); /* display pinout */ } /* show V_GT (gate trigger voltage) */ if (Semi.U_1 > 0) /* show if not zero */ { Display_NL_EEString_Space(V_GT_str); /* display: V_GT */ Display_Value(Semi.U_1, -3, 'V'); /* display V_GT in mV */ } } /* * show PUT */ void Show_PUT(void) { /* * Mapping for AltSemi structure: * A - Gate * B - Anode * C - Cathode * U_1 - V_f * U_2 - V_T * * Mapping for Semi structure: * A - Gate * B - Anode * C - Cathode */ Display_EEString(PUT_str); /* display: PUT */ Display_NextLine(); /* move to line #2 */ Show_SemiPinout('G', 'A', 'C'); /* display pinout */ /* display V_T */ Display_NL_EEString_Space(V_T_str); /* display: VT */ Display_Value(AltSemi.U_2, -3, 'V'); /* display V_T */ /* display V_f */ Display_NL_EEString_Space(Vf_str); /* display: Vf */ Display_Value(AltSemi.U_1, -3, 'V'); /* display V_f */ } #ifdef SW_UJT /* * show UJT */ void Show_UJT(void) { /* * Mapping for AltSemi structure: * A - Emitter * B - B2 * C - B1 + * Mapping for Semi structure: * A - Gate * B - Anode * C - Cathode */ Display_EEString(UJT_str); /* display: UJT */ Display_NextLine(); /* next line (#2) */ Show_SemiPinout('E', '2', '1'); /* display pinout */ /* display r_BB */ Display_NL_EEString_Space(R_BB_str); /* display: R_BB */ Display_Value(Resistors[0].Value, Resistors[0].Scale, LCD_CHAR_OMEGA); } #endif /* ************************************************************************ * voltage reference * ************************************************************************ */ /* * manage voltage references */ void CheckVoltageRefs(void) { #ifdef HW_REF25 uint16_t U_Ref; /* reference voltage */ uint32_t Temp; /* temporary value */ #endif /* * external 2.5V voltage reference */ #ifdef HW_REF25 Cfg.Samples = 200; /* perform 200 ADC samples for high accuracy */ U_Ref = ReadU(TP_REF); /* read voltage of reference (mV) */ /* check for valid voltage range */ if ((U_Ref > 2250) && (U_Ref < 2750)) /* voltage is fine */ { /* adjust Vcc (assuming 2.495V typically) */ Temp = ((uint32_t)Cfg.Vcc * UREF_25) / U_Ref; Cfg.Vcc = (uint16_t)Temp; Cfg.OP_Mode |= OP_EXT_REF; /* set flag */ } else /* voltage out of range */ { Cfg.OP_Mode &= ~OP_EXT_REF; /* clear flag */ } #endif /* * internal 1.1V bandgap reference */ Cfg.Bandgap = ReadU(ADC_CHAN_BANDGAP); /* dummy read for bandgap stabilization */ Cfg.Samples = 200; /* perform 200 ADC samples for high accuracy */ Cfg.Bandgap = ReadU(ADC_CHAN_BANDGAP); /* get voltage of bandgap reference (mV) */ Cfg.Bandgap += NV.RefOffset; /* add voltage offset */ /* clean up */ Cfg.Samples = ADC_SAMPLES; /* set ADC samples back to default */ } /* ************************************************************************ * power control and monitoring * ************************************************************************ */ /* * power off */ void PowerOff(void) { /* display feedback (otherwise the user will wait :) */ LCD_Clear(); #ifdef LCD_COLOR UI.PenColor = COLOR_TITLE; /* set pen color */ #endif Display_EEString(Bye_str); /* display: Bye! */ cli(); /* disable interrupts */ wdt_disable(); /* disable watchdog */ #ifdef POWER_SWITCH_SOFT POWER_PORT &= ~(1 << POWER_CTRL); /* power off myself */ #endif /* * As long as the user keeps the test button pressed the MCU is still * powered. Therefor we make sure that nothing happens by forcing the * MCU to sleep which also saves power. Same for a classic power switch. */ set_sleep_mode(SLEEP_MODE_PWR_DOWN); /* set sleep mode to "power down" */ sleep_mode(); /* enter sleep mode */ } #ifndef BAT_NONE /* * display battery status * - uses voltage stored in Cfg.Vbat */ void ShowBattery(void) { /* display battery voltage */ Display_EEString_Space(Battery_str); /* display: Bat. */ #ifdef BAT_EXT_UNMONITORED /* check for unmonitored external power supply */ if (Cfg.Vbat < 900) /* < 0.9V */ { /* powered by unmonitored external PSU */ /* low voltage caused by diode's leakage current */ /* display status */ #ifdef LCD_COLOR UI.PenColor = COLOR_GREEN; /* use green */ #endif Display_EEString(External_str); /* display: ext */ } else /* battery operation */ { /* powered by battery */ #endif /* display battery voltage */ Display_Value(Cfg.Vbat / 10, -2, 'V'); Display_Space(); /* display status */ if (Cfg.Vbat < BAT_LOW) /* low level reached */ { #ifdef LCD_COLOR UI.PenColor = COLOR_RED; /* use red */ #endif Display_EEString(Low_str); /* display: low */ } else if (Cfg.Vbat < BAT_WEAK) /* warning level reached */ { #ifdef LCD_COLOR UI.PenColor = COLOR_YELLOW; /* use yellow */ #endif Display_EEString(Weak_str); /* display: weak */ } else /* ok */ { #ifdef LCD_COLOR UI.PenColor = COLOR_GREEN; /* use green */ #endif Display_EEString(OK_str); /* display: ok */ } #ifdef BAT_EXT_UNMONITORED } #endif #ifdef LCD_COLOR UI.PenColor = COLOR_PEN; /* set color back to default */ #endif } /* * check battery * - store battery voltage in Cfg.Vbat * - power off in case of a low battery */ void CheckBattery(void) { uint16_t U_Bat; /* battery voltage */ /* get current battery voltage */ U_Bat = ReadU(TP_BAT); /* read voltage (mV) */ #ifdef BAT_DIVIDER uint32_t Temp; /* temporary value */ /* * ADC pin is connected to a voltage divider (top: R1 / bottom: R2). * - U2 = (Uin / (R1 + R2)) * R2 * - Uin = (U2 * (R1 + R2)) / R2 */ Temp = (((uint32_t)(BAT_R1 + BAT_R2) * 1000) / BAT_R2); /* factor (0.001) */ Temp *= U_Bat; /* Uin (0.001 mV) */ Temp /= 1000; /* Uin (mV) */ U_Bat = (uint16_t)Temp; #endif U_Bat += BAT_OFFSET; /* add offset for voltage drop */ Cfg.Vbat = U_Bat; /* save battery voltage */ Cfg.BatTimer = 100; /* reset timer for next battery check (in 100ms) */ /* about 10s */ /* check for low-voltage situation */ if (U_Bat < BAT_LOW) /* low level reached */ { #ifdef BAT_EXT_UNMONITORED /* not for unmonitored external power supply */ if (U_Bat >= 900) /* >= 0.9V */ { /* battery operation */ #endif LCD_Clear(); /* clear display */ ShowBattery(); /* display battery status */ MilliSleep(3000); /* let user read info */ PowerOff(); /* power off */ #ifdef BAT_EXT_UNMONITORED } #endif } } #endif /* ************************************************************************ * the one and only main() * ************************************************************************ */ /* * main function */ int main(void) { uint8_t Test; /* test value */ uint8_t Key; /* user feedback */ /* * init hardware */ #ifdef POWER_SWITCH_SOFT /* switch on power to keep me alive */ POWER_DDR = (1 << POWER_CTRL); /* set pin as output */ POWER_PORT = (1 << POWER_CTRL); /* set pin to drive power management transistor */ #endif /* set up MCU */ MCUCR = (1 << PUD); /* disable pull-up resistors globally */ ADCSRA = (1 << ADEN) | ADC_CLOCK_DIV; /* enable ADC and set clock divider */ #ifdef HW_DISCHARGE_RELAY /* init discharge relay (safe mode): short circuit probes */ /* ADC_PORT should be 0 */ ADC_DDR = (1 << TP_REF); /* disable relay */ #endif /* catch watchdog */ Test = (MCUSR & (1 << WDRF)); /* save watchdog flag */ MCUSR &= ~(1 << WDRF); /* reset watchdog flag */ wdt_disable(); /* disable watchdog */ /* * set important default values */ #if defined (UI_AUTOHOLD) || defined (UI_SERIAL_COMMANDS) /* reset mode/state flags and set auto-hold mode */ Cfg.OP_Mode = OP_AUTOHOLD; /* set auto-hold */ #else /* reset mode/state flags and set continuous mode */ Cfg.OP_Mode = OP_NONE; /* none = continuous */ #endif Cfg.OP_Control = OP_OUT_LCD; /* reset control/signal flags */ /* enable output to display */ #ifdef SAVE_POWER Cfg.SleepMode = SLEEP_MODE_PWR_SAVE; /* sleep mode: power save */ #endif /* we have to keep Timer2 running */ /* * set up busses and interfaces */ /* test push button */ /* set to input by default */ #ifdef HW_SERIAL /* hardware or bitbang USART */ Serial_Setup(); /* set up TTL serial interface */ #endif #ifdef HW_I2C /* hardware or bitbang I2C */ I2C_Setup(); /* set up I2C bus */ #endif #ifdef HW_SPI /* hardware or bitbang SPI */ SPI_Setup(); /* set up SPI bus */ #endif /* display module */ LCD_BusSetup(); /* set up display bus */ /* touch screen */ #ifdef HW_TOUCH Touch_BusSetup(); /* set up touch screen */ #endif #ifdef ONEWIRE_IO_PIN /* OneWire with dedicated IO pin */ OneWire_Setup(); /* set up OneWire bus */ #endif /* * watchdog was triggered (timeout 2s) * - This is after the MCU done a reset driven by the watchdog. * - Does only work if the capacitor at the base of the power management * transistor is large enough to survive a MCU reset. Otherwise the * tester simply loses power. */ if (Test) { /* Display was initialized before but some global variables in the driver might be zeroed. Drivers with line tracking won't clear screen. */ LCD_Clear(); /* clear display */ #ifdef LCD_COLOR UI.PenColor = COLOR_TITLE; /* set pen color */ #endif Display_EEString(Timeout_str); /* display: timeout */ Display_NL_EEString(Error_str); /* display: error */ MilliSleep(2000); /* give user some time to read */ #ifdef POWER_SWITCH_SOFT POWER_PORT &= ~(1 << POWER_CTRL); /* power off myself */ #elif defined (POWER_SWITCH_MANUAL) /* enter sleep mode to prevent any further action */ /* user should power off tester */ set_sleep_mode(SLEEP_MODE_PWR_DOWN); /* set sleep mode to "power down" */ sleep_mode(); /* enter sleep mode */ #endif return 0; /* exit program */ } /* * operation mode selection * - short key press -> continuous mode * - long key press -> auto-hold mode * - very long key press -> reset to defaults */ Key = 0; /* reset key press type */ /* catch key press */ if (!(BUTTON_PIN & (1 << TEST_BUTTON))) /* test button pressed */ { Test = 0; /* ticks counter */ while (Key == 0) /* loop until we got a type */ { MilliSleep(20); /* wait 20ms */ if (!(BUTTON_PIN & (1 << TEST_BUTTON))) /* button still pressed */ { Test++; /* increase counter */ if (Test > 100) Key = 3; /* >2000ms */ } else /* button released */ { Key = 1; /* <300ms */ if (Test > 15) Key = 2; /* >300ms */ } } } #ifndef UI_SERIAL_COMMANDS /* key press >300ms selects alternative operation mode */ if (Key > 1) { #ifdef UI_AUTOHOLD /* change mode to continuous */ Cfg.OP_Mode &= ~OP_AUTOHOLD; /* clear auto-hold */ #else /* change mode to auto-hold */ Cfg.OP_Mode |= OP_AUTOHOLD; /* set auto-hold */ #endif } #endif #ifdef POWER_OFF_TIMEOUT /* automatic power-off for auto-hold mode */ if (Cfg.OP_Mode & OP_AUTOHOLD) /* in auto-hold mode */ { Cfg.OP_Control |= OP_PWR_TIMEOUT; /* enable power-off timeout */ } #endif /* * init display module */ #ifdef SW_DISPLAY_ID Cfg.DisplayID = 0; /* reset display ID */ #endif LCD_Init(); /* initialize LCD */ UI.LineMode = LINE_STD; /* reset next-line mode */ #ifdef LCD_COLOR UI.PenColor = COLOR_TITLE; /* set pen color */ #endif #ifdef HW_TOUCH Touch_Init(); /* init touch screen */ #endif /* * load saved adjustment offsets and values */ if (Key == 3) /* key press >2s resets to defaults */ { SetAdjustmentDefaults(); /* set default values */ } else /* normal mode */ { /* load adjustment values: profile #1 */ ManageAdjustmentStorage(STORAGE_LOAD, 1); } /* set extra stuff */ #ifdef SW_CONTRAST LCD_Contrast(NV.Contrast); /* set LCD contrast */ #endif /* * welcome user */ #ifdef UI_SERIAL_COPY Display_Serial_On(); /* enable serial output & NL */ #endif Display_EEString(Tester_str); /* display: Component Tester */ Display_NL_EEString(Version_str); /* display firmware version */ #ifdef SW_DISPLAY_ID /* show ID of display controller */ Display_Space(); /* display space */ Display_HexValue(Cfg.DisplayID, 16); /* display ID */ #endif #ifdef UI_SERIAL_COPY Display_Serial_Off(); /* disable serial output & NL */ #endif #ifdef LCD_COLOR UI.PenColor = COLOR_PEN; /* set pen color */ #endif MilliSleep(1500); /* let the user read the display */ /* * init variables */ /* cycling */ #if CYCLE_MAX < 255 MissedParts = 0; /* reset counter */ #endif Key = KEY_POWER_ON; /* just powered on */ /* default offsets and values */ Cfg.Samples = ADC_SAMPLES; /* number of ADC samples */ Cfg.AutoScale = 1; /* enable ADC auto scaling */ Cfg.Ref = 1; /* no ADC reference set yet */ Cfg.Vcc = UREF_VCC; /* voltage of Vcc */ /* MCU */ wdt_enable(WDTO_2S); /* enable watchdog: timeout 2s */ /* * user interaction after power-on */ #ifdef HW_TOUCH /* adjust touch screen if not done yet */ if ((Touch.X_Start == 0) && (Touch.X_Stop == 0)) /* defaults */ { Test = Touch_Adjust(); /* adjust touch screen */ if (Test == 0) /* error */ { LCD_ClearLine2(); Display_EEString(Error_str); /* display: Error */ MilliSleep(1000); /* smooth UI */ TestKey(2500, CURSOR_BLINK | CHECK_OP_MODE | CHECK_BAT); } } #endif #ifdef UI_CHOOSE_PROFILE /* select adjustment profile */ AdjustmentMenu(STORAGE_LOAD | STORAGE_SHORT); #endif /* * interrupts */ sei(); /* enable interrupts */ /* * main processing loop (probing cycle) */ cycle_start: /* reset variables */ Check.Found = COMP_NONE; /* no component */ Check.Type = 0; /* reset type flags */ Check.Done = DONE_NONE; /* no transistor */ Check.AltFound = COMP_NONE; /* no alternative component */ Check.Diodes = 0; /* reset diode counter */ Check.Resistors = 0; /* reset resistor counter */ Semi.Flags = 0; /* reset flags */ Semi.U_1 = 0; /* reset values */ Semi.U_2 = 0; Semi.U_3 = 0; Semi.F_1 = 0; #ifdef SW_REVERSE_HFE Semi.F_2 = 0; #endif Semi.I_value = 0; AltSemi.U_1 = 0; AltSemi.U_2 = 0; #ifdef UI_SERIAL_COMMANDS Info.Quantity = 0; /* zero components */ Info.Selected = 1; /* select first component */ Info.Flags = INFO_NONE; /* reset flags */ Info.Comp1 = NULL; /* reset pointer to first component */ Info.Comp2 = NULL; /* reset pointer to second component */ #endif #ifdef HW_KEYS UI.KeyOld = KEY_NONE; /* no key */ UI.KeyStepOld = 1; /* step size 1 */ #endif #ifdef SW_SYMBOLS UI.SymbolLine = 3; /* default: line #3 */ #endif /* reset hardware */ ADC_DDR = 0; /* set all pins of ADC port as input */ #ifdef HW_DISCHARGE_RELAY /* * This also enables the discharge relay via the external reference * and removes the short circuit. */ #endif UI.LineMode = LINE_KEEP; /* next-line mode: keep first line */ LCD_Clear(); /* clear LCD */ /* * voltage references */ CheckVoltageRefs(); /* manage voltage references */ /* * battery check */ #ifdef BAT_NONE /* no battery monitoring */ Display_EEString(Tester_str); /* display: Component Tester */ #else /* battery monitoring */ CheckBattery(); /* check battery voltage */ /* will power off on low battery */ ShowBattery(); /* display battery status */ #endif /* * probing */ #ifdef UI_SERIAL_COMMANDS /* skip first probing after power-on */ if (Key == KEY_POWER_ON) /* first cycle */ { goto cycle_control; /* skip probing */ /* will also change Key */ } #endif /* display start of probing */ Display_NL_EEString(Probing_str); /* display: probing... */ /* try to discharge any connected component */ DischargeProbes(); if (Check.Found == COMP_ERROR) /* discharge failed */ { goto show_component; /* skip all other checks */ } #ifdef UI_SHORT_CIRCUIT_MENU /* enter main menu if requested by short-circuiting all probes */ if (ShortedProbes() == 3) /* all probes short-circuited */ { Key = KEY_MAINMENU; /* trigger main menu */ goto cycle_action; /* perform action */ } #endif /* check all 6 combinations of the 3 probes */ CheckProbes(PROBE_1, PROBE_2, PROBE_3); CheckProbes(PROBE_2, PROBE_1, PROBE_3); CheckProbes(PROBE_1, PROBE_3, PROBE_2); CheckProbes(PROBE_3, PROBE_1, PROBE_2); CheckProbes(PROBE_2, PROBE_3, PROBE_1); CheckProbes(PROBE_3, PROBE_2, PROBE_1); CheckAlternatives(); /* process alternatives */ /* if component might be a capacitor */ if ((Check.Found == COMP_NONE) || (Check.Found == COMP_RESISTOR)) { /* tell user to be patient with large caps :-) */ Display_Space(); Display_Char('C'); /* check all possible combinations */ MeasureCap(PROBE_3, PROBE_1, 0); MeasureCap(PROBE_3, PROBE_2, 1); MeasureCap(PROBE_2, PROBE_1, 2); } /* * output test results */ show_component: LCD_Clear(); /* clear LCD */ /* next-line mode */ Test = LINE_KEEP | LINE_KEY; /* keep first line and wait for key/timeout */ #ifdef UI_SERIAL_COMMANDS if (Key == KEY_PROBE) /* probing by command */ { Test = LINE_KEEP; /* don't wait for key/timeout */ } #endif UI.LineMode = Test; /* change mode */ #ifdef UI_SERIAL_COPY Display_Serial_On(); /* enable serial output & NL */ #endif #ifdef UI_SERIAL_COMMANDS if (Check.Found >= COMP_RESISTOR) { Info.Quantity = 1; /* got one at least */ } #endif /* call output function based on component type */ switch (Check.Found) { case COMP_ERROR: Show_Error(); break; case COMP_DIODE: Show_Diode(); break; case COMP_BJT: Show_BJT(); break; case COMP_FET: Show_FET(); break; case COMP_IGBT: Show_IGBT(); break; case COMP_THYRISTOR: Show_ThyristorTriac(); break; case COMP_TRIAC: Show_ThyristorTriac(); break; case COMP_PUT: Show_PUT(); break; #ifdef SW_UJT case COMP_UJT: Show_UJT(); break; #endif case COMP_RESISTOR: Show_Resistor(); break; case COMP_CAPACITOR: Show_Capacitor(); break; default: /* no component found */ Show_Fail(); break; } #ifdef UI_SERIAL_COPY Display_Serial_Off(); /* disable serial output & NL */ #endif #ifdef SW_SYMBOLS /* display fancy pinout for 3-pin semiconductors */ if (Check.Found >= COMP_BJT) /* 3-pin semi */ { if (UI.SymbolLine) /* not zero */ { LCD_FancySemiPinout(UI.SymbolLine); /* display pinout */ } } #endif #ifdef UI_SERIAL_COMMANDS if (Key == KEY_PROBE) /* probing by command */ { Display_Serial_Only(); /* switch output to serial */ Display_EEString_NL(Cmd_OK_str); /* send: OK & newline */ Display_LCD_Only(); /* switch output back to display */ /* We don't have to restore the next-line mode since it will be changed a few line below anyway. */ } #endif #if CYCLE_MAX < 255 /* component was found */ if (Check.Found >= COMP_RESISTOR) { MissedParts = 0; /* reset counter */ } #endif /* * manage cycling and power-off */ cycle_control: #ifdef HW_DISCHARGE_RELAY /* discharge relay: short circuit probes */ /* ADC_PORT should be 0 */ ADC_DDR = (1 << TP_REF); /* disable relay */ #endif #ifdef SERIAL_RW Serial_Ctrl(SER_RX_RESUME); /* enable TTL serial RX */ #endif UI.LineMode = LINE_STD; /* reset next-line mode */ /* wait for key press or timeout */ #ifdef UI_KEY_HINTS Display_LastLine(); UI.KeyHint = (unsigned char *)Menu_or_Test_str; Key = TestKey((uint16_t)CYCLE_DELAY, CURSOR_BLINK | CURSOR_TEXT | CHECK_OP_MODE | CHECK_KEY_TWICE | CHECK_BAT); #else Key = TestKey((uint16_t)CYCLE_DELAY, CURSOR_BLINK | CHECK_OP_MODE | CHECK_KEY_TWICE | CHECK_BAT); #endif if (Key == KEY_TIMEOUT) /* timeout (no key press) */ { /* implies continuous mode */ #if CYCLE_MAX < 255 /* check if we reached the maximum number of missed parts in a row */ if (MissedParts >= CYCLE_MAX) { Key = KEY_POWER_OFF; /* signal power off */ } #endif } else if (Key == KEY_TWICE) /* two short key presses */ { Key = KEY_MAINMENU; /* signal main menu */ } else if (Key == KEY_LONG) /* long key press */ { Key = KEY_POWER_OFF; /* signal power off */ } #ifdef HW_KEYS else if (Key == KEY_LEFT) /* rotary encoder: left turn */ { Key = KEY_MAINMENU; /* signal main menu */ } #endif #ifdef SERIAL_RW else if (Key == KEY_COMMAND) /* remote command */ { #ifdef UI_SERIAL_COMMANDS Key = KEY_NONE; /* reset key */ Display_Serial_Only(); /* switch output to serial */ Test = GetCommand(); /* get command */ if (Test != CMD_NONE) /* valid command */ { Key = RunCommand(Test); /* run command */ } Display_LCD_Only(); /* switch output back to display */ /* if we got a virtual key perform requested action */ if (Key != KEY_NONE) goto cycle_action; #endif goto cycle_control; /* re-run cycle control */ } #endif #if defined (UI_SHORT_CIRCUIT_MENU) || defined (UI_SERIAL_COMMANDS) cycle_action: #endif #ifdef SERIAL_RW Serial_Ctrl(SER_RX_PAUSE); /* disable TTL serial RX */ /* todo: when we got a locked buffer meanwhile? */ #endif if (Key == KEY_MAINMENU) /* run main menu */ { #ifdef SAVE_POWER /* change sleep mode the Idle to keep timers & other stuff running */ Test = Cfg.SleepMode; /* get current mode */ Cfg.SleepMode = SLEEP_MODE_IDLE; /* change sleep mode to Idle */ #endif #ifdef HW_DISCHARGE_RELAY /* discharge relay: remove short circuit */ ADC_DDR = 0; /* enable relay (via external reference) */ /* todo: move this to MainMenu()? (after selecting item) */ #endif #ifdef POWER_OFF_TIMEOUT /* automatic power-off for auto-hold mode */ if (Cfg.OP_Mode & OP_AUTOHOLD) /* in auto-hold mode */ { Cfg.OP_Control &= ~OP_PWR_TIMEOUT; /* disable power-off timeout */ } #endif MainMenu(); /* enter main menu */ #ifdef POWER_OFF_TIMEOUT /* automatic power-off for auto-hold mode */ if (Cfg.OP_Mode & OP_AUTOHOLD) /* in auto-hold mode */ { Cfg.OP_Control |= OP_PWR_TIMEOUT; /* enable power-off timeout */ } #endif #ifdef SAVE_POWER /* change sleep mode back */ Cfg.SleepMode = Test; /* change sleep mode back */ #endif goto cycle_control; /* re-run cycle control */ } else if (Key == KEY_POWER_OFF) /* power off */ { PowerOff(); /* power off */ } else /* default action */ { goto cycle_start; /* next round */ } return 0; } /* ************************************************************************ * clean-up of local constants * ************************************************************************ */ /* source management */ #undef MAIN_C /* ************************************************************************ * EOF * ************************************************************************ */
Bearbeitung
Datei öffnen
/* ************************************************************************ * * main part * * (c) 2012-2020 by Markus Reschke * based on code from Markus Frejek and Karl-Heinz Kübbeler * * ************************************************************************ */ /* * local constants */ /* source management */ #define MAIN_C /* * include header files */ /* local includes */ #include "config.h" /* global configuration */ #include "common.h" /* common header file */ #include "variables.h" /* global variables */ #include "functions.h" /* external functions */ #include "colors.h" /* color definitions */ /* * local variables */ /* program control */ #if CYCLE_MAX < 255 uint8_t MissedParts; /* counter for failed/missed components */ #endif /* ************************************************************************ * output components and errors * ************************************************************************ */ /* * show pinout for semiconductors * * required: * - character for pin A * - character for pin B * - character for pin C */ void Show_SemiPinout(uint8_t A, uint8_t B, uint8_t C) { uint8_t n; /* counter */ uint8_t Char; /* character */ #ifdef SW_PROBE_COLORS uint16_t Color; /* color value */ Color = UI.PenColor; /* save current color */ #endif /* display: 123 */ for (n = 0; n <= 2; n++) { Display_ProbeNumber(n); } /* display: = */ Display_Char('='); /* display pin IDs */ for (n = 0; n <= 2; n++) /* loop through probe pins */ { #ifdef SW_PROBE_COLORS UI.PenColor = ProbeColors[n]; /* set probe color */ #endif if (n == Semi.A) Char = A; /* probe A - ID A */ else if (n == Semi.B) Char = B; /* probe B - ID B */ else Char = C; /* - ID C */ Display_Char(Char); /* display ID */ } #ifdef SW_PROBE_COLORS UI.PenColor = Color; /* restore old color */ #endif } /* * show simple pinout * * required: * - ID: characters for probes 1, 2 and 3 * 0 -> not displayed */ void Show_SimplePinout(uint8_t ID_1, uint8_t ID_2, uint8_t ID_3) { uint8_t n; /* counter */ unsigned char ID[3]; /* component pin IDs */ #ifdef SW_PROBE_COLORS uint16_t Color; /* color value */ Color = UI.PenColor; /* save current color */ #endif /* copy probe pin characters/IDs */ ID[0] = ID_1; ID[1] = ID_2; ID[2] = ID_3; for (n = 0; n <= 2; n++) /* loop through probe pins */ { if (ID[n] != 0) /* display this one */ { Display_ProbeNumber(n); Display_Char(':'); #ifdef SW_PROBE_COLORS UI.PenColor = ProbeColors[n]; /* set probe color */ #endif Display_Char(ID[n]); #ifdef SW_PROBE_COLORS UI.PenColor = Color; /* restore old color */ #endif Display_Space(); } } } #ifdef FUNC_EVALUE /* * show E series norm values * * requires: * - Value: unsigned value * - Scale: exponent/multiplier (* 10^n) * - ESeries: E6-192 * - Tolerance: in 0.1% * - Unit: unit character */ void Show_ENormValues(uint32_t Value, int8_t Scale, uint8_t ESeries, uint8_t Tolerance, unsigned char Unit) { uint8_t n; /* number of norm values (1 or 2) */ uint8_t Pos; /* char x position */ uint8_t Temp; /* temporary value */ /* * get E series norm values * - 1st: Semi.I_value, Semi.I_scale * - 2nd: Semi.C_value, Semi.C_scale */ n = GetENormValue(Value, Scale, ESeries, Tolerance); /* * show E series and tolerance */ Display_NextLine(); /* move to next line */ /* display E series */ Display_Char('E'); /* display: E */ Display_FullValue(ESeries, 0 , 0); /* display E series */ Display_Space(); /* display: " " */ /* display tolerance */ Temp = Tolerance; /* copy tolerance */ Pos = 0; /* reset decimal places */ if (Temp < 10) /* < 1% */ { Pos = 1; /* one decimal place */ } Temp /= 10; /* scale to 1 */ Display_FullValue(Temp, Pos, '%'); /* display tolerance */ Display_Space(); /* display: " " */ /* * show norm values */ if (n) /* got norm value(s) */ { Pos = UI.CharPos_X; /* get current char position */ /* display first norm value */ Display_EValue(Semi.I_value, Semi.I_scale, Unit); if (n == 2) /* got two norm values */ { /* move to next line at same position (after E series) */ Display_NextLine(); LCD_CharPos(Pos, UI.CharPos_Y); /* display second norm value */ Display_EValue(Semi.C_value, Semi.C_scale, Unit); } } else /* no norm value */ { Display_Char('-'); /* display: - */ } } #endif #ifdef FUNC_COLORCODE /* * show E series norm value color-codes * * requires: * - Value: unsigned value * - Scale: exponent/multiplier (* 10^n) * - ESeries: E6-192 * - Tolerance: in 0.1% * - TolBand: color of tolerance band */ void Show_ENormCodes(uint32_t Value, int8_t Scale, uint8_t ESeries, uint8_t Tolerance, uint16_t TolBand) { uint8_t n; /* number of norm values (1 or 2) */ uint8_t Pos; /* char x position */ /* * tolerance band * - resistor * 20% 10% 5% 2% 1% 0.5% 0.25% 0.1% 0.05% * none silver gold red brown green blue violet grey * - inductor * 20% 10% 5% 4% 3% 2% 1% 0.5% 0.25% 0.1% 0.05% * black silver gold yellow orange red brown green blue violet grey * - caps: many different schemas * * multiplier reference * - R: 0 (10^0) -> 1 Ohms * C: -12 (10^-12) -> 1 pF * L: -6 (10^-6) -> 1 µH * - ref_scale as function argument? * scale = scale - ref_scale */ /* * get E series norm values * - 1st: Semi.I_value, Semi.I_scale * - 2nd: Semi.C_value, Semi.C_scale */ n = GetENormValue(Value, Scale, ESeries, Tolerance); /* * show E series */ Display_NextLine(); /* move to next line */ /* display E series */ Display_Char('E'); /* display: E */ Display_FullValue(ESeries, 0 , 0); /* display E series */ Display_Space(); /* display: " " */ /* * show color-codes of norm values */ if (n) /* got norm value(s) */ { Pos = UI.CharPos_X; /* get current char position */ /* display color-code of first norm value */ Display_ColorCode(Semi.I_value, Semi.I_scale, TolBand); if (n == 2) /* got two norm values */ { /* move to next line at same position (after E series) */ Display_NextLine(); LCD_CharPos(Pos, UI.CharPos_Y); /* display color-code of second norm value */ Display_ColorCode(Semi.C_value, Semi.C_scale, TolBand); } } #if 0 /* * color testing */ uint16_t Color; Display_NextLine(); /* first 5 colors plus gold */ n = 0; while (n < 5) { Color = DATA_read_word((uint16_t *)&ColorCode_table[n]); LCD_Band(Color, ALIGN_LEFT); n++; } LCD_Band(COLOR_CODE_GOLD, ALIGN_RIGHT); Display_NextLine(); /* last 5 colors plus silver */ while (n < 10) { Color = DATA_read_word((uint16_t *)&ColorCode_table[n]); LCD_Band(Color, ALIGN_LEFT); n++; } LCD_Band(COLOR_CODE_SILVER, ALIGN_RIGHT); TestKey(0, CURSOR_BLINK); #endif } #endif /* * show failed test */ void Show_Fail(void) { /* display info */ Display_EEString(Failed1_str); /* display: No component */ Display_NL_EEString(Failed2_str); /* display: found! */ #if CYCLE_MAX < 255 MissedParts++; /* increase counter */ #endif } /* * show error */ void Show_Error() { if (Check.Type == TYPE_DISCHARGE) /* discharge failed */ { Display_EEString(DischargeFailed_str); /* display: Battery? */ /* display probe number and remaining voltage */ Display_NextLine(); Display_ProbeNumber(Check.Probe); Display_Char(':'); Display_Space(); Display_Value(Check.U, -3, 'V'); } else if (Check.Type == TYPE_DETECTION) /* detection error */ { /* simply display: No component found! */ Show_Fail(); } } /* * show single (first) resistor * * requires: * - ID1: pin ID #1 character * - ID2: pin ID #2 character */ void Show_SingleResistor(uint8_t ID1, uint8_t ID2) { Resistor_Type *Resistor; /* pointer to resistor */ Resistor = &Resistors[0]; /* pointer to first resistor */ /* show pinout */ Display_Char(ID1); Display_EEString(Resistor_str); Display_Char(ID2); /* show resistance value */ Display_Space(); Display_Value(Resistor->Value, Resistor->Scale, LCD_CHAR_OMEGA); } /* * show resistor(s) */ void Show_Resistor(void) { Resistor_Type *R1; /* pointer to resistor #1 */ Resistor_Type *R2; /* pointer to resistor #2 */ uint8_t Pin; /* ID of common pin */ R1 = &Resistors[0]; /* pointer to first resistor */ if (Check.Resistors == 1) /* single resistor */ { R2 = NULL; /* disable second resistor */ Pin = R1->A; /* make B the first pin */ } else /* multiple resistors */ { R2 = R1; R2++; /* pointer to second resistor */ #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Quantity = 2; /* got two */ #endif if (Check.Resistors == 3) /* three resistors */ { Resistor_Type *Rmax; /* pointer to largest resistor */ /* * 3 resistors mean 2 single resistors and both resistors in series. * So we have to single out that series resistor by finding the * largest resistor. */ Rmax = R1; /* starting point */ for (Pin = 1; Pin <= 2; Pin++) { if (CmpValue(R2->Value, R2->Scale, Rmax->Value, Rmax->Scale) == 1) { Rmax = R2; /* update largest one */ } R2++; /* next one */ } /* get the two smaller resistors */ if (R1 == Rmax) R1++; R2 = R1; R2++; if (R2 == Rmax) R2++; } /* find common pin of both resistors */ if ((R1->A == R2->A) || (R1->A == R2->B)) { Pin = R1->A; /* pin A */ } else { Pin = R1->B; /* pin B */ } } #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Comp1 = (void *)R1; /* link first resistor */ Info.Comp2 = (void *)R2; /* link second resistor */ #endif /* * display the pins */ /* first resistor */ if (R1->A != Pin) /* A is not common pin */ { Display_ProbeNumber(R1->A); /* display pin A */ } else /* single resistor or A is common pin */ { Display_ProbeNumber(R1->B); /* display pin B */ } Display_EEString(Resistor_str); Display_ProbeNumber(Pin); /* display common pin */ if (R2) /* second resistor */ { Display_EEString(Resistor_str); if (R2->A != Pin) /* A is not common pin */ { Display_ProbeNumber(R2->A); /* display pin A */ } else /* A is common pin */ { Display_ProbeNumber(R2->B); /* display pin B */ } } /* * display the values */ /* first resistor */ Display_NextLine(); Display_Value(R1->Value, R1->Scale, LCD_CHAR_OMEGA); if (R2) /* second resistor */ { Display_Space(); Display_Value(R2->Value, R2->Scale, LCD_CHAR_OMEGA); } #ifdef SW_INDUCTOR else /* single resistor */ { /* get inductance and display if relevant */ if (MeasureInductor(R1) == 1) /* inductor */ { Display_Space(); Display_Value(Inductor.Value, Inductor.Scale, 'H'); #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Flags |= INFO_R_L; /* inductance measured */ #endif #ifdef SW_L_E6_T /* show E series norm values for E6 20% */ Show_ENormValues(Inductor.Value, Inductor.Scale, E6, 200, 'H'); #endif #ifdef SW_L_E12_T /* show E series norm values for E12 10% */ Show_ENormValues(Inductor.Value, Inductor.Scale, E12, 100, 'H'); #endif } #ifdef SW_R_EXX else /* no inductance */ { #ifdef SW_R_E24_5_T /* show E series norm values for E24 5% */ Show_ENormValues(R1->Value, R1->Scale, E24, 50, LCD_CHAR_OMEGA); #endif #ifdef SW_R_E24_5_CC /* show E series norm value color-codes for E24 5% */ Show_ENormCodes(R1->Value, R1->Scale, E24, 50, COLOR_CODE_GOLD); #endif #ifdef SW_R_E24_1_T /* show E series norm values for E24 1% */ Show_ENormValues(R1->Value, R1->Scale, E24, 10, LCD_CHAR_OMEGA); #endif #ifdef SW_R_E24_1_CC /* show E series norm value color-codes for E24 1% */ Show_ENormCodes(R1->Value, R1->Scale, E24, 10, COLOR_CODE_BROWN); #endif #ifdef SW_R_E96_T /* show E series norm values for E96 1% */ Show_ENormValues(R1->Value, R1->Scale, E96, 10, LCD_CHAR_OMEGA); #endif #ifdef SW_R_E96_CC /* show E series norm value color-codes for E96 1% */ Show_ENormCodes(R1->Value, R1->Scale, E96, 10, COLOR_CODE_BROWN); #endif } #endif } #elif defined (SW_R_EXX) else /* single resistor */ { #ifdef SW_R_E24_5_T /* show E series norm values for E24 5% */ Show_ENormValues(R1->Value, R1->Scale, E24, 50, LCD_CHAR_OMEGA); #endif #ifdef SW_R_E24_5_CC /* show E series norm value color-codes for E24 5% */ Show_ENormCodes(R1->Value, R1->Scale, E24, 50, COLOR_CODE_GOLD); #endif #ifdef SW_R_E24_1_T /* show E series norm values for E24 1% */ Show_ENormValues(R1->Value, R1->Scale, E24, 10, LCD_CHAR_OMEGA); #endif #ifdef SW_R_E24_1_CC /* show E series norm value color-codes for E24 1% */ Show_ENormCodes(R1->Value, R1->Scale, E24, 10, COLOR_CODE_BROWN); #endif #ifdef SW_R_E96_T /* show E series norm values for E96 1% */ Show_ENormValues(R1->Value, R1->Scale, E96, 10, LCD_CHAR_OMEGA); #endif #ifdef SW_R_E96_CC /* show E series norm value color-codes for E96 1% */ Show_ENormCodes(R1->Value, R1->Scale, E96, 10, COLOR_CODE_BROWN); #endif } #endif } /* * show capacitor */ void Show_Capacitor(void) { Capacitor_Type *MaxCap; /* pointer to largest cap */ Capacitor_Type *Cap; /* pointer to cap */ #if defined (SW_ESR) || defined (SW_OLD_ESR) uint16_t ESR; /* ESR (in 0.01 Ohms) */ #endif uint8_t Counter; /* loop counter */ /* find largest cap */ MaxCap = &Caps[0]; /* pointer to first cap */ Cap = MaxCap; for (Counter = 1; Counter <= 2; Counter++) { Cap++; /* next cap */ if (CmpValue(Cap->Value, Cap->Scale, MaxCap->Value, MaxCap->Scale) == 1) { MaxCap = Cap; } } #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Comp1 = (void *)MaxCap; /* link largest cap */ #endif /* display pinout */ Display_ProbeNumber(MaxCap->A); /* display pin #1 */ Display_EEString(Cap_str); /* display capacitor symbol */ Display_ProbeNumber(MaxCap->B); /* display pin #2 */ /* show capacitance */ Display_NextLine(); /* move to next line */ Display_Value(MaxCap->Value, MaxCap->Scale, 'F'); #if defined (SW_ESR) || defined (SW_OLD_ESR) /* show ESR */ ESR = MeasureESR(MaxCap); /* measure ESR */ if (ESR < UINT16_MAX) /* if successfull */ { Display_Space(); Display_Value(ESR, -2, LCD_CHAR_OMEGA); /* display ESR */ } #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Val1 = ESR; /* copy ESR */ #endif #endif /* show discharge leakage current */ if (MaxCap->I_leak > 0) { Display_NL_EEString_Space(I_leak_str); Display_Value(MaxCap->I_leak, -8, 'A'); /* in 10nA */ } #ifdef SW_C_E6_T /* show E series norm values for E6 20% */ Show_ENormValues(MaxCap->Value, MaxCap->Scale, E6, 200, 'F'); #endif #ifdef SW_C_E12_T /* show E series norm values for E12 10% */ Show_ENormValues(MaxCap->Value, MaxCap->Scale, E12, 100, 'F'); #endif } /* * show current (leakage or whatever) of semiconductor * * Mapping for Semi structure: * - I_value - current * - I_scale - scale for current (10^x) */ void Show_SemiCurrent(const unsigned char *String) { if (CmpValue(Semi.I_value, Semi.I_scale, 50, -9) >= 0) /* show if >=50nA */ { Display_NL_EEString_Space(String); /* display: <string> */ Display_Value(Semi.I_value, Semi.I_scale, 'A'); /* display current */ } } #ifndef UI_SERIAL_COMMANDS /* * display capacitance of a diode * * requires: * - pointer to diode structure */ void Show_Diode_Cap(Diode_Type *Diode) { /* get capacitance (reversed direction) */ MeasureCap(Diode->C, Diode->A, 0); /* and show capacitance */ Display_Value(Caps[0].Value, Caps[0].Scale, 'F'); } #endif /* * show diode */ void Show_Diode(void) { Diode_Type *D1; /* pointer to diode #1 */ Diode_Type *D2 = NULL; /* pointer to diode #2 */ uint8_t CapFlag = 1; /* flag for capacitance output */ uint8_t A = 5; /* ID of common anode */ uint8_t C = 5; /* ID of common cothode */ uint8_t R_Pin1 = 5; /* B_E resistor's pin #1 */ uint8_t R_Pin2 = 5; /* B_E resistor's pin #2 */ uint8_t n; /* counter */ uint8_t m; /* counter */ D1 = &Diodes[0]; /* pointer to first diode */ /* * figure out which diodes to display */ if (Check.Diodes == 1) /* single diode */ { C = D1->C; /* make cathode first pin */ } else if (Check.Diodes == 2) /* two diodes */ { D2 = D1; D2++; /* pointer to second diode */ if (D1->A == D2->A) /* common anode */ { A = D1->A; /* save common anode */ /* possible PNP BJT with low value B-E resistor and flyback diode */ R_Pin1 = D1->C; R_Pin2 = D2->C; } else if (D1->C == D2->C) /* common cathode */ { C = D1->C; /* save common cathode */ /* possible NPN BJT with low value B-E resistor and flyback diode */ R_Pin1 = D1->A; R_Pin2 = D2->A; } else if ((D1->A == D2->C) && (D1->C == D2->A)) /* anti-parallel */ { A = D1->A; /* anode and cathode */ C = A; /* are the same */ CapFlag = 0; /* skip capacitance */ } } else if (Check.Diodes == 3) /* three diodes */ { /* * Two diodes in series are detected as a virtual third diode: * - Check for any possible way the 2 diodes could be connected in series. * - Only once the cathode of diode #1 matches the anode of diode #2. */ for (n = 0; n <= 2; n++) /* loop for first diode */ { D1 = &Diodes[n]; /* get pointer of first diode */ for (m = 0; m <= 2; m++) /* loop for second diode */ { D2 = &Diodes[m]; /* get pointer of second diode */ if (n != m) /* don't check same diode :-) */ { if (D1->C == D2->A) /* got match */ { n = 5; /* end loops */ m = 5; } } } } if (n < 5) D2 = NULL; /* no match found */ C = D1->C; /* cathode of first diode */ A = 3; /* in series mode */ } else /* too much diodes */ { Display_EEString(Diode_AC_str); /* display: -|>|- */ Display_Space(); /* display space */ Display_Char(Check.Diodes + '0'); /* display number of diodes found */ #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Quantity = Check.Diodes; /* set quantity */ #endif return; } #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Comp1 = (void *)D1; /* link first diode */ Info.Comp2 = (void *)D2; /* link second diode */ #endif /* * display pins */ /* first diode */ if (A < 3) /* common anode: show C first */ { Display_ProbeNumber(D1->C); /* show C */ Display_EEString(Diode_CA_str); /* show -|<- */ Display_ProbeNumber(A); /* show A */ } else /* common cathode: show A first */ { Display_ProbeNumber(D1->A); /* show A */ Display_EEString(Diode_AC_str); /* show ->|- */ Display_ProbeNumber(C); /* show C */ } if (D2) /* second diode */ { if (A <= 3) /* common anode or in-series */ { Display_EEString(Diode_AC_str); /* show ->|- */ } else /* common cathode */ { Display_EEString(Diode_CA_str); /* show -|<- */ } if (A == C) /* anti parallel */ { n = D2->A; /* get anode */ } else if (A <= 3) /* common anode or in-series */ { n = D2->C; /* get cathode */ } else /* common cathode */ { n = D2->A; /* get anode */ } Display_ProbeNumber(n); /* display pin */ #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Quantity = 2; /* got two */ #endif } /* check for B-E resistor of possible BJT */ if (R_Pin1 < 5) /* possible BJT */ { /* B-E resistor below 25kOhms */ if (CheckSingleResistor(R_Pin1, R_Pin2, 25) == 1) { /* show: PNP/NPN? */ Display_Space(); if (A < 3) /* PNP */ { Display_EEString(PNP_str); #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Flags |= INFO_D_R_BE | INFO_D_BJT_PNP; /* R_BE & PNP */ #endif } else /* NPN */ { Display_EEString(NPN_str); #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Flags |= INFO_D_R_BE | INFO_D_BJT_NPN; /* R_BE & NPN */ #endif } Display_Char('?'); Display_NextLine(); /* move to line #2 */ R_Pin1 += '1'; /* convert pin ID to character */ R_Pin2 += '1'; Show_SingleResistor(R_Pin1, R_Pin2); /* show resistor */ CapFlag = 0; /* skip capacitance */ } } /* * display: * - Uf (forward voltage) * - reverse leakage current (for single diodes) * - capacitance (not for anti-parallel diodes) */ /* display Uf */ Display_NL_EEString_Space(Vf_str); /* display: Vf */ /* first diode */ Display_Value(D1->V_f, -3, 'V'); /* in mV */ Display_Space(); /* display low current Uf and reverse leakage current for a single diode */ if (D2 == NULL) /* single diode */ { /* display low current Uf if it's quite low (Ge/Schottky diode) */ if (D1->V_f2 < 250) /* < 250mV */ { Display_Char('('); Display_Value(D1->V_f2, 0, 0); /* no unit */ Display_Char(')'); } /* reverse leakage current */ UpdateProbes(D1->C, D1->A, 0); /* reverse diode */ GetLeakageCurrent(1); /* get current */ Show_SemiCurrent(I_R_str); /* display I_R */ #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Flags |= INFO_D_I_R; /* measured I_R */ #endif } else /* two diodes */ { /* show Uf of second diode */ Display_Value(D2->V_f, -3, 'V'); } /* display capacitance */ if (CapFlag == 1) /* if feasable */ { Display_NL_EEString_Space(DiodeCap_str); /* display: C */ #ifndef UI_SERIAL_COMMANDS /* first diode */ Show_Diode_Cap(D1); /* measure & show capacitance */ if (D2) /* second diode */ { Display_Space(); Show_Diode_Cap(D2); /* measure & show capacitance */ } #endif #ifdef UI_SERIAL_COMMANDS /* first diode */ MeasureCap(D1->C, D1->A, 0); /* get capacitance (reversed direction) */ Display_Value(Caps[0].Value, Caps[0].Scale, 'F'); if (D2) /* second diode */ { Display_Space(); MeasureCap(D2->C, D2->A, 1); /* get capacitance (reversed direction) */ Display_Value(Caps[1].Value, Caps[1].Scale, 'F'); } #endif } } /* * show BJT */ void Show_BJT(void) { Diode_Type *Diode; /* pointer to diode */ unsigned char *String; /* string pointer (EEPROM) */ uint8_t BE_A; /* V_BE: pin acting as anode */ uint8_t BE_C; /* V_BE: pin acting as cathode */ uint8_t CE_A; /* flyback diode: pin acting as anode */ uint8_t CE_C; /* flyback diode: pin acting as cathode */ uint8_t CE_Char; /* character */ #ifdef SW_SCHOTTKY_BJT uint8_t BC_A; /* clamping diode: pin acting as anode */ uint8_t BC_C; /* clamping diode: pin acting as cathode */ uint8_t BC_Char; /* character */ #endif uint16_t V_BE = 0; /* V_BE */ int16_t Slope; /* slope of forward voltage */ /* * Mapping for Semi structure: * A - Base pin * B - Collector pin * C - Emitter pin * U_1 - U_BE (mV) (not implemented yet) * U_3 - I_C/I_E (µA) * F_1 - hFE * F_2 - reverse hFE * I_value/I_scale - I_CEO */ /* * preset stuff based on BJT type */ if (Check.Type & TYPE_NPN) /* NPN */ { String = (unsigned char *)NPN_str; /* "NPN" */ /* direction of B-E diode: B -> E */ BE_A = Semi.A; /* anode at base */ BE_C = Semi.C; /* cathode at emitter */ /* direction of optional flyback diode */ CE_A = Semi.C; /* anode at emitter */ CE_C = Semi.B; /* cathode at collector */ CE_Char = LCD_CHAR_DIODE_CA; /* |<| */ #ifdef SW_SCHOTTKY_BJT /* direction of B-C diode: B -> C */ BC_A = Semi.A; /* anode at base */ BC_C = Semi.B; /* cathode at collector */ BC_Char = LCD_CHAR_DIODE_AC; /* |>| */ #endif } else /* PNP */ { String = (unsigned char *)PNP_str; /* "PNP" */ /* direction of B-E diode: E -> B */ BE_A = Semi.C; /* anode at emitter */ BE_C = Semi.A; /* cathode at base */ /* direction of optional flyback diode */ CE_A = Semi.B; /* anode at collector */ CE_C = Semi.C; /* cathode at emitter */ CE_Char = LCD_CHAR_DIODE_AC; /* |>| */ #ifdef SW_SCHOTTKY_BJT /* direction of B-C diode: C -> B */ BC_A = Semi.B; /* anode at collector */ BC_C = Semi.A; /* cathode at base */ BC_Char = LCD_CHAR_DIODE_CA; /* |<| */ #endif } /* * display type */ Display_EEString_Space(BJT_str); /* display: BJT */ Display_EEString(String); /* display: NPN / PNP */ /* parasitic BJT (freewheeling diode on same substrate) */ if (Check.Type & TYPE_PARASITIC) { Display_Char('+'); /* display: + */ } Display_NextLine(); /* next line (#2) */ /* * display pinout */ Show_SemiPinout('B', 'C', 'E'); /* optional freewheeling diode */ Diode = SearchDiode(CE_A, CE_C); /* search for matching diode */ if (Diode != NULL) /* got it */ { Display_Space(); /* display space */ Display_Char('C'); /* display: collector */ Display_Char('~'); /* display: -- */ Display_Char(CE_Char); /* display diode symbol */ Display_Char('~'); /* display: -- */ Display_Char('E'); /* display: emitter */ #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Flags |= INFO_BJT_D_FB; /* found flyback diode */ Info.Comp1 = Diode; /* link diode */ #endif } /* * display B-E resistor if detected */ /* check for B-E resistor below 25kOhms */ if (CheckSingleResistor(BE_C, BE_A, 25) == 1) /* found B-E resistor */ { Display_NextLine(); /* next line (#3) */ Show_SingleResistor('B', 'E'); /* B-E resistor renders hFE and V_BE measurements useless */ #ifdef SW_SYMBOLS UI.SymbolLine = 4; /* display fancy pinout in line #4 */ #endif #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Flags |= INFO_BJT_R_BE; /* R_BE */ #endif } /* * display h_FE */ /* display h_FE */ Display_NL_EEString_Space(h_FE_str); /* display: hFE */ Display_Value(Semi.F_1, 0, 0); /* display h_FE */ /* display hFE test circuit type */ Display_Space(); if (Semi.Flags & HFE_COMMON_EMITTER) /* common emitter */ { /* common emitter circuit */ Display_Char('e'); /* display: e */ } else if (Semi.Flags & HFE_COMMON_COLLECTOR) /* common collector */ { /* common collector circuit */ Display_Char('c'); /* display: c */ } #ifdef SW_HFE_CURRENT /* display test current for hFE measurement */ Display_NL_EEString(I_str); /* display: I_ */ if (Semi.Flags & HFE_COMMON_EMITTER) /* common emitter */ { /* I_C */ Display_Char('C'); /* display: C */ } else if (Semi.Flags & HFE_COMMON_COLLECTOR) /* common collector */ { /* I_E */ Display_Char('E'); /* display: E */ } Display_Space(); Display_SignedValue(Semi.U_3, -6, 'A'); /* display I_C/I_E */ #endif #ifdef SW_REVERSE_HFE /* display reverse hFE */ if (Diode == NULL) /* no freewheeling diode */ { if (Semi.F_2 > 0) /* valid value */ { Display_NL_EEString_Space(h_FE_r_str); /* display: hFEr */ Display_Value(Semi.F_2, 0, 0); /* display reverse h_FE */ } } #endif /* * display V_BE * (taken from diode's forward voltage) */ Diode = SearchDiode(BE_A, BE_C); /* search for matching B-E diode */ if (Diode != NULL) /* found diode */ { Display_NL_EEString_Space(V_BE_str); /* display: Vbe */ /* * V_f is quite linear for a logarithmicly scaled I_b. * So we may interpolate the V_f values of low and high test current * measurements for a virtual test current. Low test current is 10µA * and high test current is 7mA. That's a logarithmic scale of * 3 decades. */ /* calculate slope for one decade */ Slope = Diode->V_f - Diode->V_f2; Slope /= 3; /* select V_BE based on hFE */ if (Semi.F_1 < 100) /* low h_FE */ { /* * BJTs with low hFE are power transistors and need a large I_b * to drive the load. So we simply take Vf of the high test current * measurement (7mA). */ V_BE = Diode->V_f; } else if (Semi.F_1 < 250) /* mid-range h_FE */ { /* * BJTs with a mid-range hFE are signal transistors and need * a small I_b to drive the load. So we interpolate Vf for * a virtual test current of about 1mA. */ V_BE = Diode->V_f - Slope; } else /* high h_FE */ { /* * BJTs with a high hFE are small signal transistors and need * only a very small I_b to drive the load. So we interpolate Vf * for a virtual test current of about 0.1mA. */ V_BE = Diode->V_f2 + Slope; } Display_Value(V_BE, -3, 'V'); /* in mV */ #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Val1 = V_BE; /* copy V_BE */ #endif } /* I_CEO: collector emitter open current (leakage) */ Show_SemiCurrent(I_CEO_str); /* display I_CEO */ #ifdef SW_SCHOTTKY_BJT /* * Schottky transistor / Schottky-clamped BJT * - V_BC of a Germanium BJT is as low as V_f of a Schottky diode. * So we check only Silicon BJTs. */ /* check for Si BJT */ if (V_BE > 500) /* V_BE > 500mV */ { Diode = SearchDiode(BC_A, BC_C); /* search for matching diode */ if (Diode != NULL) /* found diode */ { /* check for Schottky diode */ if (Diode->V_f < 450) /* V_f < 450mV */ { Display_NextLine(); /* next line */ /* display diode */ Display_Char('B'); /* display: base */ Display_Char('~'); /* display: -- */ Display_Char(BC_Char); /* display diode symbol */ Display_Char('~'); /* display: -- */ Display_Char('C'); /* display: collector */ /* display diode's V_f */ Display_Space(); /* display space */ Display_Value(Diode->V_f, -3, 'V'); /* display V_f */ #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Flags |= INFO_BJT_SCHOTTKY; /* Schottky-clamped BJT */ // Info.Comp2 = Diode; /* link diode */ #endif } } } #endif } /* * show MOSFET/IGBT extras * - diode * - V_th * - Cgs */ void Show_FET_Extras(void) { Diode_Type *Diode; /* pointer to diode */ uint8_t Anode; /* anode of diode */ uint8_t Cathode; /* cathode of diode */ uint8_t Char_1; /* pin name */ uint8_t Char_2; /* pin name */ uint8_t Symbol; /* diode symbol */ /* * Mapping for Semi structure: * A - Gate pin * B - Drain pin * C - Source pin * U_1 - R_DS_on (0.01 Ohms) * U_2 - V_th (mV) */ /* * show instrinsic/freewheeling diode */ if (Check.Type & TYPE_N_CHANNEL) /* n-channel/NPN */ { Anode = Semi.C; /* source/emitter */ Cathode = Semi.B; /* drain/collector */ Symbol = LCD_CHAR_DIODE_CA; /* |<| */ } else /* p-channel/PNP */ { Anode = Semi.B; /* drain/collector */ Cathode = Semi.C; /* source/emitter */ Symbol = LCD_CHAR_DIODE_AC; /* |>| */ } if (Check.Found == COMP_FET) /* FET */ { Char_1 = 'D'; Char_2 = 'S'; } else /* IGBT */ { Char_1 = 'C'; Char_2 = 'E'; } /* search for matching diode */ Diode = SearchDiode(Anode, Cathode); if (Diode != NULL) /* got it */ { /* show diode */ Display_Space(); /* space */ Display_Char(Char_1); /* left pin name */ Display_Char('~'); /* display: -- */ Display_Char(Symbol); /* diode symbol */ Display_Char('~'); /* display: -- */ Display_Char(Char_2); /* right pin name */ #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Flags |= INFO_FET_D_FB; /* found flyback diode */ Info.Comp1 = Diode; /* link diode */ #endif } /* skip remaining stuff for depletion-mode FETs/IGBTs */ if (Check.Type & TYPE_DEPLETION) return; /* gate threshold voltage V_th */ if (Semi.U_2 != 0) { Display_NL_EEString_Space(Vth_str); /* display: Vth */ Display_SignedValue(Semi.U_2, -3, 'V'); /* display V_th in mV */ #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Flags |= INFO_FET_V_TH; /* measured Vth */ #endif } /* display gate-source capacitance C_GS */ /* todo: display "Cge" for IGBT? */ Display_NL_EEString_Space(Cgs_str); /* display: Cgs */ Display_Value(Semi.C_value, Semi.C_scale, 'F'); /* display value and unit */ #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Flags |= INFO_FET_C_GS; /* measured C_GS */ #endif /* display R_DS_on, if available */ if (Semi.U_1 > 0) { Display_NL_EEString_Space(R_DS_str); /* display: Rds */ Display_Value(Semi.U_1, -2, LCD_CHAR_OMEGA); /* display value */ #ifdef UI_SERIAL_COMMANDS /* set data for remote commands */ Info.Flags |= INFO_FET_R_DS; /* measured R_DS */ #endif } /* display V_f of diode, if available */ if (Diode != NULL) { Display_NL_EEString_Space(Vf_str); /* display: Vf */ Display_Value(Diode->V_f, -3, 'V'); /* display value */ } } /* * show FET/IGBT channel type */ void Show_FET_Channel(void) { Display_Space(); /* display space */ /* channel type */ if (Check.Type & TYPE_N_CHANNEL) /* n-channel */ { Display_Char('N'); /* display: N */ } else /* p-channel */ { Display_Char('P'); /* display: P */ } Display_EEString(Channel_str); /* display: -ch */ } /* * show FET/IGBT mode */ void Show_FET_Mode(void) { Display_Space(); /* display space */ if (Check.Type & TYPE_ENHANCEMENT) /* enhancement mode */ { Display_EEString(Enhancement_str); /* display: enh. */ } else /* depletion mode */ { Display_EEString(Depletion_str); /* display: dep. */ } } /* * show FET (MOSFET & JFET) */ void Show_FET(void) { /* * Mapping for Semi structure: * A - Gate pin * B - Drain pin * C - Source pin * U_1 - R_DS_on (0.01 Ohms) * U_2 - V_th (mV) * U_3 - V_GS(off) (mV) */ /* display type */ if (Check.Type & TYPE_MOSFET) /* MOSFET */ { Display_EEString(MOS_str); /* display: MOS */ } else /* JFET */ { Display_Char('J'); /* display: J */ } Display_EEString(FET_str); /* display: FET */ /* display channel type */ Show_FET_Channel(); /* display mode for MOSFETs*/ if (Check.Type & TYPE_MOSFET) Show_FET_Mode(); /* pinout */ Display_NextLine(); /* next line (#2) */ if (Check.Type & TYPE_SYMMETRICAL) /* symmetrical Drain and Source */ { /* we can't distinguish D and S */ Show_SemiPinout('G', 'x', 'x'); /* show pinout */ } else /* unsymmetrical Drain and Source */ { Show_SemiPinout('G', 'D', 'S'); /* show pinout */ } /* show body diode, V_th and Cgs for MOSFETs */ if (Check.Type & TYPE_MOSFET) Show_FET_Extras(); /* show I_DSS and V_GS(off) for depletion mode FET */ if (Check.Type & TYPE_DEPLETION) { /* I_DSS */ Show_SemiCurrent(I_DSS_str); /* display Idss */ /* V_GS(off) */ if (Semi.U_3 != 0) /* valid value */ { Display_NL_EEString_Space(V_GSoff_str); /* display: V_GS(off) */ #ifdef SW_SYMBOLS /* we need some space for the symbol: move value to next line */ Display_NextLine(); Display_Space(); #endif Display_SignedValue(Semi.U_3, -3, 'V'); /* display V_GS(off) in mV */ } } } /* * show IGBT */ void Show_IGBT(void) { /* * Mapping for Semi structure: * A - Gate pin * B - Collector pin * C - Emitter pin * U_2 - V_th (mV) */ Display_EEString(IGBT_str); /* display: IGBT */ Show_FET_Channel(); /* display channel type */ Show_FET_Mode(); /* display mode */ Display_NextLine(); /* next line (#2) */ Show_SemiPinout('G', 'C', 'E'); /* show pinout */ Show_FET_Extras(); /* show diode, V_th and C_GE */ } /* * show Thyristor and TRIAC */ void Show_ThyristorTriac(void) { /* * Mapping for Semi structure: * SCR TRIAC * A - Gate Gate * B - Anode MT2 * C - Cathode MT1 * U_1 - V_GT (mV) */ /* display component type any pinout */ if (Check.Found == COMP_THYRISTOR) /* SCR */ { Display_EEString(Thyristor_str); /* display: thyristor */ Display_NextLine(); /* next line (#2) */ Show_SemiPinout('G', 'A', 'C'); /* display pinout */ } else /* TRIAC */ { Display_EEString(Triac_str); /* display: TRIAC */ Display_NextLine(); /* next line (#2) */ Show_SemiPinout('G', '2', '1'); /* display pinout */ } /* show V_GT (gate trigger voltage) */ if (Semi.U_1 > 0) /* show if not zero */ { Display_NL_EEString_Space(V_GT_str); /* display: V_GT */ Display_Value(Semi.U_1, -3, 'V'); /* display V_GT in mV */ } } /* * show PUT */ void Show_PUT(void) { /* * Mapping for AltSemi structure: * A - Gate * B - Anode * C - Cathode * U_1 - V_f * U_2 - V_T * * Mapping for Semi structure: * A - Gate * B - Anode * C - Cathode */ Display_EEString(PUT_str); /* display: PUT */ Display_NextLine(); /* move to line #2 */ Show_SemiPinout('G', 'A', 'C'); /* display pinout */ /* display V_T */ Display_NL_EEString_Space(V_T_str); /* display: VT */ Display_Value(AltSemi.U_2, -3, 'V'); /* display V_T */ /* display V_f */ Display_NL_EEString_Space(Vf_str); /* display: Vf */ Display_Value(AltSemi.U_1, -3, 'V'); /* display V_f */ } #ifdef SW_UJT /* * show UJT */ void Show_UJT(void) { /* * Mapping for AltSemi structure: * A - Emitter * B - B2 * C - B1 + * Mapping for Semi structure: * A - Gate * B - Anode * C - Cathode */ Display_EEString(UJT_str); /* display: UJT */ Display_NextLine(); /* next line (#2) */ Show_SemiPinout('E', '2', '1'); /* display pinout */ /* display r_BB */ Display_NL_EEString_Space(R_BB_str); /* display: R_BB */ Display_Value(Resistors[0].Value, Resistors[0].Scale, LCD_CHAR_OMEGA); } #endif /* ************************************************************************ * voltage reference * ************************************************************************ */ /* * manage voltage references */ void CheckVoltageRefs(void) { #ifdef HW_REF25 uint16_t U_Ref; /* reference voltage */ uint32_t Temp; /* temporary value */ #endif /* * external 2.5V voltage reference */ #ifdef HW_REF25 Cfg.Samples = 200; /* perform 200 ADC samples for high accuracy */ U_Ref = ReadU(TP_REF); /* read voltage of reference (mV) */ /* check for valid voltage range */ if ((U_Ref > 2250) && (U_Ref < 2750)) /* voltage is fine */ { /* adjust Vcc (assuming 2.495V typically) */ Temp = ((uint32_t)Cfg.Vcc * UREF_25) / U_Ref; Cfg.Vcc = (uint16_t)Temp; Cfg.OP_Mode |= OP_EXT_REF; /* set flag */ } else /* voltage out of range */ { Cfg.OP_Mode &= ~OP_EXT_REF; /* clear flag */ } #endif /* * internal 1.1V bandgap reference */ Cfg.Bandgap = ReadU(ADC_CHAN_BANDGAP); /* dummy read for bandgap stabilization */ Cfg.Samples = 200; /* perform 200 ADC samples for high accuracy */ Cfg.Bandgap = ReadU(ADC_CHAN_BANDGAP); /* get voltage of bandgap reference (mV) */ Cfg.Bandgap += NV.RefOffset; /* add voltage offset */ /* clean up */ Cfg.Samples = ADC_SAMPLES; /* set ADC samples back to default */ } /* ************************************************************************ * power control and monitoring * ************************************************************************ */ /* * power off */ void PowerOff(void) { /* display feedback (otherwise the user will wait :) */ LCD_Clear(); #ifdef LCD_COLOR UI.PenColor = COLOR_TITLE; /* set pen color */ #endif Display_EEString(Bye_str); /* display: Bye! */ cli(); /* disable interrupts */ wdt_disable(); /* disable watchdog */ #ifdef POWER_SWITCH_SOFT POWER_PORT &= ~(1 << POWER_CTRL); /* power off myself */ #endif /* * As long as the user keeps the test button pressed the MCU is still * powered. Therefor we make sure that nothing happens by forcing the * MCU to sleep which also saves power. Same for a classic power switch. */ set_sleep_mode(SLEEP_MODE_PWR_DOWN); /* set sleep mode to "power down" */ sleep_mode(); /* enter sleep mode */ } #ifndef BAT_NONE /* * display battery status * - uses voltage stored in Cfg.Vbat */ void ShowBattery(void) { /* display battery voltage */ Display_EEString_Space(Battery_str); /* display: Bat. */ #ifdef BAT_EXT_UNMONITORED /* check for unmonitored external power supply */ if (Cfg.Vbat < 900) /* < 0.9V */ { /* powered by unmonitored external PSU */ /* low voltage caused by diode's leakage current */ /* display status */ #ifdef LCD_COLOR UI.PenColor = COLOR_GREEN; /* use green */ #endif Display_EEString(External_str); /* display: ext */ } else /* battery operation */ { /* powered by battery */ #endif /* display battery voltage */ Display_Value(Cfg.Vbat / 10, -2, 'V'); Display_Space(); /* display status */ if (Cfg.Vbat < BAT_LOW) /* low level reached */ { #ifdef LCD_COLOR UI.PenColor = COLOR_RED; /* use red */ #endif Display_EEString(Low_str); /* display: low */ } else if (Cfg.Vbat < BAT_WEAK) /* warning level reached */ { #ifdef LCD_COLOR UI.PenColor = COLOR_YELLOW; /* use yellow */ #endif Display_EEString(Weak_str); /* display: weak */ } else /* ok */ { #ifdef LCD_COLOR UI.PenColor = COLOR_GREEN; /* use green */ #endif Display_EEString(OK_str); /* display: ok */ } #ifdef BAT_EXT_UNMONITORED } #endif #ifdef LCD_COLOR UI.PenColor = COLOR_PEN; /* set color back to default */ #endif } /* * check battery * - store battery voltage in Cfg.Vbat * - power off in case of a low battery */ void CheckBattery(void) { uint16_t U_Bat; /* battery voltage */ /* get current battery voltage */ U_Bat = ReadU(TP_BAT); /* read voltage (mV) */ #ifdef BAT_DIVIDER uint32_t Temp; /* temporary value */ /* * ADC pin is connected to a voltage divider (top: R1 / bottom: R2). * - U2 = (Uin / (R1 + R2)) * R2 * - Uin = (U2 * (R1 + R2)) / R2 */ Temp = (((uint32_t)(BAT_R1 + BAT_R2) * 1000) / BAT_R2); /* factor (0.001) */ Temp *= U_Bat; /* Uin (0.001 mV) */ Temp /= 1000; /* Uin (mV) */ U_Bat = (uint16_t)Temp; #endif U_Bat += BAT_OFFSET; /* add offset for voltage drop */ Cfg.Vbat = U_Bat; /* save battery voltage */ Cfg.BatTimer = 100; /* reset timer for next battery check (in 100ms) */ /* about 10s */ /* check for low-voltage situation */ if (U_Bat < BAT_LOW) /* low level reached */ { #ifdef BAT_EXT_UNMONITORED /* not for unmonitored external power supply */ if (U_Bat >= 900) /* >= 0.9V */ { /* battery operation */ #endif LCD_Clear(); /* clear display */ ShowBattery(); /* display battery status */ MilliSleep(3000); /* let user read info */ PowerOff(); /* power off */ #ifdef BAT_EXT_UNMONITORED } #endif } } #endif /* ************************************************************************ * the one and only main() * ************************************************************************ */ /* * main function */ int main(void) { uint8_t Test; /* test value */ uint8_t Key; /* user feedback */ /* * init hardware */ #ifdef POWER_SWITCH_SOFT /* switch on power to keep me alive */ POWER_DDR = (1 << POWER_CTRL); /* set pin as output */ POWER_PORT = (1 << POWER_CTRL); /* set pin to drive power management transistor */ #endif /* set up MCU */ MCUCR = (1 << PUD); /* disable pull-up resistors globally */ ADCSRA = (1 << ADEN) | ADC_CLOCK_DIV; /* enable ADC and set clock divider */ #ifdef HW_DISCHARGE_RELAY /* init discharge relay (safe mode): short circuit probes */ /* ADC_PORT should be 0 */ ADC_DDR = (1 << TP_REF); /* disable relay */ #endif /* catch watchdog */ Test = (MCUSR & (1 << WDRF)); /* save watchdog flag */ MCUSR &= ~(1 << WDRF); /* reset watchdog flag */ wdt_disable(); /* disable watchdog */ /* * set important default values */ #if defined (UI_AUTOHOLD) || defined (UI_SERIAL_COMMANDS) /* reset mode/state flags and set auto-hold mode */ Cfg.OP_Mode = OP_AUTOHOLD; /* set auto-hold */ #else /* reset mode/state flags and set continuous mode */ Cfg.OP_Mode = OP_NONE; /* none = continuous */ #endif Cfg.OP_Control = OP_OUT_LCD; /* reset control/signal flags */ /* enable output to display */ #ifdef SAVE_POWER Cfg.SleepMode = SLEEP_MODE_PWR_SAVE; /* sleep mode: power save */ #endif /* we have to keep Timer2 running */ /* * set up busses and interfaces */ /* test push button */ /* set to input by default */ #ifdef HW_SERIAL /* hardware or bitbang USART */ Serial_Setup(); /* set up TTL serial interface */ #endif #ifdef HW_I2C /* hardware or bitbang I2C */ I2C_Setup(); /* set up I2C bus */ #endif #ifdef HW_SPI /* hardware or bitbang SPI */ SPI_Setup(); /* set up SPI bus */ #endif /* display module */ LCD_BusSetup(); /* set up display bus */ /* touch screen */ #ifdef HW_TOUCH Touch_BusSetup(); /* set up touch screen */ #endif #ifdef ONEWIRE_IO_PIN /* OneWire with dedicated IO pin */ OneWire_Setup(); /* set up OneWire bus */ #endif /* * watchdog was triggered (timeout 2s) * - This is after the MCU done a reset driven by the watchdog. * - Does only work if the capacitor at the base of the power management * transistor is large enough to survive a MCU reset. Otherwise the * tester simply loses power. */ if (Test) { /* Display was initialized before but some global variables in the driver might be zeroed. Drivers with line tracking won't clear screen. */ LCD_Clear(); /* clear display */ #ifdef LCD_COLOR UI.PenColor = COLOR_TITLE; /* set pen color */ #endif Display_EEString(Timeout_str); /* display: timeout */ Display_NL_EEString(Error_str); /* display: error */ MilliSleep(2000); /* give user some time to read */ #ifdef POWER_SWITCH_SOFT POWER_PORT &= ~(1 << POWER_CTRL); /* power off myself */ #elif defined (POWER_SWITCH_MANUAL) /* enter sleep mode to prevent any further action */ /* user should power off tester */ set_sleep_mode(SLEEP_MODE_PWR_DOWN); /* set sleep mode to "power down" */ sleep_mode(); /* enter sleep mode */ #endif return 0; /* exit program */ } /* * operation mode selection * - short key press -> continuous mode * - long key press -> auto-hold mode * - very long key press -> reset to defaults */ Key = 0; /* reset key press type */ /* catch key press */ if (!(BUTTON_PIN & (1 << TEST_BUTTON))) /* test button pressed */ { Test = 0; /* ticks counter */ while (Key == 0) /* loop until we got a type */ { MilliSleep(20); /* wait 20ms */ if (!(BUTTON_PIN & (1 << TEST_BUTTON))) /* button still pressed */ { Test++; /* increase counter */ if (Test > 100) Key = 3; /* >2000ms */ } else /* button released */ { Key = 1; /* <300ms */ if (Test > 15) Key = 2; /* >300ms */ } } } #ifndef UI_SERIAL_COMMANDS /* key press >300ms selects alternative operation mode */ if (Key > 1) { #ifdef UI_AUTOHOLD /* change mode to continuous */ Cfg.OP_Mode &= ~OP_AUTOHOLD; /* clear auto-hold */ #else /* change mode to auto-hold */ Cfg.OP_Mode |= OP_AUTOHOLD; /* set auto-hold */ #endif } #endif #ifdef POWER_OFF_TIMEOUT /* automatic power-off for auto-hold mode */ if (Cfg.OP_Mode & OP_AUTOHOLD) /* in auto-hold mode */ { Cfg.OP_Control |= OP_PWR_TIMEOUT; /* enable power-off timeout */ } #endif /* * init display module */ #ifdef SW_DISPLAY_ID Cfg.DisplayID = 0; /* reset display ID */ #endif LCD_Init(); /* initialize LCD */ UI.LineMode = LINE_STD; /* reset next-line mode */ #ifdef LCD_COLOR UI.PenColor = COLOR_TITLE; /* set pen color */ #endif #ifdef HW_TOUCH Touch_Init(); /* init touch screen */ #endif /* * load saved adjustment offsets and values */ if (Key == 3) /* key press >2s resets to defaults */ { SetAdjustmentDefaults(); /* set default values */ } else /* normal mode */ { /* load adjustment values: profile #1 */ ManageAdjustmentStorage(STORAGE_LOAD, 1); } /* set extra stuff */ #ifdef SW_CONTRAST LCD_Contrast(NV.Contrast); /* set LCD contrast */ #endif /* * welcome user */ #ifdef UI_SERIAL_COPY Display_Serial_On(); /* enable serial output & NL */ #endif LCD_CharPos(4,4); Display_EEString(Tester_str); /* display: Component Tester */ LCD_CharPos(6,5); Display_EEString(Version_str); #ifdef SW_DISPLAY_ID /* show ID of display controller */ Display_Space(); /* display space */ Display_HexValue(Cfg.DisplayID, 16); /* display ID */ #endif #ifdef UI_SERIAL_COPY Display_Serial_Off(); /* disable serial output & NL */ #endif #ifdef LCD_COLOR UI.PenColor = COLOR_PEN; /* set pen color */ #endif MilliSleep(1500); /* let the user read the display */ /* * init variables */ /* cycling */ #if CYCLE_MAX < 255 MissedParts = 0; /* reset counter */ #endif Key = KEY_POWER_ON; /* just powered on */ /* default offsets and values */ Cfg.Samples = ADC_SAMPLES; /* number of ADC samples */ Cfg.AutoScale = 1; /* enable ADC auto scaling */ Cfg.Ref = 1; /* no ADC reference set yet */ Cfg.Vcc = UREF_VCC; /* voltage of Vcc */ /* MCU */ wdt_enable(WDTO_2S); /* enable watchdog: timeout 2s */ /* * user interaction after power-on */ #ifdef HW_TOUCH /* adjust touch screen if not done yet */ if ((Touch.X_Start == 0) && (Touch.X_Stop == 0)) /* defaults */ { Test = Touch_Adjust(); /* adjust touch screen */ if (Test == 0) /* error */ { LCD_ClearLine2(); Display_EEString(Error_str); /* display: Error */ MilliSleep(1000); /* smooth UI */ TestKey(2500, CURSOR_BLINK | CHECK_OP_MODE | CHECK_BAT); } } #endif #ifdef UI_CHOOSE_PROFILE /* select adjustment profile */ AdjustmentMenu(STORAGE_LOAD | STORAGE_SHORT); #endif /* * interrupts */ sei(); /* enable interrupts */ /* * main processing loop (probing cycle) */ cycle_start: /* reset variables */ Check.Found = COMP_NONE; /* no component */ Check.Type = 0; /* reset type flags */ Check.Done = DONE_NONE; /* no transistor */ Check.AltFound = COMP_NONE; /* no alternative component */ Check.Diodes = 0; /* reset diode counter */ Check.Resistors = 0; /* reset resistor counter */ Semi.Flags = 0; /* reset flags */ Semi.U_1 = 0; /* reset values */ Semi.U_2 = 0; Semi.U_3 = 0; Semi.F_1 = 0; #ifdef SW_REVERSE_HFE Semi.F_2 = 0; #endif Semi.I_value = 0; AltSemi.U_1 = 0; AltSemi.U_2 = 0; #ifdef UI_SERIAL_COMMANDS Info.Quantity = 0; /* zero components */ Info.Selected = 1; /* select first component */ Info.Flags = INFO_NONE; /* reset flags */ Info.Comp1 = NULL; /* reset pointer to first component */ Info.Comp2 = NULL; /* reset pointer to second component */ #endif #ifdef HW_KEYS UI.KeyOld = KEY_NONE; /* no key */ UI.KeyStepOld = 1; /* step size 1 */ #endif #ifdef SW_SYMBOLS UI.SymbolLine = 3; /* default: line #3 */ #endif /* reset hardware */ ADC_DDR = 0; /* set all pins of ADC port as input */ #ifdef HW_DISCHARGE_RELAY /* * This also enables the discharge relay via the external reference * and removes the short circuit. */ #endif UI.LineMode = LINE_KEEP; /* next-line mode: keep first line */ LCD_Clear(); /* clear LCD */ /* * voltage references */ CheckVoltageRefs(); /* manage voltage references */ /* * battery check */ #ifdef BAT_NONE /* no battery monitoring */ Display_EEString(Tester_str); /* display: Component Tester */ #else /* battery monitoring */ CheckBattery(); /* check battery voltage */ /* will power off on low battery */ ShowBattery(); /* display battery status */ #endif /* * probing */ #ifdef UI_SERIAL_COMMANDS /* skip first probing after power-on */ if (Key == KEY_POWER_ON) /* first cycle */ { goto cycle_control; /* skip probing */ /* will also change Key */ } #endif /* display start of probing */ Display_NL_EEString(Probing_str); /* display: probing... */ /* try to discharge any connected component */ DischargeProbes(); if (Check.Found == COMP_ERROR) /* discharge failed */ { goto show_component; /* skip all other checks */ } #ifdef UI_SHORT_CIRCUIT_MENU /* enter main menu if requested by short-circuiting all probes */ if (ShortedProbes() == 3) /* all probes short-circuited */ { Key = KEY_MAINMENU; /* trigger main menu */ goto cycle_action; /* perform action */ } #endif /* check all 6 combinations of the 3 probes */ CheckProbes(PROBE_1, PROBE_2, PROBE_3); CheckProbes(PROBE_2, PROBE_1, PROBE_3); CheckProbes(PROBE_1, PROBE_3, PROBE_2); CheckProbes(PROBE_3, PROBE_1, PROBE_2); CheckProbes(PROBE_2, PROBE_3, PROBE_1); CheckProbes(PROBE_3, PROBE_2, PROBE_1); CheckAlternatives(); /* process alternatives */ /* if component might be a capacitor */ if ((Check.Found == COMP_NONE) || (Check.Found == COMP_RESISTOR)) { /* tell user to be patient with large caps :-) */ Display_Space(); Display_Char('C'); /* check all possible combinations */ MeasureCap(PROBE_3, PROBE_1, 0); MeasureCap(PROBE_3, PROBE_2, 1); MeasureCap(PROBE_2, PROBE_1, 2); } /* * output test results */ show_component: LCD_Clear(); /* clear LCD */ /* next-line mode */ Test = LINE_KEEP | LINE_KEY; /* keep first line and wait for key/timeout */ #ifdef UI_SERIAL_COMMANDS if (Key == KEY_PROBE) /* probing by command */ { Test = LINE_KEEP; /* don't wait for key/timeout */ } #endif UI.LineMode = Test; /* change mode */ #ifdef UI_SERIAL_COPY Display_Serial_On(); /* enable serial output & NL */ #endif #ifdef UI_SERIAL_COMMANDS if (Check.Found >= COMP_RESISTOR) { Info.Quantity = 1; /* got one at least */ } #endif /* call output function based on component type */ switch (Check.Found) { case COMP_ERROR: Show_Error(); break; case COMP_DIODE: Show_Diode(); break; case COMP_BJT: Show_BJT(); break; case COMP_FET: Show_FET(); break; case COMP_IGBT: Show_IGBT(); break; case COMP_THYRISTOR: Show_ThyristorTriac(); break; case COMP_TRIAC: Show_ThyristorTriac(); break; case COMP_PUT: Show_PUT(); break; #ifdef SW_UJT case COMP_UJT: Show_UJT(); break; #endif case COMP_RESISTOR: Show_Resistor(); break; case COMP_CAPACITOR: Show_Capacitor(); break; default: /* no component found */ Show_Fail(); break; } #ifdef UI_SERIAL_COPY Display_Serial_Off(); /* disable serial output & NL */ #endif #ifdef SW_SYMBOLS /* display fancy pinout for 3-pin semiconductors */ if (Check.Found >= COMP_BJT) /* 3-pin semi */ { if (UI.SymbolLine) /* not zero */ { LCD_FancySemiPinout(UI.SymbolLine); /* display pinout */ } } #endif #ifdef UI_SERIAL_COMMANDS if (Key == KEY_PROBE) /* probing by command */ { Display_Serial_Only(); /* switch output to serial */ Display_EEString_NL(Cmd_OK_str); /* send: OK & newline */ Display_LCD_Only(); /* switch output back to display */ /* We don't have to restore the next-line mode since it will be changed a few line below anyway. */ } #endif #if CYCLE_MAX < 255 /* component was found */ if (Check.Found >= COMP_RESISTOR) { MissedParts = 0; /* reset counter */ } #endif /* * manage cycling and power-off */ cycle_control: #ifdef HW_DISCHARGE_RELAY /* discharge relay: short circuit probes */ /* ADC_PORT should be 0 */ ADC_DDR = (1 << TP_REF); /* disable relay */ #endif #ifdef SERIAL_RW Serial_Ctrl(SER_RX_RESUME); /* enable TTL serial RX */ #endif UI.LineMode = LINE_STD; /* reset next-line mode */ /* wait for key press or timeout */ #ifdef UI_KEY_HINTS Display_LastLine(); UI.KeyHint = (unsigned char *)Menu_or_Test_str; Key = TestKey((uint16_t)CYCLE_DELAY, CURSOR_BLINK | CURSOR_TEXT | CHECK_OP_MODE | CHECK_KEY_TWICE | CHECK_BAT); #else Key = TestKey((uint16_t)CYCLE_DELAY, CURSOR_BLINK | CHECK_OP_MODE | CHECK_KEY_TWICE | CHECK_BAT); #endif if (Key == KEY_TIMEOUT) /* timeout (no key press) */ { /* implies continuous mode */ #if CYCLE_MAX < 255 /* check if we reached the maximum number of missed parts in a row */ if (MissedParts >= CYCLE_MAX) { Key = KEY_POWER_OFF; /* signal power off */ } #endif } else if (Key == KEY_TWICE) /* two short key presses */ { Key = KEY_MAINMENU; /* signal main menu */ } else if (Key == KEY_LONG) /* long key press */ { Key = KEY_POWER_OFF; /* signal power off */ } #ifdef HW_KEYS else if (Key == KEY_LEFT) /* rotary encoder: left turn */ { Key = KEY_MAINMENU; /* signal main menu */ } #endif #ifdef SERIAL_RW else if (Key == KEY_COMMAND) /* remote command */ { #ifdef UI_SERIAL_COMMANDS Key = KEY_NONE; /* reset key */ Display_Serial_Only(); /* switch output to serial */ Test = GetCommand(); /* get command */ if (Test != CMD_NONE) /* valid command */ { Key = RunCommand(Test); /* run command */ } Display_LCD_Only(); /* switch output back to display */ /* if we got a virtual key perform requested action */ if (Key != KEY_NONE) goto cycle_action; #endif goto cycle_control; /* re-run cycle control */ } #endif #if defined (UI_SHORT_CIRCUIT_MENU) || defined (UI_SERIAL_COMMANDS) cycle_action: #endif #ifdef SERIAL_RW Serial_Ctrl(SER_RX_PAUSE); /* disable TTL serial RX */ /* todo: when we got a locked buffer meanwhile? */ #endif if (Key == KEY_MAINMENU) /* run main menu */ { #ifdef SAVE_POWER /* change sleep mode the Idle to keep timers & other stuff running */ Test = Cfg.SleepMode; /* get current mode */ Cfg.SleepMode = SLEEP_MODE_IDLE; /* change sleep mode to Idle */ #endif #ifdef HW_DISCHARGE_RELAY /* discharge relay: remove short circuit */ ADC_DDR = 0; /* enable relay (via external reference) */ /* todo: move this to MainMenu()? (after selecting item) */ #endif #ifdef POWER_OFF_TIMEOUT /* automatic power-off for auto-hold mode */ if (Cfg.OP_Mode & OP_AUTOHOLD) /* in auto-hold mode */ { Cfg.OP_Control &= ~OP_PWR_TIMEOUT; /* disable power-off timeout */ } #endif MainMenu(); /* enter main menu */ #ifdef POWER_OFF_TIMEOUT /* automatic power-off for auto-hold mode */ if (Cfg.OP_Mode & OP_AUTOHOLD) /* in auto-hold mode */ { Cfg.OP_Control |= OP_PWR_TIMEOUT; /* enable power-off timeout */ } #endif #ifdef SAVE_POWER /* change sleep mode back */ Cfg.SleepMode = Test; /* change sleep mode back */ #endif goto cycle_control; /* re-run cycle control */ } else if (Key == KEY_POWER_OFF) /* power off */ { PowerOff(); /* power off */ } else /* default action */ { goto cycle_start; /* next round */ } return 0; } /* ************************************************************************ * clean-up of local constants * ************************************************************************ */ /* source management */ #undef MAIN_C /* ************************************************************************ * EOF * ************************************************************************ */
Unterschied finden