Transistor Tester for Arduino

Xumuk
Xumuk аватар
Offline
Зарегистрирован: 03.03.2016

спасибо помогло, теперь че то программатор от про мини моросит не шьет=) напасть какая то

NalisniyRoman
Offline
Зарегистрирован: 17.06.2019

Господа, не пойму в чем проблема. Собрал на нано и 16*2 дисплее. Работает не понятно. Коротишь выводы, везде 0 ом. Между 1 и 2 резистор 1к как 12 ом показывает. Между 2-м и 3-м, 3-м и 1-м вообще не видит, показывает полевой транзистор.
Ставлю полевик 2n7000 - показывает через раз. Переворачиваю зеркально- полевик показывает как биполярный. Что делать?

Xumuk
Xumuk аватар
Offline
Зарегистрирован: 03.03.2016

у наны еще светодиод вроде мешать может

NalisniyRoman
Offline
Зарегистрирован: 17.06.2019

Я сопротивление выпаял которое на диод с 13-го пина шло.

Диод тоже. Флюс отмыл сразу

xfvlad
Offline
Зарегистрирован: 06.02.2021

Еще желательно конденсатор на aref выпаять

NalisniyRoman
Offline
Зарегистрирован: 17.06.2019

Изначально не паял. Я не пойму, калибровка в нем есть? А то кнопку как не нажимаю (долгий короткий тапы)

не заходит. В коде selftest раскомментировал- тоже не помогло.

Паял еще по Ютубу- схема незначительно отличается и прошиваешь hex'ами eeprom'ами.

Там в самотест входит, но на тесте конденсаторов лагает и в итоге не работает.

Тоже на пустых щупах полевик с дикими параметрами показывает

R-998
Offline
Зарегистрирован: 23.02.2022

Приветствую всех , собрал по схеме из 298 сообщения на клоне уно , прошил скетчем из архива оттуда же изменив лишь подключение дисплея (LiquidCrystal lcd(7, 8, 2, 3, 4, 5);) и из за этого не собрана цепь 1го щупа , все включается и выдает нормально стартовую надпись но при нажатии на кнопку тест появляется на долю секунды надпись Ттестер тестинг и резко изчезает , остаются лишь темные прямоугольники по всему экрану , куда стоит копать ? Диод L выпаял по совету с другого форума , не помогло , подскажите что я делаю не так ? 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

R-998, а если собрать без изменений, работает?

R-998
Offline
Зарегистрирован: 23.02.2022

Дисплей припаян к ардуинке , остатки другого проекта , собрать то можно , но может можно не отдирать термоклей от ардуины что бы это все собрать ?) Из за чего вообще может быть такая проблема ? Мне думается что это конфликт как раз припайки дисплея на 8 вывод ардуино 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Я предложил самое дешевое решение, если Вам хочется дороже - разбирайтесь сами (за свой счет).

Vit04
Offline
Зарегистрирован: 21.04.2022

 

Комментарий на пост #663 Тапками не кидайте, пожалуйста.

Здравствуйте. Хотя уже и 2022 год но тема с Pro Micro еще актуальная. Спасибо Вам за труды. Собрал схему на макетной плате, все отлично работает в USB serial. Если не трудно вышлите в личку реально работающий проект для Proteus и разводку в Sprint-Layout. 

Если Вам еще близка тема про Ardutester на Pro Micro, ниже ссылка (компилируется без ошибок) с просторов интернета (https://github.com/tehniq3/Ardutester/blob/master/ardutester_ver06m.ino), где реализуется вывод на LCD ?. Сам не силен в программировании, разобраться не смог.   :(

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Vit04 код желательно свернуть - там есть галочка соответствующая (Сворачитьвать код по умолчанию (управляющие элементы должным быть включены))

Что в итоге надо я не понял ...

0033 #define LCD_PRINT                                //Print on I2C LCD
0034 #define DEBUG_PRINT                              //Print on Serial Port

 

Vit04
Offline
Зарегистрирован: 21.04.2022

Извините не разобрался.

Если не трудно вышлите пожалуйста на vitallix2009@yandex.ruреально работающий проект для Proteus и разводку в Sprint-Layout. из поста #663 на Pro Micro.

Эта версия скетча (https://github.com/tehniq3/Ardutester/blob/master/ardutester_ver06m.ino) будет работать на Pro Micro ? Я не разобрался с подключением резисторов, что и куда. Так как схем нет, пытался по описанию, но цифровых некоторых пинов на Pro Micro нет. Спасибо за помощь.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Vit04 не уверен что найду (но постараюсь). Там же есть в посте и картинки и скетч.

Vit04
Offline
Зарегистрирован: 21.04.2022

Здравствуйте Все Уважаемые Форумчане. Благодаря трудам Komandir  пост #663 , возникла идея.

В основном все электронщики работают за столом над своими проектами, и 100 % рядом компьютер с монитором.

Предлагаю на основе Arduino Pro Micro создать лабораторный ardutester-PC с выводом информации на мониторе (окно "ardutester-PC" поверх всех экранов c ...) Так как сам не силен в программировании, то моя идея должна кому-то понравиться для реализации.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Vit04 пишет:

Здравствуйте Все Уважаемые Форумчане. Благодаря трудам Komandir  пост #663 , возникла идея.

нарушен порядок хода, сначала ... мысль, а уж затем ... идея )))

Vit04
Offline
Зарегистрирован: 21.04.2022

Хорошо. Мысль: Ardutester-PC. Идея: использовать Pro Micro.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Может сразу к gyver пойдете ?

Vit04
Offline
Зарегистрирован: 21.04.2022

С Вашими знаниями Alex Вам будет рад. А что, никак из порта взять данные и не сможет их визуализировать? Кстати Ваш скетч все это позволяет.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Vit04 файл для Proteus отправил. Макет платы не нашел, но по картинке в посте легко можно нарисовать.

Не понимаю чего вы хотите - откройте окно терминала и смотрите там на результаты измерений.

Vit04
Offline
Зарегистрирован: 21.04.2022

Komandir пишет:

Vit04 файл для Proteus отправил. Макет платы не нашел, но по картинке в посте легко можно нарисовать.

Не понимаю чего вы хотите - откройте окно терминала и смотрите там на результаты измерений.

Komandir. Спасибо за понимание.

Интересно было-бы сделать проект на Pro Micro специально стационарный с выводом на монитор ПК красивой и понятной графикой.

b707
Offline
Зарегистрирован: 26.05.2017

Vit04 пишет:

Интересно было-бы сделать проект на Pro Micro специально стационарный с выводом на монитор ПК красивой и понятной графикой.

интересно - делайте.

Чтобы была понятна реакция - у нас тут не очень любят тех, кто предлагает идеи, которые должны реализовывать другие.

Если есть идея - отлично, пробуйте, делайте. Форум поддержит. Если пока не умеете программировать - значит учитесь, как научитесь - так и идею свою реализуете.

UlfurNorth
Offline
Зарегистрирован: 28.05.2022

Здравствуйте. Использую прошивку v1.13 и никак не могу заставить работать тестер с дисплеем Oled 0.96" i2c. Изначально подключал sda/scl к A4/A5 arduino, затем покопался в коде и нашёл что в файле "config.h" эти пины для 328 процессора определены как цифровые PORTD 5 и PORTD 2, потому подпаялся к ним, но дисплей всё так же не работал. В файле "Makefile.h" при этом раскоментированы нужные строки для работы с OLED 1306 i2c. Также проверил адрес экрана, у меня он 0x3c, что совпадает с прописанным в файле прошивки.
Но вот если попробовать выводить данные в монитор порта, предварительно раскоментировав нужные строки, то это работает, а с экранчиком не хочет. :(
Пробовал ещё прошивку версии 1.08, на ней oled работает. Изначально на ней и сидел, но там не удаётся запустить калибровку устройства, хотя в коде скетча строки для этого присутствуют. Также и eeprom там не работает, выдаёт непонятные символы вместо текста, если раскоментировать использование eeprom. Видимо раз версия урезанная, без меню и автокалибровки, то использование eeprom там бессмысленно.

Буду очень благодарен если знающие люди смогут что-то подсказать или посоветовать по поводу отказа в работе дисплея на прошивке v1.13, потому что сам уже не могу разобраться, два дня пытался, знаний не хватает.
Собирал устройство по самой простой схеме, из-за очень сильного дефицита радиодеталей. В схеме 3шт-R470k, 3шт-R680 Ом, кнопка теста с подтягивающим резистором на пин +5v номиналом в 10k, Oled i2c и Arduino Nano, с которой удалил резистор со светодиода на 13-ом пине, также тройная винтовая клемма для проводов в качестве "разъёма" под тестирование компонентов.. Может дело в самой ардуино, типа не тянет? - но видел у других что работает и на ней экран с этой версией прошивки, либо может проблема в том, что использую для прошивки скетч ардуино, так как слышал есть ещё полные прошивки, которые затирают загрузчик. Или для работы с этой прошивкой компонентов должно быть больше чем 7 резисторов и кнопка?

Также всё ещё копаюсь в коде прошивки версии 1.08, пытаясь заставить работать на ней калибровку, но пока безрезультатно. На самом деле странно, потому что видел комментарии на форумах по обсуждёнию этой версии прошивки, где люди упомянали что-то вроде "первым делом запустил само тестирование", что означает что оно у них работает и лишь в 2-х комментариях из всей массы кто-то пишет что оно не запускается, ни при замыкании всех контактов, ни при зажатии затем кнопки, при раскоментированных строках, что очень странно, ведь прошивка одна и та же, но у кого-то работает selftest/auto_cal, а у кого-то - нет. Ответов на такие коментарии нет, наверное потому что проблема не массовая и никто этим не занимался. Но всё же надеюсь кто-то с этим сталкивался и разбирался, возможно здесь, поэтому обратился к вам.

По поводу не работы Oled 0.96" SSD1306 i2c на прошивке v1.13. Общался с одним человеком на зарубежном youtube канале, у того была подобная проблема.
Если верить переводу гугл переводчика, то он ответил "У меня есть два OLED с той же проблемой, все они не подключены к источнику питания потому мне приходится повторять заводскую пайку", не совсем понял о чём он, возможно о каком-то браке в заводской пайке модуля дисплея, но сомневаюсь что проблема в этом, в других проектах дисплей ведь работает, как и в версии прошивки 1.08. Скорее всего дело в коде ПО 1.13, может где-то ещё нужно что-то изменить, какие-либо коды для включения/отключения дисплея, либо что-то ещё.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Без кода говорить не о чём ... SDA SCL аппаратного I2C на 328 это A4 A5 !

UlfurNorth
Offline
Зарегистрирован: 28.05.2022

Да, вы правы. Извините, совсем забыл про код.
Использую данную прошивку.
https://disk.yandex.ru/d/6XV5sK5FZ0SohA

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Файл lcd_hw_4_bit.ino

Строка 688

if (preg_1==0) Wire.write(0x80); else Wire.write(0x40)

поменять на

if (preg_1==0) Wire.write(0x00); else Wire.write(0x40)

Цеплять естественно на A4 A5 !

UlfurNorth
Offline
Зарегистрирован: 28.05.2022

На A4, A5 цеплял и экран не загорелся.
Также пробовал проверять так: загружал любой скетч, где используется экран и на него что-то выводится, затем прошивал следом прошивку тестера v1.13 и после окончания процесса прошивки и перезагрузки платы ардуино экран просто гаснет всё с тем же подключением к A4 A5.Питание при этом на него поступает, на scl/sda также присутствует напряжение, что-то около 3.xx вольт.

UlfurNorth
Offline
Зарегистрирован: 28.05.2022

Прошу прощения, невнимательно прочитал ваш ответ. Сейчас исправлю код.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

А файл то исправили ??? 

P.S.   :-D

UlfurNorth
Offline
Зарегистрирован: 28.05.2022

Теперь исправил, но к сожалению это не помогло.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Там же в 682 строке

#elif (LCD_INTERFACE_MODE == MODE_I2C)

меняем на 

#elif (LCD_INTERFACE_MODE == 2)

кто это накрутил - сам забыл что где ???

UlfurNorth
Offline
Зарегистрирован: 28.05.2022

Действительно странно. Скачивал прошивки из трёх разных источников и нигде не завёлся дисплей, видимо везде присутствуют одни и те же ошибки.указанные вами.
Значение в 682 заменил - без изменений, видимо там много всего нужно заменять, чтобы заработало.

UlfurNorth
Offline
Зарегистрирован: 28.05.2022

Строку 682 можно оставить в том же виде что и была:
#elif (LCD_INTERFACE_MODE == MODE_I2C)
Так как в данном случае переменной MODE_I2C присваивается значение "2" в файле "config.h", далее в том же файле значение этой переменной сравнивается со значением переменной "LCD_INTERFACE_MODE" в строке #631, затем определяется адрес экрана вида 0x3C при условии что значение переменных LCD_INTERFACE_MODE и MODE_I2C равны, а они в данном случае равны, так как в файле Makefile.h для OLED 1306 i2c для переменной LCD_INTERFACE_MODE значение стоит равное 2-м.
По идее всё правильно, но почему экран по прежнему не хочет работать ума не приложу.

UlfurNorth
Offline
Зарегистрирован: 28.05.2022

В файле lcd_hw_4_bit.ino строки с #682 по #692, там есть комментарий "// I2C working, tested with OLED Kuman KY34 , use Arduino dedicated I2C Pins SDA,SCL with full speed" - "// I2C работает, протестирован с OLED Kuman KY34, использует выделенные Arduino контакты I2C SDA, SCL с полной скоростью".
Может есть какие-либо различия у OLED Kuman KY34 и OLED SSD1306 заказанного из Китая, в любом случае наверное нужно что-то экспериментировать с этой частью кода, уже не знаю даже..

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Чем вы компилируете проект ? Ошибки Варнинги не сыпет ???

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Чем вы компилируете проект ? Ошибки Варнинги не сыпет ???

UlfurNorth
Offline
Зарегистрирован: 28.05.2022

Компилирую Arduino 1.8.19, ни ошибок не варнингов никаких нет, всё компилируется и загружается без каких-либо проблем.

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Настройка -> Сообщения компилятора -> Все

UlfurNorth
Offline
Зарегистрирован: 28.05.2022

Так, с включением этого пункта действительно посыпались варнинги.
https://disk.yandex.ru/d/Ah8CTXSvXdI6pg
Получается нужно исправлять значение SCREEN_HIGHT, LCD_LINES и всё другое на что указывают предупреждения?

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Так ArduTester_more.ino вроде заколосилось:




  #include <avr/io.h>
	#include <util/delay.h>
	#include <avr/sleep.h>
	#include <stdlib.h>
  #include "stdint.h" //JLG
	#include <string.h>
	#include <avr/eeprom.h>
	#include <avr/pgmspace.h>
	#include <avr/wdt.h>
	#include <math.h>
  #include <Wire.h>
	
	#define MAIN_C

	#include "Makefile.h" //JLG
	#include "Transistortester.h"
	#include "config.h"
	#include "part_defs.h"
	#include "lcd_routines.h"
	#include "lcd_defines.h"
	#include "wait1000ms.h"
	#include "autoconf.h"
	#include "tt_function.h"
  #include "tt_resistor.h"
  #include "font.h"
  #include "24x32update_bitmaps.h"

	
/* defines global variables in RAM and EEprom from file tt_globals.h */
/* removed ifdef MAIN_C because always defined */
#define COMMON
#ifdef AUTO_CAL
  const int8_t RefDiff EEMEM = REF_R_KORR;	// correction of internal Reference Voltage

//  const uint16_t cap_null EEMEM = C_NULL;	// Zero offset of capacity measurement 
   const int16_t ref_offset EEMEM = REF_C_KORR;	// default correction of internal reference voltage for capacity measurement
   // the zero offset for capacity measurement for all pin combinations
  // LoPin:HiPin                        2:1    3:1    1:2                    marker  3:2                   1:3    2:3
   const uint8_t c_zero_tab[] EEMEM = { C_NULL,C_NULL,C_NULL+TP2_CAP_OFFSET,C_NULL+2,C_NULL+TP2_CAP_OFFSET,C_NULL,C_NULL }; //table of zero offsets
   // if the marker position of c_zero_tab is not equal the first position, the calibration has not run before
#endif
#ifdef SamplingADC
   const uint16_t c_zero_tab2_lo[] EEMEM = { C_NULL*100,C_NULL*100,C_NULL*100,C_NULL*100,C_NULL*100,C_NULL*100,C_NULL*100 };   // zero offsets for SamplingADC capacitance measurement, in 0.01 pF, lo voltage
   const uint16_t c_zero_tab2_hi[] EEMEM = { C_NULL*100,C_NULL*100,C_NULL*100,C_NULL*100,C_NULL*100,C_NULL*100,C_NULL*100 };   // same, hi voltage
#endif
#ifdef WITH_MENU
   const int8_t big_cap_corr EEMEM = C_H_KORR;	// default correction for big capacity measurement
 #if defined(WITH_FREQUENCY_DIVIDER) && !defined(NO_FREQ_COUNTER)
  #ifndef FREQ_SCALER
   #define FREQ_SCALER 0		// 1<<0 = 1
  #endif
  const uint8_t f_scaler EEMEM = FREQ_SCALER;	// default scaler for frequency measurement
 #endif
#endif

  const uint8_t EE_ESR_ZEROtab[] EEMEM = {ESR_ZERO, ESR_ZERO, ESR_ZERO, ESR_ZERO};	// zero offset of ESR measurement
#ifdef WITH_ROTARY_SWITCH
//  const uint8_t EE_RotarySwitch EEMEM = 0;	// rotation switch is not detected
#endif
#if ((LCD_ST_TYPE == 7565) || (LCD_ST_TYPE == 1306) || (LCD_ST_TYPE == 8812) || (LCD_ST_TYPE == 8814) || defined(LCD_DOGM))
  const uint8_t EE_Volume_Value EEMEM = VOLUME_VALUE;	// Volume Value for ST7565 controller 
#endif
#ifdef LCD_CHANGE_COLOR
  const uint8_t EE_BG_COLOR1 EEMEM = LCD_BG_COLOR & 0xff;	// lower bits of background color
  const uint8_t EE_BG_COLOR2 EEMEM = LCD_BG_COLOR >> 8;		// higher bits of background color 
  const uint8_t EE_FG_COLOR1 EEMEM = LCD_FG_COLOR & 0xff;	// lower bits of foreground color
  const uint8_t EE_FG_COLOR2 EEMEM = LCD_FG_COLOR >> 8;		// higher bits of foreground color 
#endif

struct Diode_t {
  uint8_t Anode[6];
  uint8_t Cathode[6];
  unsigned int Voltage[6];
};
COMMON struct Diode_t diodes;

struct Switch_t {

  union {
  unsigned long Pw;	// combined Mask
  uint8_t R[4];	// mask to switch a Pin with R_L,  mask to switch a Pin with R_H
  } Pin;

};

COMMON uint8_t NumOfDiodes;
COMMON uint8_t diode_sequence;

typedef struct {
  unsigned long hfe;		//current amplification factor 
  unsigned int uBE;		//B-E-voltage of the Transistor or RDS for E-MOS; Idss for JFET
  unsigned int current;		// current of Drain in 1uA
  unsigned int ice0;		// for BJT ICEO in 1uA; for FET cut-off voltage in mV
  unsigned int gthvoltage;	//Gate-threshold voltage 
  				// for bipolar gthvoltage is ICEs in 1uA
 #define ices gthvoltage
	// note: don't change the total size of the above fields, since the offsets of the following 3 fields are hard-coded in PinLayout.S
  uint8_t b,c,e;		//pins of the Transistor
  uint8_t count;
}trans_t;

COMMON trans_t ptrans;		// parameters of P type transistor
COMMON trans_t ntrans;		// parameters of N type transistor
COMMON trans_t *_trans;		// pointer to trans_t structure

COMMON uint8_t tmpval, tmpval2;
COMMON unsigned int ref_mv;      //Reference-voltage  in mV units (as read with ADC)
COMMON unsigned int ref_mv_offs;       //Reference-voltage  in mV units with eeprom offset for C
COMMON unsigned int adc_internal_reference;  //internal reference voltage of ADC in mV units
COMMON unsigned int adc_vcc_reference;  // reference voltage of ADC,if switched to VCC in mV units
COMMON  unsigned int RHmultip;	// Multiplier for capacity measurement with R_H (470KOhm)

#ifdef WITH_MENU
COMMON union t_frq{
  unsigned long dw;
  uint16_t w[2];
  uint8_t b[4];
} ext_freq;	// external frequency
//COMMON unsigned long ext_period; 
COMMON unsigned int pinchange_count;
COMMON unsigned int pinchange_max;
#endif

COMMON struct cap_t {
  // Attention! If you change this structure, you must also change defines in GetESR.S !!!!
  unsigned long cval;		// capacitor value 
  unsigned long cval_max;	//capacitor with maximum value
  union t_combi{
  unsigned long dw;	// capacity value without corrections
  uint16_t w[2];
  } cval_uncorrected;

#if FLASHEND > 0x1fff
  unsigned int esr;		// serial resistance of C in 0.01 Ohm
  unsigned int v_loss;		// voltage loss 0.1%
#endif

  uint8_t ca, cb;		//pins of capacitor
  int8_t cpre;			//Prefix for capacitor value  -12=p, -9=n, -6=µ, -3=m
  int8_t cpre_max;		//Prefix of the biggest capacitor
} cap;
  unsigned int cell_mv[3];	//remaining load voltages after discharge cycle

#ifndef INHIBIT_SLEEP_MODE
 /* with sleep mode we need a global ovcnt16 */
COMMON volatile uint16_t ovcnt16;
COMMON volatile uint8_t unfinished;
#endif

COMMON int16_t load_diff;		// difference voltage of loaded capacitor and internal reference

COMMON uint8_t WithReference;		// Marker for found precision voltage reference = 1
COMMON uint8_t PartFound;	 	// type of the found part 
COMMON uint8_t PartMode;		// description of the found part
COMMON char outval[10];			// String for ASCII-output i2lcd, u2lcd
//COMMON char OutBuffer[10];		// String for ASCII-output DisplayValue
COMMON uint8_t empty_count;		// counter for max count of empty measurements
COMMON uint8_t mess_count;		// counter for max count of nonempty measurements

COMMON struct ADCconfig_t {
  uint8_t Samples;		// number of ADC samples to take
  uint8_t RefFlag;		// save Reference type VCC of IntRef
  uint16_t U_Bandgap;		// Reference Voltage in mV
  uint16_t U_AVCC;		// Voltage of AVCC
} ADCconfig;

#ifdef AUTO_CAL
COMMON uint8_t pin_combination;		// coded Pin-combination  2:1,3:1,1:2,x:x,3:2,1:3,2:3
COMMON uint16_t resis680pl;	// port output resistance + 680
COMMON uint16_t resis680mi;	// port output resistance + 680
COMMON uint16_t pin_rmi;	// port output resistance to GND side, 0.1 Ohm units
COMMON uint16_t pin_rpl;	// port output resistance to VCC side, 0.1 Ohm units
COMMON uint8_t UnCalibrated;	// 0, if the tester is calibrated
#endif

#ifdef WITH_ROTARY_SWITCH
 #define ROT_MSK 0x03		/* must be power of two - 1: 3,7,15 */
struct Rotary_t {
 uint8_t state[(ROT_MSK+1)];	// coded state history of the rotatry switch, bit 0 == state of A-switch, bit 1 = state of B-switch
 uint8_t ind;		// index to the last entry of the state history (rotary switch)
 int8_t count;		// count of right steps, negative if left steps
 uint8_t incre;		// absolute value of step count
 #if WITH_ROTARY_SWITCH == 4
 // no rotary switch connected, UP and DOWN  key is present
 uint8_t a_state;	// history of switch A state for single UP switch
 uint8_t b_state;	// history of switch B state for single DOWN switch
 #endif
};
COMMON struct Rotary_t rotary;
COMMON uint8_t rotary_switch_present;	// is set to 1, if rotary switch movement is detected
// COMMON  const uint8_t EE_RotarySwitch; 	// rotation switch is detected
#endif
#if FLASHEND > 0x1fff
COMMON uint8_t DC_Pwr_mode;
#endif

COMMON uint8_t lcd_text_line;
COMMON uint8_t _lcd_column;

COMMON uint8_t last_line_used;
//#if POWER_OFF+0 > 1
COMMON unsigned int display_time;	// display time of measurement in ms units
//#endif
#if (LCD_ST_TYPE == 7920)
COMMON uint8_t lcd_bit_mem[64][16];
#endif
#if ((LCD_ST_TYPE == 7565) || (LCD_ST_TYPE == 1306) || defined(LCD_DOGM))
 //COMMON const uint8_t EE_Volume_Value EEMEM;   // Volume Value for ST7565 controller 
#endif
#ifdef LCD_CHANGE_COLOR
COMMON union {
  uint16_t w;
  uint8_t b[2];
} lcd_bg_color;
#endif
#if defined(LCD_CHANGE_COLOR) || defined(LCD_ICON_COLOR)
COMMON union {
  uint16_t w;
  uint8_t b[2];
} lcd_fg_color;
#endif
#if defined(LCD_ICON_COLOR)
COMMON union {
  uint16_t w;
  uint8_t b[2];
} lcd_fg2_color;
#endif
/* END defines global variables in RAM and EEprom from file tt_globals.h */


	#ifndef INHIBIT_SLEEP_MODE
	  // prepare sleep mode
	  EMPTY_INTERRUPT(TIMER2_COMPA_vect);
	#endif
        #if !defined(INHIBIT_SLEEP_MODE) || defined(SamplingADC)
	  // ADC_vect is always required by samplingADC()
	  EMPTY_INTERRUPT(ADC_vect);
        #endif




/**************************************************
***      begin of transistortester program
***************************************************/
static const uint8_t PROGMEM init_bytes[]={0x00,0xAE,0xD5,0x80,0xA8,0x3F,0xD3,0x00,0x40,0x8D,0x14,0x20,0x00,0xA1,0xC8,
                                           0xDA,0x12,0xD9,0xF1,0xDB,0x40,0xA4,0xA6,0xAF};
void setup() {
    Wire.begin();
  Wire.setClock(100000);
  Wire.beginTransmission(0x3c);
  for (uint8_t i=0; i<sizeof(init_bytes); i++) {
    Wire.write(pgm_read_byte(init_bytes+i));
  }
  Wire.endTransmission();
  
#ifdef WITH_HARDWARE_SERIAL
 Serial.begin(115200); // Serial Monitor
#endif

//#ifdef ARDUINO_UNO
// pinMode(A3,INPUT_PULLUP);// avoids external 10K Pullup
//#endif
	  uint8_t ii;
	  unsigned int max_time;
	#ifdef SEARCH_PARASITIC
	  unsigned long n_cval;		// capacitor value of NPN B-E diode, for deselecting the parasitic Transistor
	  int8_t n_cpre;		// capacitor prefix of NPN B-E diode
	#endif
	#ifdef WITH_GRAPHICS
	  unsigned char options;
	#endif
        uint8_t vak_diode_nr;		// number of the protection diode of BJT
        union {
        uint16_t pw;
        uint8_t pb[2];
        } rpins;
        uint8_t x, y, z;
	  //switch on
	  ON_DDR = (1<<ON_PIN);			// switch to output
	  ON_PORT = (1<<ON_PIN); 		// switch power on 
	#ifndef PULLUP_DISABLE
	  RST_PORT |= (1<<RST_PIN); 	// enable internal Pullup for Start-Pin
	#endif
	  uint8_t tmp;
	  //ADC-Init
	  ADCSRA = (1<<ADEN) | AUTO_CLOCK_DIV;	//prescaler=8 or 64 (if 8Mhz clock)
	#ifdef __AVR_ATmega8__
	// #define WDRF_HOME MCU_STATUS_REG
	 #define WDRF_HOME MCUCSR
	#else
	 #define WDRF_HOME MCUSR
	 #if FLASHEND > 0x3fff
	  // probably was a bootloader active, disable the UART
	  UCSR0B = 0;		// disable UART, if started with bootloader
	 #endif
	#endif
          wait500ms();

	#if (PROCESSOR_TYP == 644) || (PROCESSOR_TYP == 1280)
	 #define BAUD_RATE 9600
//	  UBRR0H = (F_CPU / 16 / BAUD_RATE - 1) >> 8;
//	  UBRR0L = (F_CPU / 16 / BAUD_RATE - 1) & 0xff;
//	  UCSR0B = (1<<TXEN0);
//	  UCSR0C = (1<<USBS0) | (3<<UCSZ00);	// 2 stop bits, 8-bit
//	  while (!(UCSR0A & (1<<UDRE0))) { };	// wait for send data port ready 
         #ifdef SWUART_INVERT
	  SERIAL_PORT &= ~(1<<SERIAL_BIT);
         #else
	  SERIAL_PORT |= (1<<SERIAL_BIT);
         #endif
          SERIAL_DDR |= (1<<SERIAL_BIT);
	#endif

	  tmp = (WDRF_HOME & ((1<<WDRF)));	// save Watch Dog Flag
	  WDRF_HOME &= ~(1<<WDRF);	 	//reset Watch Dog flag
	  wdt_disable();			// disable Watch Dog
	#ifndef INHIBIT_SLEEP_MODE
	  // switch off unused Parts
	 #if PROCESSOR_TYP == 644
          #ifdef PRUSART1
	  PRR0 = (1<<PRTWI) |  (1<<PRSPI) | (1<<PRUSART1);
          #else
	  PRR0 = (1<<PRTWI) |  (1<<PRSPI) ;
          #endif
	//  PRR1 =  (1<<PRTIM3) ;
	 #elif PROCESSOR_TYP == 1280
	  PRR0 = (1<<PRTWI) |  (1<<PRSPI) | (1<<PRUSART1);
	  PRR1 = (1<<PRTIM5) | (1<<PRTIM4) | (1<<PRTIM3) | (1<<PRUSART3) | (1<<PRUSART2) | (1<<PRUSART3);
	 #else
	  PRR = (1<<PRTWI) | (1<<PRSPI) | (1<<PRUSART0);
	 #endif
//	disable digital inputs of Analog pins, but TP1-3 digital inputs must be left enabled for VGS measurement
	  DIDR0 = ((1<<ADC5D) | (1<<ADC4D) | (1<<ADC3D) | (1<<ADC2D) | (1<<ADC1D) | (1<<ADC0D)) & ~((1<<TP3) | (1<<TP2) | (1<<TP1));	
	  TCCR2A = (0<<WGM21) | (0<<WGM20);		// Counter 2 normal mode
	  TCCR2B = CNTR2_PRESCALER;	//prescaler set in autoconf
	#endif		/* INHIBIT_SLEEP_MODE */
	  sei();				// enable interrupts
	  //lcd_init();				//initialize L

		
	//  ADC_PORT = TXD_VAL;
	//  ADC_DDR = TXD_MSK;
	  if(tmp) { 
	     // check if  Watchdog-Event 
	     // this happens, if the Watchdog is not reset for 2s
	     // can happen, if any loop in the Program doen't finish.
	     lcd_line1();
             lcd_MEM_string(TestTimedOut);	//Output Timeout
	     wait_about3s();			// time to read the Timeout message
	     switch_tester_off();
//	     return 0;
	  }

	#ifdef PULLUP_DISABLE
	 #ifdef __AVR_ATmega8__
	  SFIOR = (1<<PUD);		// disable Pull-Up Resistors mega8
	 #else
	  MCUCR = (1<<PUD);		// disable Pull-Up Resistors mega168 family
	 #endif
	#endif

	//#if POWER_OFF+0 > 1
	  // tester display time selection
	#ifndef USE_EEPROM
	  EE_check_init();		// init EEprom, if unset
	#endif
	#ifdef WITH_ROTARY_SWITCH
	//  rotary_switch_present = eeprom_read_byte(&EE_RotarySwitch);
	  rotary.ind = ROT_MSK+1;		//initilize state history with next call of check_rotary()
	#endif
#ifdef WITH_HARDWARE_SERIAL
//	ii = 60;
	ii = 30;
#else
	#if 1
	  for (ii=0; ii<60; ii++) {
		if (RST_PIN_REG & (1 << RST_PIN))
			break;	// button is released
	     wait_about10ms();
	  }
	#else
	  ii = 0;
	  if (!(RST_PIN_REG & (1<<RST_PIN))) {
	     // key is still pressed
	     ii = wait_for_key_ms(700);	
	  }
	#endif
	  display_time = OFF_WAIT_TIME;		// LONG_WAIT_TIME for single mode, else SHORT_WAIT_TIME
	  if (ii > 30) {
	     display_time = LONG_WAIT_TIME;	// ... set long time display anyway
	  }
#endif // WITH_HARDWARE_SERIAL
	#if POWER_OFF+0 > 1
	  empty_count = 0;
	  mess_count = 0;
	#endif
	  ADCconfig.RefFlag = 0;
	  Calibrate_UR();		// get Ref Voltages and Pin resistance
	#ifdef WDT_enabled
	  wdt_enable(WDTO_2S);		//Watchdog on
	#endif
	#ifdef WITH_MENU
	  if (ii >= 60) {
		while(function_menu());		// selection of function
	  }
	#endif

	//*****************************************************************
	//Entry: if start key is pressed before shut down
	loop_start:
	#if ((LCD_ST_TYPE == 7565) || (LCD_ST_TYPE == 1306))
	  lcd_command(CMD_DISPLAY_ON);
	  lcd_command(CMD_SET_ALLPTS_NORMAL);		// 0xa4
	#endif
	  lcd_clear();			// clear the LCD
	  ADC_DDR = TXD_MSK;		// activate Software-UART 
          init_parts();			// reset parts info to nothing found
	  Calibrate_UR();		// get Ref Voltages and Pin resistance
	  lcd_line1();			// Cursor to 1. row, column 1
	  
	#ifdef BAT_CHECK
	  // Battery check is selected
        Battery_check();
	#else
	  lcd_MEM_string(VERSION_str);		// if no Battery check, Version .. in row 1
	#endif	/* BAT_CHECK */

	  // begin tests
	#if FLASHEND > 0x1fff
	  if (WithReference) {
	     /* 2.5V precision reference is checked OK */
	 #if POWER_OFF+0 > 1
	     if ((mess_count == 0) && (empty_count == 0))
	 #endif
	     {
		 /* display VCC= only first time */
		 lcd_line2();
		 lcd_MEM_string(VCC_str);		// VCC=
		 Display_mV(ADCconfig.U_AVCC,3);	// Display 3 Digits of this mV units
		 lcd_refresh();			// write the pixels to display, ST7920 only
		 wait_about1s();		// time to read the VCC= message
	     }
	  }
	#endif
	#ifdef WITH_VEXT
	  unsigned int Vext;
	  // show the external voltage
	  while (!(RST_PIN_REG & (1<<RST_PIN))) {
	     lcd_clear_line2();
	     lcd_MEM_string(Vext_str);		// Vext=
	     ADC_DDR = 0;		//deactivate Software-UART
	     Vext = W5msReadADC(TPext);	// read external voltage 
	//     ADC_DDR = TXD_MSK;		//activate Software-UART 
	    uart_newline();		// MAURO replaced uart_putc(' ') by uart_newline(), 'Z'
	 #if EXT_NUMERATOR <= (0xffff/U_VCC)
	     Display_mV(Vext*EXT_NUMERATOR/EXT_DENOMINATOR,3);	// Display 3 Digits of this mV units
	 #else
             DisplayValue((unsigned long)Vext*EXT_NUMERATOR/EXT_DENOMINATOR,-3,'V',3);  // Display 3 Digits of this mV units
	 #endif
	     lcd_refresh();		// write the pixels to display, ST7920 only
	     wait_about300ms();		// delay to read the Vext= message
	  }
	#endif /* WITH_VEXT */

	#ifndef DebugOut
	  lcd_line2();			//LCD position row 2, column 1
	#endif
	  EntladePins();		// discharge all capacitors!
	  if(PartFound == PART_CELL) {
	    lcd_clear();
	    lcd_MEM_string(Cell_str);	// display "Cell!"
	#if FLASHEND > 0x3fff
	    lcd_line2();		// use LCD line 2
	    Display_mV(cell_mv[0],3);
	    lcd_space();
	    Display_mV(cell_mv[1],3);
	    lcd_space();
	    Display_mV(cell_mv[2],3);
	#endif
	#ifdef WITH_SELFTEST
	    lcd_refresh();			// write the pixels to display, ST7920 only
	    wait_about2s();
	    AutoCheck(0x11);		// full Selftest with "Short probes" message
	#endif
	    goto tt_end;
	  }

	#ifdef WITH_SELFTEST
	 #ifdef AUTO_CAL
	  lcd_cursor_off();
	  UnCalibrated = (eeprom_read_byte(&c_zero_tab[3]) - eeprom_read_byte(&c_zero_tab[0]));
	  if (UnCalibrated != 0) {
	     // if calibrated, both c_zero_tab values are identical! c_zero_tab[3] is not used otherwise
	     lcd_cursor_on();
	  }
	 #endif
	 #ifdef WITH_MENU
	  AutoCheck(0x00);			//check, if selftest should be done, only calibration
	 #else
	  AutoCheck(0x01);			//check, if selftest should be done, full selftest without MENU
	 #endif
	#endif
	#if FLASHEND > 0x1fff
          lcd_clear_line2();			//LCD position row2, column 1
        #else
          lcd_line2();				//LCD position row2, column 1
        #endif
	  lcd_MEM_string(TestRunning);		//String: testing...
	  lcd_refresh();			// write the pixels to display, ST7920 only
	 #ifdef WITH_UART
	    uart_putc(0x03);		// ETX, start of new measurement 
	    uart_newline();			 // MAURO Added
	 #endif
//
	  // check all 6 combinations for the 3 pins 
	//         High  Low  Tri
	  CheckPins(TP1, TP2, TP3);
	  CheckPins(TP2, TP1, TP3);

	  CheckPins(TP1, TP3, TP2);
	  CheckPins(TP3, TP1, TP2);

	  CheckPins(TP2, TP3, TP1);
	  CheckPins(TP3, TP2, TP1);

	  // Capacity measurement is only possible correctly with two Pins connected.
	  // A third connected pin will increase the capacity value!
	//  if(((PartFound == PART_NONE) || (PartFound == PART_RESISTOR) || (PartFound == PART_DIODE)) ) {
	  if(PartFound == PART_NONE) {
	     // If no part is found yet, check separate if is is a capacitor
#ifdef DebugOut
	     lcd_data('C');
#endif
	     EntladePins();		// discharge capacities
	     //measurement of capacities in all 3 combinations
	     ReadCapacity(TP3, TP1);
#ifdef DebugOut
	     lcd_data('K');
#endif
	#if DebugOut != 10
	     ReadCapacity(TP3, TP2);
#ifdef DebugOut
	     lcd_data('K');
#endif
	     ReadCapacity(TP2, TP1);
#ifdef DebugOut
	     lcd_data('K');
#endif
	#endif
	  }

#ifdef WITH_UJT
// check for UJT
        if (PartFound==PART_DIODE       
            && NumOfDiodes==2                // UJT is detected as 2 diodes E-B1 and E-B2...
//            && ResistorsFound==1             // ...and a resistor B1-B2
            && diodes.Anode[0]==diodes.Anode[1]      // check diodes have common anode
//            && (unsigned char)(ResistorList[0]+diodes.Anode[0])==2    // and resistor is between cathodes
           ) 
           // note: there also exist CUJTs (complementary UJTs); they seem to be (even) rarer than UJTs, and are not supported for now
           {
            CheckUJT();
        }
#endif		/* defined WITH_UJT */

#ifdef WITH_XTAL
        if (PartFound==PART_NONE || ((PartFound==PART_CAPACITOR) && (cap.cpre_max == -12))) {
           // still not recognized anything? then check for ceramic resonator or crystal
           // these tests are time-consuming, so we do them last, and only on TP1/TP3
           sampling_test_xtal();
        }
#endif

	  //All checks are done, output result to display

	#ifdef DebugOut 
	  // only clear two lines of LCD

	  lcd_clear_line1();
	#else
	  lcd_clear();				// clear total display
	#endif

	  _trans = &ntrans;			// default transistor structure to show
	  if (PartFound == PART_THYRISTOR) {
#ifdef WITH_GRAPHICS
            lcd_big_icon(THYRISTOR|LCD_UPPER_LEFT);
            lcd_draw_trans_pins(-8, 16);
            lcd_set_cursor(0,TEXT_RIGHT_TO_ICON);		// position behind the icon, Line 1
	    lcd_MEM_string(Thyristor);		//"Thyristor"
#else
	    lcd_MEM_string(Thyristor);		//"Thyristor"
            PinLayout(Cathode_char,'G','A'); 	// CGA= or 123=...
#endif
            goto TyUfAusgabe;
          }

  if (PartFound == PART_TRIAC) {
#ifdef WITH_GRAPHICS
    lcd_big_icon(TRIAC|LCD_UPPER_LEFT);
    lcd_draw_trans_pins(-8, 16);
    lcd_set_cursor(0,TEXT_RIGHT_TO_ICON);		// position behind the icon, Line 1
    lcd_MEM_string(Triac);		//"Triac"
#else
    lcd_MEM_string(Triac);		//"Triac"
    PinLayout('1','G','2'); 	// CGA= or 123=...
#endif
    goto TyUfAusgabe;
  }

#ifdef WITH_PUT
   if (PartFound == PART_PUT) {
      static const unsigned char PUT_str[] MEM_TEXT = "PUT";
      lcd_MEM_string(PUT_str);
      _trans=&ptrans;
      PinLayout('A','G',Cathode_char);
      goto TyUfAusgabe;
   }
#endif

#ifdef WITH_UJT
   if (PartFound == PART_UJT) {
      static const unsigned char UJT_str[] MEM_TEXT = "UJT";
      lcd_MEM_string(UJT_str);
      PinLayout('1','E','2');
 #ifdef SamplingADC
      static const unsigned char eta_str[] MEM_TEXT = " eta=";
      lcd_next_line(0);
      ResistorChecked[ntrans.e - TP_MIN + ntrans.c - TP_MIN - 1] = 0;	// forget last resistance measurement
      GetResistance(ntrans.c, ntrans.e);	// resistor value is in ResistorVal[resnum]
      DisplayValue(ResistorVal[ntrans.e - TP_MIN + ntrans.c - TP_MIN - 1],-1,LCD_CHAR_OMEGA,2);
      lcd_MEM_string(eta_str);		//"eta="
      DisplayValue(ntrans.gthvoltage,0,'%',3);
 #else /* ! SamplingADC */
      static const unsigned char R12_str[] MEM_TEXT = "R12=";
      lcd_next_line(0);
      lcd_MEM_string(R12_str);		//"R12="
      DisplayValue(ResistorVal[ntrans.e - TP_MIN + ntrans.c - TP_MIN - 1],-1,LCD_CHAR_OMEGA,2);
      lcd_data(',');
      DisplayValue(((RR680PL * (unsigned long)(ADCconfig.U_AVCC - ntrans.uBE)) / ntrans.uBE)-RRpinPL,-1,LCD_CHAR_OMEGA,3);
 #endif	 /* SamplingADC */
      goto tt_end;
   }
#endif /* WITH_UJT */

  if (PartFound == PART_CAPACITOR) {
#if FLASHEND > 0x3fff
     if ((cap.ca + cap.cb) == (TP1 + TP3)) {
        show_Cap13();		// repeated capacity measurement
        goto shut_off;		// key was pressed or timeout
     }
     show_cap(0);		// show capacity in normal way and measure additional parameters
#else
     show_cap_simple();		// show capacity in normal way and measure additional parameters
#endif
     goto tt_end;
  } /* end PartFound == PART_CAPACITOR */

#ifdef WITH_XTAL
  if (PartFound == PART_CERAMICRESONATOR) {
//      static const unsigned char cerres_str[] MEM_TEXT = "Cer.resonator  ";
      lcd_MEM_string(cerres_str);
      if (sampling_measure_xtal()) goto loop_start;
      goto tt_end;
  }
  if (PartFound == PART_XTAL) {
//      static const unsigned char xtal_str[] MEM_TEXT = "Crystal  ";
      lcd_MEM_string(xtal_str);
      if (sampling_measure_xtal()) goto loop_start;
      goto tt_end;
  }
#endif

  // ========================================
  if(PartFound == PART_DIODE) {
  // ========================================
     if(NumOfDiodes == 1) {		//single Diode
//        lcd_MEM_string(Diode);		//"Diode: "
#if FLASHEND > 0x1fff
        // enough memory (>8k) to sort the pins and additional Ir=
        DiodeSymbol_withPins(0);
	GetIr(diodes.Cathode[0],diodes.Anode[0]);	// measure and output Ir=x.xuA
#else
        // too less memory to sort the pins
        DiodeSymbol_withPins(0);
#endif
        UfAusgabe(0x70);		// mark for additional resistor and output Uf= in line 2
#ifndef SamplingADC
        /* load current of capacity is (5V-1.1V)/(470000 Ohm) = 8298nA */
        ReadCapacity(diodes.Cathode[0],diodes.Anode[0]);	// Capacity opposite flow direction
        if (cap.cpre < -3) {	/* capacity is measured */
 #if (LCD_LINES > 2)
           lcd_line3();		// output Capacity in line 3
 #endif
           lcd_MEM_string(Cap_str);	//"C="
 #if LCD_LINE_LENGTH > 16
           DisplayValue(cap.cval,cap.cpre,'F',3);
 #else
           DisplayValue(cap.cval,cap.cpre,'F',2);
 #endif
        }
#else  // SamplingADC
showdiodecap:
        cap.cval=sampling_cap(diodes.Cathode[0],diodes.Anode[0],0);   // at low voltage
        lcd_next_line_wait(0);		// next line, wait 5s and clear line 2
        DisplayValue(cap.cval,sampling_cap_pre,'F',2);
 #ifdef PULLUP_DISABLE
        lcd_data('-');
        cap.cval=sampling_cap(diodes.Cathode[0],diodes.Anode[0],1);   // at high voltage
        if (cap.cval < 0) cap.cval = 0;		// don't show negativ value
        DisplayValue(cap.cval,sampling_cap_pre,'F',2);
  #if LCD_LINE_LENGTH > 16
        lcd_MEM_string(AT05volt);	// " @0-5V"
  #else
        lcd_MEM_string(AT05volt+1);	// "@0-5V"
  #endif
        uart_newline();			// MAURO Diode ('A')
 #else
  #warning Capacity measurement from high to low not possible for diodes without PULLUP_DISABLE option!
 #endif  /* PULLUP_DISABLE */
#endif
        goto end3;
     } else if(NumOfDiodes == 2) { // double diode
        lcd_data('2');
        lcd_MEM_string(Dioden);		//"diodes "
        if(diodes.Anode[0] == diodes.Anode[1]) { //Common Anode
           DiodeSymbol_CpinApin(0);	// 1-|<-2
           DiodeSymbol_ACpin(1);	//  ->|-3
           UfAusgabe(0x01);
#ifdef SamplingADC
           goto showdiodecap;   // double diodes are often varicap; measure capacitance of one of them
#else
           goto end3;
#endif
        } 
        if(diodes.Cathode[0] == diodes.Cathode[1]) { //Common Cathode
           DiodeSymbol_ApinCpin(0);	// 1->|-2
           DiodeSymbol_CApin(1);	//  -|<-3
           UfAusgabe(0x01);
#ifdef SamplingADC
           goto showdiodecap;   // double diodes are often varicap; measure capacitance of one of them
#else
           goto end3;
#endif
//        else if ((diodes.Cathode[0] == diodes.Anode[1]) && (diodes.Cathode[1] == diodes.Anode[0])) 
        } 
        if (diodes.Cathode[0] == diodes.Anode[1]) {
           // normaly two serial diodes are detected as three diodes, but if the threshold is high
           // for both diodes, the third diode is not detected.
           // can also be Antiparallel
           diode_sequence = 0x01;	// 0 1
           SerienDiodenAusgabe();
           goto end3;
        } 
        if (diodes.Cathode[1] == diodes.Anode[0]) {
           diode_sequence = 0x10;	// 1 0
           SerienDiodenAusgabe();
           goto end3;
        }
     } else if(NumOfDiodes == 3) {
        //Serial of 2 Diodes; was detected as 3 Diodes 
        diode_sequence = 0x33;	// 3 3
        /* Check for any constellation of 2 serial diodes:
          Only once the pin No of anyone Cathode is identical of another anode.
          two diodes in series is additionally detected as third big diode.
        */
			if (diodes.Cathode[0] == diodes.Anode[1]) {
           diode_sequence = 0x01;	// 0 1
          }
			if (diodes.Anode[0] == diodes.Cathode[1]) {
           diode_sequence = 0x10;	// 1 0
          }
			if (diodes.Cathode[0] == diodes.Anode[2]) {
           diode_sequence = 0x02;	// 0 2
          }
			if (diodes.Anode[0] == diodes.Cathode[2]) {
           diode_sequence = 0x20;	// 2 0
          }
			if (diodes.Cathode[1] == diodes.Anode[2]) {
           diode_sequence = 0x12;	// 1 2
          }
			if (diodes.Anode[1] == diodes.Cathode[2]) {
           diode_sequence = 0x21;	// 2 1
          }
//        if((ptrans.b<3) && (ptrans.c<3)) 
        if(diode_sequence < 0x22) {
           lcd_data('3');
           lcd_MEM_string(Dioden);	//"Diodes "
           SerienDiodenAusgabe();
           goto end3;
        }
     }  // end (NumOfDiodes == 3)
     lcd_MEM_string(Bauteil);		//"Bauteil"
     lcd_MEM_string(Unknown); 		//" unbek."
     lcd_line2(); //2. row 
     lcd_data(NumOfDiodes + '0');
     lcd_data('*');
     lcd_MEM_string(AnKat_str);		//"->|-"
     lcd_MEM_string(Detected);		//" detected"
     goto not_known;
     // end (PartFound == PART_DIODE)
  // ========================================
  } else if (PartFound == PART_TRANSISTOR) {
  // ========================================
#ifdef SEARCH_PARASITIC
    if ((ptrans.count != 0) && (ntrans.count !=0)) {
       // Special Handling of NPNp and PNPn Transistor.
       // If a protection diode is built on the same structur as the NPN-Transistor,
       // a parasitic PNP-Transistor will be detected. 
       ReadCapacity(ntrans.e, ntrans.b);	// read capacity of NPN base-emitter
       n_cval = cap.cval;			// save the found capacity value
       n_cpre  = cap.cpre;			// and dimension
       ReadCapacity(ptrans.b, ptrans.e);	// read capacity of PNP base-emitter
       // check if one hfe is very low. If yes, simulate a very low BE capacity
       if ((ntrans.hfe < 500) && (ptrans.hfe >= 500)) n_cpre = -16; // set NPN BE capacity to low value
       if ((ptrans.hfe < 500) && (ntrans.hfe >= 500)) cap.cpre = -16; // set PNP BE capacity to low value

       if (((n_cpre == cap.cpre) && (cap.cval > n_cval))
					|| (cap.cpre > n_cpre)) {
          // the capacity value or dimension of the PNP B-E is greater than the NPN B-E
          PartMode = PART_MODE_PNP;
       } else {
          PartMode = PART_MODE_NPN;
       }
    }  /* end ((ptrans.count != 0) && (ntrans.count !=0)) */
#endif
    // not possible for mega8, change Pin sequence instead.
		if ((ptrans.count != 0) && (ntrans.count != 0)
				&& (!(RST_PIN_REG & (1 << RST_PIN)))) {
       // if the Start key is still pressed, use the other Transistor
#if 0
       if (PartMode == PART_MODE_NPN) {
          PartMode = PART_MODE_PNP;	// switch to parasitic transistor
       } else {
          PartMode = PART_MODE_NPN;	// switch to parasitic transistor
       }
#else
       PartMode ^= (PART_MODE_PNP - PART_MODE_NPN);
#endif
    }

#ifdef WITH_GRAPHICS
    lcd_set_cursor(0,TEXT_RIGHT_TO_ICON);			// position behind the icon, Line 1
    lcd_big_icon(BJT_NPN|LCD_UPPER_LEFT);	// show the NPN Icon at lower left corner
    if(PartMode == PART_MODE_NPN) {
//       _trans = &ntrans;  is allready selected a default
       lcd_MEM_string(NPN_str);		//"NPN "
       if (ptrans.count != 0) {
          lcd_data('p');		// mark for parasitic PNp
       }
    } else {
       _trans = &ptrans;		// change transistor structure
       lcd_update_icon(bmp_pnp);	// update for PNP
       lcd_MEM_string(PNP_str);		//"PNP "
       if (ntrans.count != 0) {
          lcd_data('n');		// mark for parasitic NPn
       }
    }
#else 	/* only character display */
    if(PartMode == PART_MODE_NPN) {
//       _trans = &ntrans;  is allready selected a default
       lcd_MEM_string(NPN_str);		//"NPN "
       if (ptrans.count != 0) {
          lcd_data('p');		// mark for parasitic PNp
       }
    } else {
       _trans = &ptrans;		// change transistor structure
       lcd_MEM_string(PNP_str);		//"PNP "
       if (ntrans.count != 0) {
          lcd_data('n');		// mark for parasitic NPn
       }
    }
    lcd_space();
#endif

    // show the protection diode of the BJT
    vak_diode_nr = search_vak_diode();
    if (vak_diode_nr < 5) {
    // no side of the diode is connected to the base, this must be the protection diode   
#ifdef WITH_GRAPHICS
       options = 0;
       if (_trans->c != diodes.Anode[vak_diode_nr])
          options |= OPT_VREVERSE;
       lcd_update_icon_opt(bmp_vakdiode,options);	// show the protection diode right to the Icon
#else    /* only character display, show the diode in correct direction */    
       char an_cat;			// diode is anode-cathode type
       an_cat = 0;
 #ifdef EBC_STYLE
  #if EBC_STYLE == 321
       // Layout with 321= style
       an_cat = (((PartMode == PART_MODE_NPN) && (ntrans.c < ntrans.e)) ||
                 ((PartMode != PART_MODE_NPN) && (ptrans.c > ptrans.e)));
  #else
       // Layout with EBC= style
       an_cat = (PartMode == PART_MODE_NPN);
  #endif
 #else
       // Layout with 123= style
       an_cat = (((PartMode == PART_MODE_NPN) && (ntrans.c > ntrans.e))
		|| ((PartMode != PART_MODE_NPN) && (ptrans.c < ptrans.e)));
 #endif
       if (an_cat) {
          lcd_MEM_string(AnKat_str);	//"->|-"
       } else {
          lcd_MEM_string(KatAn_str);	//"-|<-"
       }
#endif    /* !WITH_GRAPHICS */
    }  /* endif vak_diode_nr < 6 */

#ifdef WITH_GRAPHICS
    lcd_draw_trans_pins(-7, 16);	// show the pin numbers
    lcd_next_line(TEXT_RIGHT_TO_ICON);	// position behind the icon, Line 2
    lcd_MEM_string(hfe_str);		//"B="  (hFE)
    DisplayValue(_trans->hfe,-2,0,3);

    lcd_next_line(TEXT_RIGHT_TO_ICON+1-LOW_H_SPACE); // position behind the icon+1, Line 3
    lcd_data('I');
    if (_trans->current >= 10000) {
       lcd_data('e');				// emitter current has 10mA offset
       _trans->current -= 10000;
    } else {
       lcd_data('c');
    }
    lcd_equal();			// lcd_data('=');
    DisplayValue16(_trans->current,-6,'A',2);	// display Ic or Ie current

    lcd_next_line(TEXT_RIGHT_TO_ICON); // position behind the icon, Line 4
    lcd_MEM_string(Ube_str);		//"Ube="
    Display_mV(_trans->uBE,3-LOW_H_SPACE);
    last_line_used = 1;

 #ifdef SHOW_ICE
    if (_trans->ice0 > 0) {
       lcd_next_line_wait(TEXT_RIGHT_TO_ICON-1-LOW_H_SPACE); // position behind the icon, Line 4 & wait and clear last line
       lcd_MEM2_string(ICE0_str);		// "ICE0="
       DisplayValue16(_trans->ice0,-6,'A',2);	// display ICEO
    }
    if (_trans->ices > 0) {
       lcd_next_line_wait(TEXT_RIGHT_TO_ICON-1-LOW_H_SPACE); // position behind the icon, Line 4 & wait and clear last line
       lcd_MEM2_string(ICEs_str);		// "ICEs="
       DisplayValue16(_trans->ices,-6,'A',2);	// display ICEs
    }
 #endif
#else		/* character display */
    PinLayout('E','B','C'); 		//  EBC= or 123=...
    lcd_line2(); //2. row 
    lcd_MEM_string(hfe_str);		//"B="  (hFE)
    DisplayValue(_trans->hfe,-2,0,3);
 #if FLASHEND > 0x1fff
    lcd_space();

    lcd_data('I');
    if (_trans->current >= 10000) {
       lcd_data('e');				// emitter current has 10mA offset
       _trans->current -= 10000;
    } else {
       lcd_data('c');
    }
    lcd_equal();			// lcd_data('=');
    DisplayValue16(_trans->current,-6,'A',2);	// display Ic or Ie current
 #endif

 #if defined(SHOW_ICE)
    lcd_next_line_wait(0);		// next line, wait 5s and clear line 2
    lcd_MEM_string(Ube_str);		//"Ube=" 
    Display_mV(_trans->uBE,3);

    if (_trans->ice0 > 0) {
       lcd_next_line_wait(0);		// next line, wait 5s and clear line 2
       lcd_MEM2_string(ICE0_str);		// "ICE0="
       DisplayValue16(_trans->ice0,-6,'A',3);
    }
    if (_trans->ices > 0) {
       lcd_next_line_wait(0);		// next line, wait 5s and clear line 2
       lcd_MEM2_string(ICEs_str);		// "ICEs="
       DisplayValue16(_trans->ices,-6,'A',3);
    }
 #endif
#endif  /* WITH_GRAPHICS */
#ifdef SHOW_VAKDIODE
    if (vak_diode_nr < 5) {
       lcd_next_line_wait(0); 		// next line, wait 5s and clear line 2/4
       DiodeSymbol_withPins(vak_diode_nr);
       lcd_MEM_string(Uf_str);			//"Uf="
       mVAusgabe(vak_diode_nr);
       uart_newline();			// MAURO not verified ('D')
    } /* end if (vak_diode_nr < 5) */
#endif
#ifdef WITH_GRAPHICS
    PinLayoutLine('E','B','C'); 		//  Pin 1=E ...
    uart_newline();			// MAURO OK BJT ('E')
#endif
    goto tt_end;
    // end (PartFound == PART_TRANSISTOR)

  // ========================================
  } else if (PartFound == PART_FET) {	/* JFET or MOSFET */
  // ========================================
#ifdef WITH_GRAPHICS
    unsigned char fetidx = 0;
    lcd_set_cursor(0,TEXT_RIGHT_TO_ICON);	// position behind the icon, Line 1
#endif
    if((PartMode&P_CHANNEL) == P_CHANNEL) {
       lcd_data('P');			//P-channel
       _trans = &ptrans;
#ifdef WITH_GRAPHICS
       fetidx = 2;
#endif
    } else {
       lcd_data('N');			//N-channel
//       _trans = &ntrans;	is allready selected as default
    }
    lcd_data('-');		// minus is used for JFET, D-MOS, E-MOS ...

    uint8_t part_code;
    part_code = PartMode&0x0f;
#ifdef WITH_GRAPHICS
    if (part_code == PART_MODE_JFET) {
       lcd_MEM_string(jfet_str);	//"JFET"
       lcd_big_icon(N_JFET|LCD_UPPER_LEFT);
       if (fetidx != 0) {
          lcd_update_icon(bmp_p_jfet); // update the n_jfet bitmap to p_jfet
       }
    } else {		// no JFET
       if ((PartMode&D_MODE) == D_MODE) {
          lcd_data('D');			// N-D or P-D
          fetidx += 1;
       } else {
          lcd_data('E');			// N-E or P-E
       }
       if (part_code == (PART_MODE_IGBT)) {
          lcd_MEM_string(igbt_str);	//"-IGBT"
          lcd_big_icon(N_E_IGBT|LCD_UPPER_LEFT);
          if (fetidx == 1)  lcd_update_icon(bmp_n_d_igbt);
          if (fetidx == 2)  lcd_update_icon(bmp_p_e_igbt);
          if (fetidx == 3)  lcd_update_icon(bmp_p_d_igbt);
       } else {
          lcd_MEM_string(mosfet_str);	//"-MOS "
          lcd_big_icon(N_E_MOS|LCD_UPPER_LEFT);
          if (fetidx == 1)  lcd_update_icon(bmp_n_d_mos);
          if (fetidx == 2)  lcd_update_icon(bmp_p_e_mos);
          if (fetidx == 3)  lcd_update_icon(bmp_p_d_mos);
       }
    } /* end PART_MODE_JFET */
#else	/* normal character display */
    if (part_code == PART_MODE_JFET) {
       lcd_MEM_string(jfet_str);	//"-JFET"
    } else {		// no JFET
       if ((PartMode&D_MODE) == D_MODE) {
          lcd_data('D');			// N-D or P-D
       } else {
          lcd_data('E');			// N-E or P-E
       }
       if (part_code == (PART_MODE_IGBT)) {
          lcd_MEM_string(igbt_str);	//"-IGBT"
       } else {
          lcd_MEM_string(mosfet_str);	//"-MOS "
       }
    } /* end PART_MODE_JFET */

    if (part_code == PART_MODE_IGBT) {
       PinLayout('E','G','C'); 		//  SGD= or 123=...
    } else if (part_code == PART_MODE_JFET) {
       PinLayout('?','G','?'); 		//  ?G?= or 123=...
    } else {
       PinLayout('S','G','D'); 		//  SGD= or 123=...
    }
#endif  /* WITH_GRAPHICS */

    vak_diode_nr = search_vak_diode();
    if(vak_diode_nr < 5) {
       //MOSFET with protection diode; only with enhancement-FETs

#ifndef WITH_GRAPHICS
 #if FLASHEND <= 0x1fff
       char an_cat;			// diode is anode-cathode type
       an_cat = 0;
  #ifdef EBC_STYLE
   #if EBC_STYLE == 321
       // layout with 321= style
       an_cat = (((PartMode&P_CHANNEL) && (ptrans.c > ptrans.e)) || ((!(PartMode&P_CHANNEL)) && (ntrans.c < ntrans.e)));
   #else
       // Layout with SGD= style
       an_cat = (PartMode&P_CHANNEL);	/* N or P MOS */
   #endif
  #else /* EBC_STYLE not defined */
       // layout with 123= style
			an_cat = (((PartMode & P_CHANNEL) && (ptrans.c < ptrans.e))
					|| ((!(PartMode & P_CHANNEL)) && (ntrans.c > ntrans.e)));
  #endif /* end ifdef EBC_STYLE */
       //  show diode symbol in right direction  (short form for less flash memory)
       if (an_cat) {
          lcd_data(LCD_CHAR_DIODE1);	//show Diode symbol >|
       } else {
          lcd_data(LCD_CHAR_DIODE2);	//show Diode symbol |<
       }
 #endif
#endif  /* not WITH_GRAPHICS */
#ifdef WITH_GRAPHICS
       options = 0;
       if (_trans->c != diodes.Anode[vak_diode_nr])
          options |= OPT_VREVERSE;
       lcd_update_icon_opt(bmp_vakdiode,options);	// update Icon with protection diode
#endif

    } /* end if NumOfDiodes == 1 */

#ifdef WITH_GRAPHICS
    lcd_draw_trans_pins(-7, 16);	// update of pin numbers must be done after diode update
    lcd_next_line(TEXT_RIGHT_TO_ICON);	// position text behind the icon, Line 2
 #if LCD_LINES > 6
       lcd_next_line(TEXT_RIGHT_TO_ICON);	// double line
 #endif
    if((PartMode&D_MODE) != D_MODE) {	//enhancement-MOSFET
       lcd_MEM_string(vt_str+1);		// "Vt="
       Display_mV(_trans->gthvoltage,2);	//Gate-threshold voltage
	//Gate capacity
       ReadCapacity(_trans->b,_trans->e);	//measure capacity
       lcd_next_line(TEXT_RIGHT_TO_ICON);	// position text behind the icon, Line 3
       lcd_show_Cg();	// show Cg=xxxpF
 #ifdef SHOW_R_DS
       lcd_show_rds(TEXT_RIGHT_TO_ICON-1); 	// show RDS at column behind the icon -1
 #endif
    } else {   /* depletion mode */
       if ((PartMode&0x0f)  != PART_MODE_JFET) {     /* kein JFET */
          ReadCapacity(_trans->b,_trans->e);	//measure capacity
          lcd_show_Cg();	// show Cg=xxxpF
  #ifdef FET_Idss
       } else { 	// it is a JFET
          // display the I_DSS, if measured
          if (_trans->uBE!=0) {
             static const unsigned char str_Idss[] MEM_TEXT = "Idss=";
             lcd_MEM_string(str_Idss);
             DisplayValue16(_trans->uBE,-6,'A',2);
          }
  #endif
       }
       // set cursor below the icon
  #define LINE_BELOW_ICON ((ICON_HEIGHT/8)/((FONT_HEIGHT+7)/8))
 #if LCD_LINES > 6
       lcd_set_cursor((LINE_BELOW_ICON + 1) * PAGES_PER_LINE,0);
 #else
       lcd_set_cursor(LINE_BELOW_ICON * PAGES_PER_LINE,0);
 #endif
       lcd_data('I');
 #if (LCD_LINE_LENGTH > 17)
       lcd_data('d');
 #endif
       lcd_equal();			// lcd_data('=');
       DisplayValue16(_trans->current,-6,'A',2);
       lcd_MEM_string(Vgs_str);		// "@Vg="
       Display_mV(_trans->gthvoltage,2);	//Gate-threshold voltage

 #ifdef SHOW_ICE
       // Display also the cutoff gate voltage, idea from Pieter-Tjerk
       if (_trans->ice0<4800) { // can't trust cutoff voltage if close to 5V supply voltage, since then the transistor may not have been cut off at all
          lcd_next_line_wait(0);
          lcd_data('I');
  #if (LCD_LINE_LENGTH > 17)
          lcd_data('d');
  #endif
          lcd_equal();			// lcd_data('=');
          DisplayValue16(0,-5,'A',2);
          lcd_MEM_string(Vgs_str);		// "@Vg="
          Display_mV(_trans->ice0,2);	// cutoff Gate voltage
 #endif
       }
 #ifdef SHOW_R_DS
       lcd_show_rds(0);                // show Drain-Source resistance RDS at column 0
 #endif
    }	/* end of enhancement or depletion mode WITH_GRAPHICS */
#else	/* character display */
    if((PartMode&D_MODE) != D_MODE) {	//enhancement-MOSFET
	//Gate capacity
       lcd_line2();		// line 2
       ReadCapacity(_trans->b,_trans->e);	//measure capacity
       lcd_show_Cg();	// show Cg=xxxpF
       lcd_MEM_string(vt_str);		// " Vt="
       Display_mV(_trans->gthvoltage,2);	//Gate-threshold voltage
  #ifdef SHOW_R_DS
       lcd_show_rds(0);                // show Drain-Source resistance RDS at column 0
  #endif
    } else {
      // depletion
 #if FLASHEND > 0x1fff
       if ((PartMode&0x0f)  != PART_MODE_JFET) {     /* kein JFET */
          lcd_next_line(0);		// line 2
          ReadCapacity(_trans->b,_trans->e);	//measure capacity
          lcd_show_Cg();	// show Cg=xxxpF
  #ifdef FET_Idss
       } else {     // it is a JFET
          // display the I_DSS, if measured
          if (_trans->uBE!=0) {
             lcd_next_line(0);
             static const unsigned char str_Idss[] MEM_TEXT = "Idss=";
             lcd_MEM_string(str_Idss);
             DisplayValue16(_trans->uBE,-6,'A',2);
          }
  #endif
       }
       lcd_next_line_wait(0);		// line 2 or 3, if possible & wait and clear last line
 #endif
       lcd_data('I');			// show I=xmA@Vg=y.yV at line 2 or 3
 #if (LCD_LINE_LENGTH > 17)
       lcd_data('d');
 #endif
       lcd_equal();			// lcd_data('=');
       DisplayValue16(_trans->current,-6,'A',2);
       lcd_MEM_string(Vgs_str);		// "@Vg="
       Display_mV(_trans->gthvoltage,2);	//Gate-threshold voltage
 #ifdef SHOW_ICE
       // Display also the cutoff gate voltage, idea from Pieter-Tjerk
       if (_trans->ice0<4800) { // can't trust cutoff voltage if close to 5V supply voltage, since then the transistor may not have been cut off at all
          lcd_next_line_wait(0);
          lcd_data('I');
  #if (LCD_LINE_LENGTH > 17)
          lcd_data('d');
  #endif
          lcd_equal();			// lcd_data('=');
          DisplayValue16(0,-5,'A',2);
          lcd_MEM_string(Vgs_str);		// "@Vg="
          Display_mV(_trans->ice0,2);	// cutoff Gate voltage
       }
 #endif
 #ifdef SHOW_R_DS
       lcd_show_rds(0);                // show Drain-Source resistance RDS at column 0
 #endif
    }   /* end of enhancement or depletion mode */
#endif  /* WITH_GRAPHICS or without */

#if DebugOut == 5
    lcd_line4();
    lcd_data('>');
    lcd_data('|');
    lcd_space();
    DisplayValue16(NumOfDiodes,0,' ',3);
#endif
#if FLASHEND > 0x1fff
    if (part_code != PART_MODE_JFET) {
       for (ii=0;ii<NumOfDiodes;ii++) {
          // there is enough space for long form of presenting protection diode
 #if LCD_LINES > 6
          if (ii == 0) lcd_next_line(0);		// line 5 , if possible
 #endif
          lcd_next_line_wait(0);		// line 4, if possible & wait 5s and clear last line 
          DiodeSymbol_withPins(ii);
          lcd_MEM_string(Uf_str);			//"Uf="
          mVAusgabe(ii);
//          uart_newline();			// MAURO OK N-E-MOS/IGBT ('F')
       } /* end for ii (NumOfDiodes) */
    }  /* PART_MODE != JFET */
#endif
#ifdef WITH_GRAPHICS
    if (part_code == PART_MODE_IGBT) {
       PinLayoutLine('E','G','C'); 		//  Pin 1=...
    } else if (part_code == PART_MODE_JFET) {
       PinLayoutLine('?','G','?'); 		//  Pin 1=...
    } else {
       PinLayoutLine('S','G','D'); 		//  Pin 1=...
    }
       uart_newline();			// MAURO OK IGBT ('G')
#endif
    goto tt_end;
  }  /* end (PartFound == PART_FET) */

//   if(PartFound == PART_RESISTOR) 
resistor_out:
  if (ResistorsFound != 0) {
    if (ResistorsFound == 1) { // single resistor

       rpins.pw = Rnum2pins(ResistorList[0]);	// get pin numbers for resistor 1
#if FLASHEND <= 0x1fff
       lcd_testpin(rpins.pb[0]);  	//Pin-number 1
       lcd_MEM_string(Resistor_str);	// -[=]-
       lcd_testpin(rpins.pb[1]);	//Pin-number 2
       lcd_line2(); //2. row 
       RvalOut(ResistorList[0]);
#else
 #if FLASHEND > 0x3fff
       if ((ResistorList[0] == 1) && (NumOfDiodes == 0)) {
          // is the TP1:TP3 resistor and no additional diode
          show_Resis13();		// call of the special resistor measurement
          goto shut_off;		// key is pressed or timeout
       }
 #endif
       show_resis(rpins.pb[0],rpins.pb[1],0);
#endif

    } else { // multiple resistors found, R-Max suchen

       ii = ResistorList[0];	// first resistor in the list with number 0,1,2
       if (ResistorVal[ResistorList[1]] > ResistorVal[ii])
          ii = ResistorList[1]; // second resistor in the list with number 0,1,2
       if (ResistorsFound == 2) {
          ii = (3 - ResistorList[0] - ResistorList[1]);
       } else {
          if (ResistorVal[ResistorList[2]] > ResistorVal[ii]) {
             ii = ResistorList[2];
          }
       }
       // ResistorVal[0] TP1:TP2, [1] TP1:TP3, [2] TP2:TP3
#if (TP2!=TP1+1 || TP3!=TP2+1)
       x = TP1;
       y = TP3;
       z = TP2;
       if (ii == 1) {	/* TP1:TP3 is maximum */
          x = TP1;
          y = TP2;
          z = TP3;
       }
       if (ii == 2) {	/* TP2:TP3 is maximum */
          x = TP2;
          y = TP1;
          z = TP3;
       }
#else
    // the following does the same as the above, but more cryptically (and in fewer instructions)
       x = TP1+(ii>>1);
       y = TP3-ii;
       z = TP2+(ii>0);
#endif
       lcd_testpin(x);  	//Pin-number 1
       lcd_MEM_string(Resistor_str);    // -[=]-
       lcd_testpin(y);		//Pin-number 2
       lcd_MEM_string(Resistor_str);    // -[=]-
       lcd_testpin(z);		//Pin-number 3

       lcd_next_line(0);
       // output resistor values in right order
    //  if (ii == 0) { /* resistor 0 has maximum */
    //     RvalOut(1);
    //     RvalOut(2);
    //  }
    //  if (ii == 1) { /* resistor 1 has maximum */
    //     RvalOut(0);
    //     RvalOut(2);
    //  }
    //  if (ii == 2) { /* resistor 2 has maximum */
    //     RvalOut(0);
    //     RvalOut(1);
    //  }
    // again a shorter but cryptical equivalent:
       RvalOut(ii==0);
       RvalOut(2-(ii>>1));
    }  // end ResistorsFound==1
    goto tt_end;

  } // end (PartFound == PART_RESISTOR)

  lcd_MEM_string(TestFailed1); 	//"Kein,unbek. oder"
  lcd_line2(); //2. row 
#if defined(LANG_ITALIAN) || defined(LANG_FRANCAIS)	//italiano or francais
  lcd_MEM_string(Bauteil);		//"campione"
  lcd_space();
  lcd_MEM_string(TestFailed2); 		//"guasto "
#else
  lcd_MEM_string(TestFailed2); 		//"defektes "
  lcd_MEM_string(Bauteil);		//"Bauteil"
#endif
not_known:
//   uart_newline();		// MAURO added
#ifdef WITH_GRAPHICS
     lcd_big_icon(QUESTION);		// show big question mark
#endif
#if POWER_OFF+0 > 1
  empty_count++;
  mess_count = 0;
#endif
  max_time = SHORT_WAIT_TIME;		// use allways the short wait time
  goto end2;

//gakAusgabe:
//  PinLayout(Cathode_char,'G','A'); 	// CGA= or 123=...
TyUfAusgabe:
#ifdef WITH_THYRISTOR_GATE_V
 #ifdef WITH_GRAPHICS
  lcd_set_cursor(1*PAGES_PER_LINE,TEXT_RIGHT_TO_ICON);		// position behind the icon,line 2
 #else
  lcd_line2(); //2. row 
 #endif
  lcd_MEM_string(Uf_str);		// "Uf="
 #ifdef WITH_PUT
  Display_mV(_trans->uBE,2);    // needed instead of ntrans for PUT, but costs 4 bytes more flash...
 #else
  Display_mV(ntrans.uBE,2);
 #endif
//  uart_newline();		// MAURO ('I')
#endif
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - 
 tt_end:
#if POWER_OFF+0 > 1
  empty_count = 0;		// reset counter, if part is found
  mess_count++;			// count measurements
#endif
  max_time = display_time;	// full specified wait time

 end2:
  ADC_DDR = (1<<TPRELAY) | TXD_MSK; 	// switch pin with reference to GND, release relay
  lcd_refresh();			// write the pixels to display, ST7920 only
	while (!(RST_PIN_REG & (1 << RST_PIN)))
		;	//wait ,until button is released
#ifdef WITH_ROTARY_SWITCH
wait_again:
#endif
  ii = wait_for_key_ms(max_time);
#if POWER_OFF+0 > 1
 #ifdef WITH_ROTARY_SWITCH
  if ((ii > 0) || (rotary.incre > 0))
 #else
  if (ii > 0)
 #endif
  {
     empty_count = 0;		// reset counter, if any switch activity
     mess_count = 0; }
#endif
#ifdef WITH_MENU
 #ifdef WITH_ROTARY_SWITCH
  if ((ii >=50) || (rotary.incre > 2))
 #else
  if (ii >= 50) 
 #endif
  {
     // menu selected by long key press or rotary switch
		while(function_menu());// start the function menu
     goto loop_start;
  }
#endif
	if (ii != 0)
		goto loop_start;
	// key is pressed again, repeat measurement
#ifdef WITH_ROTARY_SWITCH
  if (rotary.incre > 0) goto wait_again;
#endif
#ifdef POWER_OFF
 #if POWER_OFF > 127
  #define POWER2_OFF 255
 #else
  #define POWER2_OFF POWER_OFF*2
 #endif
 #if POWER_OFF+0 > 1
  if ((empty_count < POWER_OFF) && (mess_count < POWER2_OFF)) {
     goto loop_start;			// repeat measurement POWER_OFF times
  }
 #endif
  // only one Measurement requested, shut off
 #if FLASHEND > 0x3fff
shut_off:
  // look, if the tester is uncalibrated (C-source will be included directly)
  lcd_cursor_off();
  /* HelpCalibration Begin */
#if defined(AUTO_CAL) && (FLASHEND > 0x3fff)
// Check is direct included in the main source of the TransistorTester
// a function with a call from main will use additional 38 bytes of flash
  // define additional variables , ii is already defined in main
 #define TIME_TO_READ 10000
  if (UnCalibrated) {
#ifndef SHORT_UNCAL_MSG
  unsigned int jj;
  char zeich;
  uint8_t space_pos;
  uint8_t line_nr;
  uint8_t sub_line;
    // Output the help text for calibration.
    // The text is formatted for two 16 character display lines.
    jj = 0;
    zeich = ' ';		// initial value for while loop
    line_nr = LCD_LINES;		// begin with the first LCD line, but don't wait
    while (zeich != (char)0) {	// zero is end of text
       space_pos = LCD_LINE_LENGTH;		// if no space is found
       for (ii=0;ii<(LCD_LINE_LENGTH+1);ii++) {	// look for the last space character
         zeich = pgm_read_byte(&HelpCalibration_str[ii+jj]);
         if (zeich == ' ')  space_pos = ii; // save the position
       }
       if (line_nr == 0) {
          // it is the first LCD line, wait for showing the last message
          if ((wait_for_key_ms(TIME_TO_READ)) != 0) break;	// key pressed
       }
       sub_line = line_nr % LCD_LINES;
       if (sub_line == 0) lcd_clear();  // clear display, line_nr is 0 or 4
       lcd_set_cursor(sub_line*PAGES_PER_LINE ,0);
       uart_newline();
       wdt_reset();
       line_nr = (line_nr + 1) % LCD_LINES;
       for (ii=0;ii<space_pos;ii++) {
         zeich = pgm_read_byte(&HelpCalibration_str[ii+jj]);
         if (zeich == (char)0) break;	// end of text found
         if (zeich == LCD_CHAR_INSEP) {
            lcd_space();	// replace with space
         } else {
            lcd_data(zeich);		// display the character without offset
         }
       }
       if (zeich == (char)0) break;	// end of text found
       jj += space_pos;		// start position of line 2
       if((pgm_read_byte(&HelpCalibration_str[jj])) == ' ') jj++; // no space at begin of line
    }  /* end while */
#else
    lcd_clear();
    lcd_pgm_string(HelpCalibration_str);	// only short message!
	#ifdef WITH_UART		//Mauro 
//		uart_newline();		//Mauro 
	#endif					//Mauro 
#endif
    wait_for_key_ms(TIME_TO_READ);	// key pressed
  }
#endif  /* AUTO_CAL && (FLASHEND > 0x3fff) */
/* HelpCalibration End */

 #endif
//  MCUSR = 0;
  switch_tester_off();
#else   /* no POWER_OFF */
shut_off:
  // look, if the tester is uncalibrated (C-source will be included directly)
  lcd_cursor_off();
  /* HelpCalibration Begin */
#if defined(AUTO_CAL) && (FLASHEND > 0x3fff)
// Check is direct included in the main source of the TransistorTester
// a function with a call from main will use additional 38 bytes of flash
  // define additional variables , ii is already defined in main
 #define TIME_TO_READ 10000
  if (UnCalibrated) {
#ifndef SHORT_UNCAL_MSG
  unsigned int jj;
  char zeich;
  uint8_t space_pos;
  uint8_t line_nr;
  uint8_t sub_line;
    // Output the help text for calibration.
    // The text is formatted for two 16 character display lines.
    jj = 0;
    zeich = ' ';		// initial value for while loop
    line_nr = LCD_LINES;		// begin with the first LCD line, but don't wait
    while (zeich != (char)0) {	// zero is end of text
       space_pos = LCD_LINE_LENGTH;		// if no space is found
       for (ii=0;ii<(LCD_LINE_LENGTH+1);ii++) {	// look for the last space character
         zeich = pgm_read_byte(&HelpCalibration_str[ii+jj]);
         if (zeich == ' ')  space_pos = ii; // save the position
       }
       if (line_nr == 0) {
          // it is the first LCD line, wait for showing the last message
          if ((wait_for_key_ms(TIME_TO_READ)) != 0) break;	// key pressed
       }
       sub_line = line_nr % LCD_LINES;
       if (sub_line == 0) lcd_clear();  // clear display, line_nr is 0 or 4
       lcd_set_cursor(sub_line*PAGES_PER_LINE ,0);
       uart_newline();
       wdt_reset();
       line_nr = (line_nr + 1) % LCD_LINES;
       for (ii=0;ii<space_pos;ii++) {
         zeich = pgm_read_byte(&HelpCalibration_str[ii+jj]);
         if (zeich == (char)0) break;	// end of text found
         if (zeich == LCD_CHAR_INSEP) {
            lcd_space();	// replace with space
         } else {
            lcd_data(zeich);		// display the character without offset
         }
       }
       if (zeich == (char)0) break;	// end of text found
       jj += space_pos;		// start position of line 2
       if((pgm_read_byte(&HelpCalibration_str[jj])) == ' ') jj++; // no space at begin of line
    }  /* end while */
#else
    lcd_clear();
    lcd_pgm_string(HelpCalibration_str);	// only short message!
	#ifdef WITH_UART		//Mauro 
//		uart_newline();		//Mauro 
	#endif					//Mauro 
#endif
    wait_for_key_ms(TIME_TO_READ);	// key pressed
  }
#endif  /* AUTO_CAL && (FLASHEND > 0x3fff) */
/* HelpCalibration End */

#endif
	goto loop_start;
	// POWER_OFF not selected, repeat measurement
//  return 0;

end3:
//        uart_newline();		// MAURO  ('H')
  // the diode  is already shown on the LCD
	if (ResistorsFound == 0)
		goto tt_end;
  ADC_DDR = (1<<TPRELAY) | TXD_MSK; 	// switch pin with reference to GND, release relay
  // there is one resistor or more detected
#if (LCD_LINES > 3)
  ADC_DDR =  TXD_MSK; 	// switch pin with reference to input, activate relay
 #ifdef WAIT_LINE2_CLEAR
  lcd_next_line_wait(0);
 #else
  lcd_line3();
 #endif
#else
  wait_for_key_ms(display_time);
  ADC_DDR =  TXD_MSK; 	// switch pin with reference to input, activate relay
  lcd_clear();
//#if FLASHEND > 0x1fff
  lcd_data('0'+NumOfDiodes);
  lcd_MEM_string(Dioden);	//"Diodes "
//#endif
#endif
  goto resistor_out;

}   // ****** end setup()  ***** end main




// function search_vak_diode try to find a diode, which has no side connected to the transistor base
// returns 20, if no diode found
uint8_t search_vak_diode() {
    uint8_t ii;
    for (ii=0; ii<NumOfDiodes; ii++) {
			if ((diodes.Anode[ii] == _trans->b)
					|| (diodes.Cathode[ii] == _trans->b))
				continue;
       // no side of the diode is connected to the base, this must be the protection diode   
       if (diodes.Voltage[ii] > 1000) break; // Voltage is too high for protection diode
       return ii;
    }
    return 20;
}

/* init_parts initialize all parts to nothing found */
void init_parts(void) {
  PartFound = PART_NONE;	// no part found
  NumOfDiodes = 0;		// Number of diodes = 0
  ptrans.count = 0;		// Number of found P type transistors
  ntrans.count = 0;		// Number of found N type transistors
  PartMode = PART_MODE_NONE;
  WithReference = 0;		// no precision reference voltage
  ResistorsFound = 0;		// no resistors found
  ResistorChecked[0] = 0;
  ResistorChecked[1] = 0;
  ResistorChecked[2] = 0;
  cap.ca = TP1;
  cap.cb = TP3;
#if FLASHEND > 0x1fff
  inductor_lpre = 0;		// mark as zero
  cap.v_loss = 0;		// set Vloss to zero
#endif
  cap.cval_max = 0;		// set max to zero
  cap.cpre_max = -15;	// set max to fF unit
}

void switch_tester_off(void)
{
 #ifdef WITH_UART
  uart_putc('O');	// MAURO
  uart_putc('F');	// MAURO
  uart_putc('F');	// MAURO
//  uart_newline();	// MAURO
 #endif
 #if ((LCD_ST_TYPE == 7565) || (LCD_ST_TYPE == 1306))
  lcd_powersave();			// set graphical display to power save mode
 #endif
  ON_PORT &= ~(1<<ON_PIN);		//switch off power
  wait2s();
  wait_for_key_ms(0); //never ending loop 
}


#ifdef WITH_SELFTEST
 /* Begin AutoCheck.c */
// Selftest of the device and calibration 
#ifdef WITH_SELFTEST
void AutoCheck(uint8_t test_mode) {
  /* (test_mode & 0x0f) == 0 , only calibration without T1-T7 */
  /* (test_mode & 0x0f) == 1 , calibration and additional T1-T7 */
  /* (test_mode & 0xf0) == 0 , check for shorted probes, if unshorted, return */
  /* (test_mode & 0xf0) == 0x10 , ask for shorted probes */

 uint8_t ww;		// counter for repeating the tests
 int  adcmv[7];
 #ifdef EXTENDED_TESTS
  uint16_t u680;	// 3 * (Voltage at 680 Ohm)
  uint8_t taste;	// ist key pressed? 0 = no
 #else
  #ifndef NO_TEST_T1_T7
  #warning "Selftest without extended tests T1 to T7!"
  #endif
 #endif
 #if defined(EXTENDED_TESTS) || defined(WITH_MENU)
  uint8_t tt;		// number of running test
 #endif

 #ifdef FREQUENCY_50HZ
  uint8_t ff50;		// loop counter for 2s
 #endif

// define the maximum count of repetitions MAX_REP
#define MAX_REP 4

 #ifdef AUTO_CAL
uint8_t cap_found;	// counter for found capacitor
  #ifdef AUTOSCALE_ADC
int8_t udiff;		// difference between ADC Voltage with VCC or Bandgap reference
int8_t udiff2;
  #endif
 #endif
PartFound = PART_NONE;		// no part found before
if ((test_mode & 0xf0) == 0) {
  // probed should be shorted already to begin selftest
  if (AllProbesShorted() != 3) return;
  lcd_clear();
  lcd_MEM_string(SELFTEST);		// "Selftest mode.."
  lcd_line2();
  lcd_data('?');			// wait for key pressed for confirmation
  if (wait_for_key_ms(2000) > 10) goto begin_selftest;	// key is pressed again
 #ifdef WITH_MENU
} else {
  // report to user, that probes should be shorted
  ww = 0;
  for (tt=0;tt<150;tt++) {	/* wait about 30 seconds for shorted probes */
    lcd_clear();
    lcd_MEM2_string(SHORT_PROBES_str);	// message "Short probes!" to LCD
    if (AllProbesShorted() == 3) {
       ww++;	// all probes now shorted
    } else {
       ww = 0;	// connection not stable, retry
    }
    if (ww > 3) break;	// connection seems to be stable
    lcd_refresh();		// write the pixels to display, ST7920 only
    wait_about200ms();			// wait 200ms and try again
  }  /* end for (tt...) */
  if (tt < 150) goto begin_selftest;		// is shorted before time limit
  goto no_zero_resistance;			// skip measuring of the zero resistance
 #endif
}
// no key pressed for 2s
lcd_clear();
lcd_MEM_string(VERSION_str);	//"Version ..."
return;

begin_selftest:
lcd_line2();
Calibrate_UR();		// get Reference voltage, Pin resistance
lcd_MEM2_string(R0_str);		// "R0="
eeprom_write_byte((uint8_t *)(&EE_ESR_ZEROtab[2]), (uint8_t)0);	// clear zero offset
eeprom_write_byte((uint8_t *)(&EE_ESR_ZEROtab[3]), (uint8_t)0);	// clear zero offset
eeprom_write_byte((uint8_t *)(&EE_ESR_ZEROtab[1]), (uint8_t)0);	// clear zero offset

adcmv[0] = GetESR(TP3, TP1);
adcmv[1] = GetESR(TP3, TP2);
adcmv[2] = GetESR(TP2, TP1);
DisplayValue16(adcmv[0],-2,' ',3);
DisplayValue16(adcmv[1],-2,' ',3);
DisplayValue16(adcmv[2],-2,LCD_CHAR_OMEGA,3);
if (adcmv[0] >= 90) {
  adcmv[0] = ESR_ZERO;	// set back to default value
}
eeprom_write_byte((uint8_t *)(&EE_ESR_ZEROtab[2]), (uint8_t)adcmv[0]);	// fix zero offset
if (adcmv[1] >= 90) {
  adcmv[1] = ESR_ZERO;	// set back to default value
}
eeprom_write_byte((uint8_t *)(&EE_ESR_ZEROtab[3]), (uint8_t)adcmv[1]);	// fix zero offset
if (adcmv[2] >= 90) {
  adcmv[2] = ESR_ZERO;	// set back to default value
}
eeprom_write_byte((uint8_t *)(&EE_ESR_ZEROtab[1]), (uint8_t)adcmv[2]);	// fix zero offset
last_line_used = 2;
wait_for_key_5s_line2();		// wait up to 5 seconds and clear line 2

 #ifdef WITH_MENU
no_zero_resistance:
 #endif
 #ifdef EXTENDED_TESTS
#define TEST_COUNT 8
if((test_mode & 0x0f) == 1) {  /* full test requested */

for(tt=1;tt<TEST_COUNT;tt++) {		// loop for all Tests
for(ww=0;ww<MAX_REP;ww++) {	// repeat the test MAX_REP times
   lcd_clear_line2();		// clear total line 2
   lcd_clear_line1();		// clear total line 1
   lcd_data('T');			//output the Testmode "T"
   u2lcd(tt);		//lcd_string(utoa(tt, outval, 10));	//output Test number
   lcd_space();
				//############################################
   if (tt == 1) {   // output of reference voltage and factors for capacity measurement
      lcd_MEM2_string(URef_str);	//"URef="
      Display_mV(ref_mv,4);
      lcd_line2();			//Cursor to column 1, row 2
      lcd_MEM2_string(RHfakt_str);	//"RHf="
      u2lcd(RHmultip);	//lcd_string(utoa(RHmultip, outval, 10));
      ADCconfig.Samples = R_ANZ_MESS;	// set number of ADC reads near to maximum
   }
				//############################################
   if (tt == 2) { // how equal are the RL resistors? 
      u680 = ((long)ADCconfig.U_AVCC * (PIN_RM + R_L_VAL) / (PIN_RM + R_L_VAL + R_L_VAL + PIN_RP));
      R_PORT = 1<<PIN_RL1;		//RL1 to VCC
      R_DDR = (1<<PIN_RL1) | (1<<PIN_RL2);	//RL2 to -
      adcmv[0] = W20msReadADC(TP1);
      adcmv[0] -= u680;
      R_DDR = (1<<PIN_RL1) | (1<<PIN_RL3);	//RL3 to -
      adcmv[1] = W20msReadADC(TP1);
      adcmv[1] -= u680;
      R_PORT = 1<<PIN_RL2;		//RL2 to VCC
      R_DDR = (1<<PIN_RL2) | (1<<PIN_RL3);	//RL3 to -
      adcmv[2] = W20msReadADC(TP2);
      adcmv[2] -= u680;
      lcd_MEM_string(RLRL_str);	// "RLRL"
   }
				//############################################
   if (tt == 3) { // how equal are the RH resistors
      R_PORT = 1<<PIN_RH1;		//RH1 to VCC
      R_DDR = (1<<PIN_RH1) | (1<<PIN_RH2);	//RH2 to -
      adcmv[0] = W20msReadADC(TP1);
      adcmv[3] = ADCconfig.U_AVCC / 2;
      adcmv[0] -= adcmv[3];
      R_DDR = (1<<PIN_RH1) | (1<<PIN_RH3);	//RH3 to -
      adcmv[1] = W20msReadADC(TP1);
      adcmv[1] -= adcmv[3];
      R_PORT = 1<<PIN_RH2;		//RH2 to VCC
      R_DDR = (1<<PIN_RH2) | (1<<PIN_RH3);	//RH3 to -
      adcmv[2] = W20msReadADC(TP2);
      adcmv[2] -= adcmv[3];
      lcd_MEM_string(RHRH_str);	// "RHRH"
   }
				//############################################
   if (tt == 4) { // Text release probes
      lcd_MEM_string(RELPROBE);	// "Release Probes"
      if (AllProbesShorted() != 0) ww = MAX_REP-2;
   }
				//############################################
   if (tt == 5) { // can we switch the ADC pins to GND across R_H resistor?
      R_PORT = 0;
      R_DDR = 1<<PIN_RH1;		//Pin 1 over R_H to GND
      adcmv[0] = W20msReadADC(TP1);

      R_DDR = 1<<PIN_RH2;		//Pin 2 over R_H to GND
      adcmv[1] = W20msReadADC(TP2);

      R_DDR = 1<<PIN_RH3;		//Pin 3 over R_H to GND
      adcmv[2] = W20msReadADC(TP3);
      lcd_MEM_string(RH1L_str);	// "RH_Lo="
   }
				//############################################
   if (tt == 6) { // can we switch the ADC pins to VCC across the R_H resistor?
      R_DDR = 1<<PIN_RH1;		//Pin 1 over R_H to VCC
      R_PORT = 1<<PIN_RH1;
      adcmv[0] = W20msReadADC(TP1) - ADCconfig.U_AVCC;
      R_DDR = 1<<PIN_RH2;		//Pin 2 over R_H to VCC
      R_PORT = 1<<PIN_RH2;
      adcmv[1] = W20msReadADC(TP2) - ADCconfig.U_AVCC;
      R_DDR = 1<<PIN_RH3;		//Pin 3 over R_H to VCC
      R_PORT = 1<<PIN_RH3;
      adcmv[2] = W20msReadADC(TP3) - ADCconfig.U_AVCC;
      lcd_MEM_string(RH1H_str);	// "RH_Hi="
   }
   if (tt == 7) { // is the voltage of all R_H / R_L dividers correct?
      u680 = ((long)ADCconfig.U_AVCC * (PIN_RM + R_L_VAL) / (PIN_RM + R_L_VAL + (unsigned long)R_H_VAL*100));
      R_PORT = 1<<PIN_RH1;		//RH1 to VCC
      R_DDR = (1<<PIN_RH1) | (1<<PIN_RL1);	//RH1 to +, RL1 to -
      adcmv[0] = W20msReadADC(TP1);
      adcmv[0] -= u680;
      R_PORT = 1<<PIN_RH2;		//RH2 to VCC
      R_DDR = (1<<PIN_RH2) | (1<<PIN_RL2);	//RH2 to +, RL2 to -
      adcmv[1] = W20msReadADC(TP2);
      adcmv[1] -= u680;
      R_PORT = 1<<PIN_RH3;		//RH3 to VCC
      R_DDR = (1<<PIN_RH3) | (1<<PIN_RL3);	//RH3 to +, RL3 to -
      adcmv[2] = W20msReadADC(TP3);
      adcmv[2] -= u680;
      lcd_MEM_string(RHRL_str);	// "RH/RL"
   }
				//############################################
   if (tt > 1) {	// output 3 voltages 
      lcd_line2();			//Cursor to column 1, row 2
      i2lcd(adcmv[0]);		// lcd_string(itoa(adcmv[0], outval, 10));	//output voltage 1
      lcd_space();
      i2lcd(adcmv[1]);		// lcd_string(itoa(adcmv[1], outval, 10));	//output voltage 2
      lcd_space();
      i2lcd(adcmv[2]);		// lcd_string(itoa(adcmv[2], outval, 10));	//output voltage 3
   }
   ADC_DDR =  TXD_MSK;		// all-Pins to Input
   ADC_PORT = TXD_VAL;		// all ADC-Ports to GND
   R_DDR = 0;			// all R-Ports to Input
   R_PORT = 0;
   taste = wait_for_key_ms(1000);	// wait up to 1 second or key is pressed
   if ((tt != 4) && (taste > 10)) {
      // don't finish repetition  for T4 with pressed key
      break; // if key is pressed, don't repeat
   }
} //end for ww
wait_for_key_ms(1000);	// wait up to 1 second or key is pressed
} //end for tt
  #if PROCESSOR_TYP == 1280
lcd_clear();
lcd_testpin(TP1);
lcd_data('L');
lcd_equal();			// lcd_data('=');
ADC_PORT = TXD_VAL;
ADC_DDR = (1<<TP1) | TXD_MSK;
R_PORT = (1<<PIN_RL1);
R_DDR = (1<<PIN_RL1);
adcmv[0] = W5msReadADC(TP1);
ADCSRB = (1<<MUX5);		// switch to upper 8 MUX inputs
adcmv[1] = ReadADC(PIN_RL1);
ADCSRB = 0;			// switch back to lower 8 MUX inputs
ResistorVal[0] = (adcmv[0] * (unsigned long)R_L_VAL) / (adcmv[1] - adcmv[0]);
DisplayValue(ResistorVal[0],-1,LCD_CHAR_OMEGA,3);
lcd_space();
lcd_data('H');
lcd_equal();			// lcd_data('=');
ResistorVal[1] = (vcc_diff(adcmv[1]) * (unsigned long)R_L_VAL) / (adcmv[1] - adcmv[0]);
DisplayValue(ResistorVal[1],-1,LCD_CHAR_OMEGA,3);
lcd_line2();
lcd_testpin(TP1);
lcd_space();
lcd_data('H');
lcd_equal();			// lcd_data('=');
ADC_PORT = (1<<TP1) | TXD_VAL;
R_PORT = 0;
adcmv[0] = W5msReadADC(TP1);
ADCSRB = (1<<MUX5);		// switch to upper 8 MUX inputs
adcmv[1] = ReadADC(PIN_RL1);
ADCSRB = 0;			// switch back to lower 8 MUX inputs
ResistorVal[1] = (vcc_diff(adcmv[0]) * (unsigned long)R_L_VAL) / (adcmv[0] - adcmv[1]);
DisplayValue(ResistorVal[1],-1,LCD_CHAR_OMEGA,3);
lcd_space();
lcd_data('L');
lcd_equal();			// lcd_data('=');
ResistorVal[0] = (adcmv[1] * (unsigned long)R_L_VAL) / (adcmv[0] - adcmv[1]);
DisplayValue(ResistorVal[0],-1,LCD_CHAR_OMEGA,3);
wait_about1s();			// only for mega1280
last_line_used = 2;
wait_for_key_5s_line2();		// wait up to 5 seconds and clear line 2
// 
lcd_clear();
lcd_testpin(TP2);
lcd_data('L');
lcd_equal();			// lcd_data('=');
ADC_PORT = TXD_VAL;
ADC_DDR = (1<<TP2) | TXD_MSK;
R_PORT = (1<<PIN_RL2);
R_DDR = (1<<PIN_RL2);
adcmv[0] = W5msReadADC(TP2);
ADCSRB = (1<<MUX5);		// switch to upper 8 MUX inputs
adcmv[1] = ReadADC(PIN_RL2);
ADCSRB = 0;			// switch back to lower 8 MUX inputs
ResistorVal[0] = (adcmv[0] * (unsigned long)R_L_VAL) / (adcmv[1] - adcmv[0]);
DisplayValue(ResistorVal[0],-1,LCD_CHAR_OMEGA,3);
lcd_space();
lcd_data('H');
lcd_equal();			// lcd_data('=');
ResistorVal[1] = (vcc_diff(adcmv[1]) * (unsigned long)R_L_VAL) / (adcmv[1] - adcmv[0]);
DisplayValue(ResistorVal[1],-1,LCD_CHAR_OMEGA,3);
lcd_line2();
lcd_testpin(TP2);
lcd_data('H');
lcd_equal();			// lcd_data('=');
ADC_PORT = (1<<TP2) | TXD_VAL;
R_PORT = 0;
adcmv[0] = W5msReadADC(TP2);
ADCSRB = (1<<MUX5);		// switch to upper 8 MUX inputs
adcmv[1] = ReadADC(PIN_RL2);
ADCSRB = 0;			// switch back to lower 8 MUX inputs
ResistorVal[1] = (vcc_diff(adcmv[0]) * (unsigned long)R_L_VAL) / (adcmv[0] - adcmv[1]);
DisplayValue(ResistorVal[1],-1,LCD_CHAR_OMEGA,3);
lcd_space();
lcd_data('L');
lcd_equal();			// lcd_data('=');
ResistorVal[0] = (adcmv[1] * (unsigned long)R_L_VAL) / (adcmv[0] - adcmv[1]);
DisplayValue(ResistorVal[0],-1,LCD_CHAR_OMEGA,3);
wait_about1s();			// only for mega1280
last_line_used = 2;
wait_for_key_5s_line2();		// wait up to 5 seconds and clear line 2
//
lcd_clear();
lcd_testpin(TP3);
lcd_data('L');
lcd_equal();			// lcd_data('=');
ADC_DDR = (1<<TP3) | TXD_MSK;
R_PORT = (1<<PIN_RL3);
R_DDR = (1<<PIN_RL3);
adcmv[0] = W5msReadADC(TP3);
ADCSRB = (1<<MUX5);		// switch to upper 8 MUX inputs
adcmv[1] = ReadADC(PIN_RL3);
ADCSRB = 0;
ResistorVal[0] = (adcmv[0] * (unsigned long)R_L_VAL) / (adcmv[1] - adcmv[0]);
DisplayValue(ResistorVal[0],-1,LCD_CHAR_OMEGA,3);
lcd_space();
lcd_data('H');
lcd_equal();			// lcd_data('=');
ResistorVal[1] = (vcc_diff(adcmv[1]) * (unsigned long)R_L_VAL) / (adcmv[1] - adcmv[0]);
DisplayValue(ResistorVal[1],-1,LCD_CHAR_OMEGA,3);
lcd_line2();
lcd_testpin(TP3);
lcd_data('H');
lcd_equal();			// lcd_data('=');
ADC_PORT = (1<<TP3) | TXD_VAL;
R_PORT = 0;
adcmv[0] = W5msReadADC(TP3);
ADCSRB = (1<<MUX5);		// switch to upper 8 MUX inputs
adcmv[1] = ReadADC(PIN_RL3);
ADCSRB = 0;			// switch back to lower 8 MUX inputs
ResistorVal[1] = (vcc_diff(adcmv[0]) * (unsigned long)R_L_VAL) / (adcmv[0] - adcmv[1]);
DisplayValue(ResistorVal[1],-1,LCD_CHAR_OMEGA,3);
lcd_space();
lcd_data('L');
lcd_equal();			// lcd_data('=');
ResistorVal[0] = (adcmv[1] * (unsigned long)R_L_VAL) / (adcmv[0] - adcmv[1]);
DisplayValue(ResistorVal[0],-1,LCD_CHAR_OMEGA,3);
wait_about1s();			// only for mega1280
last_line_used = 2;
wait_for_key_5s_line2();		// wait up to 5 seconds and clear line 2
  #endif	/* PROCESSOR_TYP == 1280 */
}	/* end if((test_mode & 0x0f) == 1) */
 #endif		/* end EXTENDED_TESTS */

for (ww=0;ww<120;ww++) {
  // wait up to 1 minute for releasing the probes
  if (AllProbesShorted() == 0) break;
  lcd_clear_line2();		// clear total line2
  lcd_MEM_string(RELPROBE);	// "Release Probes"
  lcd_refresh();		// write the pixels to display, ST7920 only
  wait_about500ms();
}



lcd_clear();
lcd_MEM_string(RIHI_str);	// "RiHi="
DisplayValue16(RRpinPL,-1,LCD_CHAR_OMEGA,3);
lcd_line2();
lcd_MEM_string(RILO_str);	// "RiLo="
DisplayValue16(RRpinMI,-1,LCD_CHAR_OMEGA,3);
last_line_used = 2;
wait_for_key_5s_line2();		// wait up to 5 seconds and clear line 2

//measure Zero offset for Capacity measurement
PartFound = PART_NONE;
lcd_clear();
lcd_MEM_string(C0_str);			//output "C0 "
ReadCapacity(TP3, TP1);
adcmv[5] = (unsigned int) cap.cval_uncorrected.dw;	//save capacity value of empty Pin 1:3
ReadCapacity(TP3, TP2);
adcmv[6] = (unsigned int) cap.cval_uncorrected.dw;	//save capacity value of empty Pin 2:3
ReadCapacity(TP2, TP1);
adcmv[2] = (unsigned int) cap.cval_uncorrected.dw;	//save capacity value of empty Pin 1:2
ReadCapacity(TP1, TP3);
adcmv[1] = (unsigned int) cap.cval_uncorrected.dw;	//save capacity value of empty Pin 3:1
ReadCapacity(TP2, TP3);
adcmv[4] = (unsigned int) cap.cval_uncorrected.dw;	//save capacity value of empty Pin 3:2
ReadCapacity(TP1, TP2);
adcmv[0] = (unsigned int) cap.cval_uncorrected.dw;	//save capacity value of empty Pin 2:1
 #ifdef WITH_MENU
if (((test_mode & 0x0f) == 1) || (UnCalibrated == 2))
 #else
if (UnCalibrated == 2)
 #endif
{
  adcmv[3] = adcmv[0] + 2;		// mark as uncalibrated until Cap > 100nF has success
} else {
  adcmv[3] = adcmv[0];			// mark as calibrated, short calibration is finished
  UnCalibrated = 0;			// clear the UnCalibrated Flag
  lcd_cursor_off();			// switch cursor off
}
u2lcd_space(adcmv[5]);	//DisplayValue(adcmv[5],0,' ',3);		//output cap0 1:3
u2lcd_space(adcmv[6]);	//DisplayValue(adcmv[6],0,' ',3);		//output cap0 2:3
DisplayValue(adcmv[2],-12,'F',3);		//output cap0 1:2
 #ifdef AUTO_CAL
for (ww=0;ww<7;ww++) {			//checking loop
if ((adcmv[ww] > 190) || (adcmv[ww] < 10)) goto no_c0save;
}
for (ww=0;ww<7;ww++) {
  // write all zero offsets to the EEprom 
  (void) eeprom_write_byte((uint8_t *)(&c_zero_tab[ww]),adcmv[ww]+(COMP_SLEW1 / (CC0 + CABLE_CAP + COMP_SLEW2)));
}
lcd_line2();
lcd_MEM_string(OK_str);		// output "OK"
no_c0save:
 #endif
last_line_used = 2;
wait_for_key_5s_line2();		// wait up to 5 seconds and clear line 2

#ifdef SamplingADC
  sampling_cap_calibrate();		// measure zero capacity for samplingADC
#endif

 #ifdef AUTO_CAL
  #ifdef WITH_MENU
if (((test_mode & 0x0f) == 1) || (UnCalibrated == 2))
  #endif
// without menu function the capacitor is requested every time,
// because there is no way to request recaltbration again
// With menu function the capacitor is only requested for first time 
// calibration (UnCalibrated = 2) or for the full selftest call (test_mode = 1) 
// of the menu function, not with the automatically call (test_mode = 1).
{
// for full test or first time calibration, use external capacitor
// Message C > 100nF at TP1 and TP3
cap_found = 0;
#if (TPCAP <= 0)
lcd_clear();
lcd_testpin(TP1);
lcd_MEM_string(CapZeich);	// "-||-"
lcd_testpin(TP3);
lcd_MEM2_string(MinCap_str);	// " >100nF!"
#endif
for (ww=0;ww<64;ww++) {
  init_parts();
  #if (TPCAP >= 0)
  CalibrationCap();	// measure with internal calibration capacitor
  #else
  PartFound = PART_NONE;
  ReadCapacity(TP3, TP1);	// look for capacitor > 100nF
  #endif
  while (cap.cpre < -9) {
   cap.cpre++;
   cap.cval /= 10;
  }
  if ((cap.cpre == -9) && (cap.cval > 95) && (cap.cval < 22000) &&
    (load_diff > -150) && (load_diff < 150)) {
   cap_found++;
  } else {
   cap_found = 0;		// wait for stable connection
  }
  if (cap_found > 4) {
     // value of capacitor is correct
     (void) eeprom_write_word((uint16_t *)(&ref_offset), load_diff);	// hold zero offset + slew rate dependend offset
     lcd_clear();
     lcd_MEM2_string(REF_C_str);	// "REF_C="
     i2lcd(load_diff);		// lcd_string(itoa(load_diff, outval, 10));	//output REF_C_KORR
     RefVoltage();			// new ref_mv_offs and RHmultip
  #if 0
//#######################################
   // Test for switching level of the digital input of port TP3
   for (tt=0;tt<8;tt++) {
     ADC_PORT =  TXD_VAL;	//ADC-Port 1 to GND
     ADC_DDR = 1<<TP1 | TXD_MSK;	//ADC-Pin  1 to output 0V
     R_PORT = 1<<PIN_RH3;		//Pin 3 over R_H to VCC
     R_DDR = 1<<PIN_RH3;		//Pin 3 over R_H to VCC
     while (1) {
        wdt_reset();
        if ((ADC_PIN&(1<<TP3)) == (1<<TP3)) break;
     }
     R_DDR = 0;		//Pin 3 without current
     R_PORT = 0;
     adcmv[0] = ReadADC(TP3);
     lcd_line3();
     Display_mV(adcmv[0],4);
     R_DDR = 1<<PIN_RH3;		//Pin 3 over R_H to GND
     while (1) {
        wdt_reset();
        if ((ADC_PIN&(1<<TP3)) != (1<<TP3)) break;
     }
     R_DDR = 0;		//Pin 3 without current
     lcd_line4();
     adcmv[0] = ReadADC(TP3);
     Display_mV(adcmv[0],4);
     last_line_used = 2;
     wait_for_key_5s_line2();		// wait up to 5 seconds and clear line 2
   }
//#######################################
  #endif
  #ifdef AUTOSCALE_ADC
   #if (TPCAP >= 0)
    #define CAP_ADC TPCAP	/* Cap >100nF is integrated at TPCAP */
   TCAP_PORT &= ~(1<<TCAP_RH);	// 470k resistor to GND
   TCAP_DDR |= (1<<TCAP_RH);	// enable output
   #else
    #define CAP_ADC TP3		/* Cap >100nF at TP3 */
   ADC_PORT =  TXD_VAL;	//ADC-Port 1 to GND
   ADC_DDR = 1<<TP1 | TXD_MSK;	//ADC-Pin  1 to output 0V
   R_DDR = 1<<PIN_RH3;		//Pin 3 over R_H to GND
   #endif
   do {
      adcmv[0] = ReadADC(CAP_ADC);
   } while (adcmv[0] > 980);
   #if (TPCAP >= 0)
   TCAP_DDR &= ~(1<<TCAP_RH);	// 470k resistor port to input mode
   #else
   R_DDR = 0;		//all Pins to input 
   #endif
   ADCconfig.U_Bandgap = 0;	// do not use internal Ref
   adcmv[0] = ReadADC(CAP_ADC);  // get cap voltage with VCC reference
   ADCconfig.U_Bandgap = adc_internal_reference;
   adcmv[1] = ReadADC(CAP_ADC);	// get cap voltage with internal reference
   adcmv[1] += adcmv[1];		// double the value
   ADCconfig.U_Bandgap = 0;	// do not use internal Ref
   adcmv[2] = ReadADC(CAP_ADC);  // get cap voltage with VCC reference
   ADCconfig.U_Bandgap = adc_internal_reference;
   udiff = (int8_t)(((signed long)(adcmv[0] + adcmv[2] - adcmv[1])) * adc_internal_reference / adcmv[1])+REF_R_KORR;
   lcd_line2();
   lcd_MEM2_string(REF_R_str);	// "REF_R="
   udiff2 = udiff + (int8_t)eeprom_read_byte((uint8_t *)(&RefDiff));
   (void) eeprom_write_byte((uint8_t *)(&RefDiff), (uint8_t)udiff2);	// hold offset for true reference Voltage
   i2lcd(udiff2);		// output correction voltage
   RefVoltage();			// set new ADCconfig.U_Bandgap
  #endif	/* end AUTOSCALE_ADC */
   last_line_used = 2;
   wait_for_key_5s_line2();		// wait up to 5 seconds and clear line 2
   UnCalibrated = 0;		// clear the UnCalibrated Flag
   lcd_cursor_off();		// switch cursor off
   cap_found = eeprom_read_byte((uint8_t *)&c_zero_tab[0]);	// read first capacity zero offset
   eeprom_write_byte((uint8_t *)&c_zero_tab[3], cap_found);	// mark as calibrated permanent
   break;			// leave the ww for loop
  }  /* end if (cap_found > 4) */
  lcd_line2();
  DisplayValue(cap.cval,cap.cpre,'F',4);
  lcd_clear_line();
  lcd_refresh();		// write the pixels to display, ST7920 only
  wait_about200ms();			// wait additional time
} // end for ww
}	/* end if((test_mode & 0x0f) == 1) */
 #endif  /* end AUTO_CAL */

ADCconfig.Samples = ANZ_MESS;	// set to configured number of ADC samples

#if defined(SamplingADC) && !defined(AUTO_LC_CAP)
  sampling_lc_calibrate(0);	// Cap for L-meas
#endif


 #ifdef FREQUENCY_50HZ
//#define TEST_SLEEP_MODE	/* only select for checking the sleep delay */
 lcd_clear();
 lcd_MEM_string(T50HZ);	//" 50Hz"
 lcd_refresh();		// write the pixels to display, ST7920 only
 ADC_PORT = TXD_VAL;
 ADC_DDR = 1<<TP1 | TXD_MSK;	// Pin 1 to GND
 R_DDR = (1<<PIN_RL3) | (1<<PIN_RL2);
 for(ww=0;ww<30;ww++) {	// repeat the signal up to 30 times (1 minute)
   for (ff50=0;ff50<100;ff50++) {	// for 2 s generate 50 Hz
      R_PORT = (1<<PIN_RL2);	// Pin 2 over R_L to VCC, Pin 3 over R_L to GND
  #ifdef TEST_SLEEP_MODE
      sleep_5ms(2); 		// test of timing of sleep mode call 
  #else
      wait10ms();		// normal delay
  #endif
      R_PORT = (1<<PIN_RL3);	// Pin 3 over R_L to VCC, Pin 2 over R_L to GND
  #ifdef TEST_SLEEP_MODE
      sleep_5ms(2); 		// test of timing of sleep mode call 
  #else
      wait10ms();		// normal delay
  #endif
      wdt_reset();
   } /* end for ff50 */
   if (!(RST_PIN_REG & (1<<RST_PIN))) {
      // if key is pressed, don't repeat
      break;
   }
 } /* end for ww */
 #endif		/* end FREQUENCY_50HZ */
lcd_clear();
lcd_MEM_string(VERSION_str);	//"Version ..."
lcd_line2();
lcd_MEM_string(ATE);		//"Selftest End"
PartFound = PART_NONE;
     last_line_used = 2;
wait_for_key_5s_line2();		// wait up to 5 seconds and clear line 2
} /* end AutoCheck */ 

 
/*
 *  check for a short circuit between two probes
 *  from Markus R.
 *
 *  requires:
 *  - ID of first probe (0-2)
 *  - ID of second probe (0-2)
 *
 *  returns:
 *  - 0 if not shorted
 *  - 1 if shorted
 */

uint8_t ShortedProbes(uint8_t Probe1, uint8_t Probe2)
{
  uint8_t           Flag1 = 0;      /* return value */
  unsigned int      U1;            /* voltage at probe #1 in mV */
  unsigned int      U2;            /* voltage at probe #2 in mV */
  unsigned int      URH;	   /* half of reference voltage */
  const uint8_t *addr;
  uint8_t pp;
  /*
   *  Set up a voltage divider between the two probes:
   *  - Probe1: Rl pull-up
   *  - Probe2: Rl pull-down
   */

  ADC_DDR =  TXD_MSK;		// all-Pins to Input
  ADC_PORT = TXD_VAL;		// all ADC-Ports to GND
  addr = &PinRLRHADCtab[Probe1];
  pp = pgm_read_byte(addr);
  R_PORT = pp;
  addr += (int8_t)(Probe2-Probe1);
  R_DDR =  pp | pgm_read_byte(addr);	// pgm_read_byte(PinRHtab[Probe1]) | pgm_read_byte(PinRLtab[Probe2]);

  /* read voltages */
  U1 = ReadADC(Probe1);
  U2 = ReadADC(Probe2);

  /*
   *  We expect both probe voltages to be about the same and
   *  to be half of Vcc (allowed difference +/- 20mV).
   */
 #ifndef MAX_UH_DIFF
  #define MAX_UH_DIFF 30
 #endif

  URH = ADCconfig.U_AVCC / 2;
  URH -= ((long)U_VCC * (long)(PIN_RP-PIN_RM)) / (4*(unsigned long)(R_L_VAL+PIN_RM));			// differenz of Pin resistance high (22) and low (20)
  if (((U1 + MAX_UH_DIFF) > URH ) && (U1 < (URH + MAX_UH_DIFF)))
  {
    if (((U2 + MAX_UH_DIFF) > URH) && (U2 < (URH + MAX_UH_DIFF)))
    {
      Flag1 = 1;
    }
  }

  /* reset port */
  R_DDR = 0;

  return Flag1;
}
/*
 *  check for a short circuit between all probes
 *  from Markus R.
 *
 *  returns:
 *  - 0 if no probes are short-circuited
 *  - number of probe pairs short-circuited (3 = all)
 */

uint8_t AllProbesShorted(void)
{
  uint8_t           Flag2;      /* return value */

  /* check all possible combinations */
  Flag2 = ShortedProbes(TP1, TP2);
  Flag2 += ShortedProbes(TP1, TP3);
  Flag2 += ShortedProbes(TP2, TP3);

  return Flag2;
}
#endif /* end #ifdef WITH_SELFTEST */
/* End AutoCheck.c */
#endif


#ifdef AUTO_CAL
 /* Begin mark_as_uncalibrated.c */
void mark_as_uncalibrated( void) {
 uint8_t ii;
 if (!UnCalibrated) {
    // equipment has changed, zero capacity value is too high or zero resistance is too high
    // but the device is marked as Calibrated.
    ii = eeprom_read_byte((uint8_t *)&c_zero_tab[0]);	// read first zero offset
    ii++;
    // make the unused c_zero_tab[3] different to c_zero_tab[0] to mark uncalibrated 
    eeprom_write_byte((uint8_t *)&c_zero_tab[3], ii);	// mark uncalibrated permanent
    UnCalibrated = 1;		// set back to uncalibrated
 }
}
/* End mark_as_uncalibrated.c */
#endif


#if FLASHEND > 0x1fff
 /* Begin GetIr.c */
/* Get residual current in reverse direction of a diode */ 
//=================================================================
void GetIr(uint8_t hipin, uint8_t lopin) {
  unsigned int u_res;	// reverse voltage at 470k
  unsigned int u_res_old;
  unsigned int ir_nano;
  uint8_t HiADC;

#if (((PIN_RL1 + 1) != PIN_RH1) || ((PIN_RL2 + 1) != PIN_RH2) || ((PIN_RL3 + 1) != PIN_RH3))
  HiADC = pgm_read_byte(&PinRLRHADCtab[hipin-TP_MIN]+6);	// Table of ADC pins including | TXD_VAL
  ADC_PORT = HiADC;		 	// switch ADC port to high level
  ADC_DDR = HiADC | TXD_MSK;		// switch High Pin direct to VCC
  R_PORT = 0;				// switch R-Port to GND
  LoPinR_L = pgm_read_byte(&PinRHRLADCtab[lopin-TP_MIN]);  //R_L mask for LowPin R_L load
#else
  uint8_t LoPinR_L;
  HiADC = pgm_read_byte(&PinRLRHADCtab[hipin-TP_MIN]+3);	// Table of ADC pins including | TXD_VAL
  ADC_PORT = HiADC;		 	// switch ADC port to high level
  ADC_DDR = HiADC | TXD_MSK;		// switch High Pin direct to VCC
  R_PORT = 0;				// switch R-Port to GND
  LoPinR_L = pgm_read_byte(&PinRLRHADCtab[lopin-TP_MIN]);  //R_L mask for LowPin R_L load
  // R_H Pin must always be one pin number higher
#endif
  R_DDR = LoPinR_L;		// switch R_L port for LowPin to output (GND)
  u_res = U_VCC;
  // first load the parallel capacity with 680 Ohm resistor, then measure current with 470k
  do {
     u_res_old = u_res;
     u_res = W20msReadADC(lopin);		// read voltage
#if (((PIN_RL1 + 1) != PIN_RH1) || ((PIN_RL2 + 1) != PIN_RH2) || ((PIN_RL3 + 1) != PIN_RH3))
     R_DDR = pgm_read_byte(&PinRHRLADCtab[lopin-TP_MIN+3]);  //R_H mask for LowPin R_H load
#else
     R_DDR = LoPinR_L + LoPinR_L;		// switch R_H port for LowPin to output (GND)
#endif
  } while (u_res < u_res_old);
  if (u_res == 0) return;		// no Output, if no current in reverse direction
#if (LCD_LINES > 3)
 #define IR_DIGITS 3
  lcd_line4();				// use Line 4 for Ir output
  lcd_MEM_string(Ir_str);		// output text "Ir="
#else
 #define IR_DIGITS 2
  lcd_MEM_string(Ir_str);		// output text "  Ir="
#endif
#ifdef WITH_IRMICRO
  unsigned int ir_micro;
  if (u_res < 2500) {
#endif
     /* R_H_VAL has units of 10 Ohm, u_res has units of mV, ir_nano has units of nA */
     ir_nano = (unsigned long)(u_res * 100000UL) / R_H_VAL;
     DisplayValue16(ir_nano,-9,'A',2);	// output two digits of current with nA units
#ifdef WITH_IRMICRO
  } else {
     R_DDR = LoPinR_L;			// switch R_L port for LowPin to output (GND)
     u_res = W5msReadADC(lopin);	// read voltage
     ir_nano = 0xffff;			// set to max
     /* RR680MI has units of 0.1 Ohm, u_res has units of mV, ir_micro has units of uA */
     ir_micro = (unsigned long)(u_res * 10000UL) / RR680MI;
     DisplayValue16(ir_micro,-6,'A',IR_DIGITS);	// output 2 or 3 digits of current in uA units
  }
#endif
  ADC_DDR = TXD_MSK;			// switch off
  ADC_PORT = TXD_VAL;			// switch off
  R_DDR = 0;				// switch off current

  return ;
}
/* End GetIr.c */
#endif
  
//}


void loop() {
    
}

 

UlfurNorth
Offline
Зарегистрирован: 28.05.2022

Судя по варнингам ничего не выводится на экран либо из-за того что не указан шрифт, либо может всё-таки выводится, но где-то за пределами экрана:

C:\Users\UlfurNorth\Desktop\ArduTester_more\font.h:108:5 : предупреждение: #предупреждение Шрифт не указан. Проверьте Makefile! [-Wcpp]
#предупреждение Шрифт не указан. Проверьте Makefile!

В файле, включенном из C:\Users\UlfurNorth\Desktop\ArduTester_more\config.h:1101:0,
из C:\Users\UlfurNorth\Desktop\ArduTester_more\Transistortester.h:14 ,
из C:\Users\UlfurNorth\Desktop\ArduTester_more\ArduTester_more.ino:18:
C:\Users\UlfurNorth\Desktop\ArduTester_more\autoconf.h:80:3 : предупреждение: #предупреждение LCD_ST7565_Y_START установлен выше, чем SCREEN_HEIGHT! [-Wcpp]
#предупреждение LCD_ST7565_Y_START установлен выше, чем SCREEN_HEIGHT!

C:\Users\UlfurNorth\Desktop\ArduTester_more\autoconf.h:98:3 : предупреждение: #предупреждение Неправильно установлено значение LCD_LINES! [-Wcpp]
#предупреждение Неправильно задан параметр LCD_LINES

Чуть позже попытаюсь разобраться сегодня в этом.

UlfurNorth
Offline
Зарегистрирован: 28.05.2022

Но вот к примеру для переменной "LCD_ST7565_Y_START" задано значение "0", в "autoconf.h", а у "SCREEN_HEIGHT" задано значение "64" в файле "lcd_defines.h". Предупреждение о том, что "LCD_ST7565_Y_START" выше чем "SCREEN_HEIGHT" выводится только в том случае, если первая переменная больше либо равна второй, судя по строке #79 в "autoconf.h", но ведь это не так.

P.S.: А по поводу варнинга о "LCD_LINES", так там вообще какой-то тёмный лес в коде, как его значение рассчитывается понятно кажется, вроде бы, там кроме всего прочего для рассчёта значения "LCD_LINES" происходит деление на значение переменной "PAGES_PER_LINE", которая равна "((FONT_HEIGHT + 7) / 8), а учитывая первый варнинг о том, что шрифт не указан, то причиной может быть это, нужно менять код, пробовать, чуть позже это сделаю. Там чёрт ногу сломит, одно завязано на другом.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018
UlfurNorth
Offline
Зарегистрирован: 28.05.2022

Действительно, всё теперь работает, только откалибровать нужно, а то немного привирает.
Первым делом огромное вам СПАСИБО!!! Сам бы я неделю копался и не заставил бы в итоге его работать думаю.
Можете сказать в чём была проблема?

UlfurNorth
Offline
Зарегистрирован: 28.05.2022

Сравнил свой код с вашим и понял в чём было дело. :)
Ещё раз спасибо.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Я просто устал скакать по файлам в поисках ошибки в инициализации дисплея и поменял её на свою - проверенную. И сделал это в одном месте - в самом начале setup(), а не в 100500 файлах. В передаче данных на дисплей им было сложнее накосячить - вот оно и заработало.

UlfurNorth
Offline
Зарегистрирован: 28.05.2022

Пришлось пожертвовать меню кстати, иначе на atmega 328 прошивка не влезает, занимает что-то около 104% памяти. Но главное что всё остальное работает, разве что кроме измерения кварцев и калибровка никак не запускается, но можно вручную внести калибровочные изменения в файлы.

UlfurNorth
Offline
Зарегистрирован: 28.05.2022

Также частоту для связи i2c изменил на 400000L, шустрее работает.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

И на 800000 будет работать. Напишите вместо команды установки скорости I2C - TWBR=1 ; Будет что то около 888000 - максимум аппаратного I2C для 328.

UlfurNorth
Offline
Зарегистрирован: 28.05.2022

Попробую потом ради эксперимента.