Может есть смысл переработать проект и сделать как сделал K3NG в контроллере поворотки?
У него весь проект разбит на отдельные функции (хидеры) и эти функции выведены в отдельные файлы.
Может есть смысл переработать проект и сделать как сделал K3NG в контроллере поворотки?
У него весь проект разбит на отдельные функции (хидеры) и эти функции выведены в отдельные файлы.
если знаешь, что кусок кода менялся в конкретном файле то наверное всё же проще
такой механизм стыкуется с git
к примеру - tester_setup.h, tester_features.h, tester_hardware.h, tester_pins.h, tester_display.h и основной скетч )))
в начале файла в комментах указываем, откуда и что попадает
да и листинги будут тогда удобоваримыми, как мне кажется...
в молодости я тоже тысячи строк держал в уме, сейчас - УВЫ )))
если знаешь, что кусок кода менялся в конкретном файле то наверное всё же проще
такой механизм стыкуется с git
к примеру - tester_setup.h, tester_features.h, tester_hardware.h, tester_pins.h, tester_display.h и основной скетч
в начале файла в комментах указываем, откуда и что попадает
И что мешает самому преобразовать код разработчиков в рабочий скетч для Ардуино?
если знаешь, что кусок кода менялся в конкретном файле то наверное всё же проще
такой механизм стыкуется с git
к примеру - tester_setup.h, tester_features.h, tester_hardware.h, tester_pins.h, tester_display.h и основной скетч
в начале файла в комментах указываем, откуда и что попадает
И что мешает самому преобразовать код разработчиков в рабочий скетч для Ардуино?
Отсутствие какого-нибудь опыта в этом, на СИ программ не писал, только ассемблер и в машинных кодах, да и по процессорам интел и моторола, честно сказать попытался, с ходу не получилось ))) все свои программы были написаны до 1990 года однако )))
Но "религия ардуино" мне понравилась, эти бы возможности лет бы так тридцать, сорок назад )))
Странная ситуёвина, на работе компилировал под версией 1.6.5 и компилировалось без ошибок
(под дисплей I2C), под версией 1.6.8 и 1.6.12 не пошло, это да )))
Сейчас второй час дома пытаюсь скомпилировать и эффект нулевой (собрал девайс на макетке пытаюсь залить), видимо всё дело в библиотеке под I2C, с этой же библиотекой контроллер K3NG и компилируется и заливается без проблем ))) чудеса с этими ардуинками, IDE девственно чистый, даже перекачал заново, а не сбросите свою библиотеку по I2C?
Кстати, правильная строка инициализации для моей библиотеки LCD_I2C (и моего дисплея)
В продолжении темы - притащил с работы всё в конфигурации где компилируется, выполняю, заливаю, не "выходит каменный цветок"
Вот это реально отпугивает... кто готов помочь?
да это понятно - я про инициализационную строку lcd
Библиотека заработала, но эту строку поправил - #define lcd_init() lcd.begin(16,2)
Поменял на lcd.begin()
Под 1.6.5 не компилил из-за этого
На дисплее что-то есть, всё на макетке, нет конденсатора на aref и кнопку еще не ставил, но уже что-то там тестит, какие-то транзисторы находит )))
а вот версия 1.08.2 скомпилилась, ничего править не пришлось, макетирую на UNO, наверное я что-то напутал в схеме - несёт пургу ))), если что-то к измерительным выводам присоеденено на момент включения - встряёт, кнопка не работает
Но самое главное - ожил )))
Пошевелил проводки, попередёргивал и, как-то неожиданно заработало )))
Резисторы меряет вполне точно, а вот электролиты врёт, завышает более чем в два раза.
А как ввести ИОН в схему?
ARDUINEC - а Вы это в своём устройстве задействовали?
// Port pin for 2.5V precision reference used for VCC check (optional)
#define TPREF 4
// Port pin for Battery voltage measuring
#define TPBAT 5
А то точность процентов 5-10 на резисторах у меня на UNO получилась, резисторы в прибор специально не отбирал )))
Всё таки дисплейчики надо бы выделить как-то в отдельный класс...
Правлю для дисплея 2004 под I2С, код по всему скетчу разбросан, как-то несиматишна )))
Понимаю, это будет уже совсем другой проект по сравнению с авторским от разработчика тестера
ЗЫ дисплей работает но есть мешанина, я о LCD2004, правлю
Добрый день. Помогите пожалуста. Собрал tt108001 NANO V3.0 LCD1602A. Заливал скейчи с начала темы - Arduino1.6.12 выдаетошибки и с поста 115 пишет - ошибка компиляции для платы Arduino NANO. Подскажите ход действий, желательно подробней - я только начал пробовать изучать ардуино.
И подскажите как вставить снимок экрана - пробовал, неполучается - отправляет на внешний сервер.
Добрый день. Помогите пожалуста. Собрал tt108001 NANO V3.0 LCD1602A. Заливал скейчи с начала темы - Arduino1.6.12 выдаетошибки и с поста 115 пишет - ошибка компиляции для платы Arduino NANO. Подскажите ход действий, желательно подробней - я только начал пробовать изучать ардуино.
Не поленился, добавил себе Arduino IDE 1.6.12 - скетч tt108001 у меня компилируется без проблем:
Скетч использует 15 296 байт (49%) памяти устройства. Всего доступно 30 720 байт.
Глобальные переменные используют 383 байт (18%) динамической памяти, оставляя 1 665 байт для локальных переменных. Максимум: 2 048 байт.
Для подробного хода действий не хватает информации (на что ругается компилятор).
splin62 пишет:
И подскажите как вставить снимок экрана - пробовал, неполучается - отправляет на внешний сервер.
Програмирую при помощи arduino 1.6.12 заливаю скейч tt108001, программа выдает ошибки. Естествено я их исправить не могу. Скоптровал скейч с поста 115, вставил в программу, нажал проверку - программа выдает сообщение - "ошибка компиляции для платы arduino nano" и снизу в окне куча текста на английском.
А если я Вам сброшу на почту снимки экрана, может быть Вы сможете мне помочь разобраться в этом поле информации?
всем привет, у меня проблема, загрузил скетчи все которые только тут были, все компилируется но почему то не работает.... горят квадратики слабенько верхний ряд, проверял дисплей и конвертер i2c все работает, SDA и SCLдисплея подключать к А4, А5 или к SDA SCL дуины? перепробовал все варианты не было изменений, может я что-то делаю не так((
у меня проблема, загрузил скетчи все которые только тут были, все компилируется но почему то не работает.... горят квадратики слабенько верхний ряд, проверял дисплей и конвертер i2c все работает,
В скетче из поста 18 раскомментировали нужные строки?
Xumuk пишет:
SDA и SCL дисплея подключать к А4, А5 или к SDA SCL дуины?
Для Arduino Uno/Nano/ProMini это равнозначно, а на других Ардуинах (Mega, Leonardo) скетч не проверял.
у меня проблема, загрузил скетчи все которые только тут были, все компилируется но почему то не работает.... горят квадратики слабенько верхний ряд, проверял дисплей и конвертер i2c все работает,
В скетче из поста 18 раскомментировали нужные строки?
Xumuk пишет:
SDA и SCL дисплея подключать к А4, А5 или к SDA SCL дуины?
Для Arduino Uno/Nano/ProMini это равнозначно, а на других Ардуинах (Mega, Leonardo) скетч не проверял.
раскоментил 1602 i2c только одну же строку нужно раскоментить? из-за сопротивлений возможны глюки? когда нажимаю тест кнопку чуток притухает дсплей
не совпадение выводов в скейче со схемой, схему прилагаю
ArduTester07f
Подскажите пожалуйста, что Вы делали, по возможности подробней, т.к. я совсем в этой теме зеленый. Заранее благодарен. Сергей
Вы оказывается скетч ArduTester07f компилируете. Он в моих архивах только для примера приведён, так как автор его 3 года назад забросил. Компиляцию он проходит, но за работоспособность его не ручаюсь.
щас там стоит 100нан,без него тоже примерно такое же значение показывает
Взял свой скетч из поста 18 (раскомментировал/закомментировал нужное), соединил детальки как описано в постах 2,3,5 и с конденсатором 100 нФ получил следующий результат:
щас там стоит 100нан,без него тоже примерно такое же значение показывает
Взял свой скетч из поста 18 (раскомментировал/закомментировал нужное), соединил детальки как описано в постах 2,3,5 и с конденсатором 100 нФ получил следующий результат:
я не сомневаюсь в работоспособности кода, если я подключу чисто дисплей без всех делителей чтобы проверить чисто дисплей он будет работать? или нужно обязательно все резисторы ставить?
Полученный адрес вставляется в строку 1253 скетча tt108002.ino вместо 0x3F: LiquidCrystal_I2C lcd(0x3F, 16, 2);
спасибо, вечером попробую
Р.S. все работает спасибо, но показания всеравно какие то не такие, подключил резистор на 10 кОм он пишет No unknown or damaged part, либо как будто конденсатор на 170vrA? это может быть связано с тем что собрано на макетке беспаячной?
показания всеравно какие то не такие, подключил резистор на 10 кОм он пишет No unknown or damaged part, либо как будто конденсатор на 170vrA? это может быть связано с тем что собрано на макетке беспаячной?
Возможно из-за плохого контакта на беспаечной макетной плате. Ещё светодиод на пине 13 иногда мешает.
Но я недолго с беспаечной макеткой экспериментировал. Как понял, что с 6 резисторами Ардуина может как транзистор-тестер работать, так сразу спаял плату, которую и показал в посте 3.
показания всеравно какие то не такие, подключил резистор на 10 кОм он пишет No unknown or damaged part, либо как будто конденсатор на 170vrA? это может быть связано с тем что собрано на макетке беспаячной?
Возможно из-за плохого контакта на беспаечной макетной плате. Ещё светодиод на пине 13 иногда мешает.
Но я недолго с беспаечной макеткой экспериментировал. Как понял, что с 6 резисторами Ардуина может как транзистор-тестер работать, так сразу спаял плату, которую и показал в посте 3.
))) понял, макетки под рукой нету, придется травить,спасибо за помощь
Интересно, а появится ли когда нибудь прошивка и программа к PC, что бы результаты измерений видеть не на экранчике, а на мониторе (там графичеких возможностей поболе)?
Интересно, а появится ли когда нибудь прошивка и программа к PC, что бы результаты измерений видеть не на экранчике, а на мониторе (там графичеких возможностей поболе)?
Скетчи выдают результаты также и в Serial Monitor, так что желающие могут сделать программу для PC и изображать измерения в любом удобном виде на мониторе.
Спасибо, кто откликнулся на мои просьбы! Схема была собрана на макетке, сегодня разобрал ее и снова собрал аналогично, как в посту 3. Скейч с 1 поста залился, но при включении яркость дисплея и надписи яркие, затем начинают тухнуть и становятся еле видными. Сейчас немного проветрюсь, займусь снова, но прогресс на лицо - это уже радует!!! Как отлажу, выложу фото.
Спасибо, кто откликнулся на мои просьбы! Схема была собрана на макетке, сегодня разобрал ее и снова собрал аналогично, как в посту 3. Скейч с 1 поста залился, но при включении яркость дисплея и надписи яркие, затем начинают тухнуть и становятся еле видными. Сейчас немного проветрюсь, займусь снова, но прогресс на лицо - это уже радует!!! Как отлажу, выложу фото.
если дисплей от нокии то у них помоему у большинства проблема с прилеганием резинок к плате... я такой выкинул так и не смог побороть такую как у тебя проблему
всем привет еще раз, сделал я шилд для ардуины уно, но вот опять незадача при пустом разьеме tp он выдает что подключен конденсатор примерно 50мкф, может ли быть что с самой ардуины он гдето берет это значение, не машает ли ему на 13 пине светодиод дуинывский? а если делаю измерение резистора на 10ком он показывает 12, резюки использовал 670 ом, в скетче тоже написал 670 ом, без исправления показывало примерно тоже самое
Спасибо, с резистором действительно работает. У конденсатора, который измерял выше, получилось ESR=0.04 Ом.
Т.е. хорошие конденсаторы будут по нулям, тогда нет смысла добиваться точных показаний, этого достаточно.
Как я уже писал в посте 43 данной темы, более свежий код в скетч я уже преобразовал, но он пока не хочет работать.
как успехи с 1.12 версией, получилось?
Как я уже писал в посте 43 данной темы, более свежий код в скетч я уже преобразовал, но он пока не хочет работать.
как успехи с 1.12 версией, получилось?
Если бы получилось, то обязательно выложил бы в эту тему.
Может есть смысл переработать проект и сделать как сделал K3NG в контроллере поворотки?
У него весь проект разбит на отдельные функции (хидеры) и эти функции выведены в отдельные файлы.
https://github.com/k3ng/k3ng_rotator_controller
Тогда станет понятно, где копать.
Я начинающий ардуинщик, смогу помочь только тестированием оного проекта )))
Может есть смысл переработать проект и сделать как сделал K3NG в контроллере поворотки?
У него весь проект разбит на отдельные функции (хидеры) и эти функции выведены в отдельные файлы.
В исходном коде разработчиков (http://www.mikrocontroller.net/svnbrowser/transistortester/Software/trunk/) функции находятся в отдельных файлах, но искать там не проще.
...здесь я рыбу заворачивал... )))
если знаешь, что кусок кода менялся в конкретном файле то наверное всё же проще
такой механизм стыкуется с git
к примеру - tester_setup.h, tester_features.h, tester_hardware.h, tester_pins.h, tester_display.h и основной скетч )))
в начале файла в комментах указываем, откуда и что попадает
да и листинги будут тогда удобоваримыми, как мне кажется...
в молодости я тоже тысячи строк держал в уме, сейчас - УВЫ )))
если знаешь, что кусок кода менялся в конкретном файле то наверное всё же проще
такой механизм стыкуется с git
к примеру - tester_setup.h, tester_features.h, tester_hardware.h, tester_pins.h, tester_display.h и основной скетч
в начале файла в комментах указываем, откуда и что попадает
И что мешает самому преобразовать код разработчиков в рабочий скетч для Ардуино?
если знаешь, что кусок кода менялся в конкретном файле то наверное всё же проще
такой механизм стыкуется с git
к примеру - tester_setup.h, tester_features.h, tester_hardware.h, tester_pins.h, tester_display.h и основной скетч
в начале файла в комментах указываем, откуда и что попадает
И что мешает самому преобразовать код разработчиков в рабочий скетч для Ардуино?
Отсутствие какого-нибудь опыта в этом, на СИ программ не писал, только ассемблер и в машинных кодах, да и по процессорам интел и моторола, честно сказать попытался, с ходу не получилось ))) все свои программы были написаны до 1990 года однако )))
Но "религия ардуино" мне понравилась, эти бы возможности лет бы так тридцать, сорок назад )))
Компилировал на Arduino IDE версии 1.0.5.
Странная ситуёвина, на работе компилировал под версией 1.6.5 и компилировалось без ошибок
(под дисплей I2C), под версией 1.6.8 и 1.6.12 не пошло, это да )))
Сейчас второй час дома пытаюсь скомпилировать и эффект нулевой (собрал девайс на макетке пытаюсь залить), видимо всё дело в библиотеке под I2C, с этой же библиотекой контроллер K3NG и компилируется и заливается без проблем ))) чудеса с этими ардуинками, IDE девственно чистый, даже перекачал заново, а не сбросите свою библиотеку по I2C?
Кстати, правильная строка инициализации для моей библиотеки LCD_I2C (и моего дисплея)
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
В продолжении темы - притащил с работы всё в конфигурации где компилируется, выполняю, заливаю, не "выходит каменный цветок"
Вот это реально отпугивает... кто готов помочь?
Смотрю скетч - LiquidCrystal lcd(7, 6, 5, 4, 3, 2); // RS,E,D4,D5,D6,D7
Смотрю свой дисплей -LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
адрес - 0х3F
enable - 2
read/write - 1
Rs - 0
D4 - 4
D5 - 5
D6 - 6
D7 - 7
#define HW_LCD_EN_PORT PORTD
#define HW_LCD_EN_PIN 6
#define HW_LCD_RS_PORT PORTD
#define HW_LCD_RS_PIN 7
#define HW_LCD_B4_PORT PORTD
#define HW_LCD_B4_PIN 5
#define HW_LCD_B5_PORT PORTD
#define HW_LCD_B5_PIN 4
#define HW_LCD_B6_PORT PORTD
#define HW_LCD_B6_PIN 3
#define HW_LCD_B7_PORT PORTD
#define HW_LCD_B7_PIN 2
А ноги то не попадают, и как это исправляется?
а не сбросите свою библиотеку по I2C?
https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library
А ноги то не попадают, и как это исправляется?
При I2C используются ноги SDA и SCL
да это понятно - я про инициализационную строку lcd
Библиотека заработала, но эту строку поправил - #define lcd_init() lcd.begin(16,2)
Поменял на lcd.begin()
Под 1.6.5 не компилил из-за этого
На дисплее что-то есть, всё на макетке, нет конденсатора на aref и кнопку еще не ставил, но уже что-то там тестит, какие-то транзисторы находит )))
а вот версия 1.08.2 скомпилилась, ничего править не пришлось, макетирую на UNO, наверное я что-то напутал в схеме - несёт пургу ))), если что-то к измерительным выводам присоеденено на момент включения - встряёт, кнопка не работает
Но самое главное - ожил )))
Пошевелил проводки, попередёргивал и, как-то неожиданно заработало )))
Резисторы меряет вполне точно, а вот электролиты врёт, завышает более чем в два раза.
А как ввести ИОН в схему?
ARDUINEC - а Вы это в своём устройстве задействовали?
// Port pin for 2.5V precision reference used for VCC check (optional)
#define TPREF 4
// Port pin for Battery voltage measuring
#define TPBAT 5
А то точность процентов 5-10 на резисторах у меня на UNO получилась, резисторы в прибор специально не отбирал )))
Всё таки дисплейчики надо бы выделить как-то в отдельный класс...
Правлю для дисплея 2004 под I2С, код по всему скетчу разбросан, как-то несиматишна )))
Понимаю, это будет уже совсем другой проект по сравнению с авторским от разработчика тестера
ЗЫ дисплей работает но есть мешанина, я о LCD2004, правлю
Добрый вечер! не получается скомпелировать, скетч переписал под i2c дисплей 1602, где может быть ошибка?
библиотеки рабочие
Добрый вечер! не получается скомпелировать, скетч переписал под i2c дисплей 1602, где может быть ошибка?
библиотеки рабочие
Модификация скетча 1.08.001 для дисплея 1602 с I2C описана в посте 5.
В посте 18 прилагается скетч 1.08.002, в котором проще подключаются другие дисплеи.
Вот крайний скетч под 1602/2004
0001
/* \\\|///
0002
\\ - - //
0003
( @ @ )
0004
/--------------------oOOo-(_)-oOOo---------------------\
0005
| |
0006
| |
0007
| Transistor Tester for Arduino (version 1.08a) |
0008
| |
0009
| based on code: Karl-Heinz Kubbeler (version 1.08k) |
0010
| |
0011
| |
0012
| Oooo |
0013
\--------------------oooO----( )---------------------/
0014
( ) ) /
0015
\ ( (_/
0016
\_) */
0017
0018
0019
#include <avr/io.h>
0020
#include <util/delay.h>
0021
#include <avr/sleep.h>
0022
#include <stdlib.h>
0023
#include <string.h>
0024
#include <avr/eeprom.h>
0025
#include <avr/pgmspace.h>
0026
#include <avr/wdt.h>
0027
#include <avr/interrupt.h>
0028
#include <math.h>
0029
#include <stdint.h>
0030
#include <avr/power.h>
0031
0032
#define LCD1602
0033
//#define LCD2004
0034
#define LCD_I2C
0035
//#define NOK5110
0036
0037
#ifdef LCD2004
0038
#ifdef LCD_I2C
0039
#include <Wire.h>
0040
#include <LiquidCrystal_I2C.h>
0041
#else
0042
#include <LiquidCrystal.h>
0043
#endif
0044
0045
#endif
0046
#ifdef LCD1602
0047
#ifdef LCD_I2C
0048
#include <Wire.h>
0049
#include <LiquidCrystal_I2C.h>
0050
#else
0051
#include <LiquidCrystal.h>
0052
#endif
0053
#endif
0054
0055
#ifdef NOK5110
0056
#include <SPI.h>
0057
#include <Adafruit_GFX.h>
0058
#include <Adafruit_PCD8544.h>
0059
#endif
0060
0061
0062
// ******** config options for your Semiconductor tester
0063
0064
// Every changing of this Makefile will result in new compiling the whole
0065
// programs, if you call make or make upload.
0066
0067
#define MCU atmega328p
0068
#define F_CPU 16000000UL
0069
0070
// Select your language:
0071
// Available languages are: LANG_ENGLISH, LANG_GERMAN, LANG_POLISH, LANG_CZECH, LANG_SLOVAK, LANG_SLOVENE,
0072
// LANG_DUTCH, LANG_BRASIL, LANG_RUSSIAN, LANG_UKRAINIAN
0073
#define LANG_ENGLISH
0074
0075
// The LCD_CYRILLIC option is necessary, if you have a display with cyrillic characterset.
0076
// This lcd-display don't have a character for Ohm and for u (micro).
0077
// Russian language requires a LCD controller with russian characterset and option LCD_CYRILLIC!
0078
#define LCD_CYRILLIC
0079
0080
// The LCD_DOGM option must be set for support of the DOG-M type of LCD modules with ST7036 controller.
0081
// For this LCD type the contrast must be set with software command.
0082
//#define LCD_DOGM
0083
0084
// Option STRIP_GRID_BOARD selects different board-layout, do not set for standard board!
0085
// The connection of LCD is totally different for both versions.
0086
//#define STRIP_GRID_BOARD
0087
0088
// The WITH_SELFTEST option enables selftest function (only for mega168 or mega328).
0089
//#define WITH_SELFTEST
0090
0091
// AUTO_CAL will enable the autocalibration of zero offset of capacity measurement and
0092
// also the port output resistance values will be find out in SELFTEST section.
0093
// With a external capacitor a additionally correction of reference voltage is figured out for
0094
// low capacity measurement and also for the AUTOSCALE_ADC measurement.
0095
// The AUTO_CAL option is only selectable for mega168 and mega328.
0096
//#define AUTO_CAL
0097
0098
// FREQUENCY_50HZ enables a 50 Hz frequency generator for up to one minute at the end of selftests.
0099
//#define FREQUENCY_50HZ
0100
0101
// The WITH_AUTO_REF option enables reading of internal REF-voltage to get factors for the Capacity measuring.
0102
#define WITH_AUTO_REF
0103
// REF_C_KORR corrects the reference Voltage for capacity measurement (<40uF) and has mV units.
0104
// Greater values gives lower capacity results.
0105
#define REF_C_KORR 12
0106
// REF_L_KORR corrects the reference Voltage for inductance measurement and has mV units.
0107
#define REF_L_KORR 40
0108
// C_H_KORR defines a correction of 0.1% units for big capacitor measurement.
0109
// Positive values will reduce measurement results.
0110
#define C_H_KORR 0
0111
0112
// The WITH_UART option enables the software UART (TTL level output at Pin PC3, 26).
0113
// If the option is deselected, PC3 can be used as external voltage input with a
0114
// 10:1 resistor divider.
0115
//#define WITH_UART
0116
0117
// The CAP_EMPTY_LEVEL defines the empty voltage level for capacitors in mV.
0118
// Choose a higher value, if your Tester reports "Cell!" by unloading capacitors.
0119
#define CAP_EMPTY_LEVEL 4
0120
0121
// The AUTOSCALE_ADC option enables the autoscale ADC (ADC use VCC and Bandgap Ref).
0122
#define AUTOSCALE_ADC
0123
#define REF_R_KORR 3
0124
0125
// The ESR_ZERO value define the zero value of ESR measurement (units = 0.01 Ohm).
0126
//#define ESR_ZERO 29
0127
#define ESR_ZERO 20
0128
0129
// NO_AREF_CAP tells your Software, that you have no Capacitor installed at pin AREF (21).
0130
// This enables a shorter wait-time for AUTOSCALE_ADC function.
0131
// A capacitor with 1nF can be used with the option NO_AREF_CAP set.
0132
#define NO_AREF_CAP
0133
0134
// The OP_MHZ option tells the software the Operating Frequency of your ATmega.
0135
// OP_MHZ 16
0136
0137
// Restart from sleep mode will be delayed for 16384 clock tics with crystal mode.
0138
// Operation with the internal RC-Generator or external clock will delay the restart by only 6 clock tics.
0139
// You must specify this with "#define RESTART_DELAY_TICS=6", if you don't use the crystal mode.
0140
//#define RESTART_DELAY_TICS 6
0141
0142
// The USE_EEPROM option specify where you wish to locate fix text and tables.
0143
// If USE_EEPROM is unset, program memory (flash) is taken for fix text and tables.
0144
//#define USE_EEPROM
0145
0146
// Setting EBC_STYPE will select the old style to present the order of Transistor connection (EBC=...).
0147
// Omitting the option will select the 123=... style. Every point is replaced by a character identifying
0148
// type of connected transistor pin (B=Base, E=Emitter, C=Collector, G=Gate, S=Source, D=Drain).
0149
// If you select EBC_STYLE=321 , the style will be 321=... , the inverted order to the 123=... style.
0150
//#define EBC_STYLE
0151
//#define EBC_STYLE 321
0152
0153
// Setting of NO_NANO avoids the use of n as prefix for Farad (nF), the mikro prefix is used insted (uF).
0154
//#define NO_NANO
0155
0156
// The PULLUP_DISABLE option disable the pull-up Resistors of IO-Ports.
0157
// To use this option a external pull-up Resistor (10k to 30k)
0158
// from Pin 13 to VCC must be installed!
0159
#define PULLUP_DISABLE
0160
0161
// The ANZ_MESS option specifies, how often an ADC value is read and accumulated.
0162
// Possible values of ANZ_MESS are 5 to 200.
0163
#define ANZ_MESS 25
0164
0165
// The POWER_OFF option enables the power off function, otherwise loop measurements infinitely
0166
// until power is disconnected with a ON/OFF switch (#define POWER_OFF).
0167
// If you have the tester without the power off transistors, you can deselect POWER_OFF .
0168
// If you have NOT selected the POWER_OFF option with the transistors installed,
0169
// you can stop measuring by holding the key several seconds after a result is
0170
// displayed. After releasing the key, the tester will be shut off by timeout.
0171
// Otherwise you can also specify, after how many measurements without found part
0172
// the tester will shut down (#define POWER_OFF=5).
0173
// The tester will also shut down with found part,
0174
// but successfull measurements are allowed double of the specified number.
0175
// You can specify up to 255 empty measurements (#define POWER_OFF=255).
0176
//#define POWER_OFF 5
0177
//#define POWER_OFF
0178
0179
// Option BAT_CHECK enables the Battery Voltage Check, otherwise the SW Version is displayed instead of Bat.
0180
// BAT_CHECK should be set for battery powered tester version.
0181
//#define BAT_CHECK
0182
0183
// The BAT_OUT option enables Battery Voltage Output on LCD (if BAT_CHECK is selected).
0184
// If your 9V supply has a diode installed, use the BAT_OUT=600 form to specify the
0185
// threshold voltage of your diode to adjust the output value.
0186
// This threshold level is added to LCD-output and does not affect the voltage checking levels.
0187
//#define BAT_OUT 150
0188
0189
// To adjust the warning-level and poor-level of battery check to the capability of a
0190
// low drop voltage regulator, you can specify the Option BAT_POOR=5400 .
0191
// The unit for this option value is 1mV , 5400 means a poor level of 5.4V.
0192
// The warning level is 0.8V higher than the specified poor level (>5.3V).
0193
// The warning level is 0.4V higher than the specified poor level (>2.9V, <=5.3V).
0194
// The warning level is 0.2V higher than the specified poor level (>1.3V, <=2.9V).
0195
// The warning level is 0.1V higher than the specified poor level (<=1.3V).
0196
// Setting the poor level to low values is not recommended for rechargeable Batteries,
0197
// because this increase the danger for deep discharge!!
0198
#define BAT_POOR 6400
0199
0200
// The sleep mode of the ATmega168 or ATmega328 is normally used by the software to save current.
0201
// You can inhibit this with the option INHIBIT_SLEEP_MODE .
0202
//#define INHIBIT_SLEEP_MODE
0203
0204
// ******** end of selectable options
0205
0206
/* -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- */
0207
0208
// ######## Configuration
0209
0210
#ifndef ADC_PORT
0211
//#define DebugOut 3 // if set, output of voltages of resistor measurements in row 2,3,4
0212
//#define DebugOut 4 // if set, output of voltages of Diode measurement in row 3+4
0213
//#define DebugOut 5 // if set, output of Transistor checks in row 2+3
0214
//#define DebugOut 10 // if set, output of capacity measurements (ReadCapacity) in row 3+4
0215
0216
/*
0217
Port, that is directly connected to the probes.
0218
This Port must have an ADC-Input (ATmega8: PORTC).
0219
The lower pins of this Port must be used for measurements.
0220
Please don't change the definitions of TP1, TP2 and TP3!
0221
The TPREF pin can be connected with a 2.5V precision voltage reference
0222
The TPext can be used with a 10:1 resistor divider as external voltage probe up to 50V
0223
*/
0224
0225
#define ADC_PORT PORTC
0226
#define ADC_DDR DDRC
0227
#define ADC_PIN PINC
0228
#define TP1 0
0229
#define TP2 1
0230
#define TP3 2
0231
#define TPext 3
0232
// Port pin for 2.5V precision reference used for VCC check (optional)
0233
#define TPREF 4
0234
// Port pin for Battery voltage measuring
0235
#define TPBAT 5
0236
0237
/*
0238
exact values of used resistors (Ohm).
0239
The standard value for R_L is 680 Ohm, for R_H 470kOhm.
0240
0241
To calibrate your tester the resistor-values can be adjusted:
0242
*/
0243
#define R_L_VAL 6800 // standard value 680 Ohm, multiplied by 10 for 0.1 Ohm resolution
0244
//#define R_L_VAL 6690 // this will be define a 669 Ohm
0245
#define R_H_VAL 47000 // standard value 470000 Ohm, multiplied by 10, divided by 100
0246
//#define R_H_VAL 47900 // this will be define a 479000 Ohm, divided by 100
0247
0248
#define R_DDR DDRB
0249
#define R_PORT PORTB
0250
0251
/*
0252
Port for the Test resistors
0253
The Resistors must be connected to the lower 6 Pins of the Port in following sequence:
0254
RLx = 680R-resistor for Test-Pin x
0255
RHx = 470k-resistor for Test-Pin x
0256
0257
RL1 an Pin 0
0258
RH1 an Pin 1
0259
RL2 an Pin 2
0260
RH2 an Pin 3
0261
RL3 an Pin 4
0262
RH3 an Pin 5
0263
*/
0264
0265
#define ON_DDR DDRD
0266
#define ON_PORT PORTD
0267
#define ON_PIN_REG PIND
0268
#define ON_PIN 18 // Pin, must be switched to high to switch power on
0269
0270
#ifdef STRIP_GRID_BOARD
0271
// Strip Grid board version
0272
#define RST_PIN 0 // Pin, is switched to low, if push button is pressed
0273
#else
0274
// normal layout version
0275
#define RST_PIN 17 // Pin, is switched to low, if push button is pressed
0276
#endif
0277
0278
0279
// Port(s) / Pins for LCD
0280
0281
#ifdef STRIP_GRID_BOARD
0282
// special Layout for strip grid board
0283
#define HW_LCD_EN_PORT PORTD
0284
#define HW_LCD_EN_PIN 5
0285
0286
#define HW_LCD_RS_PORT PORTD
0287
#define HW_LCD_RS_PIN 7
0288
0289
#define HW_LCD_B4_PORT PORTD
0290
#define HW_LCD_B4_PIN 4
0291
#define HW_LCD_B5_PORT PORTD
0292
#define HW_LCD_B5_PIN 3
0293
#define HW_LCD_B6_PORT PORTD
0294
#define HW_LCD_B6_PIN 2
0295
#define HW_LCD_B7_PORT PORTD
0296
#define HW_LCD_B7_PIN 1
0297
#else
0298
// normal Layout
0299
#define HW_LCD_EN_PORT PORTD
0300
#define HW_LCD_EN_PIN 6
0301
0302
#define HW_LCD_RS_PORT PORTD
0303
#define HW_LCD_RS_PIN 7
0304
0305
#define HW_LCD_B4_PORT PORTD
0306
#define HW_LCD_B4_PIN 5
0307
#define HW_LCD_B5_PORT PORTD
0308
#define HW_LCD_B5_PIN 4
0309
#define HW_LCD_B6_PORT PORTD
0310
#define HW_LCD_B6_PIN 3
0311
#define HW_LCD_B7_PORT PORTD
0312
#define HW_LCD_B7_PIN 2
0313
#endif
0314
0315
0316
// U_VCC defines the VCC Voltage of the ATmega in mV units
0317
0318
#define U_VCC 5000
0319
// integer factors are used to change the ADC-value to mV resolution in ReadADC !
0320
0321
// With the option NO_CAP_HOLD_TIME you specify, that capacitor loaded with 680 Ohm resistor will not
0322
// be tested to hold the voltage same time as load time.
0323
// Otherwise (without this option) the voltage drop during load time is compensated to avoid displaying
0324
// too much capacity for capacitors with internal parallel resistance.
0325
// #define NO_CAP_HOLD_TIME
0326
0327
0328
// U_SCALE can be set to 4 for better resolution of ReadADC function for resistor measurement
0329
#define U_SCALE 4
0330
0331
// R_ANZ_MESS can be set to a higher number of measurements (up to 200) for resistor measurement
0332
#define R_ANZ_MESS 190
0333
0334
// Watchdog
0335
//#define WDT_enabled
0336
/*
0337
If you remove the "#define WDT_enabled" , the Watchdog will not be activated.
0338
This is only for Test or debugging usefull.
0339
For normal operation please activate the Watchdog !
0340
*/
0341
0342
// ######## End of configuration
0343
0344
0345
#if R_ANZ_MESS < ANZ_MESS
0346
#undef R_ANZ_MESS
0347
#define R_ANZ_MESS ANZ_MESS
0348
#endif
0349
#if U_SCALE < 0
0350
// limit U_SCALE
0351
#undef U_SCALE
0352
#define U_SCALE 1
0353
#endif
0354
#if U_SCALE > 4
0355
// limit U_SCALE
0356
#undef U_SCALE
0357
#define U_SCALE 4
0358
#endif
0359
#ifndef REF_L_KORR
0360
#define REF_L_KORR 50
0361
#endif
0362
0363
0364
// the following definitions specify where to load external data from: EEprom or flash
0365
#ifdef USE_EEPROM
0366
#define MEM_TEXT EEMEM
0367
0368
#if E2END > 0X1FF
0369
#define MEM2_TEXT EEMEM
0370
#define MEM2_read_byte(a) eeprom_read_byte(a)
0371
#define MEM2_read_word(a) eeprom_read_word(a)
0372
#define lcd_fix2_string(a) lcd_fix_string(a)
0373
#else
0374
#define MEM2_TEXT PROGMEM
0375
#define MEM2_read_byte(a) pgm_read_byte(a)
0376
#define MEM2_read_word(a) pgm_read_word(a)
0377
#define lcd_fix2_string(a) lcd_pgm_string(a)
0378
#define use_lcd_pgm
0379
#endif
0380
0381
#define MEM_read_word(a) eeprom_read_word(a)
0382
#define MEM_read_byte(a) eeprom_read_byte(a)
0383
0384
#else
0385
#define MEM_TEXT PROGMEM
0386
#define MEM2_TEXT PROGMEM
0387
#define MEM_read_word(a) pgm_read_word(a)
0388
#define MEM_read_byte(a) pgm_read_byte(a)
0389
#define MEM2_read_byte(a) pgm_read_byte(a)
0390
#define MEM2_read_word(a) pgm_read_word(a)
0391
#define lcd_fix2_string(a) lcd_pgm_string(a)
0392
#define use_lcd_pgm
0393
#endif
0394
0395
0396
// RH_OFFSET : systematic offset of resistor measurement with RH (470k)
0397
// resolution is 0.1 Ohm, 3500 defines a offset of 350 Ohm
0398
#define RH_OFFSET 3500
0399
0400
// TP2_CAP_OFFSET is a additionally offset for TP2 capacity measurements in pF units
0401
#define TP2_CAP_OFFSET 2
0402
0403
// CABLE_CAP defines the capacity (pF) of 12cm cable with clip at the terminal pins
0404
#define CABLE_CAP 3
0405
0406
0407
// select the right Processor Typ
0408
/*
0409
#if defined(__AVR_ATmega48__)
0410
#define PROCESSOR_TYP 168
0411
#elif defined(__AVR_ATmega48P__)
0412
#define PROCESSOR_TYP 168
0413
#elif defined(__AVR_ATmega88__)
0414
#define PROCESSOR_TYP 168
0415
#elif defined(__AVR_ATmega88P__)
0416
#define PROCESSOR_TYP 168
0417
#elif defined(__AVR_ATmega168__)
0418
#define PROCESSOR_TYP 168
0419
#elif defined(__AVR_ATmega168P__)
0420
#define PROCESSOR_TYP 168
0421
#elif defined(__AVR_ATmega328__)
0422
#define PROCESSOR_TYP 328
0423
#elif defined(__AVR_ATmega328P__)
0424
#define PROCESSOR_TYP 328
0425
#elif defined(__AVR_ATmega640__)
0426
#define PROCESSOR_TYP 1280
0427
#elif defined(__AVR_ATmega1280__)
0428
#define PROCESSOR_TYP 1280
0429
#elif defined(__AVR_ATmega2560__)
0430
#define PROCESSOR_TYP 1280
0431
#else
0432
#define PROCESSOR_TYP 8
0433
#endif
0434
*/
0435
#define PROCESSOR_TYP 328
0436
0437
0438
// automatic selection of right call type
0439
#if FLASHEND > 0X1FFF
0440
#define ACALL call
0441
#else
0442
#define ACALL rcall
0443
#endif
0444
0445
0446
// automatic selection of option and parameters for different AVRs
0447
0448
//------------------=========----------
0449
#if PROCESSOR_TYP == 168
0450
//------------------=========----------
0451
#define MCU_STATUS_REG MCUCR
0452
#define ADC_COMP_CONTROL ADCSRB
0453
#define TI1_INT_FLAGS TIFR1
0454
#define DEFAULT_BAND_GAP 1070
0455
#define DEFAULT_RH_FAKT 884 // mega328 1070 mV
0456
// LONG_HFE activates computation of current amplification factor with long variables
0457
#define LONG_HFE
0458
// COMMON_COLLECTOR activates measurement of current amplification factor in common collector circuit (Emitter follower)
0459
#define COMMON_COLLECTOR
0460
#define MEGA168A 17
0461
#define MEGA168PA 18
0462
0463
// Pin resistor values of ATmega168
0464
//#define PIN_RM 196
0465
//#define PIN_RP 225
0466
#define PIN_RM 190
0467
#define PIN_RP 220
0468
// CC0 defines the capacity of empty terminal pins 1 & 3 without cable
0469
#define CC0 36
0470
// Slew rate correction val += COMP_SLEW1 / (val + COMP_SLEW2)
0471
#define COMP_SLEW1 4000
0472
#define COMP_SLEW2 220
0473
#define C_NULL CC0+CABLE_CAP+(COMP_SLEW1 / (CC0 + CABLE_CAP + COMP_SLEW2))
0474
#define MUX_INT_REF 0x0e // channel number of internal 1.1 V
0475
0476
//------------------=========----------
0477
#elif PROCESSOR_TYP == 328
0478
//------------------=========----------
0479
#define MCU_STATUS_REG MCUCR
0480
#define ADC_COMP_CONTROL ADCSRB
0481
#define TI1_INT_FLAGS TIFR1
0482
#define DEFAULT_BAND_GAP 1070
0483
#define DEFAULT_RH_FAKT 884 // mega328 1070 mV
0484
// LONG_HFE activates computation of current amplification factor with long variables
0485
#define LONG_HFE
0486
// COMMON_COLLECTOR activates measurement of current amplification factor in common collector circuit (Emitter follower)
0487
#define COMMON_COLLECTOR
0488
0489
#define PIN_RM 200
0490
#define PIN_RP 220
0491
// CC0 defines the capacity of empty terminal pins 1 & 3 without cable
0492
#define CC0 36
0493
// Slew rate correction val += COMP_SLEW1 / (val + COMP_SLEW2)
0494
#define COMP_SLEW1 4000
0495
#define COMP_SLEW2 180
0496
#define C_NULL CC0+CABLE_CAP+(COMP_SLEW1 / (CC0 + CABLE_CAP + COMP_SLEW2))
0497
#define MUX_INT_REF 0x0e // channel number of internal 1.1 V
0498
0499
//------------------=========----------
0500
#elif PROCESSOR_TYP == 1280
0501
//------------------=========----------
0502
#define MCU_STATUS_REG MCUCR
0503
#define ADC_COMP_CONTROL ADCSRB
0504
#define TI1_INT_FLAGS TIFR1
0505
#define DEFAULT_BAND_GAP 1070
0506
#define DEFAULT_RH_FAKT 884 // mega328 1070 mV
0507
// LONG_HFE activates computation of current amplification factor with long variables
0508
#define LONG_HFE
0509
// COMMON_COLLECTOR activates measurement of current amplification factor in common collector circuit (Emitter follower)
0510
#define COMMON_COLLECTOR
0511
0512
#define PIN_RM 200
0513
#define PIN_RP 220
0514
// CC0 defines the capacity of empty terminal pins 1 & 3 without cable
0515
#define CC0 36
0516
// Slew rate correction val += COMP_SLEW1 / (val + COMP_SLEW2)
0517
#define COMP_SLEW1 4000
0518
#define COMP_SLEW2 180
0519
#define C_NULL CC0+CABLE_CAP+(COMP_SLEW1 / (CC0 + CABLE_CAP + COMP_SLEW2))
0520
#define MUX_INT_REF 0x1e /* channel number of internal 1.1 V */
0521
0522
//------------------=========----------
0523
#else
0524
// ATmega8
0525
//------------------=========----------
0526
#define MCU_STATUS_REG MCUCSR
0527
#define ADC_COMP_CONTROL SFIOR
0528
#define TI1_INT_FLAGS TIFR
0529
#define DEFAULT_BAND_GAP 1298 //mega8 1298 mV
0530
#define DEFAULT_RH_FAKT 740 // mega8 1250 mV
0531
// LONG_HFE activates computation of current amplification factor with long variables
0532
#define LONG_HFE
0533
// COMMON_COLLECTOR activates measurement of current amplification factor in common collector circuit (Emitter follower)
0534
#define COMMON_COLLECTOR
0535
0536
#define PIN_RM 196
0537
#define PIN_RP 240
0538
// CC0 defines the capacity of empty terminal pins 1 & 3 without cable
0539
#define CC0 27
0540
// Slew rate correction val += COMP_SLEW1 / (val + COMP_SLEW2)
0541
#define COMP_SLEW1 0
0542
#define COMP_SLEW2 33
0543
#define C_NULL CC0+CABLE_CAP+(COMP_SLEW1 / (CC0 + CABLE_CAP + COMP_SLEW2))
0544
#define MUX_INT_REF 0x0e /* channel number of internal 1.1 V */
0545
0546
#ifndef INHIBIT_SLEEP_MODE
0547
#define INHIBIT_SLEEP_MODE /* do not use the sleep mode of ATmega */
0548
#endif
0549
#endif
0550
0551
#if PROCESSOR_TYP == 8
0552
// 2.54V reference voltage + correction (fix for ATmega8)
0553
#ifdef AUTO_CAL
0554
#define ADC_internal_reference (2560 + (int8_t)eeprom_read_byte((uint8_t *)&RefDiff))
0555
#else
0556
#define ADC_internal_reference (2560 + REF_R_KORR)
0557
#endif
0558
#else
0559
// all other processors use a 1.1V reference
0560
#ifdef AUTO_CAL
0561
#define ADC_internal_reference (ref_mv + (int8_t)eeprom_read_byte((uint8_t *)&RefDiff))
0562
#else
0563
#define ADC_internal_reference (ref_mv + REF_R_KORR)
0564
#endif
0565
#endif
0566
0567
0568
#ifndef REF_R_KORR
0569
#define REF_R_KORR 0
0570
#endif
0571
#ifndef REF_C_KORR
0572
#define REF_C_KORR 0
0573
#endif
0574
0575
#define LONG_WAIT_TIME 28000
0576
#define SHORT_WAIT_TIME 5000
0577
0578
#ifdef POWER_OFF
0579
// if POWER OFF function is selected, wait 14s
0580
// if POWER_OFF with parameter > 2, wait only 5s before repeating
0581
#if (POWER_OFF+0) > 2
0582
#define OFF_WAIT_TIME SHORT_WAIT_TIME
0583
#else
0584
#define OFF_WAIT_TIME LONG_WAIT_TIME
0585
#endif
0586
#else
0587
// if POWER OFF function is not selected, wait 14s before repeat measurement
0588
#define OFF_WAIT_TIME LONG_WAIT_TIME
0589
#endif
0590
0591
0592
//**********************************************************
0593
// defines for the selection of a correctly ADC-Clock
0594
// will match for 1MHz, 2MHz, 4MHz, 8MHz and 16MHz
0595
// ADC-Clock can be 125000 or 250000
0596
// 250 kHz is out of the full accuracy specification!
0597
// clock divider is 4, when CPU_Clock==1MHz and ADC_Clock==250kHz
0598
// clock divider is 128, when CPU_Clock==16MHz and ADC_Clock==125kHz
0599
#define F_ADC 125000
0600
//#define F_ADC 250000
0601
#if F_CPU/F_ADC == 2
0602
#define AUTO_CLOCK_DIV (1<<ADPS0)
0603
#endif
0604
#if F_CPU/F_ADC == 4
0605
#define AUTO_CLOCK_DIV (1<<ADPS1)
0606
#endif
0607
#if F_CPU/F_ADC == 8
0608
#define AUTO_CLOCK_DIV (1<<ADPS1) | (1<<ADPS0)
0609
#endif
0610
#if F_CPU/F_ADC == 16
0611
#define AUTO_CLOCK_DIV (1<<ADPS2)
0612
#endif
0613
#if F_CPU/F_ADC == 32
0614
#define AUTO_CLOCK_DIV (1<<ADPS2) | (1<<ADPS0)
0615
#endif
0616
#if F_CPU/F_ADC == 64
0617
#define AUTO_CLOCK_DIV (1<<ADPS2) | (1<<ADPS1)
0618
#endif
0619
#if F_CPU/F_ADC == 128
0620
#define AUTO_CLOCK_DIV (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)
0621
#endif
0622
//**********************************************************
0623
#define F_ADC_F 500000
0624
#if F_CPU/F_ADC_F == 2
0625
#define FAST_CLOCK_DIV (1<<ADPS0)
0626
#endif
0627
#if F_CPU/F_ADC_F == 4
0628
#define FAST_CLOCK_DIV (1<<ADPS1)
0629
#endif
0630
#if F_CPU/F_ADC_F == 8
0631
#define FAST_CLOCK_DIV (1<<ADPS1) | (1<<ADPS0)
0632
#endif
0633
#if F_CPU/F_ADC_F == 16
0634
#define FAST_CLOCK_DIV (1<<ADPS2)
0635
#endif
0636
#if F_CPU/F_ADC_F == 32
0637
#define FAST_CLOCK_DIV (1<<ADPS2) | (1<<ADPS0)
0638
#endif
0639
#if F_CPU/F_ADC_F == 64
0640
#define FAST_CLOCK_DIV (1<<ADPS2) | (1<<ADPS1)
0641
#endif
0642
#if F_CPU/F_ADC_F == 128
0643
#define FAST_CLOCK_DIV (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)
0644
#endif
0645
0646
0647
#ifndef PIN_RP
0648
#define PIN_RP 220 // estimated internal resistance PORT to VCC
0649
// will only be used, if not set before in config.h
0650
#endif
0651
#ifndef PIN_RM
0652
#define PIN_RM 190 // estimated internal resistance PORT to GND
0653
// will only be used, if not set before in config.h
0654
#endif
0655
0656
//**********************************************************
0657
0658
// defines for the WITH_UART option
0659
/*
0660
With define SWUART_INVERT you can specify,
if
the software-UART operates normal or invers.
0661
in
the normal mode the UART sends with usual logik level (Low = 0; High = 1).
0662
You can use
this
mode
for
direct connection to a uC, or a level converter like MAX232.
0663
0664
With invers mode the UART sends with invers logik (Low = 1, High = 0).
0665
This
is
the level of a standard RS232 port of a PC.
0666
In most cases the output of the software UART can so be connected to the RxD of a PC.
0667
The specification say, that level -3V to 3V
is
unspecified, but
in
most cases it works.
0668
Is a simple but unclean solution.
0669
0670
Is SWUART_INVERT defined, the UART works
is
inverse mode
0671
*/
0672
//#define SWUART_INVERT
0673
0674
#define TxD 3 // TxD-Pin of Software-UART; must be at Port C !
0675
#ifdef WITH_UART
0676
#define TXD_MSK (1<<TxD)
0677
#else
0678
#define TXD_MSK 0xF8
0679
#endif
0680
0681
#ifdef SWUART_INVERT
0682
#define TXD_VAL 0
0683
#else
0684
#define TXD_VAL TXD_MSK
0685
#endif
0686
0687
0688
#ifdef INHIBIT_SLEEP_MODE
0689
// save memory, do not use the sleep mode
0690
#define wait_about5ms() wait5ms()
0691
#define wait_about10ms() wait10ms()
0692
#define wait_about20ms() wait20ms()
0693
#define wait_about30ms() wait30ms()
0694
#define wait_about50ms() wait50ms()
0695
#define wait_about100ms() wait100ms()
0696
#define wait_about200ms() wait200ms()
0697
#define wait_about300ms() wait300ms()
0698
#define wait_about400ms() wait400ms()
0699
#define wait_about500ms() wait500ms()
0700
#define wait_about1s() wait1s()
0701
#define wait_about2s() wait2s()
0702
#define wait_about3s() wait3s()
0703
#define wait_about4s() wait4s()
0704
#else
0705
// use sleep mode to save current for user interface
0706
#define wait_about5ms() sleep_5ms(1)
0707
#define wait_about10ms() sleep_5ms(2)
0708
#define wait_about20ms() sleep_5ms(4)
0709
#define wait_about30ms() sleep_5ms(6)
0710
#define wait_about50ms() sleep_5ms(10)
0711
#define wait_about100ms() sleep_5ms(20)
0712
#define wait_about200ms() sleep_5ms(40)
0713
#define wait_about300ms() sleep_5ms(60)
0714
#define wait_about400ms() sleep_5ms(80)
0715
#define wait_about500ms() sleep_5ms(100)
0716
#define wait_about1s() sleep_5ms(200)
0717
#define wait_about2s() sleep_5ms(400)
0718
#define wait_about3s() sleep_5ms(600)
0719
#define wait_about4s() sleep_5ms(800)
0720
#endif
0721
0722
0723
#undef AUTO_RH
0724
#ifdef WITH_AUTO_REF
0725
#define AUTO_RH
0726
#else
0727
#ifdef AUTO_CAL
0728
#define AUTO_RH
0729
#endif
0730
#endif
0731
0732
#undef CHECK_CALL
0733
#ifdef WITH_SELFTEST
0734
// AutoCheck Function is needed
0735
#define CHECK_CALL
0736
#endif
0737
0738
#ifdef AUTO_CAL
0739
// AutoCheck Function is needed
0740
#define CHECK_CALL
0741
#define RR680PL resis680pl
0742
#define RR680MI resis680mi
0743
#define RRpinPL pin_rpl
0744
#define RRpinMI pin_rmi
0745
#else
0746
#define RR680PL (R_L_VAL + PIN_RP)
0747
#define RR680MI (R_L_VAL + PIN_RM)
0748
#define RRpinPL (PIN_RP)
0749
#define RRpinMI (PIN_RM)
0750
#endif
0751
0752
#ifndef ESR_ZERO
0753
// define a default zero value for ESR measurement (0.01 Ohm units)
0754
#define ESR_ZERO 20
0755
#endif
0756
0757
#ifndef RESTART_DELAY_TICS
0758
// define the processor restart delay for crystal oscillator 16K
0759
// only set, if no preset (Makefile) exists.
0760
#define RESTART_DELAY_TICS 16384
0761
// for ceramic oscillator 258 or 1024 Clock tics can be selected with fuses
0762
// for external oscillator or RC-oscillator is only a delay of 6 clock tics.
0763
#endif
0764
0765
// with EBC_STYLE you can select the Pin-description in EBC= style instead of 123=??? style
0766
//#define EBC_STYLE
0767
#if EBC_STYLE == 123
0768
// unset the option for the 123 selection, since this style is default.
0769
#undef EBC_STYLE
0770
#endif
0771
0772
0773
#ifdef NOK5110
0774
#define LCD_CHAR_DIODE1 0x91
0775
#define LCD_CHAR_DIODE2 0x92
0776
#define LCD_CHAR_CAP 0x93
0777
#define LCD_CHAR_RESIS1 0x94
0778
#define LCD_CHAR_RESIS2 0x95
0779
#define LCD_CHAR_OMEGA 0x90
0780
#define LCD_CHAR_U 0xB5
0781
0782
#else
0783
// self build characters
0784
#define LCD_CHAR_DIODE1 1 // Diode-Icon; will be generated as custom character
0785
#define LCD_CHAR_DIODE2 2 // Diode-Icon; will be generated as custom character
0786
#define LCD_CHAR_CAP 3 // Capacitor-Icon; will be generated as custom character
0787
// numbers of RESIS1 and RESIS2 are swapped for OLED display, which shows a corrupt RESIS1 character otherwise ???
0788
#define LCD_CHAR_RESIS1 7 // Resistor left part will be generated as custom character
0789
#define LCD_CHAR_RESIS2 6 // Resistor right part will be generated as custom character
0790
0791
#ifdef LCD_CYRILLIC
0792
#define LCD_CHAR_OMEGA 4 // Omega-character
0793
#define LCD_CHAR_U 5 // micro-character
0794
#else
0795
#define LCD_CHAR_OMEGA 244 // Omega-character
0796
#define LCD_CHAR_U 228 // micro-character
0797
#endif
0798
0799
#ifdef LCD_DOGM
0800
#undef LCD_CHAR_OMEGA
0801
#define LCD_CHAR_OMEGA 0x1e // Omega-character for DOGM module
0802
#undef LCD_CHAR_U
0803
#define LCD_CHAR_U 5 // micro-character for DOGM module loadable
0804
#endif
0805
0806
#define LCD_CHAR_DEGREE 0xdf // Character for degree
0807
#endif
0808
0809
#endif // #ifndef ADC_PORT
0810
0811
0812
// the hFE (B) can be determined with common collector and common emitter circuit
0813
// with more than 16K both methodes are possible
0814
#ifdef COMMON_COLLECTOR
0815
#if FLASHEND > 0x3fff
0816
#define COMMON_EMITTER
0817
#endif
0818
#else
0819
#define COMMON_EMITTER
0820
#endif
0821
0822
/* -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- */
0823
0824
#define MAIN_C
0825
0826
#if defined (MAIN_C)
0827
#define COMMON
0828
/*
0829
The voltage at a capacitor grows with Uc = VCC * (1 - e**(-t/T))
0830
The voltage 1.3V is reached at t = -ln(3.7/5)*T = 0.3011*T .
0831
Time constant is T = R * C ; also
0832
C = T / R
0833
for the resistor 470 kOhm is C = t / (0.3011 * 470000)
0834
H_Fakt = 707/100 for a result in pF units.
0835
*/
0836
0837
// Big Capacities (>50uF) are measured with up to 500 load-pulses with the 680 Ohm resistor.
0838
// Each of this load-puls has an length of 10ms. After every load-pulse the voltage of the
0839
// capacitor is measured. If the voltage is more than 300mV, the capacity is computed by
0840
// interpolating the corresponding values of the table RLtab and multiply that with the number
0841
// of load pulses (*10).
0842
0843
// Widerstand 680 Ohm 300 325 350 375 400 425 450 475 500 525 550 575 600 625 650 675 700 725 750 775 800 825 850 875 900 925 950 975 1000 1025 1050 1075 1100 1125 1150 1175 1200 1225 1250 1275 1300 1325 1350 1375 1400 mV
0844
const
uint16_t RLtab[] MEM_TEXT = {22447,20665,19138,17815,16657,15635,14727,13914,13182,12520,11918,11369,10865,10401, 9973, 9577, 9209, 8866, 8546, 8247, 7966, 7702, 7454, 7220, 6999, 6789, 6591, 6403, 6224, 6054, 5892, 5738, 5590, 5449, 5314, 5185, 5061, 4942, 4828, 4718, 4613, 4511, 4413, 4319, 4228};
0845
0846
#if FLASHEND > 0x1fff
0847
// {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91 };
0848
const
uint16_t LogTab[] PROGMEM = {0, 20, 41, 62, 83, 105, 128, 151, 174, 198, 223, 248, 274, 301, 329, 357, 386, 416, 446, 478, 511, 545, 580, 616, 654, 693, 734, 777, 821, 868, 916, 968, 1022, 1079, 1139, 1204, 1273, 1347, 1427, 1514, 1609, 1715, 1833, 1966, 2120, 2303, 2526 };
0849
#endif
0850
0851
#ifdef AUTO_RH
0852
// resistor 470000 Ohm 1000 1050 1100 1150 1200 1250 1300 1350 1400 mV
0853
const
uint16_t RHtab[] PROGMEM = { 954, 903, 856, 814, 775, 740, 707, 676, 648};
0854
#endif
0855
0856
// with integer factors the ADC-value will be changed to mV resolution in ReadADC !
0857
// all if statements are corrected to the mV resolution.
0858
0859
0860
// Strings in PROGMEM or in EEprom
0861
0862
#if defined(LANG_GERMAN) // deutsch
0863
const
unsigned
char
TestRunning[] MEM_TEXT =
"Testen..."
;
0864
const
unsigned
char
BatWeak[] MEM_TEXT =
"gering"
;
0865
const
unsigned
char
BatEmpty[] MEM_TEXT =
"leer!"
;
0866
const
unsigned
char
TestFailed2[] MEM_TEXT =
"defektes "
;
0867
const
unsigned
char
Component[] MEM_TEXT =
"Bauteil"
;
0868
// const unsigned char Diode[] MEM_TEXT = "Diode: ";
0869
const
unsigned
char
Triac[] MEM_TEXT =
"Triac"
;
0870
const
unsigned
char
Thyristor[] MEM_TEXT =
"Thyristor"
;
0871
const
unsigned
char
Unknown[] MEM_TEXT =
" unbek."
;
0872
const
unsigned
char
TestFailed1[] MEM_TEXT =
"Kein,unbek. oder"
;
0873
const
unsigned
char
OrBroken[] MEM_TEXT =
"oder defekt "
;
0874
const
unsigned
char
TestTimedOut[] MEM_TEXT =
"Timeout!"
;
0875
#define Cathode_char 'K'
0876
#ifdef WITH_SELFTEST
0877
const
unsigned
char
SELFTEST[] MEM_TEXT =
"Selbsttest .."
;
0878
const
unsigned
char
RELPROBE[] MEM_TEXT =
"isolate Probe!"
;
0879
const
unsigned
char
ATE[] MEM_TEXT =
"Test Ende"
;
0880
#endif
0881
#endif
0882
0883
#if defined(LANG_ENGLISH) // english
0884
const
unsigned
char
TestRunning[] MEM_TEXT =
"testing..."
;
0885
const
unsigned
char
BatWeak[] MEM_TEXT =
"weak"
;
0886
const
unsigned
char
BatEmpty[] MEM_TEXT =
"empty!"
;
0887
const
unsigned
char
TestFailed2[] MEM_TEXT =
"damaged "
;
0888
const
unsigned
char
Component[] MEM_TEXT =
"part"
;
0889
//const unsigned char Diode[] MEM_TEXT = "Diode: ";
0890
const
unsigned
char
Triac[] MEM_TEXT =
"Triac"
;
0891
const
unsigned
char
Thyristor[] MEM_TEXT =
"Thyristor"
;
0892
const
unsigned
char
Unknown[] MEM_TEXT =
" unknown"
;
0893
const
unsigned
char
TestFailed1[] MEM_TEXT =
"No, unknown, or"
;
0894
const
unsigned
char
OrBroken[] MEM_TEXT =
"or damaged "
;
0895
const
unsigned
char
TestTimedOut[] MEM_TEXT =
"Timeout!"
;
0896
#define Cathode_char 'C'
0897
0898
#ifdef WITH_SELFTEST
0899
const
unsigned
char
SELFTEST[] MEM_TEXT =
"Selftest mode.."
;
0900
const
unsigned
char
RELPROBE[] MEM_TEXT =
"isolate Probe!"
;
0901
const
unsigned
char
ATE[] MEM_TEXT =
"Test End"
;
0902
#endif
0903
#endif
0904
0905
0906
// Strings, which are not dependent of any language
0907
const
unsigned
char
Bat_str[] MEM_TEXT =
"Bat. "
;
0908
const
unsigned
char
OK_str[] MEM_TEXT =
"OK"
;
0909
const
unsigned
char
mosfet_str[] MEM_TEXT =
"-MOS"
;
0910
const
unsigned
char
jfet_str[] MEM_TEXT =
"JFET"
;
0911
const
unsigned
char
GateCap_str[] MEM_TEXT =
"C="
;
0912
const
unsigned
char
hfe_str[] MEM_TEXT =
"B="
;
0913
const
unsigned
char
NPN_str[] MEM_TEXT =
"NPN "
;
0914
const
unsigned
char
PNP_str[] MEM_TEXT =
"PNP "
;
0915
0916
#ifndef EBC_STYLE
0917
const
unsigned
char
N123_str[] MEM_TEXT =
" 123="
;
0918
//const unsigned char N123_str[] MEM_TEXT = " Pin=";
0919
#else
0920
#if EBC_STYLE == 321
0921
const
unsigned
char
N321_str[] MEM_TEXT =
" 321="
;
0922
#endif
0923
#endif
0924
0925
const
unsigned
char
Uf_str[] MEM_TEXT =
"Uf="
;
0926
const
unsigned
char
vt_str[] MEM_TEXT =
" Vt="
;
0927
const
unsigned
char
Vgs_str[] MEM_TEXT =
"@Vgs="
;
0928
const
unsigned
char
CapZeich[] MEM_TEXT = {
'-'
,LCD_CHAR_CAP,
'-'
,0};
0929
const
unsigned
char
Cell_str[] MEM_TEXT =
"Cell!"
;
0930
const
unsigned
char
VCC_str[] MEM_TEXT =
"VCC="
;
0931
0932
#if FLASHEND > 0x1fff
0933
const
unsigned
char
ESR_str[] MEM_TEXT =
" ESR="
;
0934
const
unsigned
char
VLOSS_str[] MEM_TEXT =
" Vloss="
;
0935
const
unsigned
char
Lis_str[] MEM_TEXT =
"L="
;
0936
const
unsigned
char
Ir_str[] MEM_TEXT =
" Ir="
;
0937
0938
#ifndef WITH_UART
0939
//#define WITH_VEXT
0940
#endif
0941
#else
0942
#ifndef BAT_CHECK
0943
#ifndef WITH_UART
0944
//#define WITH_VEXT
0945
#endif
0946
#endif
0947
#endif
0948
0949
#ifdef WITH_VEXT
0950
const
unsigned
char
Vext_str[] MEM_TEXT =
"Vext="
;
0951
#define LCD_CLEAR
0952
#endif
0953
0954
0955
const
unsigned
char
VERSION_str[] MEM2_TEXT =
"Ttester 1.08.73"
;
0956
0957
const
unsigned
char
AnKat[] MEM_TEXT = {
'-'
, LCD_CHAR_DIODE1,
'-'
,0};
0958
const
unsigned
char
KatAn[] MEM_TEXT = {
'-'
, LCD_CHAR_DIODE2,
'-'
,0};
0959
const
unsigned
char
Diodes[] MEM_TEXT = {
'*'
,LCD_CHAR_DIODE1,
' '
,
' '
,0};
0960
const
unsigned
char
Resistor_str[] MEM_TEXT = {
'-'
, LCD_CHAR_RESIS1, LCD_CHAR_RESIS2,
'-'
,0};
0961
0962
#ifdef WITH_SELFTEST
0963
const
unsigned
char
URefT[] MEM2_TEXT =
"Ref="
;
0964
const
unsigned
char
RHfakt[] MEM2_TEXT =
"RHf="
;
0965
const
unsigned
char
RH1L[] MEM_TEXT =
"RH-"
;
0966
const
unsigned
char
RH1H[] MEM_TEXT =
"RH+"
;
0967
const
unsigned
char
RLRL[] MEM_TEXT =
"+RL- 12 13 23"
;
0968
const
unsigned
char
RHRH[] MEM_TEXT =
"+RH- 12 13 23"
;
0969
const
unsigned
char
RHRL[] MEM_TEXT =
"RH/RL"
;
0970
const
unsigned
char
R0_str[] MEM2_TEXT =
"R0="
;
0971
#define LCD_CLEAR
0972
#endif
0973
0974
#ifdef CHECK_CALL
0975
const
unsigned
char
RIHI[] MEM_TEXT =
"Ri_Hi="
;
0976
const
unsigned
char
RILO[] MEM_TEXT =
"Ri_Lo="
;
0977
const
unsigned
char
C0_str[] MEM_TEXT =
"C0 "
;
0978
const
unsigned
char
T50HZ[] MEM_TEXT =
" 50Hz"
;
0979
#endif
0980
0981
#ifdef AUTO_CAL
0982
const
unsigned
char
MinCap_str[] MEM2_TEXT =
" >100nF"
;
0983
const
unsigned
char
REF_C_str[] MEM2_TEXT =
"REF_C="
;
0984
const
unsigned
char
REF_R_str[] MEM2_TEXT =
"REF_R="
;
0985
#endif
0986
0987
#ifdef DebugOut
0988
#define LCD_CLEAR
0989
#endif
0990
0991
0992
const
unsigned
char
DiodeIcon1[] MEM_TEXT = { 0x11, 0x19, 0x1d, 0x1f, 0x1d, 0x19, 0x11, 0x00 };
// Diode-Icon Anode left
0993
const
unsigned
char
DiodeIcon2[] MEM_TEXT = { 0x11, 0x13, 0x17, 0x1f, 0x17, 0x13, 0x11, 0x00 };
// Diode-Icon Anode right
0994
const
unsigned
char
CapIcon[] MEM_TEXT = { 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00 };
// Capacitor Icon
0995
const
unsigned
char
ResIcon1[] MEM_TEXT = { 0x00, 0x0f, 0x08, 0x18, 0x08, 0x0f, 0x00, 0x00 };
// Resistor Icon1 left
0996
const
unsigned
char
ResIcon2[] MEM_TEXT = { 0x00, 0x1e, 0x02, 0x03, 0x02, 0x1e, 0x00, 0x00 };
// Resistor Icon2 right
0997
const
unsigned
char
OmegaIcon[] MEM_TEXT = { 0x00, 0x00, 0x0e, 0x11, 0x11, 0x0a, 0x1b, 0x00 };
// Omega Icon
0998
const
unsigned
char
MicroIcon[] MEM_TEXT = { 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x0e, 0x09, 0x10 };
// Micro Icon
0999
1000
const
unsigned
char
PinRLtab[] PROGMEM = { (1<<(TP1*2)), (1<<(TP2*2)), (1<<(TP3*2))};
// Table of commands to switch the R-L resistors Pin 0,1,2
1001
const
unsigned
char
PinADCtab[] PROGMEM = { (1<<TP1), (1<<TP2), (1<<TP3)};
// Table of commands to switch the ADC-Pins 0,1,2
1002
1003
/*
1004
// generate Omega- and u-character as Custom-character, if these characters has a number of loadable type
1005
#if LCD_CHAR_OMEGA < 8
1006
const unsigned char CyrillicOmegaIcon[] MEM_TEXT = {0,0,14,17,17,10,27,0}; // Omega
1007
#endif
1008
#if LCD_CHAR_U < 8
1009
const unsigned char CyrillicMuIcon[] MEM_TEXT = {0,17,17,17,19,29,16,16}; // micro
1010
#endif
1011
*/
1012
1013
#ifdef AUTO_CAL
1014
//const uint16_t R680pl EEMEM = R_L_VAL+PIN_RP; // total resistor to VCC
1015
//const uint16_t R680mi EEMEM = R_L_VAL+PIN_RM; // total resistor to GND
1016
const
int8_t RefDiff EEMEM = REF_R_KORR;
// correction of internal Reference Voltage
1017
#endif
1018
1019
const
uint8_t PrefixTab[] MEM_TEXT = {
'p'
,
'n'
,LCD_CHAR_U,
'm'
,0,
'k'
,
'M'
};
// p,n,u,m,-,k,M
1020
1021
#ifdef AUTO_CAL
1022
//const uint16_t cap_null EEMEM = C_NULL; // Zero offset of capacity measurement
1023
const
int16_t ref_offset EEMEM = REF_C_KORR;
// default correction of internal reference voltage for capacity measurement
1024
// LoPin:HiPin 2:1 3:1 1:2 : 3:2 1:3 2:3
1025
const
uint8_t c_zero_tab[] EEMEM = { C_NULL,C_NULL,C_NULL+TP2_CAP_OFFSET,C_NULL,C_NULL+TP2_CAP_OFFSET,C_NULL,C_NULL };
// table of zero offsets
1026
#endif
1027
1028
const
uint8_t EE_ESR_ZEROtab[] PROGMEM = {ESR_ZERO, ESR_ZERO, ESR_ZERO, ESR_ZERO};
// zero offset of ESR measurement
1029
1030
// End of EEPROM-Strings
1031
1032
// Multiplier for capacity measurement with R_H (470KOhm)
1033
unsigned
int
RHmultip = DEFAULT_RH_FAKT;
1034
1035
1036
#else
1037
// no MAIN_C
1038
#define COMMON extern
1039
#ifdef WITH_SELFTEST
1040
extern
const
unsigned
char
SELFTEST[] MEM_TEXT;
1041
extern
const
unsigned
char
RELPROBE[] MEM_TEXT;
1042
extern
const
unsigned
char
ATE[] MEM_TEXT;
1043
#endif
1044
1045
#ifdef AUTO_CAL
1046
//extern uint16_t R680pl;
1047
//extern uint16_t R680mi;
1048
extern
int8_t RefDiff;
1049
extern
uint16_t ref_offset;
1050
extern
uint8_t c_zero_tab[];
1051
#endif
1052
1053
extern
const
uint8_t EE_ESR_ZEROtab[] EEMEM;
// zero offset of ESR measurement
1054
extern
const
uint16_t RLtab[];
1055
1056
#if FLASHEND > 0x1fff
1057
extern
uint16_t LogTab[];
1058
extern
const
unsigned
char
ESR_str[];
1059
#endif
1060
1061
#ifdef AUTO_RH
1062
extern
const
uint16_t RHtab[];
1063
#endif
1064
1065
extern
const
unsigned
char
PinRLtab[];
1066
extern
const
unsigned
char
PinADCtab[];
1067
extern
unsigned
int
RHmultip;
1068
1069
#endif // MAIN_C
1070
1071
1072
struct
Diode_t {
1073
uint8_t Anode;
1074
uint8_t Cathode;
1075
unsigned
int
Voltage;
1076
};
1077
1078
COMMON
struct
Diode_t diodes[6];
1079
COMMON uint8_t NumOfDiodes;
1080
1081
COMMON
struct
{
1082
unsigned
long
hfe[2];
// current amplification factor
1083
unsigned
int
uBE[2];
// B-E-voltage of the Transistor
1084
uint8_t b,c,e;
// pins of the Transistor
1085
}trans;
1086
1087
COMMON unsigned
int
gthvoltage;
// Gate-threshold voltage
1088
1089
COMMON uint8_t PartReady;
// part detection is finished
1090
COMMON uint8_t PartMode;
1091
COMMON uint8_t tmpval, tmpval2;
1092
COMMON unsigned
int
ref_mv;
// Reference-voltage in mV units
1093
1094
COMMON
struct
resis_t{
1095
unsigned
long
rx;
// value of resistor RX
1096
#if FLASHEND > 0x1fff
1097
unsigned
long
lx;
// inductance 10uH or 100uH
1098
int8_t lpre;
// prefix for inductance
1099
#endif
1100
uint8_t ra,rb;
// Pins of RX
1101
uint8_t rt;
// Tristate-Pin (inactive)
1102
} resis[3];
1103
1104
COMMON uint8_t ResistorsFound;
// Number of found resistors
1105
COMMON uint8_t ii;
// multipurpose counter
1106
1107
COMMON
struct
cap_t {
1108
unsigned
long
cval;
// capacitor value
1109
unsigned
long
cval_max;
// capacitor with maximum value
1110
union t_combi{
1111
unsigned
long
dw;
// capacity value without corrections
1112
uint16_t w[2];
1113
} cval_uncorrected;
1114
#if FLASHEND > 0x1fff
1115
unsigned
int
esr;
// serial resistance of C in 0.01 Ohm
1116
unsigned
int
v_loss;
// voltage loss 0.1%
1117
#endif
1118
uint8_t ca, cb;
// pins of capacitor
1119
int8_t cpre;
// Prefix for capacitor value -12=p, -9=n, -6=u, -3=m
1120
int8_t cpre_max;
// Prefix of the biggest capacitor
1121
} cap;
1122
1123
#ifndef INHIBIT_SLEEP_MODE
1124
// with sleep mode we need a global ovcnt16
1125
COMMON volatile uint16_t ovcnt16;
1126
COMMON volatile uint8_t unfinished;
1127
#endif
1128
1129
COMMON int16_t load_diff;
// difference voltage of loaded capacitor and internal reference
1130
1131
COMMON uint8_t WithReference;
// Marker for found precision voltage reference = 1
1132
COMMON uint8_t PartFound;
// the found part
1133
COMMON
char
outval[12];
// String for ASCII-outpu
1134
COMMON uint8_t empty_count;
// counter for max count of empty measurements
1135
COMMON uint8_t mess_count;
// counter for max count of nonempty measurements
1136
1137
COMMON
struct
ADCconfig_t {
1138
uint8_t Samples;
// number of ADC samples to take
1139
uint8_t RefFlag;
// save Reference type VCC of IntRef
1140
uint16_t U_Bandgap;
// Reference Voltage in mV
1141
uint16_t U_AVCC;
// Voltage of AVCC
1142
} ADCconfig;
1143
1144
#ifdef AUTO_CAL
1145
COMMON uint8_t pin_combination;
// coded Pin-combination 2:1,3:1,1:2,x:x,3:2,1:3,2:3
1146
COMMON uint16_t resis680pl;
// port output resistance + 680
1147
COMMON uint16_t resis680mi;
// port output resistance + 680
1148
COMMON uint16_t pin_rmi;
// port output resistance to GND side, 0.1 Ohm units
1149
COMMON uint16_t pin_rpl;
// port output resistance to VCC side, 0.1 Ohm units
1150
#endif
1151
1152
#if POWER_OFF+0 > 1
1153
COMMON unsigned
int
display_time;
// display time of measurement in ms units
1154
#endif
1155
1156
/* -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- */
1157
1158
// definitions of parts
1159
#define PART_NONE 0
1160
#define PART_DIODE 1
1161
#define PART_TRANSISTOR 2
1162
#define PART_FET 3
1163
#define PART_TRIAC 4
1164
#define PART_THYRISTOR 5
1165
#define PART_RESISTOR 6
1166
#define PART_CAPACITOR 7
1167
#define PART_CELL 8
1168
1169
// special definition for different parts
1170
// FETs
1171
#define PART_MODE_N_E_MOS 2
1172
#define PART_MODE_P_E_MOS 3
1173
#define PART_MODE_N_D_MOS 4
1174
#define PART_MODE_P_D_MOS 5
1175
#define PART_MODE_N_JFET 6
1176
#define PART_MODE_P_JFET 7
1177
1178
// Bipolar
1179
#define PART_MODE_NPN 1
1180
#define PART_MODE_PNP 2
1181
1182
/* -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- */
1183
1184
// wait functions
1185
#define wait5s() delay(5000)
1186
#define wait4s() delay(4000)
1187
#define wait3s() delay(3000)
1188
#define wait2s() delay(2000)
1189
#define wait1s() delay(1000)
1190
#define wait500ms() delay(500)
1191
#define wait400ms() delay(400)
1192
#define wait300ms() delay(300)
1193
#define wait200ms() delay(200)
1194
#define wait100ms() delay(100)
1195
#define wait50ms() delay(50)
1196
#define wait40ms() delay(40)
1197
#define wait30ms() delay(30)
1198
#define wait20ms() delay(20)
1199
#define wait10ms() delay(10)
1200
#define wait5ms() delay(5)
1201
#define wait4ms() delay(4)
1202
#define wait3ms() delay(3)
1203
#define wait2ms() delay(2)
1204
#define wait1ms() delay(1)
1205
#define wait500us() delayMicroseconds(500)
1206
#define wait400us() delayMicroseconds(400)
1207
#define wait300us() delayMicroseconds(300)
1208
#define wait200us() delayMicroseconds(200)
1209
#define wait100us() delayMicroseconds(100)
1210
#define wait50us() delayMicroseconds(50)
1211
#define wait40us() delayMicroseconds(40)
1212
#define wait30us() delayMicroseconds(30)
1213
#define wait20us() delayMicroseconds(20)
1214
#define wait10us() delayMicroseconds(10)
1215
#define wait5us() delayMicroseconds(5)
1216
#define wait4us() delayMicroseconds(4)
1217
#define wait3us() delayMicroseconds(3)
1218
#define wait2us() delayMicroseconds(2)
1219
#define wait1us() delayMicroseconds(1)
1220
1221
/* -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- */
1222
1223
// Interfacing of a HD44780 compatible LCD with 4-Bit-Interface mode
1224
1225
// LCD-commands
1226
#define CMD_ClearDisplay 0x01
1227
#define CMD_ReturnHome 0x02
1228
#define CMD_SetEntryMode 0x04
1229
#define CMD_SetDisplayAndCursor 0x08
1230
#define CMD_SetIFOptions 0x20
1231
#define CMD_SetCGRAMAddress 0x40 // for Custom character
1232
#define CMD_SetDDRAMAddress 0x80 // set Cursor
1233
1234
#define CMD1_SetBias 0x10 // set Bias (instruction table 1, DOGM)
1235
#define CMD1_PowerControl 0x50 // Power Control, set Contrast C5:C4 (instruction table 1, DOGM)
1236
#define CMD1_FollowerControl 0x60 // Follower Control, amplified ratio (instruction table 1, DOGM)
1237
#define CMD1_SetContrast 0x70 // set Contrast C3:C0 (instruction table 1, DOGM)
1238
1239
// Makros for LCD
1240
#define lcd_line1() lcd_set_cursor(0,0) // move to beginning of 1 row
1241
#define lcd_line2() lcd_set_cursor(1,0) // move to beginning of 2 row
1242
#define lcd_line3() lcd_set_cursor(2,0) // move to beginning of 3 row
1243
#define lcd_line4() lcd_set_cursor(3,0) // move to beginning of 4 row
1244
1245
#define uart_newline() Serial.println()
1246
1247
/* -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- */
1248
1249
#ifndef INHIBIT_SLEEP_MODE
1250
// prepare sleep mode
1251
EMPTY_INTERRUPT(TIMER2_COMPA_vect);
1252
EMPTY_INTERRUPT(ADC_vect);
1253
#endif
1254
1255
uint8_t tmp = 0;
1256
//unsigned int PRR;
1257
1258
byte
TestKey;
1259
byte
TestKeyPin = 17;
// A3
1260
1261
// *** моя инициализация дисплеев ***
1262
#ifdef LCD_I2C
1263
#ifdef LCD1602
1264
LiquidCrystal_I2C lcd(0x3F, 16, 2);
1265
#endif
1266
#ifdef LCD2004
1267
LiquidCrystal_I2C lcd(0x3F, 20, 4);
1268
#endif
1269
#else //Если дисплей не IIC то инициализируем как
1270
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
// RS,E,D4,D5,D6,D7
1271
#endif
1272
1273
// *** окончание инициализации дисплеев
1274
1275
/*
1276
#ifdef LCD1602
1277
#ifdef LCD_I2C
1278
LiquidCrystal_I2C lcd(0x3F, 16, 2);
1279
#else
1280
LiquidCrystal lcd(7, 6, 5, 4, 3, 2); // RS,E,D4,D5,D6,D7
1281
#endif
1282
#endif
1283
1284
#ifdef LCD2004
1285
#ifdef LCD_I2C
1286
LiquidCrystal_I2C lcd(0x3F, 20, 4);
1287
#else
1288
LiquidCrystal lcd(7, 6, 5, 4, 3, 2); // RS,E,D4,D5,D6,D7
1289
#endif
1290
#endif
1291
*/
1292
#ifdef NOK5110
1293
Adafruit_PCD8544 lcd = Adafruit_PCD8544(3, 4, 5, 6, 7);
// CLK,DIN,DC,CE,RST
1294
#endif
1295
1296
1297
1298
// begin of transistortester program
1299
void
setup
()
1300
{
1301
Serial
.begin(9600);
1302
1303
pinMode(TestKeyPin, INPUT);
1304
1305
#ifdef LCD1602
1306
#ifdef LCD_I2C
1307
lcd.begin();
1308
#else
1309
lcd.begin(16,2);
1310
#endif
1311
1312
1313
lcd_pgm_custom_char(LCD_CHAR_DIODE1, DiodeIcon1);
// Custom-Character Diode symbol >|
1314
lcd_pgm_custom_char(LCD_CHAR_DIODE2, DiodeIcon2);
// Custom-Character Diode symbol |<
1315
lcd_pgm_custom_char(LCD_CHAR_CAP, CapIcon);
// Custom-Character Capacitor symbol ||
1316
lcd_pgm_custom_char(LCD_CHAR_RESIS1, ResIcon1);
// Custom-Character Resistor symbol [
1317
lcd_pgm_custom_char(LCD_CHAR_RESIS2, ResIcon2);
// Custom-Character Resistor symbol ]
1318
lcd_pgm_custom_char(LCD_CHAR_OMEGA, OmegaIcon);
// load Omega as Custom-Character
1319
lcd_pgm_custom_char(LCD_CHAR_U, MicroIcon);
// load Micro as Custom-Character
1320
lcd.home();
1321
1322
lcd_string(
"TransistorTester"
);
1323
lcd_set_cursor(1, 0);
1324
lcd_string(
"forArduino 1.08a"
);
1325
1326
#endif
1327
1328
#ifdef LCD2004
1329
#ifdef LCD_I2C
1330
lcd.begin();
1331
#else
1332
lcd.begin(20,4);
1333
#endif
1334
1335
lcd_pgm_custom_char(LCD_CHAR_DIODE1, DiodeIcon1);
// Custom-Character Diode symbol >|
1336
lcd_pgm_custom_char(LCD_CHAR_DIODE2, DiodeIcon2);
// Custom-Character Diode symbol |<
1337
lcd_pgm_custom_char(LCD_CHAR_CAP, CapIcon);
// Custom-Character Capacitor symbol ||
1338
lcd_pgm_custom_char(LCD_CHAR_RESIS1, ResIcon1);
// Custom-Character Resistor symbol [
1339
lcd_pgm_custom_char(LCD_CHAR_RESIS2, ResIcon2);
// Custom-Character Resistor symbol ]
1340
lcd_pgm_custom_char(LCD_CHAR_OMEGA, OmegaIcon);
// load Omega as Custom-Character
1341
lcd_pgm_custom_char(LCD_CHAR_U, MicroIcon);
// load Micro as Custom-Character
1342
lcd.home();
1343
1344
lcd_set_cursor(0, 0);
1345
lcd_string(
"TransistorTester"
);
1346
// lcd_set_cursor(1, 0);
1347
lcd_string(
"forArduino 1.08a-73"
);
1348
// lcd_set_cursor(3, 0);
1349
lcd_string(
"www.cherkessk.su"
);
1350
// lcd_set_cursor(4, 0);
1351
lcd_string(
"made UA6EM"
);
1352
1353
#endif
1354
1355
#ifdef NOK5110
1356
lcd.begin();
1357
lcd.cp437(
true
);
1358
lcd.setContrast(50);
1359
lcd.clearDisplay();
1360
1361
lcd_string(
"Transistor"
);
1362
lcd_set_cursor(1, 0);
1363
lcd_string(
"Tester"
);
1364
lcd_set_cursor(2, 0);
1365
lcd_string(
"for Arduino"
);
1366
lcd_set_cursor(3, 0);
1367
lcd_string(
"1.08.002"
);
1368
#endif
1369
1370
//ON_DDR = 0;
1371
//ON_PORT = 0;
1372
1373
/*
1374
// switch on
1375
ON_DDR = (1<<ON_PIN); // switch to output
1376
#ifdef PULLUP_DISABLE
1377
ON_PORT = (1<<ON_PIN); // switch power on
1378
#else
1379
ON_PORT = (1<<ON_PIN)|(1<<RST_PIN); // switch power on , enable internal Pullup for Start-Pin
1380
#endif
1381
*/
1382
1383
// ADC-Init
1384
ADCSRA = (1<<ADEN) | AUTO_CLOCK_DIV;
// prescaler=8 or 64 (if 8Mhz clock)
1385
1386
#ifdef __AVR_ATmega8__
1387
//#define WDRF_HOME MCU_STATUS_REG
1388
#define WDRF_HOME MCUCSR
1389
#else
1390
#define WDRF_HOME MCUSR
1391
#endif
1392
1393
/*
1394
tmp = (WDRF_HOME & (1<<WDRF)); // save Watch Dog Flag
1395
WDRF_HOME &= ~(1<<WDRF); // reset Watch Dog flag
1396
wdt_disable(); // disable Watch Dog
1397
*/
1398
1399
/*
1400
#ifndef INHIBIT_SLEEP_MODE
1401
// switch off unused Parts
1402
PRR = (1<<PRTWI) | (1<<PRTIM0) | (1<<PRSPI) | (1<<PRUSART0);
1403
DIDR0 = (1<<ADC5D) | (1<<ADC4D) | (1<<ADC3D);
1404
TCCR2A = (0<<WGM21) | (0<<WGM20); // Counter 2 normal mode
1405
1406
#if F_CPU <= 1000000UL
1407
TCCR2B = (1<<CS22) | (0<<CS21) | (1<<CS20); // prescaler 128, 128us @ 1MHz
1408
#define T2_PERIOD 128
1409
#endif
1410
#if F_CPU == 2000000UL
1411
TCCR2B = (1<<CS22) | (1<<CS21) | (0<<CS20); // prescaler 256, 128us @ 2MHz
1412
#define T2_PERIOD 128
1413
#endif
1414
#if F_CPU == 4000000UL
1415
TCCR2B = (1<<CS22) | (1<<CS21) | (0<<CS20); // prescaler 256, 64us @ 2MHz
1416
#define T2_PERIOD 64
1417
#endif
1418
#if F_CPU >= 8000000UL
1419
TCCR2B = (1<<CS22) | (1<<CS21) | (1<<CS20); // prescaler 1024, 128us @ 8MHz, 64us @ 16MHz
1420
#define T2_PERIOD (1024 / (F_CPU / 1000000UL)); // set to 128 or 64 us
1421
#endif
1422
1423
sei(); // enable interrupts
1424
#endif
1425
*/
1426
1427
#define T2_PERIOD (1024 / (F_CPU / 1000000UL)); // set to 128 or 64 us
1428
1429
//ADC_PORT = TXD_VAL;
1430
//ADC_DDR = TXD_MSK;
1431
1432
if
(tmp) {
1433
// check if Watchdog-Event
1434
// this happens, if the Watchdog is not reset for 2s
1435
// can happen, if any loop in the Program doen't finish.
1436
lcd_line1();
1437
lcd_fix_string(TestTimedOut);
// Output Timeout
1438
wait_about3s();
// wait for 3 s
1439
//ON_PORT = 0; // shut off!
1440
//ON_DDR = (1<<ON_PIN); // switch to GND
1441
//return;
1442
}
1443
1444
#ifdef PULLUP_DISABLE
1445
#ifdef __AVR_ATmega8__
1446
SFIOR = (1<<PUD);
// disable Pull-Up Resistors mega8
1447
#else
1448
MCUCR = (1<<PUD);
// disable Pull-Up Resistors mega168 family
1449
#endif
1450
#endif
1451
1452
//DIDR0 = 0x3f; // disable all Input register of ADC
1453
1454
/*
1455
#if POWER_OFF+0 > 1
1456
// tester display time selection
1457
display_time = OFF_WAIT_TIME; // LONG_WAIT_TIME for single mode, else SHORT_WAIT_TIME
1458
if (!(ON_PIN_REG & (1<<RST_PIN))) {
1459
// if power button is pressed ...
1460
wait_about300ms(); // wait to catch a long key press
1461
if (!(ON_PIN_REG & (1<<RST_PIN))) {
1462
// check if power button is still pressed
1463
display_time = LONG_WAIT_TIME; // ... set long time display anyway
1464
}
1465
}
1466
#else
1467
#define display_time OFF_WAIT_TIME
1468
#endif
1469
*/
1470
1471
#define display_time OFF_WAIT_TIME
1472
1473
empty_count = 0;
1474
mess_count = 0;
1475
}
1476
1477
void
loop
()
1478
{
1479
// Entry: if start key is pressed before shut down
1480
start:
1481
1482
#ifdef NOK5110
1483
lcd.display();
1484
#endif
1485
1486
#ifdef LCD2004
1487
lcd.display();
1488
#endif
1489
1490
TestKey = 1;
1491
while
(TestKey) {
1492
TestKey = digitalRead(TestKeyPin);
1493
delay(100);
1494
}
1495
while
(!TestKey) {
1496
TestKey = digitalRead(TestKeyPin);
1497
delay(100);
1498
}
1499
lcd_clear();
1500
delay(100);
1501
1502
PartFound = PART_NONE;
// no part found
1503
NumOfDiodes = 0;
// Number of diodes = 0
1504
PartReady = 0;
1505
PartMode = 0;
1506
WithReference = 0;
// no precision reference voltage
1507
ADC_DDR = TXD_MSK;
// activate Software-UART
1508
ResistorsFound = 0;
// no resistors found
1509
cap.ca = 0;
1510
cap.cb = 0;
1511
1512
#ifdef WITH_UART
1513
uart_newline();
// start of new measurement
1514
#endif
1515
1516
ADCconfig.RefFlag = 0;
1517
Calibrate_UR();
// get Ref Voltages and Pin resistance
1518
lcd_line1();
// 1 row
1519
1520
ADCconfig.U_Bandgap = ADC_internal_reference;
// set internal reference voltage for ADC
1521
1522
#ifdef BAT_CHECK
1523
// Battery check is selected
1524
ReadADC(TPBAT);
// Dummy-Readout
1525
trans.uBE[0] = W5msReadADC(TPBAT);
// with 5V reference
1526
lcd_fix_string(Bat_str);
// output: "Bat. "
1527
1528
#ifdef BAT_OUT
1529
// display Battery voltage
1530
// The divisor to get the voltage in 0.01V units is ((10*33)/133) witch is about 2.4812
1531
// A good result can be get with multiply by 4 and divide by 10 (about 0.75%).
1532
//cap.cval = (trans.uBE[0]*4)/10+((BAT_OUT+5)/10); // usually output only 2 digits
1533
//DisplayValue(cap.cval,-2,'V',2); // Display 2 Digits of this 10mV units
1534
cap.cval = (trans.uBE[0]*4)+BAT_OUT;
// usually output only 2 digits
1535
DisplayValue(cap.cval,-3,
'V'
,2);
// Display 2 Digits of this 10mV units
1536
lcd_space();
1537
#endif
1538
1539
#if (BAT_POOR > 12000)
1540
#warning "Battery POOR level is set very high!"
1541
#endif
1542
#if (BAT_POOR < 2500)
1543
#warning "Battery POOR level is set very low!"
1544
#endif
1545
1546
#if (BAT_POOR > 5300)
1547
// use .8 V difference to Warn-Level
1548
#define WARN_LEVEL (((unsigned long)(BAT_POOR+800)*(unsigned long)33)/133)
1549
#elif (BAT_POOR > 3249)
1550
// less than 5.4 V only .4V difference to Warn-Level
1551
#define WARN_LEVEL (((unsigned long)(BAT_POOR+400)*(unsigned long)33)/133)
1552
#elif (BAT_POOR > 1299)
1553
// less than 2.9 V only .2V difference to Warn-Level
1554
#define WARN_LEVEL (((unsigned long)(BAT_POOR+200)*(unsigned long)33)/133)
1555
#else
1556
// less than 1.3 V only .1V difference to Warn-Level
1557
#define WARN_LEVEL (((unsigned long)(BAT_POOR+100)*(unsigned long)33)/133)
1558
#endif
1559
1560
#define POOR_LEVEL (((unsigned long)(BAT_POOR)*(unsigned long)33)/133)
1561
1562
// check the battery voltage
1563
if
(trans.uBE[0] < WARN_LEVEL) {
1564
1565
// Vcc < 7,3V; show Warning
1566
if
(trans.uBE[0] < POOR_LEVEL) {
1567
// Vcc <6,3V; no proper operation is possible
1568
lcd_fix_string(BatEmpty);
// Battery empty!
1569
wait_about2s();
1570
PORTD = 0;
// switch power off
1571
return
;
1572
}
1573
1574
lcd_fix_string(BatWeak);
// Battery weak
1575
}
else
{
// Battery-voltage OK
1576
lcd_fix_string(OK_str);
// "OK"
1577
}
1578
1579
#else
1580
lcd_fix2_string(VERSION_str);
// if no Battery check, Version .. in row 1
1581
#endif
1582
1583
#ifdef WDT_enabled
1584
//wdt_enable(WDTO_2S); // Watchdog on
1585
#endif
1586
1587
//wait_about1s(); // add more time for reading batterie voltage
1588
1589
// begin tests
1590
1591
#ifdef AUTO_RH
1592
RefVoltage();
// compute RHmultip = f(reference voltage)
1593
#endif
1594
1595
#if FLASHEND > 0x1fff
1596
if
(WithReference) {
1597
// 2.5V precision reference is checked OK
1598
if
((mess_count == 0) && (empty_count == 0)) {
1599
// display VCC= only first time
1600
lcd_line2();
1601
lcd_fix_string(VCC_str);
// VCC=
1602
DisplayValue(ADCconfig.U_AVCC,-3,
'V'
,3);
// Display 3 Digits of this mV units
1603
//lcd_space();
1604
//DisplayValue(RRpinMI,-1,LCD_CHAR_OMEGA,4);
1605
wait_about1s();
1606
}
1607
}
1608
#endif
1609
1610
#ifdef WITH_VEXT
1611
// show the external voltage
1612
while
(!(ON_PIN_REG & (1<<RST_PIN))) {
1613
lcd_line2();
1614
lcd_clear_line();
1615
lcd_line2();
1616
lcd_fix_string(Vext_str);
// Vext=
1617
ADC_DDR = 0;
// deactivate Software-UART
1618
trans.uBE[1] = W5msReadADC(TPext);
// read external voltage
1619
ADC_DDR = TXD_MSK;
// activate Software-UART
1620
1621
#ifdef WITH_UART
1622
uart_newline();
// start of new measurement
1623
#endif
1624
1625
DisplayValue(trans.uBE[1]*10,-3,
'V'
,3);
// Display 3 Digits of this mV units
1626
wait_about300ms();
1627
}
1628
#endif
1629
1630
lcd_line2();
// LCD position row 2, column 1
1631
lcd_fix_string(TestRunning);
// String: testing...
1632
1633
#ifndef DebugOut
1634
lcd_line2();
// LCD position row 2, column 1
1635
#endif
1636
1637
#ifdef NOK5110
1638
lcd.display();
1639
#endif
1640
#ifdef LCD2004
1641
lcd.display();
1642
#endif
1643
1644
EntladePins();
// discharge all capacitors!
1645
1646
if
(PartFound == PART_CELL) {
1647
lcd_clear();
1648
lcd_fix_string(Cell_str);
// display "Cell!"
1649
goto
end2;
1650
}
1651
1652
#ifdef CHECK_CALL
1653
AutoCheck();
// check, if selftest should be done
1654
#endif
1655
1656
// check all 6 combinations for the 3 pins
1657
// High Low Tri
1658
CheckPins(TP1, TP2, TP3);
1659
CheckPins(TP2, TP1, TP3);
1660
CheckPins(TP1, TP3, TP2);
1661
CheckPins(TP3, TP1, TP2);
1662
CheckPins(TP2, TP3, TP1);
1663
CheckPins(TP3, TP2, TP1);
1664
1665
// separate check if is is a capacitor
1666
if
(((PartFound == PART_NONE) || (PartFound == PART_RESISTOR) || (PartFound == PART_DIODE)) ) {
1667
EntladePins();
// discharge capacities
1668
// measurement of capacities in all 3 combinations
1669
cap.cval_max = 0;
// set max to zero
1670
cap.cpre_max = -12;
// set max to pF unit
1671
ReadCapacity(TP3, TP1);
1672
ReadCapacity(TP3, TP2);
1673
ReadCapacity(TP2, TP1);
1674
1675
#if FLASHEND > 0x1fff
1676
ReadInductance();
// measure inductance
1677
#endif
1678
}
1679
1680
// All checks are done, output result to display
1681
lcd_clear();
1682
1683
if
(PartFound == PART_DIODE) {
1684
if
(NumOfDiodes == 1) {
// single Diode
1685
//lcd_fix_string(Diode); // "Diode: "
1686
1687
#if FLASHEND > 0x1fff
1688
// enough memory to sort the pins
1689
1690
#if EBC_STYLE == 321
1691
// the higher test pin number is left side
1692
if
(diodes[0].Anode > diodes[0].Cathode) {
1693
lcd_testpin(diodes[0].Anode);
1694
lcd_fix_string(AnKat);
// "->|-"
1695
lcd_testpin(diodes[0].Cathode);
1696
}
else
{
1697
lcd_testpin(diodes[0].Cathode);
1698
lcd_fix_string(KatAn);
// "-|<-"
1699
lcd_testpin(diodes[0].Anode);
1700
}
1701
#else
1702
// the higher test pin number is right side
1703
if
(diodes[0].Anode < diodes[0].Cathode) {
1704
lcd_testpin(diodes[0].Anode);
1705
lcd_fix_string(AnKat);
// "->|-"
1706
lcd_testpin(diodes[0].Cathode);
1707
}
else
{
1708
lcd_testpin(diodes[0].Cathode);
1709
lcd_fix_string(KatAn);
// "-|<-"
1710
lcd_testpin(diodes[0].Anode);
1711
}
1712
#endif
1713
1714
#else
1715
// too less memory to sort the pins
1716
lcd_testpin(diodes[0].Anode);
1717
lcd_fix_string(AnKat);
// "->|-"
1718
lcd_testpin(diodes[0].Cathode);
1719
#endif
1720
1721
#if FLASHEND > 0x1fff
1722
GetIr(diodes[0].Cathode,diodes[0].Anode);
1723
#endif
1724
1725
UfOutput(0x70);
1726
1727
#ifdef NOK5110
1728
lcd_line3();
1729
#endif
1730
1731
#ifdef LCD2004
1732
lcd_line3();
1733
#endif
1734
1735
// load current of capacity is (5V-1.1V)/(470000 Ohm) = 8298nA
1736
lcd_fix_string(GateCap_str);
// "C="
1737
ReadCapacity(diodes[0].Cathode,diodes[0].Anode);
// Capacity opposite flow direction
1738
DisplayValue(cap.cval,cap.cpre,
'F'
,3);
1739
goto
end;
1740
1741
}
else
if
(NumOfDiodes == 2) {
// double diode
1742
lcd_data(
'2'
);
1743
lcd_fix_string(Diodes);
// "diodes "
1744
1745
if
(diodes[0].Anode == diodes[1].Anode) {
//Common Anode
1746
lcd_testpin(diodes[0].Cathode);
1747
lcd_fix_string(KatAn);
// "-|<-"
1748
lcd_testpin(diodes[0].Anode);
1749
lcd_fix_string(AnKat);
// "->|-"
1750
lcd_testpin(diodes[1].Cathode);
1751
UfOutput(0x01);
1752
goto
end;
1753
1754
}
else
if
(diodes[0].Cathode == diodes[1].Cathode) {
//Common Cathode
1755
lcd_testpin(diodes[0].Anode);
1756
lcd_fix_string(AnKat);
// "->|-"
1757
lcd_testpin(diodes[0].Cathode);
1758
lcd_fix_string(KatAn);
// "-|<-"
1759
lcd_testpin(diodes[1].Anode);
1760
UfOutput(0x01);
1761
goto
end;
1762
1763
}
else
if
((diodes[0].Cathode == diodes[1].Anode) && (diodes[1].Cathode == diodes[0].Anode)) {
1764
// Antiparallel
1765
lcd_testpin(diodes[0].Anode);
1766
lcd_fix_string(AnKat);
// "->|-"
1767
lcd_testpin(diodes[0].Cathode);
1768
lcd_fix_string(AnKat);
// "->|-"
1769
lcd_testpin(diodes[1].Cathode);
1770
UfOutput(0x01);
1771
goto
end;
1772
}
1773
1774
}
else
if
(NumOfDiodes == 3) {
1775
// Serial of 2 Diodes; was detected as 3 Diodes
1776
trans.b = 3;
1777
trans.c = 3;
1778
1779
// Check for any constallation of 2 serial diodes:
1780
// Only once the pin No of anyone Cathode is identical of another anode.
1781
// two diodes in series is additionally detected as third big diode.
1782
1783
if
(diodes[0].Cathode == diodes[1].Anode) {
1784
trans.b = 0;
1785
trans.c = 1;
1786
}
1787
if
(diodes[0].Anode == diodes[1].Cathode) {
1788
trans.b = 1;
1789
trans.c = 0;
1790
}
1791
if
(diodes[0].Cathode == diodes[2].Anode) {
1792
trans.b = 0;
1793
trans.c = 2;
1794
}
1795
if
(diodes[0].Anode == diodes[2].Cathode) {
1796
trans.b = 2;
1797
trans.c = 0;
1798
}
1799
if
(diodes[1].Cathode == diodes[2].Anode) {
1800
trans.b = 1;
1801
trans.c = 2;
1802
}
1803
if
(diodes[1].Anode == diodes[2].Cathode) {
1804
trans.b = 2;
1805
trans.c = 1;
1806
}
1807
1808
#if DebugOut == 4
1809
lcd_line3();
1810
lcd_testpin(diodes[0].Anode);
1811
lcd_data(
':'
);
1812
lcd_testpin(diodes[0].Cathode);
1813
lcd_space();
1814
lcd_string(utoa(diodes[0].Voltage, outval, 10));
1815
lcd_space();
1816
lcd_testpin(diodes[1].Anode);
1817
lcd_data(
':'
);
1818
lcd_testpin(diodes[1].Cathode);
1819
lcd_space();
1820
lcd_string(utoa(diodes[1].Voltage, outval, 10));
1821
lcd_line4();
1822
lcd_testpin(diodes[2].Anode);
1823
lcd_data(
':'
);
1824
lcd_testpin(diodes[2].Cathode);
1825
lcd_space();
1826
lcd_string(utoa(diodes[2].Voltage, outval, 10));
1827
lcd_line1();
1828
#endif
1829
1830
if
((trans.b < 3) && (trans.c < 3)) {
1831
lcd_data(
'3'
);
1832
lcd_fix_string(Diodes);
// "Diodes "
1833
lcd_testpin(diodes[trans.b].Anode);
1834
lcd_fix_string(AnKat);
// "->|-"
1835
lcd_testpin(diodes[trans.b].Cathode);
1836
lcd_fix_string(AnKat);
// "->|-"
1837
lcd_testpin(diodes[trans.c].Cathode);
1838
UfOutput( (trans.b<<4)|trans.c);
1839
goto
end;
1840
}
1841
}
1842
// end (PartFound == PART_DIODE)
1843
1844
}
else
if
(PartFound == PART_TRANSISTOR) {
1845
if
(PartReady != 0) {
1846
if
((trans.hfe[0]>trans.hfe[1])) {
1847
// if the amplification factor was higher at first testr: swap C and E !
1848
tmp = trans.c;
1849
trans.c = trans.e;
1850
trans.e = tmp;
1851
}
else
{
1852
trans.hfe[0] = trans.hfe[1];
1853
trans.uBE[0] = trans.uBE[1];
1854
}
1855
}
1856
1857
if
(PartMode == PART_MODE_NPN) {
1858
lcd_fix_string(NPN_str);
// "NPN "
1859
}
else
{
1860
lcd_fix_string(PNP_str);
// "PNP "
1861
}
1862
1863
if
( NumOfDiodes > 2) {
// Transistor with protection diode
1864
1865
#ifdef EBC_STYLE
1866
#if EBC_STYLE == 321
1867
// Layout with 321= style
1868
if
(((PartMode == PART_MODE_NPN) && (trans.c < trans.e)) || ((PartMode != PART_MODE_NPN) && (trans.c > trans.e)))
1869
#else
1870
// Layout with EBC= style
1871
if
(PartMode == PART_MODE_NPN)
1872
#endif
1873
#else
1874
// Layout with 123= style
1875
if
(((PartMode == PART_MODE_NPN) && (trans.c > trans.e)) || ((PartMode != PART_MODE_NPN) && (trans.c < trans.e)))
1876
#endif
1877
{
1878
lcd_fix_string(AnKat);
// "->|-"
1879
}
else
{
1880
lcd_fix_string(KatAn);
// "-|<-"
1881
}
1882
}
1883
1884
#ifdef NOK5110
1885
lcd_line2();
1886
#endif
1887
1888
#ifdef LCD2004
1889
lcd_line2();
1890
#endif
1891
1892
PinLayout(
'E'
,
'B'
,
'C'
);
// EBC= or 123=...
1893
1894
#ifdef NOK5110
1895
lcd_line3();
1896
#else
1897
lcd_line2();
// 2 row
1898
#endif
1899
1900
#ifdef LCD2004
1901
lcd_line3();
1902
#endif
1903
1904
lcd_fix_string(hfe_str);
// "B=" (hFE)
1905
DisplayValue(trans.hfe[0],0,0,3);
1906
lcd_space();
1907
1908
#ifdef NOK5110
1909
lcd_line4();
1910
#endif
1911
1912
#ifdef LCD2004
1913
lcd_line4();
1914
#endif
1915
1916
lcd_fix_string(Uf_str);
// "Uf="
1917
DisplayValue(trans.uBE[0],-3,
'V'
,3);
1918
goto
end;
1919
1920
// end (PartFound == PART_TRANSISTOR)
1921
1922
}
else
if
(PartFound == PART_FET) {
// JFET or MOSFET
1923
1924
if
(PartMode&1) {
1925
lcd_data(
'P'
);
// P-channel
1926
}
else
{
1927
lcd_data(
'N'
);
// N-channel
1928
}
1929
lcd_data(
'-'
);
1930
1931
tmp = PartMode/2;
1932
if
(tmp == (PART_MODE_N_D_MOS/2)) {
1933
lcd_data(
'D'
);
// N-D
1934
}
1935
if
(tmp == (PART_MODE_N_E_MOS/2)) {
1936
lcd_data(
'E'
);
// N-E
1937
}
1938
1939
if
(tmp == (PART_MODE_N_JFET/2)) {
1940
lcd_fix_string(jfet_str);
// "JFET"
1941
}
else
{
1942
lcd_fix_string(mosfet_str);
// "-MOS "
1943
}
1944
1945
#ifdef NOK5110
1946
lcd_line2();
1947
#endif
1948
1949
PinLayout(
'S'
,
'G'
,
'D'
);
// SGD= or 123=...
1950
1951
if
((NumOfDiodes > 0) && (PartMode < PART_MODE_N_D_MOS)) {
1952
// MOSFET with protection diode; only with enhancement-FETs
1953
1954
#ifdef EBC_STYLE
1955
#if EBC_STYLE == 321
1956
// layout with 321= style
1957
if
(((PartMode&1) && (trans.c > trans.e)) || ((!(PartMode&1)) && (trans.c < trans.e)))
1958
#else
1959
// Layout with SGD= style
1960
if
(PartMode&1)
// N or P MOS
1961
#endif
1962
#else
1963
// layout with 123= style
1964
if
(((PartMode&1) && (trans.c < trans.e)) || ((!(PartMode&1)) && (trans.c > trans.e)))
1965
#endif
1966
{
1967
lcd_data(LCD_CHAR_DIODE1);
// show Diode symbol >|
1968
}
else
{
1969
lcd_data(LCD_CHAR_DIODE2);
// show Diode symbol |<
1970
}
1971
}
1972
1973
#ifdef NOK5110
1974
lcd_line3();
1975
#else
1976
lcd_line2();
// 2 row
1977
#endif
1978
1979
#ifdef LCD2004
1980
lcd_line3();
1981
#endif
1982
1983
if
(PartMode < PART_MODE_N_D_MOS) {
// enhancement-MOSFET
1984
// Gate capacity
1985
lcd_fix_string(GateCap_str);
// "C="
1986
ReadCapacity(trans.b,trans.e);
// measure capacity
1987
DisplayValue(cap.cval,cap.cpre,
'F'
,3);
1988
1989
#ifdef NOK5110
1990
lcd_line4();
1991
#endif
1992
#ifdef LCD2004
1993
lcd_line4();
1994
#endif
1995
1996
lcd_fix_string(vt_str);
// "Vt="
1997
}
else
{
1998
lcd_data(
'I'
);
1999
lcd_data(
'='
);
2000
DisplayValue(trans.uBE[1],-5,
'A'
,2);
2001
2002
#ifdef NOK5110
2003
lcd_line4();
2004
#endif
2005
2006
#ifdef LCD2004
2007
lcd_line4();
2008
#endif
2009
2010
lcd_fix_string(Vgs_str);
// " Vgs="
2011
}
2012
2013
// Gate-threshold voltage
2014
DisplayValue(gthvoltage,-3,
'V'
,2);
2015
goto
end;
2016
2017
// end (PartFound == PART_FET)
2018
2019
}
else
if
(PartFound == PART_THYRISTOR) {
2020
lcd_fix_string(Thyristor);
// "Thyristor"
2021
goto
gakOutput;
2022
2023
}
else
if
(PartFound == PART_TRIAC) {
2024
lcd_fix_string(Triac);
// "Triac"
2025
goto
gakOutput;
2026
2027
}
else
if
(PartFound == PART_RESISTOR) {
2028
if
(ResistorsFound == 1) {
// single resistor
2029
lcd_testpin(resis[0].rb);
// Pin-number 1
2030
lcd_fix_string(Resistor_str);
2031
lcd_testpin(resis[0].ra);
// Pin-number 2
2032
}
else
{
// R-Max suchen
2033
ii = 0;
2034
if
(resis[1].rx > resis[0].rx)
2035
ii = 1;
2036
2037
if
(ResistorsFound == 2) {
2038
ii = 2;
2039
}
else
{
2040
if
(resis[2].rx > resis[ii].rx)
2041
ii = 2;
2042
}
2043
2044
char
x =
'1'
;
2045
char
y =
'3'
;
2046
char
z =
'2'
;
2047
2048
if
(ii == 1) {
2049
//x = '1';
2050
y =
'2'
;
2051
z =
'3'
;
2052
}
2053
2054
if
(ii == 2) {
2055
x =
'2'
;
2056
y =
'1'
;
2057
z =
'3'
;
2058
}
2059
2060
lcd_data(x);
2061
lcd_fix_string(Resistor_str);
// "-[=]-"
2062
lcd_data(y);
2063
lcd_fix_string(Resistor_str);
// "-[=]-"
2064
lcd_data(z);
2065
}
2066
2067
lcd_line2();
// 2 row
2068
2069
if
(ResistorsFound == 1) {
2070
RvalOut(0);
2071
2072
#if FLASHEND > 0x1fff
2073
if
(resis[0].lx != 0) {
2074
// resistor have also Inductance
2075
2076
#ifdef NOK5110
2077
lcd_line3();
2078
#endif
2079
#ifdef LCD2004
2080
lcd_line3();
2081
#endif
2082
2083
lcd_fix_string(Lis_str);
// "L="
2084
DisplayValue(resis[0].lx,resis[0].lpre,
'H'
,3);
// output inductance
2085
}
2086
#endif
2087
2088
}
else
{
2089
// output resistor values in right order
2090
if
(ii == 0) {
2091
RvalOut(1);
2092
RvalOut(2);
2093
}
2094
if
(ii == 1) {
2095
RvalOut(0);
2096
RvalOut(2);
2097
}
2098
if
(ii == 2) {
2099
RvalOut(0);
2100
RvalOut(1);
2101
}
2102
}
2103
goto
end;
2104
2105
// end (PartFound == PART_RESISTOR)
2106
2107
// capacity measurement is wanted
2108
}
else
if
(PartFound == PART_CAPACITOR) {
2109
//lcd_fix_string(Capacitor);
2110
lcd_testpin(cap.ca);
// Pin number 1
2111
lcd_fix_string(CapZeich);
// capacitor sign
2112
lcd_testpin(cap.cb);
// Pin number 2
2113
2114
#if FLASHEND > 0x1fff
2115
GetVloss();
// get Voltage loss of capacitor
2116
if
(cap.v_loss != 0) {
2117
2118
#ifdef NOK5110
2119
lcd_line4();
2120
#endif
2121
#ifdef LCD2004
2122
lcd_line4();
2123
#endif
2124
2125
lcd_fix_string(VLOSS_str);
// " Vloss="
2126
DisplayValue(cap.v_loss,-1,
'%'
,2);
2127
}
2128
#endif
2129
2130
lcd_line2();
// 2 row
2131
DisplayValue(cap.cval_max,cap.cpre_max,
'F'
,4);
2132
2133
#if FLASHEND > 0x1fff
2134
cap.esr = GetESR(cap.cb, cap.ca);
// get ESR of capacitor
2135
if
(cap.esr < 65530) {
2136
2137
#ifdef NOK5110
2138
lcd_line3();
2139
#endif
2140
#ifdef LCD2004
2141
lcd_line3();
2142
#endif
2143
2144
lcd_fix_string(ESR_str);
2145
DisplayValue(cap.esr,-2,LCD_CHAR_OMEGA,2);
2146
}
2147
#endif
2148
2149
goto
end;
2150
}
2151
2152
if
(NumOfDiodes == 0) {
// no diodes are found
2153
lcd_fix_string(TestFailed1);
// "No, unknown, or"
2154
lcd_line2();
// 2 row
2155
lcd_fix_string(TestFailed2);
// "damaged "
2156
lcd_fix_string(Component);
// "part"
2157
}
else
{
2158
lcd_fix_string(Component);
// "part"
2159
lcd_fix_string(Unknown);
// " unknown"
2160
lcd_line2();
// 2 row
2161
lcd_fix_string(OrBroken);
// "or damaged "
2162
lcd_data(NumOfDiodes +
'0'
);
2163
lcd_fix_string(AnKat);
// "->|-"
2164
}
2165
2166
empty_count++;
2167
mess_count = 0;
2168
goto
end2;
2169
2170
gakOutput:
2171
lcd_line2();
// 2 row
2172
PinLayout(Cathode_char,
'G'
,
'A'
);
// CGA= or 123=...
2173
2174
//- - - - - - - - - - - - - - - - - - - - - - - - - - - -
2175
end:
2176
empty_count = 0;
// reset counter, if part is found
2177
mess_count++;
// count measurements
2178
2179
end2:
2180
//ADC_DDR = (1<<TPREF) | TXD_MSK; // switch pin with reference to GND, release relay
2181
ADC_DDR = TXD_MSK;
// switch pin with reference to GND, release relay
2182
goto
start;
2183
2184
while
(!(ON_PIN_REG & (1<<RST_PIN)));
// wait ,until button is released
2185
wait_about200ms();
2186
// wait 14 seconds or 5 seconds (if repeat function)
2187
2188
for
(gthvoltage = 0;gthvoltage<display_time;gthvoltage+=10) {
2189
if
(!(ON_PIN_REG & (1<<RST_PIN))) {
2190
// If the key is pressed again...
2191
// goto start of measurement
2192
goto
start;
2193
}
2194
wdt_reset();
2195
wait_about10ms();
2196
}
2197
2198
#ifdef POWER_OFF
2199
#if POWER_OFF > 127
2200
#define POWER2_OFF 255
2201
#else
2202
#define POWER2_OFF POWER_OFF*2
2203
#endif
2204
2205
#if POWER_OFF+0 > 1
2206
if
((empty_count < POWER_OFF) && (mess_count < POWER2_OFF)) {
2207
goto
start;
// repeat measurement POWER_OFF times
2208
}
2209
#endif
2210
2211
// only one Measurement requested, shut off
2212
//MCUSR = 0;
2213
ON_PORT &= ~(1<<ON_PIN);
// switch off power
2214
// never ending loop
2215
while
(1) {
2216
if
(!(ON_PIN_REG & (1<<RST_PIN))) {
2217
// The statement is only reached if no auto off equipment is installed
2218
goto
start;
2219
}
2220
wdt_reset();
2221
wait_about10ms();
2222
}
2223
2224
#else
2225
goto
start;
// POWER_OFF not selected, repeat measurement
2226
#endif
2227
2228
return
;
2229
}
// end main
2230
2231
2232
//******************************************************************
2233
// output of flux voltage for 1-2 diodes in row 2
2234
// bcdnum = Numbers of both Diodes:
2235
// higher 4 Bit number of first Diode
2236
// lower 4 Bit number of second Diode (Structure diodes[nn])
2237
// if number >= 3 no output is done
2238
void
UfOutput(uint8_t bcdnum) {
2239
lcd_line2();
// 2 row
2240
lcd_fix_string(Uf_str);
// "Uf="
2241
mVOutput(bcdnum >> 4);
2242
mVOutput(bcdnum & 0x0f);
2243
}
2244
2245
void
mVOutput(uint8_t nn) {
2246
if
(nn < 3) {
2247
// Output in mV units
2248
DisplayValue(diodes[nn].Voltage,-3,
'V'
,3);
2249
lcd_space();
2250
}
2251
}
2252
2253
void
RvalOut(uint8_t ii) {
2254
// output of resistor value
2255
2256
#if FLASHEND > 0x1fff
2257
uint16_t rr;
2258
if
((resis[ii].rx < 100) && (resis[0].lx == 0)) {
2259
rr = GetESR(resis[ii].ra,resis[ii].rb);
2260
DisplayValue(rr,-2,LCD_CHAR_OMEGA,3);
2261
}
else
{
2262
DisplayValue(resis[ii].rx,-1,LCD_CHAR_OMEGA,4);
2263
}
2264
#else
2265
DisplayValue(resis[ii].rx,-1,LCD_CHAR_OMEGA,4);
2266
#endif
2267
2268
lcd_space();
2269
}
2270
2271
//******************************************************************
2272
2273
void
ChargePin10ms(uint8_t PinToCharge, uint8_t ChargeDirection) {
2274
// Load the specified pin to the specified direction with 680 Ohm for 10ms.
2275
// Will be used by discharge of MOSFET Gates or to load big capacities.
2276
// Parameters:
2277
// PinToCharge: specifies the pin as mask for R-Port
2278
// ChargeDirection: 0 = switch to GND (N-Kanal-FET), 1= switch to VCC(P-Kanal-FET)
2279
2280
if
(ChargeDirection&1) {
2281
R_PORT |= PinToCharge;
// R_PORT to 1 (VCC)
2282
}
else
{
2283
R_PORT &= ~PinToCharge;
// or 0 (GND)
2284
}
2285
2286
R_DDR |= PinToCharge;
// switch Pin to output, across R to GND or VCC
2287
wait_about10ms();
// wait about 10ms
2288
// switch back Input, no current
2289
R_DDR &= ~PinToCharge;
// switch back to input
2290
R_PORT &= ~PinToCharge;
// no Pull up
2291
}
2292
2293
2294
// first discharge any charge of capacitors
2295
void
EntladePins() {
2296
uint8_t adc_gnd;
// Mask of ADC-outputs, which can be directly connected to GND
2297
unsigned
int
adcmv[3];
// voltages of 3 Pins in mV
2298
unsigned
int
clr_cnt;
// Clear Counter
2299
uint8_t lop_cnt;
// loop counter
2300
2301
// max. time of discharge in ms (10000/20) == 10s
2302
#define MAX_ENTLADE_ZEIT (10000/20)
2303
2304
for
(lop_cnt=0;lop_cnt<10;lop_cnt++) {
2305
adc_gnd = TXD_MSK;
// put all ADC to Input
2306
ADC_DDR = adc_gnd;
2307
ADC_PORT = TXD_VAL;
// ADC-outputs auf 0
2308
R_PORT = 0;
// R-outputs auf 0
2309
R_DDR = (2<<(TP3*2)) | (2<<(TP2*2)) | (2<<(TP1*2));
// R_H for all Pins to GND
2310
2311
adcmv[0] = W5msReadADC(TP1);
// which voltage has Pin 1?
2312
adcmv[1] = ReadADC(TP2);
// which voltage has Pin 2?
2313
adcmv[2] = ReadADC(TP3);
// which voltage has Pin 3?
2314
2315
if
((PartFound == PART_CELL) || (adcmv[0] < CAP_EMPTY_LEVEL)
2316
& (adcmv[1] < CAP_EMPTY_LEVEL)
2317
& (adcmv[2] < CAP_EMPTY_LEVEL)) {
2318
ADC_DDR = TXD_MSK;
// switch all ADC-Pins to input
2319
R_DDR = 0;
// switch all R_L Ports (and R_H) to input
2320
return
;
// all is discharged
2321
}
2322
2323
// all Pins with voltage lower than 1V can be connected directly to GND (ADC-Port)
2324
if
(adcmv[0] < 1000) {
2325
adc_gnd |= (1<<TP1);
// Pin 1 directly to GND
2326
}
2327
if
(adcmv[1] < 1000) {
2328
adc_gnd |= (1<<TP2);
// Pin 2 directly to GND
2329
}
2330
if
(adcmv[2] < 1000) {
2331
adc_gnd |= (1<<TP3);
// Pin 3 directly to GND
2332
}
2333
ADC_DDR = adc_gnd;
// switch all selected ADC-Ports at the same time
2334
2335
// additionally switch the leaving Ports with R_L to GND.
2336
// since there is no disadvantage for the already directly switched pins, we can
2337
// simply switch all R_L resistors to GND
2338
R_DDR = (1<<(TP3*2)) | (1<<(TP2*2)) | (1<<(TP1*2));
// Pins across R_L resistors to GND
2339
2340
for
(clr_cnt=0;clr_cnt<MAX_ENTLADE_ZEIT;clr_cnt++) {
2341
wdt_reset();
2342
adcmv[0] = W20msReadADC(TP1);
// which voltage has Pin 1?
2343
adcmv[1] = ReadADC(TP2);
// which voltage has Pin 2?
2344
adcmv[2] = ReadADC(TP3);
// which voltage has Pin 3?
2345
2346
if
(adcmv[0] < 1300) {
2347
ADC_DDR |= (1<<TP1);
// below 1.3V , switch directly with ADC-Port to GND
2348
}
2349
if
(adcmv[1] < 1300) {
2350
ADC_DDR |= (1<<TP2);
// below 1.3V, switch directly with ADC-Port to GND
2351
}
2352
if
(adcmv[2] < 1300) {
2353
ADC_DDR |= (1<<TP3);
// below 1.3V, switch directly with ADC-Port to GND
2354
}
2355
if
((adcmv[0] < (CAP_EMPTY_LEVEL+2)) && (adcmv[1] < (CAP_EMPTY_LEVEL+2)) && (adcmv[2] < (CAP_EMPTY_LEVEL+2))) {
2356
break
;
2357
}
2358
}
2359
2360
if
(clr_cnt == MAX_ENTLADE_ZEIT) {
2361
PartFound = PART_CELL;
// mark as Battery
2362
// there is charge on capacitor, warn later!
2363
}
2364
2365
for
(adcmv[0]=0;adcmv[0]<clr_cnt;adcmv[0]++) {
2366
// for safety, discharge 5% of discharge time
2367
wait1ms();
2368
}
2369
}
// end for lop_cnt
2370
}
2371
2372
2373
#ifdef AUTO_RH
2374
void
RefVoltage(
void
) {
2375
// RefVoltage interpolates table RHtab corresponding to voltage ref_mv .
2376
// RHtab contain the factors to get capacity from load time with 470k for
2377
// different Band gab reference voltages.
2378
// for remember:
2379
// resistor 470000 Ohm 1000 1050 1100 1150 1200 1250 1300 1350 1400 mV
2380
// uint16_t RHTAB[] MEM_TEXT = { 954, 903, 856, 814, 775, 740, 707, 676, 648};
2381
2382
#define Ref_Tab_Abstand 50 // displacement of table is 50mV
2383
#define Ref_Tab_Beginn 1000 // begin of table is 1000mV
2384
2385
unsigned
int
referenz;
2386
unsigned
int
y1, y2;
2387
uint8_t tabind;
2388
uint8_t tabres;
2389
2390
#ifdef AUTO_CAL
2391
referenz = ref_mv + (int16_t)eeprom_read_word((uint16_t *)(&ref_offset));
2392
#else
2393
referenz = ref_mv + REF_C_KORR;
2394
#endif
2395
2396
if
(referenz >= Ref_Tab_Beginn) {
2397
referenz -= Ref_Tab_Beginn;
2398
}
else
{
2399
referenz = 0;
// limit to begin of table
2400
}
2401
2402
tabind = referenz / Ref_Tab_Abstand;
2403
tabres = referenz % Ref_Tab_Abstand;
2404
tabres = Ref_Tab_Abstand-tabres;
2405
2406
if
(tabind > 7) {
2407
tabind = 7;
// limit to end of table
2408
}
2409
2410
// interpolate the table of factors
2411
y1 = pgm_read_word(&RHtab[tabind]);
2412
y2 = pgm_read_word(&RHtab[tabind+1]);
2413
// RHmultip is the interpolated factor to compute capacity from load time with 470k
2414
RHmultip = ((y1 - y2) * tabres + (Ref_Tab_Abstand/2)) / Ref_Tab_Abstand + y2;
2415
}
2416
#endif
2417
2418
#ifdef LCD_CLEAR
2419
void
lcd_clear_line(
void
) {
2420
// writes 20 spaces to LCD-Display, Cursor must be positioned to first column
2421
unsigned
char
ll;
2422
for
(ll=0;ll<20;ll++) {
2423
lcd_space();
2424
}
2425
}
2426
#endif
2427
2428
2429
/* ************************************************************************
2430
* display of values and units
2431
* ************************************************************************ */
2432
/*
2433
* display value and unit
2434
* - max. 4 digits excluding "." and unit
2435
*
2436
* requires:
2437
* - value
2438
* - exponent of factor related to base unit (value * 10^x)
2439
* e.g: p = 10^-12 -> -12
2440
* - unit character (0 = none)
2441
* digits = 2, 3 or 4
2442
*/
2443
void
DisplayValue(unsigned
long
Value, int8_t Exponent, unsigned
char
Unit, unsigned
char
digits)
2444
{
2445
char
OutBuffer[15];
2446
unsigned
int
Limit;
2447
unsigned
char
Prefix;
// prefix character
2448
uint8_t Offset;
// exponent of offset to next 10^3 step
2449
uint8_t Index;
// index ID
2450
uint8_t Length;
// string length
2451
2452
Limit = 100;
// scale value down to 2 digits
2453
if
(digits == 3) Limit = 1000;
// scale value down to 3 digits
2454
if
(digits == 4) Limit = 10000;
// scale value down to 4 digits
2455
2456
while
(Value >= Limit)
2457
{
2458
Value += 5;
// for automatic rounding
2459
Value = Value / 10;
// scale down by 10^1
2460
Exponent++;
// increase exponent by 1
2461
}
2462
2463
// determine prefix
2464
2465
Length = Exponent + 12;
2466
if
((int8_t)Length < 0) Length = 0;
// Limit to minimum prefix
2467
if
(Length > 18) Length = 18;
// Limit to maximum prefix
2468
Index = Length / 3;
2469
Offset = Length % 3;
2470
2471
if
(Offset > 0)
2472
{
2473
Index++;
// adjust index for exponent offset, take next prefix
2474
Offset = 3 - Offset;
// reverse value (1 or 2)
2475
}
2476
2477
#ifdef NO_NANO
2478
if
(Index == 1)
2479
{
// use no nano
2480
Index++;
// use mikro instead of nano
2481
Offset += 3;
// can be 3,4 or 5
2482
}
2483
#endif
2484
2485
Prefix = MEM_read_byte((uint8_t *)(&PrefixTab[Index]));
// look up prefix in table
2486
2487
// display value
2488
2489
// convert value into string
2490
utoa((unsigned
int
)Value, OutBuffer, 10);
2491
Length = strlen(OutBuffer);
2492
2493
// position of dot
2494
Exponent = Length - Offset;
// calculate position
2495
2496
if
(Exponent <= 0)
// we have to prepend "0."
2497
{
2498
// 0: factor 10 / -1: factor 100
2499
//lcd_data('0');
2500
lcd_data(
'.'
);
2501
2502
#ifdef NO_NANO
2503
while
(Exponent < 0)
2504
{
2505
lcd_data(
'0'
);
// extra 0 for factor 10
2506
Exponent++;
2507
}
2508
#else
2509
if
(Exponent < 0) lcd_data(
'0'
);
// extra 0 for factor 100
2510
#endif
2511
}
2512
2513
if
(Offset == 0) Exponent = -1;
// disable dot if not needed
2514
2515
// adjust position to array or disable dot if set to 0
2516
//Exponent--;
2517
2518
// display value and add dot if requested
2519
Index = 0;
2520
while
(Index < Length)
// loop through string
2521
{
2522
lcd_data(OutBuffer[Index]);
// display char
2523
Index++;
// next one
2524
if
(Index == Exponent) {
2525
lcd_data(
'.'
);
// display dot
2526
}
2527
}
2528
2529
// display prefix and unit
2530
if
(Prefix != 0) lcd_data(Prefix);
2531
if
(Unit) lcd_data(Unit);
2532
}
2533
2534
2535
#ifndef INHIBIT_SLEEP_MODE
2536
// set the processor to sleep state
2537
// wake up will be done with compare match interrupt of counter 2
2538
void
sleep_5ms(uint16_t pause){
2539
// pause is the delay in 5ms units
2540
uint8_t t2_offset;
2541
2542
#define RESTART_DELAY_US (RESTART_DELAY_TICS/(F_CPU/1000000UL))
2543
// for 8 MHz crystal the Restart delay is 16384/8 = 2048us
2544
2545
while
(pause > 0) {
2546
2547
#if 3000 > RESTART_DELAY_US
2548
if
(pause > 1) {
2549
// Startup time is too long with 1MHz Clock!!!!
2550
t2_offset = (10000 - RESTART_DELAY_US) / T2_PERIOD;
// set to 10ms above the actual counter
2551
pause -= 2;
2552
}
else
{
2553
t2_offset = (5000 - RESTART_DELAY_US) / T2_PERIOD;
// set to 5ms above the actual counter
2554
pause = 0;
2555
}
2556
2557
OCR2A = TCNT2 + t2_offset;
// set the compare value
2558
TIMSK2 = (0<<OCIE2B) | (1<<OCIE2A) | (0<<TOIE2);
// enable output compare match A interrupt
2559
2560
set_sleep_mode(SLEEP_MODE_PWR_SAVE);
2561
//set_sleep_mode(SLEEP_MODE_IDLE);
2562
sleep_mode();
2563
// wake up after output compare match interrupt
2564
#else
2565
// restart delay ist too long, use normal delay of 5ms
2566
wait5ms();
2567
#endif
2568
2569
wdt_reset();
2570
}
2571
2572
TIMSK2 = (0<<OCIE2B) | (0<<OCIE2A) | (0<<TOIE2);
// disable output compare match A interrupt
2573
}
2574
#endif
2575
2576
2577
// show the Pin Layout of the device
2578
void
PinLayout(
char
pin1,
char
pin2,
char
pin3) {
2579
// pin1-3 is EBC or SGD or CGA
2580
#ifndef EBC_STYLE
2581
// Layout with 123= style
2582
lcd_fix_string(N123_str);
// " 123="
2583
for
(ii=0;ii<3;ii++) {
2584
if
(ii == trans.e) lcd_data(pin1);
// Output Character in right order
2585
if
(ii == trans.b) lcd_data(pin2);
2586
if
(ii == trans.c) lcd_data(pin3);
2587
}
2588
#else
2589
#if EBC_STYLE == 321
2590
// Layout with 321= style
2591
lcd_fix_string(N321_str);
// " 321="
2592
ii = 3;
2593
while
(ii != 0) {
2594
ii--;
2595
if
(ii == trans.e) lcd_data(pin1);
// Output Character in right order
2596
if
(ii == trans.b) lcd_data(pin2);
2597
if
(ii == trans.c) lcd_data(pin3);
2598
}
2599
#else
2600
// Layout with EBC= style
2601
lcd_space();
2602
lcd_data(pin1);
2603
lcd_data(pin2);
2604
lcd_data(pin3);
2605
lcd_data(
'='
);
2606
lcd_testpin(trans.e);
2607
lcd_testpin(trans.b);
2608
lcd_testpin(trans.c);
2609
#endif
2610
#endif
2611
}
2612
2613
/* -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- */
2614
2615
void
AutoCheck(
void
) {
2616
#ifdef WITH_SELFTEST
2617
2618
uint8_t tt;
// number of running test
2619
uint8_t ww;
// counter for repeating the tests
2620
int
adcmv[7];
2621
uint16_t u680;
// 3 * (Voltage at 680 Ohm)
2622
2623
// define the maximum count of repetitions MAX_REP
2624
#define MAX_REP 4
2625
2626
#ifdef AUTO_CAL
2627
uint8_t cap_found;
// counter for found capacitor
2628
2629
#ifdef AUTOSCALE_ADC
2630
int8_t udiff;
// difference between ADC Voltage with VCC or Bandgap reference
2631
int8_t udiff2;
2632
#endif
2633
#endif
2634
2635
ADC_PORT = TXD_VAL;
2636
ADC_DDR = TXD_MSK;
2637
2638
#define RequireShortedProbes
2639
2640
if
(AllProbesShorted() != 3)
return
;
2641
2642
lcd_clear();
2643
lcd_fix_string(SELFTEST);
// "Selftest mode.."
2644
2645
lcd_line2();
2646
lcd_fix2_string(R0_str);
// "R0="
2647
2648
eeprom_write_byte((uint8_t *)(&EE_ESR_ZEROtab[2]), (int8_t)0);
// clear zero offset
2649
eeprom_write_byte((uint8_t *)(&EE_ESR_ZEROtab[3]), (int8_t)0);
// clear zero offset
2650
eeprom_write_byte((uint8_t *)(&EE_ESR_ZEROtab[1]), (int8_t)0);
// clear zero offset
2651
2652
adcmv[0] = GetESR(TP3, TP1);
2653
adcmv[1] = GetESR(TP3, TP2);
2654
adcmv[2] = GetESR(TP2, TP1);
2655
2656
DisplayValue(adcmv[0],-2,
' '
,3);
2657
DisplayValue(adcmv[1],-2,
' '
,3);
2658
DisplayValue(adcmv[2],-2,LCD_CHAR_OMEGA,3);
2659
2660
if
(adcmv[0] < 60) {
2661
eeprom_write_byte((uint8_t *)(&EE_ESR_ZEROtab[2]), (int8_t)adcmv[0]);
// fix zero offset
2662
}
2663
if
(adcmv[1] < 60) {
2664
eeprom_write_byte((uint8_t *)(&EE_ESR_ZEROtab[3]), (int8_t)adcmv[1]);
// fix zero offset
2665
}
2666
if
(adcmv[2] < 60) {
2667
eeprom_write_byte((uint8_t *)(&EE_ESR_ZEROtab[1]), (int8_t)adcmv[2]);
// fix zero offset
2668
}
2669
2670
for
(tt=0; tt<12; tt++) {
2671
wait_about500ms();
2672
2673
if
(!(ON_PIN_REG & (1<<RST_PIN))) {
2674
// if key is pressed, don't repeat
2675
break
;
2676
}
2677
}
// end for tt
2678
2679
#define TEST_COUNT 8
2680
2681
for
(tt=1; tt<TEST_COUNT; tt++) {
// loop for all Tests
2682
for
(ww=0; ww<MAX_REP; ww++) {
// repeat the test MAX_REP times
2683
lcd_line2();
// Cursor to column 1, row 2
2684
lcd_clear_line();
// clear total line
2685
lcd_line1();
// Cursor to column 1, row 1
2686
lcd_clear_line();
// clear total line
2687
lcd_line1();
// Cursor to column 1, row 1
2688
lcd_data(
'T'
);
// output the Testmode "T"
2689
lcd_string(utoa(tt, outval, 10));
// output Test number
2690
lcd_space();
2691
2692
if
(tt == 1) {
// output of reference voltage and factors for capacity measurement
2693
Calibrate_UR();
// get Reference voltage, Pin resistance
2694
lcd_fix2_string(URefT);
// "URef="
2695
DisplayValue(ref_mv,-3,
'V'
,4);
2696
lcd_line2();
// Cursor to column 1, row 2
2697
lcd_fix2_string(RHfakt);
// "RHf="
2698
lcd_string(utoa(RHmultip, outval, 10));
2699
ADCconfig.Samples = 190;
// set number of ADC reads near to maximum
2700
}
2701
2702
if
(tt == 2) {
// how equal are the RL resistors?
2703
u680 = ((
long
)ADCconfig.U_AVCC * (PIN_RM + R_L_VAL) / (PIN_RM + R_L_VAL + R_L_VAL + PIN_RP));
2704
R_PORT = 1<<(TP1*2);
// RL1 to VCC
2705
R_DDR = (1<<(TP1*2)) | (1<<(TP2*2));
// RL2 to -
2706
adcmv[0] = W20msReadADC(TP1);
2707
adcmv[0] -= u680;
2708
R_DDR = (1<<(TP1*2)) | (1<<(TP3*2));
// RL3 to -
2709
adcmv[1] = W20msReadADC(TP1);
2710
adcmv[1] -= u680;
2711
R_PORT = 1<<(TP2*2);
// RL2 to VCC
2712
R_DDR = (1<<(TP2*2)) | (1<<(TP3*2));
// RL3 to -
2713
adcmv[2] = W20msReadADC(TP2);
2714
adcmv[2] -= u680;
2715
lcd_fix_string(RLRL);
// "RLRL"
2716
}
2717
2718
if
(tt == 3) {
// how equal are the RH resistors
2719
R_PORT = 2<<(TP1*2);
// RH1 to VCC
2720
R_DDR = (2<<(TP1*2)) | (2<<(TP2*2));
// RH2 to -
2721
adcmv[0] = W20msReadADC(TP1);
2722
adcmv[3] = ADCconfig.U_AVCC / 2;
2723
adcmv[0] -= adcmv[3];
2724
R_DDR = (2<<(TP1*2)) | (2<<(TP3*2));
// RH3 to -
2725
adcmv[1] = W20msReadADC(TP1);
2726
adcmv[1] -= adcmv[3];
2727
R_PORT = 2<<(TP2*2);
// RH2 to VCC
2728
R_DDR = (2<<(TP2*2)) | (2<<(TP3*2));
// RH3 to -
2729
adcmv[2] = W20msReadADC(TP2);
2730
adcmv[2] -= adcmv[3];
2731
lcd_fix_string(RHRH);
// "RHRH"
2732
}
2733
2734
if
(tt == 4) {
// Text release probes
2735
lcd_fix_string(RELPROBE);
// "Release Probes"
2736
if
(AllProbesShorted() != 0) ww = MAX_REP-2;
2737
}
2738
2739
if
(tt == 5) {
// can we switch the ADC pins to GND across R_H resistor?
2740
R_PORT = 0;
2741
R_DDR = 2<<(TP1*2);
// Pin 1 over R_H to GND
2742
adcmv[0] = W20msReadADC(TP1);
2743
2744
R_DDR = 2<<(TP2*2);
// Pin 2 over R_H to GND
2745
adcmv[1] = W20msReadADC(TP2);
2746
2747
R_DDR = 2<<(TP3*2);
// Pin 3 over R_H to GND
2748
adcmv[2] = W20msReadADC(TP3);
2749
lcd_fix_string(RH1L);
// "RH_Lo="
2750
}
2751
2752
if
(tt == 6) {
// can we switch the ADC pins to VCC across the R_H resistor?
2753
R_DDR = 2<<(TP1*2);
// Pin 1 over R_H to VCC
2754
R_PORT = 2<<(TP1*2);
2755
adcmv[0] = W20msReadADC(TP1) - ADCconfig.U_AVCC;
2756
R_DDR = 2<<(TP2*2);
// Pin 2 over R_H to VCC
2757
R_PORT = 2<<(TP2*2);
2758
adcmv[1] = W20msReadADC(TP2) - ADCconfig.U_AVCC;
2759
R_DDR = 2<<(TP3*2);
// Pin 3 over R_H to VCC
2760
R_PORT = 2<<(TP3*2);
2761
adcmv[2] = W20msReadADC(TP3) - ADCconfig.U_AVCC;
2762
lcd_fix_string(RH1H);
// "RH_Hi="
2763
}
2764
2765
if
(tt == 7) {
// can we switch the ADC pins to VCC across the R_H resistor?
2766
u680 = ((
long
)ADCconfig.U_AVCC * (PIN_RM + R_L_VAL) / (PIN_RM + R_L_VAL + R_H_VAL*100));
2767
R_PORT = 2<<(TP1*2);
// RH1 to VCC
2768
R_DDR = (2<<(TP1*2)) | (1<<(TP1*2));
// RH1 to +, RL1 to -
2769
adcmv[0] = W20msReadADC(TP1);
2770
adcmv[0] -= u680;
2771
R_PORT = 2<<(TP2*2);
// RH2 to VCC
2772
R_DDR = (2<<(TP2*2)) | (1<<(TP2*2));
// RH2 to +, RL2 to -
2773
adcmv[1] = W20msReadADC(TP2);
2774
adcmv[1] -= u680;
2775
R_PORT = 2<<(TP3*2);
// RH3 to VCC
2776
R_DDR = (2<<(TP3*2)) | (1<<(TP3*2));
// RH3 to +, RL3 to -
2777
adcmv[2] = W20msReadADC(TP3);
2778
adcmv[2] -= u680;
2779
lcd_fix_string(RHRL);
// "RH/RL"
2780
}
2781
2782
if
(tt > 1) {
// output 3 voltages
2783
lcd_line2();
// Cursor to column 1, row 2
2784
lcd_string(itoa(adcmv[0], outval, 10));
// output voltage 1
2785
lcd_space();
2786
lcd_string(itoa(adcmv[1], outval, 10));
// output voltage 2
2787
lcd_space();
2788
lcd_string(itoa(adcmv[2], outval, 10));
// output voltage 3
2789
}
2790
2791
ADC_DDR = TXD_MSK;
// all-Pins to Input
2792
ADC_PORT = TXD_VAL;
// all ADC-Ports to GND
2793
R_DDR = 0;
// all R-Ports to Input
2794
R_PORT = 0;
2795
2796
if
(!(ON_PIN_REG & (1<<RST_PIN))) {
2797
// if key is pressed, don't repeat
2798
break
;
2799
}
2800
wait_about500ms();
2801
2802
if
(!(ON_PIN_REG & (1<<RST_PIN))) {
2803
// if key is pressed, don't repeat
2804
break
;
2805
}
2806
wait_about500ms();
2807
2808
}
// end for ww
2809
wait_about1s();
2810
2811
}
// end for tt
2812
2813
lcd_clear();
2814
lcd_fix_string(RIHI);
// "RiHi="
2815
DisplayValue(RRpinPL,-1,LCD_CHAR_OMEGA,3);
2816
lcd_line2();
2817
lcd_fix_string(RILO);
// "RiLo="
2818
DisplayValue(RRpinMI,-1,LCD_CHAR_OMEGA,3);
2819
wait_about2s();
2820
2821
//measure Zero offset for Capacity measurement
2822
adcmv[3] = 0;
2823
PartFound = PART_NONE;
2824
ReadCapacity(TP3, TP1);
2825
adcmv[5] = (unsigned
int
) cap.cval_uncorrected.dw;
// save capacity value of empty Pin 1:3
2826
ReadCapacity(TP3, TP2);
2827
adcmv[6] = (unsigned
int
) cap.cval_uncorrected.dw;
// save capacity value of empty Pin 2:3
2828
ReadCapacity(TP2, TP1);
2829
adcmv[2] = (unsigned
int
) cap.cval_uncorrected.dw;
// save capacity value of empty Pin 1:2
2830
ReadCapacity(TP1, TP3);
2831
adcmv[1] = (unsigned
int
) cap.cval_uncorrected.dw;
// save capacity value of empty Pin 3:1
2832
ReadCapacity(TP2, TP3);
2833
adcmv[4] = (unsigned
int
) cap.cval_uncorrected.dw;
// save capacity value of empty Pin 3:2
2834
ReadCapacity(TP1, TP2);
2835
adcmv[0] = (unsigned
int
) cap.cval_uncorrected.dw;
// save capacity value of empty Pin 2:1
2836
2837
lcd_clear();
2838
lcd_fix_string(C0_str);
// output "C0 "
2839
DisplayValue(adcmv[5],0,
' '
,3);
// output cap0 1:3
2840
DisplayValue(adcmv[6],0,
' '
,3);
// output cap0 2:3
2841
DisplayValue(adcmv[2],-12,
'F'
,3);
// output cap0 1:2
2842
2843
#ifdef AUTO_CAL
2844
for
(ww=0;ww<7;ww++) {
2845
if
(adcmv[ww] > 70)
goto
no_c0save;
2846
}
2847
2848
for
(ww=0;ww<7;ww++) {
2849
// write all zero offsets to the EEprom
2850
(
void
) eeprom_write_byte((uint8_t *)(&c_zero_tab[ww]),adcmv[ww]+(COMP_SLEW1 / (CC0 + CABLE_CAP + COMP_SLEW2)));
2851
}
2852
2853
lcd_line2();
2854
lcd_fix_string(OK_str);
// output "OK"
2855
2856
no_c0save:
2857
#endif
2858
2859
wait_about2s();
2860
2861
#ifdef AUTO_CAL
2862
// Message C > 100nF
2863
cap_found = 0;
2864
for
(ww=0; ww<64; ww++) {
2865
lcd_clear();
2866
lcd_data(
'1'
);
2867
lcd_fix_string(CapZeich);
// "-||-"
2868
lcd_data(
'3'
);
2869
lcd_fix2_string(MinCap_str);
// " >100nF!"
2870
2871
PartFound = PART_NONE;
2872
// measure offset Voltage of analog Comparator for Capacity measurement
2873
ReadCapacity(TP3, TP1);
// look for capacitor > 100nF
2874
2875
while
(cap.cpre < -9) {
2876
cap.cpre++;
2877
cap.cval /= 10;
2878
}
2879
2880
if
((cap.cpre == -9) && (cap.cval > 95) && (cap.cval < 22000)) {
2881
cap_found++;
2882
}
else
{
2883
cap_found = 0;
// wait for stable connection
2884
}
2885
2886
if
(cap_found > 1) {
2887
// value of capacitor is correct
2888
(
void
) eeprom_write_word((uint16_t *)(&ref_offset), load_diff);
// hold zero offset + slew rate dependend offset
2889
lcd_clear();
2890
lcd_fix2_string(REF_C_str);
// "REF_C="
2891
lcd_string(itoa(load_diff, outval, 10));
// output REF_C_KORR
2892
2893
#if 0
2894
// Test for switching level of the digital input of port TP3
2895
2896
for
(ii=0;ii<8;ii++) {
2897
ADC_PORT = TXD_VAL;
// ADC-Port 1 to GND
2898
ADC_DDR = 1<<TP1 | TXD_MSK;
// ADC-Pin 1 to output 0V
2899
R_PORT = 2<<(TP3*2);
// Pin 3 over R_H to VCC
2900
R_DDR = 2<<(TP3*2);
// Pin 3 over R_H to VCC
2901
2902
while
(1) {
2903
wdt_reset();
2904
if
((ADC_PIN&(1<<TP3)) == (1<<TP3))
break
;
2905
}
2906
2907
R_DDR = 0;
// Pin 3 without current
2908
R_PORT = 0;
2909
adcmv[0] = ReadADC(TP3);
2910
lcd_line3();
2911
DisplayValue(adcmv[0],-3,
'V'
,4);
2912
R_DDR = 2<<(TP3*2);
// Pin 3 over R_H to GND
2913
2914
while
(1) {
2915
wdt_reset();
2916
if
((ADC_PIN&(1<<TP3)) != (1<<TP3))
break
;
2917
}
2918
2919
R_DDR = 0;
// Pin 3 without current
2920
lcd_line4();
2921
adcmv[0] = ReadADC(TP3);
2922
DisplayValue(adcmv[0],-3,
'V'
,4);
2923
wait_about1s();
2924
}
2925
#endif
2926
2927
#ifdef AUTOSCALE_ADC
2928
ADC_PORT = TXD_VAL;
// ADC-Port 1 to GND
2929
ADC_DDR = 1<<TP1 | TXD_MSK;
// ADC-Pin 1 to output 0V
2930
R_DDR = 2<<(TP3*2);
// Pin 3 over R_H to GND
2931
2932
do
{
2933
adcmv[0] = ReadADC(TP3);
2934
}
while
(adcmv[0] > 980);
2935
2936
R_DDR = 0;
// all Pins to input
2937
2938
ADCconfig.U_Bandgap = 0;
// do not use internal Ref
2939
adcmv[0] = ReadADC(TP3);
// get cap voltage with VCC reference
2940
ADCconfig.U_Bandgap = ADC_internal_reference;
2941
adcmv[1] = ReadADC(TP3);
// get cap voltage with internal reference
2942
ADCconfig.U_Bandgap = 0;
// do not use internal Ref
2943
adcmv[2] = ReadADC(TP3);
// get cap voltage with VCC reference
2944
ADCconfig.U_Bandgap = ADC_internal_reference;
2945
2946
udiff = (int8_t)(((signed
long
)(adcmv[0] + adcmv[2] - adcmv[1] - adcmv[1])) * ADC_internal_reference / (2*adcmv[1]))+REF_R_KORR;
2947
2948
lcd_line2();
2949
lcd_fix2_string(REF_R_str);
// "REF_R="
2950
2951
udiff2 = udiff + (int8_t)eeprom_read_byte((uint8_t *)(&RefDiff));
2952
(
void
) eeprom_write_byte((uint8_t *)(&RefDiff), (uint8_t)udiff2);
// hold offset for true reference Voltage
2953
2954
lcd_string(itoa(udiff2, outval, 10));
// output correction voltage
2955
#endif
2956
2957
wait_about4s();
2958
break
;
2959
}
2960
2961
lcd_line2();
2962
DisplayValue(cap.cval,cap.cpre,
'F'
,4);
2963
wait_about200ms();
// wait additional time
2964
2965
}
// end for ww
2966
#endif
2967
2968
ADCconfig.Samples = ANZ_MESS;
// set to configured number of ADC samples
2969
2970
lcd_clear();
2971
lcd_line2();
2972
lcd_fix2_string(VERSION_str);
// "Version ..."
2973
lcd_line1();
2974
lcd_fix_string(ATE);
// "Selftest End"
2975
2976
#ifdef FREQUENCY_50HZ
2977
//#define TEST_SLEEP_MODE // only select for checking the sleep delay
2978
lcd_fix_string(T50HZ);
// " 50Hz"
2979
ADC_PORT = TXD_VAL;
2980
ADC_DDR = 1<<TP1 | TXD_MSK;
// Pin 1 to GND
2981
R_DDR = (1<<(TP3*2)) | (1<<(TP2*2));
2982
2983
for
(ww=0;ww<30;ww++) {
// repeat the signal up to 30 times (1 minute)
2984
for
(ii=0;ii<100;ii++) {
// for 2 s generate 50 Hz
2985
R_PORT = (1<<(TP2*2));
// Pin 2 over R_L to VCC, Pin 3 over R_L to GND
2986
2987
#ifdef TEST_SLEEP_MODE
2988
sleep_5ms(2);
// test of timing of sleep mode call
2989
#else
2990
wait10ms();
// normal delay
2991
#endif
2992
2993
R_PORT = (1<<(TP3*2));
// Pin 3 over R_L to VCC, Pin 2 over R_L to GND
2994
2995
#ifdef TEST_SLEEP_MODE
2996
sleep_5ms(2);
// test of timing of sleep mode call
2997
#else
2998
wait10ms();
// normal delay
2999
#endif
3000
3001
wdt_reset();
3002
}
3003
3004
if
(!(ON_PIN_REG & (1<<RST_PIN))) {
3005
// if key is pressed, don't repeat
3006
break
;
3007
}
3008
}
3009
#endif
3010
3011
PartFound = PART_NONE;
3012
wait_about1s();
3013
#endif
3014
}
3015
3016
3017
#ifdef RequireShortedProbes
3018
/*
3019
* check for a short circuit between two probes
3020
* from Markus R.
3021
*
3022
* requires:
3023
* - ID of first probe (0-2)
3024
* - ID of second probe (0-2)
3025
*
3026
* returns:
3027
* - 0 if not shorted
3028
* - 1 if shorted
3029
*/
3030
3031
uint8_t ShortedProbes(uint8_t Probe1, uint8_t Probe2)
3032
{
3033
uint8_t Flag1 = 0;
// return value
3034
unsigned
int
U1;
// voltage at probe #1 in mV
3035
unsigned
int
U2;
// voltage at probe #2 in mV
3036
unsigned
int
URH;
// half of reference voltage
3037
3038
// Set up a voltage divider between the two probes:
3039
// - Probe1: Rl pull-up
3040
// - Probe2: Rl pull-down
3041
3042
R_PORT = pgm_read_byte(&PinRLtab[Probe1]);
3043
R_DDR = pgm_read_byte(&PinRLtab[Probe1]) | pgm_read_byte(&PinRLtab[Probe2]);
3044
3045
// read voltages
3046
U1 = ReadADC(Probe1);
3047
U2 = ReadADC(Probe2);
3048
3049
// We expect both probe voltages to be about the same and
3050
// to be half of Vcc (allowed difference +/- 20mV).
3051
3052
URH = ADCconfig.U_AVCC / 2;
3053
if
((U1 > URH - 20) && (U1 < URH + 20))
3054
{
3055
if
((U2 > URH - 20) && (U2 < URH + 20))
3056
{
3057
Flag1 = 1;
3058
}
3059
}
3060
3061
// reset port
3062
R_DDR = 0;
3063
3064
return
Flag1;
3065
}
3066
3067
/*
3068
* check for a short circuit between all probes
3069
* from Markus R.
3070
*
3071
* returns:
3072
* - 0 if no probes are short-circuited
3073
* - number of probe pairs short-circuited (3 = all)
3074
*/
3075
3076
uint8_t AllProbesShorted(
void
)
3077
{
3078
uint8_t Flag2;
// return value
3079
3080
// check all possible combinations
3081
Flag2 = ShortedProbes(TP1, TP2);
3082
Flag2 += ShortedProbes(TP1, TP3);
3083
Flag2 += ShortedProbes(TP2, TP3);
3084
3085
return
Flag2;
3086
}
3087
#endif
3088
3089
/* -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- */
3090
3091
//******************************************************************
3092
void
CheckPins(uint8_t HighPin, uint8_t LowPin, uint8_t TristatePin) {
3093
/*
3094
Function
for
checking the characteristic of a component with the following pin assignment
3095
parameters:
3096
HighPin: Pin, which will be switched to VCC at the beginning
3097
LowPin: Pin, which will be
switch
to GND at the beginning
3098
TristatePin: Pin, which will be undefined at the beginning
3099
TristatePin will be switched to GND and VCC also .
3100
*/
3101
struct
{
3102
unsigned
int
lp_otr;
3103
unsigned
int
hp1;
3104
unsigned
int
hp2;
3105
unsigned
int
hp3;
3106
unsigned
int
lp1;
3107
unsigned
int
lp2;
3108
unsigned
int
tp1;
3109
unsigned
int
tp2;
3110
} adc;
3111
uint8_t LoPinRL;
// mask to switch the LowPin with R_L
3112
uint8_t LoPinRH;
// mask to switch the LowPin with R_H
3113
uint8_t TriPinRL;
// mask to switch the TristatePin with R_L
3114
uint8_t TriPinRH;
// mask to switch the TristatePin with R_H
3115
uint8_t HiPinRL;
// mask to switch the HighPin with RL
3116
uint8_t HiPinRH;
// mask to switch the HighPin with R_H
3117
uint8_t HiADCp;
// mask to switch the ADC port High-Pin
3118
uint8_t LoADCp;
// mask to switch the ADC port Low-Pin
3119
uint8_t HiADCm;
// mask to switch the ADC DDR port High-Pin
3120
uint8_t LoADCm;
// mask to switch the ADC DDR port Low-Pin
3121
uint8_t PinMSK;
3122
uint8_t ii;
// temporary variable
3123
3124
#ifdef COMMON_EMITTER
3125
unsigned
int
tmp16;
// temporary variable
3126
#else
3127
#warning "without common emitter hFE"
3128
#endif
3129
3130
#if FLASHEND > 0x1fff
3131
int
udiff;
3132
#endif
3133
3134
#ifdef COMMON_COLLECTOR
3135
unsigned
long
c_hfe;
// amplification factor for common Collector (Emitter follower)
3136
#endif
3137
3138
struct
resis_t *thisR;
3139
unsigned
long
lrx1;
3140
unsigned
long
lirx1;
3141
unsigned
long
lirx2;
3142
3143
/*
3144
switch HighPin directls to VCC
3145
switch R_L port for LowPin to GND
3146
TristatePin remains switched to input , no action required
3147
*/
3148
3149
wdt_reset();
3150
//#ifdef AUTO_CAL
3151
// uint16_t resis680pl;
3152
// uint16_t resis680mi;
3153
// resis680pl = eeprom_read_word(&R680pl);
3154
// resis680mi = eeprom_read_word(&R680mi);
3155
// #define RR680PL resis680pl
3156
// #define RR680MI resis680mi
3157
//#else
3158
// #define RR680PL (R_L_VAL + PIN_RP)
3159
// #define RR680MI (R_L_VAL + PIN_RM)
3160
//#endif
3161
3162
LoPinRL = pgm_read_byte(&PinRLtab[LowPin]);
// instruction for LowPin R_L
3163
LoPinRH = LoPinRL + LoPinRL;
// instruction for LowPin R_H
3164
TriPinRL = pgm_read_byte(&PinRLtab[TristatePin]);
// instruction for TristatePin R_L
3165
TriPinRH = TriPinRL + TriPinRL;
// instruction for TristatePin R_H
3166
HiPinRL = pgm_read_byte(&PinRLtab[HighPin]);
// instruction for HighPin R_L
3167
HiPinRH = HiPinRL + HiPinRL;
// instruction for HighPin R_H
3168
3169
HiADCp = pgm_read_byte(&PinADCtab[HighPin]);
// instruction for ADC High-Pin
3170
LoADCp = pgm_read_byte(&PinADCtab[LowPin]);
// instruction for ADC Low-Pin
3171
HiADCm = HiADCp | TXD_MSK;
3172
HiADCp |= TXD_VAL;
3173
LoADCm = LoADCp | TXD_MSK;
3174
LoADCp |= TXD_VAL;
3175
3176
// setting of Pins
3177
R_PORT = 0;
// resistor-Port outputs to 0
3178
R_DDR = LoPinRL;
// Low-Pin to output and across R_L to GND
3179
ADC_DDR = HiADCm;
// High-Pin to output
3180
ADC_PORT = HiADCp;
// High-Pin fix to Vcc
3181
3182
// for some MOSFET the gate (TristatePin) must be discharged
3183
ChargePin10ms(TriPinRL,0);
// discharge for N-Kanal
3184
adc.lp_otr = W5msReadADC(LowPin);
// read voltage of Low-Pin
3185
if
(adc.lp_otr >= 977) {
// no current now?
3186
ChargePin10ms(TriPinRL,1);
// else: discharge for P-channel (Gate to VCC)
3187
adc.lp_otr = ReadADC(LowPin);
// read voltage of Low-Pin again
3188
}
3189
3190
#if DebugOut == 5
3191
lcd_line2();
3192
lcd_clear_line();
3193
lcd_line2();
3194
#endif
3195
3196
//if(adc.lp_otr > 92) { // there is some current without TristatePin current
3197
if
(adc.lp_otr > 455) {
// there is more than 650uA current without TristatePin current
3198
#if DebugOut == 5
3199
lcd_testpin(LowPin);
3200
lcd_data(
'F'
);
3201
lcd_testpin(HighPin);
3202
lcd_space();
3203
wait_about1s();
3204
#endif
3205
3206
// Test if N-JFET or if self-conducting N-MOSFET
3207
R_DDR = LoPinRL | TriPinRH;
// switch R_H for Tristate-Pin (probably Gate) to GND
3208
adc.lp1 = W20msReadADC(LowPin);
// measure voltage at the assumed Source
3209
adc.tp1 = ReadADC(TristatePin);
// measure Gate voltage
3210
R_PORT = TriPinRH;
// switch R_H for Tristate-Pin (probably Gate) to VCC
3211
adc.lp2 = W20msReadADC(LowPin);
// measure voltage at the assumed Source again
3212
3213
// If it is a self-conducting MOSFET or JFET, then must be: adc.lp2 > adc.lp1
3214
if
(adc.lp2>(adc.lp1+488)) {
3215
if
(PartFound != PART_FET) {
3216
// measure voltage at the Gate, differ between MOSFET and JFET
3217
ADC_PORT = TXD_VAL;
3218
ADC_DDR = LoADCm;
// Low-Pin fix to GND
3219
R_DDR = TriPinRH | HiPinRL;
// High-Pin to output
3220
R_PORT = TriPinRH | HiPinRL;
// switch R_L for High-Pin to VCC
3221
adc.lp2 = W20msReadADC(TristatePin);
// read voltage of assumed Gate
3222
3223
if
(adc.lp2>3911) {
// MOSFET
3224
PartFound = PART_FET;
// N-Kanal-MOSFET
3225
PartMode = PART_MODE_N_D_MOS;
// Depletion-MOSFET
3226
}
else
{
// JFET (pn-passage between Gate and Source is conducting )
3227
PartFound = PART_FET;
// N-Kanal-JFET
3228
PartMode = PART_MODE_N_JFET;
3229
}
3230
3231
#if DebugOut == 5
3232
lcd_data(
'N'
);
3233
lcd_data(
'J'
);
3234
#endif
3235
3236
//if ((PartReady == 0) || (adc.lp1 > trans.uBE[0]))
3237
// there is no way to find out the right Source / Drain
3238
trans.uBE[0] = adc.lp1;
3239
gthvoltage = adc.lp1 - adc.tp1;
// voltage GS (Source - Gate)
3240
trans.uBE[1] = (unsigned
int
)(((unsigned
long
)adc.lp1 * 1000) / RR680MI);
// Id 0.01mA
3241
trans.b = TristatePin;
// save Pin numbers found for this FET
3242
trans.c = HighPin;
3243
trans.e = LowPin;
3244
}
3245
}
3246
3247
ADC_PORT = TXD_VAL;
// direct outputs to GND
3248
3249
// Test, if P-JFET or if self-conducting P-MOSFET
3250
ADC_DDR = LoADCm;
// switch Low-Pin (assumed Drain) direct to GND,
3251
// R_H for Tristate-Pin (assumed Gate) is already switched to VCC
3252
R_DDR = TriPinRH | HiPinRL;
// High-Pin to output
3253
R_PORT = TriPinRH | HiPinRL;
// High-Pin across R_L to Vcc
3254
adc.hp1 = W20msReadADC(HighPin);
// measure voltage at assumed Source
3255
adc.tp1 = ReadADC(TristatePin);
// measure Gate voltage
3256
R_PORT = HiPinRL;
// switch R_H for Tristate-Pin (assumed Gate) to GND
3257
adc.hp2 = W20msReadADC(HighPin);
// read voltage at assumed Source again
3258
3259
// if it is a self-conducting P_MOSFET or P-JFET , then must be: adc.hp1 > adc.hp2
3260
if
(adc.hp1>(adc.hp2+488)) {
3261
if
(PartFound != PART_FET) {
3262
// read voltage at the Gate , to differ between MOSFET and JFET
3263
ADC_PORT = HiADCp;
// switch High-Pin directly to VCC
3264
ADC_DDR = HiADCm;
// switch High-Pin to output
3265
adc.tp2 = W20msReadADC(TristatePin);
//read voltage at the assumed Gate
3266
3267
if
(adc.tp2<977) {
// MOSFET
3268
PartFound = PART_FET;
// P-Kanal-MOSFET
3269
PartMode = PART_MODE_P_D_MOS;
// Depletion-MOSFET
3270
}
else
{
// JFET (pn-passage between Gate and Source is conducting)
3271
PartFound = PART_FET;
// P-Kanal-JFET
3272
PartMode = PART_MODE_P_JFET;
3273
}
3274
3275
#if DebugOut == 5
3276
lcd_data(
'P'
);
3277
lcd_data(
'J'
);
3278
#endif
3279
3280
gthvoltage = adc.tp1 - adc.hp1;
// voltage GS (Gate - Source)
3281
trans.uBE[1] = (unsigned
int
)(((unsigned
long
)(ADCconfig.U_AVCC - adc.hp1) * 1000) / RR680PL);
// Id 0.01mA
3282
trans.b = TristatePin;
// save Pin numbers found for this FET
3283
trans.c = LowPin;
3284
trans.e = HighPin;
3285
}
3286
}
3287
}
// end component has current without TristatePin signal
3288
3289
3290
#ifdef COMMON_COLLECTOR
3291
// Test circuit with common collector (Emitter follower) PNP
3292
ADC_PORT = TXD_VAL;
3293
ADC_DDR = LoADCm;
// Collector direct to GND
3294
R_PORT = HiPinRL;
// switch R_L port for HighPin (Emitter) to VCC
3295
R_DDR = TriPinRL | HiPinRL;
// Base resistor R_L to GND
3296
adc.hp1 = ADCconfig.U_AVCC - W5msReadADC(HighPin);
// voltage at the Emitter resistor
3297
adc.tp1 = ReadADC(TristatePin);
// voltage at the base resistor
3298
3299
if
(adc.tp1 < 10) {
3300
R_DDR = TriPinRH | HiPinRL;
// Tripin=RH-
3301
adc.hp1 = ADCconfig.U_AVCC - W5msReadADC(HighPin);
3302
adc.tp1 = ReadADC(TristatePin);
// voltage at base resistor
3303
3304
#ifdef LONG_HFE
3305
c_hfe = ((unsigned
long
)adc.hp1 * (unsigned
long
)(((unsigned
long
)R_H_VAL * 100) /
3306
(unsigned
int
)RR680PL)) / (unsigned
int
)adc.tp1;
3307
#else
3308
c_hfe = ((adc.hp1 / ((RR680PL+500)/1000)) * (R_H_VAL/500)) / (adc.tp1/500);
3309
#endif
3310
3311
}
else
{
3312
c_hfe = (unsigned
long
)((adc.hp1 - adc.tp1) / adc.tp1);
3313
}
3314
#endif
3315
3316
// set Pins again for circuit with common Emitter PNP
3317
R_DDR = LoPinRL;
// switch R_L port for Low-Pin to output (GND)
3318
R_PORT = 0;
// switch all resistor ports to GND
3319
ADC_DDR = HiADCm;
// switch High-Pin to output
3320
ADC_PORT = HiADCp;
// switch High-Pin to VCC
3321
wait_about5ms();
3322
3323
if
(adc.lp_otr < 977) {
3324
// if the component has no connection between HighPin and LowPin
3325
3326
#if DebugOut == 5
3327
lcd_testpin(LowPin);
3328
lcd_data(
'P'
);
3329
lcd_testpin(HighPin);
3330
lcd_space();
3331
wait_about1s();
3332
#endif
3333
3334
// Test to PNP
3335
R_DDR = LoPinRL | TriPinRL;
// switch R_L port for Tristate-Pin to output (GND), for Test of PNP
3336
adc.lp1 = W5msReadADC(LowPin);
// measure voltage at LowPin
3337
3338
if
(adc.lp1 > 3422) {
3339
// component has current => PNP-Transistor or equivalent
3340
// compute current amplification factor in both directions
3341
R_DDR = LoPinRL | TriPinRH;
// switch R_H port for Tristate-Pin (Base) to output (GND)
3342
3343
adc.lp1 = W5msReadADC(LowPin);
// measure voltage at LowPin (assumed Collector)
3344
adc.tp2 = ReadADC(TristatePin);
// measure voltage at TristatePin (Base)
3345
3346
// check, if Test is done before
3347
if
((PartFound == PART_TRANSISTOR) || (PartFound == PART_FET)) {
3348
PartReady = 1;
3349
}
3350
3351
#ifdef COMMON_EMITTER
3352
trans.uBE[PartReady] = ReadADC(HighPin) - adc.tp2;
// Base Emitter Voltage
3353
3354
// compute current amplification factor for circuit with common Emitter
3355
// hFE = B = Collector current / Base current
3356
3357
if
(adc.tp2 < 53) {
3358
#if DebugOut == 5
3359
lcd_data(
'<'
);
3360
lcd_data(
'5'
);
3361
lcd_data(
'3'
);
3362
#endif
3363
3364
adc.tp2 = 53;
3365
}
3366
tmp16 = adc.lp1;
3367
3368
if
(tmp16 > adc.lp_otr) {
3369
tmp16 -= adc.lp_otr;
3370
}
3371
3372
#ifdef LONG_HFE
3373
trans.hfe[PartReady] = ((unsigned
int
)tmp16 * (unsigned
long
)(((unsigned
long
)R_H_VAL * 100) /
3374
(unsigned
int
)RR680MI)) / (unsigned
int
)adc.tp2;
3375
#else
3376
trans.hfe[PartReady] = ((tmp16 / ((RR680MI+500)/1000)) * (R_H_VAL/500)) / (adc.tp2/500);
3377
#endif
3378
#endif
3379
3380
#ifdef COMMON_COLLECTOR
3381
// current amplification factor for common Collector (Emitter follower)
3382
// c_hFE = (Emitter current - Base current) / Base current
3383
#ifdef COMMON_EMITTER
3384
if
(c_hfe > trans.hfe[PartReady]) {
3385
#endif
3386
trans.hfe[PartReady] = c_hfe;
3387
trans.uBE[PartReady] = ADCconfig.U_AVCC - adc.hp1 - adc.tp1;
// Base Emitter Voltage common collector
3388
#ifdef COMMON_EMITTER
3389
}
3390
#endif
3391
#endif
3392
3393
3394
if
(PartFound != PART_THYRISTOR) {
3395
if
(adc.tp2 > 977) {
3396
// PNP-Transistor is found (Base voltage moves to VCC)
3397
PartFound = PART_TRANSISTOR;
3398
PartMode = PART_MODE_PNP;
3399
}
else
{
3400
if
((adc.lp_otr < 97) && (adc.lp1 > 2000)) {
3401
// is flow voltage low enough in the closed state?
3402
// (since D-Mode-FET would be by mistake detected as E-Mode )
3403
PartFound = PART_FET;
// P-Kanal-MOSFET is found (Basis/Gate moves not to VCC)
3404
PartMode = PART_MODE_P_E_MOS;
3405
3406
// measure the Gate threshold voltage
3407
// Switching of Drain is monitored with digital input
3408
// Low level is specified up to 0.3 * VCC
3409
// High level is specified above 0.6 * VCC
3410
PinMSK = LoADCm & 7;
3411
ADMUX = TristatePin | (1<<REFS0);
// switch to TristatePin, Ref. VCC
3412
gthvoltage = 1;
// round up ((1*4)/9)
3413
3414
for
(ii=0;ii<11;ii++) {
3415
wdt_reset();
3416
ChargePin10ms(TriPinRL,1);
3417
R_DDR = LoPinRL | TriPinRH;
// switch R_H for Tristate-Pin (Basis) to GND
3418
3419
while
(!(ADC_PIN&PinMSK));
// Wait, until the MOSFET switches and Drain moves to VCC
3420
// 1 is detected with more than 2.5V (up to 2.57V) with tests of mega168 and mega328
3421
R_DDR = LoPinRL;
3422
ADCSRA |= (1<<ADSC);
// Start Conversion
3423
3424
while
(ADCSRA&(1<<ADSC));
// wait
3425
3426
gthvoltage += (1023 - ADCW);
// Add Tristatepin-Voltage
3427
}
3428
3429
gthvoltage *= 4;
// is equal to 44*ADCW
3430
gthvoltage /= 9;
// gives resolution in mV
3431
}
3432
}
3433
3434
trans.b = TristatePin;
3435
trans.c = LowPin;
3436
trans.e = HighPin;
3437
}
// end if PartFound != PART_THYRISTOR
3438
}
// end component has current => PNP
3439
3440
#ifdef COMMON_COLLECTOR
3441
// Low-Pin=RL- HighPin=VCC
3442
R_DDR = LoPinRL | TriPinRL;
3443
R_PORT = TriPinRL;
// TriPin=RL+ NPN with common Collector
3444
adc.lp1 = W5msReadADC(LowPin);
// voltage at Emitter resistor
3445
adc.tp1 = ADCconfig.U_AVCC - ReadADC(TristatePin);
// voltage at Base resistor
3446
3447
if
(adc.tp1 < 10) {
3448
R_DDR = LoPinRL | TriPinRH;
3449
R_PORT = TriPinRH;
// Tripin=RH+
3450
adc.lp1 = W5msReadADC(LowPin);
3451
adc.tp1 = ADCconfig.U_AVCC - ReadADC(TristatePin);
// voltage at Base resistor
3452
3453
#ifdef LONG_HFE
3454
c_hfe = ((unsigned
long
)adc.lp1 * (unsigned
long
)(((unsigned
long
)R_H_VAL * 100) /
3455
(unsigned
int
)RR680MI)) / (unsigned
int
)adc.tp1;
3456
#else
3457
c_hfe = ((adc.lp1 / ((RR680MI+500)/1000)) * (R_H_VAL/500)) / (adc.tp2/500);
3458
#endif
3459
3460
}
else
{
3461
c_hfe = (adc.lp1 - adc.tp1) / adc.tp1;
3462
}
3463
3464
#if DebugOut == 5
3465
lcd_line4();
3466
lcd_clear_line();
3467
lcd_line4();
3468
lcd_data(
'L'
);
3469
lcd_data(
'P'
);
3470
lcd_string(utoa(adc.lp1,outval,10));
3471
lcd_space();
3472
lcd_data(
'T'
);
3473
lcd_data(
'P'
);
3474
lcd_string(utoa(adc.tp1,outval,10));
3475
wait_about1s();
3476
#endif
3477
#endif
3478
3479
// Tristate (can be Base) to VCC, Test if NPN
3480
ADC_DDR = LoADCm;
// Low-Pin to output 0V
3481
ADC_PORT = TXD_VAL;
// switch Low-Pin to GND
3482
R_DDR = TriPinRL | HiPinRL;
// RL port for High-Pin and Tristate-Pin to output
3483
R_PORT = TriPinRL | HiPinRL;
// RL port for High-Pin and Tristate-Pin to Vcc
3484
adc.hp1 = W5msReadADC(HighPin);
// measure voltage at High-Pin (Collector)
3485
3486
if
(adc.hp1 < 1600) {
3487
// component has current => NPN-Transistor or somthing else
3488
3489
#if DebugOut == 5
3490
lcd_testpin(LowPin);
3491
lcd_data(
'N'
);
3492
lcd_testpin(HighPin);
3493
lcd_space();
3494
wait_about1s();
3495
#endif
3496
3497
if
(PartReady==1) {
3498
goto
widmes;
3499
}
3500
3501
// Test auf Thyristor:
3502
// Gate discharge
3503
ChargePin10ms(TriPinRL,0);
// Tristate-Pin (Gate) across R_L 10ms to GND
3504
adc.hp3 = W5msReadADC(HighPin);
// read voltage at High-Pin (probably Anode) again
3505
// current should still flow, if not,
3506
// no Thyristor or holding current to low
3507
3508
R_PORT = 0;
// switch R_L for High-Pin (probably Anode) to GND (turn off)
3509
wait_about5ms();
3510
R_PORT = HiPinRL;
// switch R_L for High-Pin (probably Anode) again to VCC
3511
adc.hp2 = W5msReadADC(HighPin);
// measure voltage at the High-Pin (probably Anode) again
3512
3513
if
((adc.hp3 < 1600) && (adc.hp2 > 4400)) {
3514
// if the holding current was switched off the thyristor must be switched off too.
3515
// if Thyristor was still swiched on, if gate was switched off => Thyristor
3516
PartFound = PART_THYRISTOR;
3517
3518
// Test if Triac
3519
R_DDR = 0;
3520
R_PORT = 0;
3521
ADC_PORT = LoADCp;
// Low-Pin fix to VCC
3522
wait_about5ms();
3523
3524
R_DDR = HiPinRL;
// switch R_L port HighPin to output (GND)
3525
if
(W5msReadADC(HighPin) > 244) {
3526
goto
savenresult;
// measure voltage at the High-Pin (probably A2); if too high:
3527
// component has current => kein Triac
3528
}
3529
3530
R_DDR = HiPinRL | TriPinRL;
// switch R_L port for TristatePin (Gate) to output (GND) => Triac should be triggered
3531
if
(W5msReadADC(TristatePin) < 977) {
3532
goto
savenresult;
// measure voltage at the Tristate-Pin (probably Gate) ;
3533
// if to low, abort
3534
}
3535
3536
if
(ReadADC(HighPin) < 733) {
3537
goto
savenresult;
// component has no current => no Triac => abort
3538
}
3539
3540
R_DDR = HiPinRL;
// TristatePin (Gate) to input
3541
if
(W5msReadADC(HighPin) < 733) {
3542
goto
savenresult;
// component has no current without base current => no Triac => abort
3543
}
3544
3545
R_PORT = HiPinRL;
// switch R_L port for HighPin to VCC => switch off holding current
3546
wait_about5ms();
3547
R_PORT = 0;
// switch R_L port for HighPin again to GND; Triac should now switched off
3548
if
(W5msReadADC(HighPin) > 244) {
3549
goto
savenresult;
// measure voltage at the High-Pin (probably A2) ;
3550
// if to high, component is not switched off => no Triac, abort
3551
}
3552
3553
PartFound = PART_TRIAC;
3554
PartReady = 1;
3555
goto
savenresult;
3556
}
3557
3558
// Test if NPN Transistor or MOSFET
3559
//ADC_DDR = LoADCm; // Low-Pin to output 0V
3560
R_DDR = HiPinRL | TriPinRH;
// R_H port of Tristate-Pin (Basis) to output
3561
R_PORT = HiPinRL | TriPinRH;
// R_H port of Tristate-Pin (Basis) to VCC
3562
wait_about50ms();
3563
adc.hp2 = ADCconfig.U_AVCC - ReadADC(HighPin);
// measure the voltage at the collector resistor
3564
adc.tp2 = ADCconfig.U_AVCC - ReadADC(TristatePin);
// measure the voltage at the base resistor
3565
3566
#if DebugOut == 5
3567
lcd_line3();
3568
lcd_clear_line();
3569
lcd_line3();
3570
lcd_data(
'H'
);
3571
lcd_data(
'P'
);
3572
lcd_string(utoa(adc.hp2,outval,10));
3573
lcd_space();
3574
lcd_data(
'T'
);
3575
lcd_data(
'P'
);
3576
lcd_string(utoa(adc.tp2,outval,10));
3577
#endif
3578
3579
if
((PartFound == PART_TRANSISTOR) || (PartFound == PART_FET)) {
3580
PartReady = 1;
// check, if test is already done once
3581
}
3582
3583
#ifdef COMMON_EMITTER
3584
trans.uBE[PartReady] = ADCconfig.U_AVCC - adc.tp2 - ReadADC(LowPin);
3585
3586
// compute current amplification factor for common Emitter
3587
// hFE = B = Collector current / Base current
3588
if
(adc.tp2 < 53) {
3589
3590
#if DebugOut == 5
3591
lcd_data(
'<'
);
3592
lcd_data(
'5'
);
3593
lcd_data(
'3'
);
3594
#endif
3595
3596
adc.tp2 = 53;
3597
}
3598
3599
tmp16 = adc.hp2;
3600
if
(tmp16 > adc.lp_otr) {
3601
tmp16 -= adc.lp_otr;
3602
}
3603
3604
#ifdef LONG_HFE
3605
trans.hfe[PartReady] = ((unsigned
int
)tmp16 * (unsigned
long
)(((unsigned
long
)R_H_VAL * 100) /
3606
(unsigned
int
)RR680PL)) / (unsigned
int
)adc.tp2;
3607
#else
3608
trans.hfe[PartReady] = ((tmp16 / ((RR680PL+500)/1000)) * (R_H_VAL/500)) / (adc.tp2/500);
3609
#endif
3610
#endif
3611
3612
#ifdef COMMON_COLLECTOR
3613
// compare current amplification factor for common Collector (Emitter follower)
3614
// hFE = (Emitterstrom - Basisstrom) / Basisstrom
3615
3616
#ifdef COMMON_EMITTER
3617
if
(c_hfe > trans.hfe[PartReady]) {
3618
#endif
3619
trans.hfe[PartReady] = c_hfe;
3620
trans.uBE[PartReady] = ADCconfig.U_AVCC - adc.lp1 - adc.tp1;
3621
#ifdef COMMON_EMITTER
3622
}
3623
#endif
3624
#endif
3625
3626
if
(adc.tp2 > 2557) {
// Basis-voltage R_H is low enough
3627
PartFound = PART_TRANSISTOR;
// NPN-Transistor is found (Base is near GND)
3628
PartMode = PART_MODE_NPN;
3629
}
else
{
// Basis has low current
3630
if
((adc.lp_otr < 97) && (adc.hp2 > 3400)) {
3631
// if flow voltage in switched off mode low enough?
3632
// (since D-Mode-FET will be detected in error as E-Mode )
3633
PartFound = PART_FET;
// N-Kanal-MOSFET is found (Basis/Gate will Not be pulled down)
3634
PartMode = PART_MODE_N_E_MOS;
3635
3636
#if DebugOut == 5
3637
lcd_line3();
3638
lcd_clear_line();
3639
lcd_line3();
3640
lcd_data(
'N'
);
3641
lcd_data(
'F'
);
3642
wait_about1s();
3643
#endif
3644
3645
// Switching of Drain is monitored with digital input
3646
// Low level is specified up to 0.3 * VCC
3647
// High level is specified above 0.6 * VCC
3648
PinMSK = HiADCm & 7;
3649
3650
// measure Threshold voltage of Gate
3651
ADMUX = TristatePin | (1<<REFS0);
// measure TristatePin, Ref. VCC
3652
gthvoltage = 1;
// round up ((1*4)/9)
3653
3654
for
(ii=0;ii<11;ii++) {
3655
wdt_reset();
3656
ChargePin10ms(TriPinRL,0);
// discharge Gate 10ms with RL
3657
R_DDR = HiPinRL | TriPinRH;
// slowly charge Gate
3658
R_PORT = HiPinRL | TriPinRH;
3659
while
((ADC_PIN&PinMSK));
// Wait, until the MOSFET switch and Drain moved to low
3660
// 0 is detected with input voltage of 2.12V to 2.24V (tested with mega168 & mega328)
3661
R_DDR = HiPinRL;
// switch off current
3662
ADCSRA |= (1<<ADSC);
// start ADC conversion
3663
while
(ADCSRA&(1<<ADSC));
// wait until ADC finished
3664
gthvoltage += ADCW;
// add result of ADC
3665
}
3666
3667
gthvoltage *= 4;
// is equal to 44 * ADCW
3668
gthvoltage /= 9;
// scale to mV
3669
}
3670
}
3671
3672
savenresult:
3673
trans.b = TristatePin;
// save Pin-constellation
3674
trans.c = HighPin;
3675
trans.e = LowPin;
3676
}
// end component conduct => npn
3677
3678
ADC_DDR = TXD_MSK;
// switch all ADC-Ports to input
3679
ADC_PORT = TXD_VAL;
// switch all ADC-Ports to 0 (no Pull up)
3680
3681
// Finish
3682
// end component has no connection between HighPin and LowPin
3683
goto
widmes;
3684
}
3685
3686
// component has current
3687
// Test if Diode
3688
ADC_PORT = TXD_VAL;
3689
3690
for
(ii=0;ii<200;ii++) {
3691
ADC_DDR = LoADCm | HiADCm;
// discharge by short of Low and High side
3692
wait_about5ms();
// Low and Highpin to GND for discharge
3693
ADC_DDR = LoADCm;
// switch only Low-Pin fix to GND
3694
adc.hp1 = ReadADC(HighPin);
// read voltage at High-Pin
3695
if
(adc.hp1 < (150/8))
break
;
3696
}
3697
3698
/*
3699
It is possible, that wrong Parts are detected without discharging, because
3700
the gate of a MOSFET can be charged.
3701
The additional measurement with the big resistor R_H is made, to differ antiparallel diodes
3702
from resistors.
3703
A diode has a voltage, that is nearly independent from the current.
3704
The voltage of a resistor is proportional to the current.
3705
*/
3706
3707
#if 0
3708
// first check with higher current (R_L=680)
3709
// A diode is found better with a parallel mounted capacitor,
3710
// but some capacitors can be detected a a diode.
3711
R_DDR = HiPinRL;
// switch R_L port for High-Pin to output (VCC)
3712
R_PORT = HiPinRL;
3713
ChargePin10ms(TriPinRL,1);
// discharge of P-Kanal-MOSFET gate
3714
adc.lp_otr = W5msReadADC(HighPin) - ReadADC(LowPin);
3715
R_DDR = HiPinRH;
// switch R_H port for High-Pin output (VCC)
3716
R_PORT = HiPinRH;
3717
adc.hp2 = W5msReadADC(HighPin);
// M--|<--HP--R_H--VCC
3718
3719
R_DDR = HiPinRL;
// switch R_L port for High-Pin to output (VCC)
3720
R_PORT = HiPinRL;
3721
ChargePin10ms(TriPinRL,0);
// discharge for N-Kanal-MOSFET gate
3722
adc.hp1 = W5msReadADC(HighPin) - W5msReadADC(LowPin);
3723
R_DDR = HiPinRH;
// switch R_H port for High-Pin to output (VCC)
3724
R_PORT = HiPinRH;
3725
adc.hp3 = W5msReadADC(HighPin);
// M--|<--HP--R_H--VCC
3726
3727
if
(adc.lp_otr > adc.hp1) {
3728
adc.hp1 = adc.lp_otr;
// the higher value wins
3729
adc.hp3 = adc.hp2;
3730
}
3731
#else
3732
// check first with low current (R_H=470k)
3733
// With this method the diode can be better differed from a capacitor,
3734
// but a parallel to a capacitor mounted diode can not be found.
3735
R_DDR = HiPinRH;
// switch R_H port for High-Pin output (VCC)
3736
R_PORT = HiPinRH;
3737
ChargePin10ms(TriPinRL,1);
// discharge of P-Kanal-MOSFET gate
3738
adc.hp2 = W5msReadADC(HighPin);
// M--|<--HP--R_H--VCC
3739
ChargePin10ms(TriPinRL,0);
// discharge for N-Kanal-MOSFET gate
3740
adc.hp3 = W5msReadADC(HighPin);
// M--|<--HP--R_H--VCC
3741
3742
// check with higher current (R_L=680)
3743
R_DDR = HiPinRL;
// switch R_L port for High-Pin to output (VCC)
3744
R_PORT = HiPinRL;
3745
adc.hp1 = W5msReadADC(HighPin) - ReadADC(LowPin);
3746
ChargePin10ms(TriPinRL,1);
// discharge for N-Kanal-MOSFET gate
3747
adc.lp_otr = W5msReadADC(HighPin) - ReadADC(LowPin);
3748
3749
R_DDR = HiPinRH;
// switch R_H port for High-Pin output (VCC)
3750
R_PORT = HiPinRH;
3751
3752
if
(adc.lp_otr > adc.hp1) {
3753
adc.hp1 = adc.lp_otr;
// the higher value wins
3754
adc.hp3 = adc.hp2;
3755
}
else
{
3756
ChargePin10ms(TriPinRL,0);
// discharge for N-Kanal-MOSFET gate
3757
}
3758
3759
adc.hp2 = W5msReadADC(HighPin);
// M--|<--HP--R_H--VCC
3760
#endif
3761
3762
#if DebugOut == 4
3763
lcd_line3();
3764
lcd_clear_line();
3765
lcd_line3();
3766
lcd_testpin(HighPin);
3767
lcd_data(
'D'
);
3768
lcd_testpin(LowPin);
3769
lcd_space();
3770
lcd_data(
'h'
);
3771
lcd_string(utoa(adc.hp3,outval,10));
3772
lcd_space();
3773
lcd_data(
'L'
);
3774
lcd_string(utoa(adc.hp1,outval,10));
3775
lcd_space();
3776
lcd_data(
'H'
);
3777
lcd_string(utoa(adc.hp2,outval,10));
3778
lcd_space();
3779
wait_about1s();
3780
#endif
3781
3782
//if((adc.hp1 > 150) && (adc.hp1 < 4640) && (adc.hp1 > (adc.hp3+(adc.hp3/8))) && (adc.hp3*8 > adc.hp1)) {
3783
if
((adc.hp1 > 150) && (adc.hp1 < 4640) && (adc.hp2 < adc.hp1) && (adc.hp1 > (adc.hp3+(adc.hp3/8))) && (adc.hp3*16 > adc.hp1)) {
3784
// voltage is above 0,15V and below 4,64V => Ok
3785
if
((PartFound == PART_NONE) || (PartFound == PART_RESISTOR)) {
3786
PartFound = PART_DIODE;
// mark for diode only, if no other component is found
3787
// since there is a problem with Transistors with a protection diode
3788
#if DebugOut == 4
3789
lcd_data(
'D'
);
3790
#endif
3791
}
3792
3793
diodes[NumOfDiodes].Anode = HighPin;
3794
diodes[NumOfDiodes].Cathode = LowPin;
3795
diodes[NumOfDiodes].Voltage = adc.hp1;
// voltage in Millivolt
3796
NumOfDiodes++;
3797
}
// end voltage is above 0,15V and below 4,64V
3798
3799
#if DebugOut == 4
3800
lcd_data(NumOfDiodes+
'0'
);
3801
#endif
3802
3803
widmes:
3804
if
(NumOfDiodes > 0)
goto
clean_ports;
3805
// resistor measurement
3806
wdt_reset();
3807
3808
// U_SCALE can be set to 4 for better resolution of ReadADC result
3809
#if U_SCALE != 1
3810
ADCconfig.U_AVCC *= U_SCALE;
// scale to higher resolution, mV scale is not required
3811
ADCconfig.U_Bandgap *= U_SCALE;
3812
#endif
3813
3814
#if R_ANZ_MESS != ANZ_MESS
3815
ADCconfig.Samples = R_ANZ_MESS;
// switch to special number of repetitions
3816
#endif
3817
3818
#define MAX_REPEAT (700 / (5 + R_ANZ_MESS/8))
3819
3820
ADC_PORT = TXD_VAL;
3821
ADC_DDR = LoADCm;
// switch Low-Pin to output (GND)
3822
R_DDR = HiPinRL;
// switch R_L port for High-Pin to output (VCC)
3823
R_PORT = HiPinRL;
3824
3825
#if FLASHEND > 0x1fff
3826
adc.hp2 = 0;
3827
3828
for
(ii=1;ii<MAX_REPEAT;ii++) {
3829
// wait until voltage is stable
3830
adc.tp1 = W5msReadADC(LowPin);
// low-voltage at Rx with load
3831
adc.hp1 = ReadADC(HighPin);
// voltage at resistor Rx with R_L
3832
udiff = adc.hp1 - adc.hp2;
3833
if
(udiff < 0) udiff = -udiff;
3834
if
(udiff < 3)
break
;
3835
adc.hp2 = adc.hp1;
3836
wdt_reset();
3837
}
3838
3839
if
(ii == MAX_REPEAT)
goto
testend;
3840
#else
3841
adc.tp1 = W5msReadADC(LowPin);
// low-voltage at Rx with load
3842
adc.hp1 = ReadADC(HighPin);
// voltage at resistor Rx with R_L
3843
#endif
3844
3845
if
(adc.tp1 > adc.hp1) {
3846
adc.tp1 = adc.hp1;
3847
}
3848
3849
R_PORT = 0;
3850
R_DDR = HiPinRH;
// switch R_H port for High-Pin to output (GND)
3851
adc.hp2 = W5msReadADC(HighPin);
// read voltage, should be down
3852
3853
if
(adc.hp2 > (20*U_SCALE)) {
3854
// if resistor, voltage should be down
3855
3856
#if DebugOut == 3
3857
lcd_line3();
3858
lcd_clear_line();
3859
lcd_line3();
3860
lcd_testpin(LowPin);
3861
lcd_data(
'U'
);
3862
lcd_testpin(HighPin);
3863
lcd_data(
'A'
);
3864
lcd_string(utoa(adc.hp1, outval, 10));
3865
lcd_data(
'B'
);
3866
lcd_string(utoa(adc.hp2, outval, 10));
3867
lcd_space();
3868
#endif
3869
3870
goto
testend;
3871
}
3872
3873
R_PORT = HiPinRH;
// switch R_H for High-Pin to VCC
3874
adc.hp2 = W5msReadADC(HighPin);
// voltage at resistor Rx with R_H
3875
3876
ADC_DDR = HiADCm;
// switch High-Pin to output
3877
ADC_PORT = HiADCp;
// switch High-Pin to VCC
3878
R_PORT = 0;
3879
R_DDR = LoPinRL;
// switch R_L for Low-Pin to GND
3880
3881
#if FLASHEND > 0x1fff
3882
adc.lp2 = 0;
3883
3884
for
(ii=1;ii<MAX_REPEAT;ii++) {
3885
// wait until voltage is stable
3886
adc.tp2 = W5msReadADC(HighPin);
// high voltage with load
3887
adc.lp1 = ReadADC(LowPin);
// voltage at the other end of Rx
3888
udiff = adc.lp1 - adc.lp2;
3889
if
(udiff < 0) udiff = -udiff;
3890
if
(udiff < 3)
break
;
3891
adc.lp2 = adc.lp1;
3892
wdt_reset();
3893
}
3894
3895
if
(ii == MAX_REPEAT)
goto
testend;
3896
#else
3897
adc.tp2 = W5msReadADC(HighPin);
// high voltage with load
3898
adc.lp1 = ReadADC(LowPin);
// voltage at the other end of Rx
3899
#endif
3900
3901
if
(adc.tp2 < adc.lp1) {
3902
adc.tp2 = adc.lp1;
3903
}
3904
3905
R_DDR = LoPinRH;
// switch R_H for Low-Pin to GND
3906
adc.lp2 = W5msReadADC(LowPin);
3907
3908
if
((adc.hp1 < (4400*U_SCALE)) && (adc.hp2 > (97*U_SCALE))) {
3909
//voltage break down isn't insufficient
3910
3911
#if DebugOut == 3
3912
lcd_data(
'F'
);
3913
#endif
3914
3915
goto
testend;
3916
}
3917
3918
//if ((adc.hp2 + (adc.hp2 / 61)) < adc.hp1)
3919
if
(adc.hp2 < (4972*U_SCALE)) {
3920
// voltage breaks down with low test current and it is not nearly shorted => resistor
3921
//if (adc.lp1 < 120) { // take measurement with R_H
3922
if
(adc.lp1 < (169*U_SCALE)) {
// take measurement with R_H
3923
ii =
'H'
;
3924
3925
if
(adc.lp2 < (38*U_SCALE)) {
3926
// measurement > 60MOhm to big resistance
3927
goto
testend;
3928
}
3929
3930
// two measurements with R_H resistors (470k) are made:
3931
// lirx1 (measurement at HighPin)
3932
lirx1 = (unsigned
long
)((unsigned
int
)R_H_VAL) * (unsigned
long
)adc.hp2 / (ADCconfig.U_AVCC - adc.hp2);
3933
// lirx2 (measurement at LowPin)
3934
lirx2 = (unsigned
long
)((unsigned
int
)R_H_VAL) * (unsigned
long
)(ADCconfig.U_AVCC - adc.lp2) / adc.lp2;
3935
3936
#define U_INT_LIMIT (990*U_SCALE) // 1V switch limit in ReadADC for atmega family
3937
3938
#ifdef __AVR_ATmega8__
3939
#define FAKT_LOW 2 // resolution is about twice as good
3940
#else
3941
#define FAKT_LOW 4 // resolution is about four times better
3942
#endif
3943
3944
#ifdef AUTOSCALE_ADC
3945
if
(adc.hp2 < U_INT_LIMIT) {
3946
lrx1 = (lirx1*FAKT_LOW + lirx2) / (FAKT_LOW+1);
// weighted average of both R_H measurements
3947
}
else
if
(adc.lp2 < U_INT_LIMIT){
3948
lrx1 = (lirx2*FAKT_LOW + lirx1) / (FAKT_LOW+1);
// weighted average of both R_H measurements
3949
}
else
3950
#endif
3951
{
3952
lrx1 = (lirx1 + lirx2) / 2;
// average of both R_H measurements
3953
}
3954
3955
lrx1 *= 100;
3956
lrx1 += RH_OFFSET;
// add constant for correction of systematic error
3957
3958
}
else
{
3959
ii =
'L'
;
3960
// two measurements with R_L resistors (680) are made:
3961
// lirx1 (measurement at HighPin)
3962
3963
if
(adc.tp1 > adc.hp1) {
3964
adc.hp1 = adc.tp1;
// diff negativ is illegal
3965
}
3966
3967
lirx1 =(unsigned
long
)RR680PL * (unsigned
long
)(adc.hp1 - adc.tp1) / (ADCconfig.U_AVCC - adc.hp1);
3968
3969
if
(adc.tp2 < adc.lp1) {
3970
adc.lp1 = adc.tp2;
// diff negativ is illegal
3971
}
3972
3973
// lirx2 (Measurement at LowPin)
3974
lirx2 =(unsigned
long
)RR680MI * (unsigned
long
)(adc.tp2 -adc.lp1) / adc.lp1;
3975
//lrx1 =(unsigned long)R_L_VAL * (unsigned long)adc.hp1 / (adc.hp3 - adc.hp1);
3976
3977
#ifdef AUTOSCALE_ADC
3978
if
(adc.hp1 < U_INT_LIMIT) {
3979
lrx1 = (lirx1*FAKT_LOW + lirx2) / (FAKT_LOW+1);
// weighted average of both R_L measurements
3980
}
else
if
(adc.lp1 < U_INT_LIMIT) {
3981
lrx1 = (lirx2*FAKT_LOW + lirx1) / (FAKT_LOW+1);
// weighted average of both R_L measurements
3982
}
else
3983
#endif
3984
{
3985
lrx1 = (lirx1 + lirx2) / 2;
// average of both R_L measurements
3986
}
3987
}
3988
// lrx1 is tempory result
3989
3990
#if 0
3991
// The zero resistance is in 0.01 Ohm units and usually so little, that correction for resistors above 10 Ohm
3992
// is not necassary
3993
ii = eeprom_read_byte(&EE_ESR_ZEROtab[LowPin+HighPin]) / 10;
// Resistance offset in 0,1 Ohm units
3994
if
(ii < lrx1) {
3995
lrx1 -= ii;
3996
}
else
{
3997
lrx1 = 0;
3998
}
3999
#endif
4000
4001
#if DebugOut == 3
4002
lcd_line3();
4003
lcd_clear_line();
4004
lcd_line3();
4005
lcd_testpin(LowPin);
4006
lcd_data(ii);
4007
lcd_testpin(HighPin);
4008
lcd_space();
4009
4010
if
(ii ==
'H'
) {
4011
lcd_data(
'X'
);
4012
DisplayValue(lirx1,1,LCD_CHAR_OMEGA,4)
4013
lcd_space();
4014
lcd_data(
'Y'
);
4015
DisplayValue(lirx2,1,LCD_CHAR_OMEGA,4)
4016
lcd_space();
4017
}
else
{
4018
lcd_data(
'x'
);
4019
DisplayValue(lirx1,-1,LCD_CHAR_OMEGA,4)
4020
lcd_space();
4021
lcd_data(
'y'
);
4022
DisplayValue(lirx2,-1,LCD_CHAR_OMEGA,4)
4023
}
4024
4025
lcd_space();
4026
lcd_line4();
4027
lcd_clear_line();
4028
lcd_line4();
4029
DisplayValue(lirx2,-1,LCD_CHAR_OMEGA,4)
4030
lcd_space();
4031
lcd_line2();
4032
#endif
4033
4034
if
((PartFound == PART_DIODE) || (PartFound == PART_NONE) || (PartFound == PART_RESISTOR)) {
4035
for
(ii=0; ii<ResistorsFound; ii++) {
4036
// search measurements with inverse polarity
4037
thisR = &resis[ii];
4038
if
(thisR->rt != TristatePin)
continue
;
4039
4040
// must be measurement with inverse polarity
4041
// resolution is 0.1 Ohm, 1 Ohm = 10 !
4042
lirx1 = (labs((
long
)lrx1 - (
long
)thisR->rx) * 10) / (lrx1 + thisR->rx + 100);
4043
4044
if
(lirx1 > 0) {
4045
#if DebugOut == 3
4046
lcd_data(
'R'
);
4047
lcd_data(
'!'
);
4048
lcd_data(
'='
);
4049
DisplayValue(thisR->rx,-1,LCD_CHAR_OMEGA,3)
4050
lcd_space();
4051
DisplayValue(lirx1,-1,LCD_CHAR_OMEGA,3)
4052
lcd_space();
4053
#endif
4054
4055
goto
testend;
// <10% mismatch
4056
}
4057
4058
PartFound = PART_RESISTOR;
4059
goto
testend;
4060
}
// end for
4061
4062
// no same resistor with the same Tristate-Pin found, new one
4063
thisR = &resis[ResistorsFound];
// pointer to a free resistor structure
4064
thisR->rx = lrx1;
// save resistor value
4065
4066
#if FLASHEND > 0x1fff
4067
thisR->lx = 0;
// no inductance
4068
#endif
4069
4070
thisR->ra = LowPin;
// save Pin numbers
4071
thisR->rb = HighPin;
4072
thisR->rt = TristatePin;
// Tristate is saved for easier search of inverse measurement
4073
ResistorsFound++;
// 1 more resistor found
4074
4075
#if DebugOut == 3
4076
lcd_data(ResistorsFound+
'0'
);
4077
lcd_data(
'R'
);
4078
#endif
4079
}
4080
}
4081
4082
testend:
4083
4084
#if U_SCALE != 1
4085
ADCconfig.U_AVCC /= U_SCALE;
// scale back to mV resolution
4086
ADCconfig.U_Bandgap /= U_SCALE;
4087
#endif
4088
4089
#if R_ANZ_MESS != ANZ_MESS
4090
ADCconfig.Samples = ANZ_MESS;
// switch back to standard number of repetition
4091
#endif
4092
4093
#ifdef DebugOut
4094
#if DebugOut < 10
4095
wait_about2s();
4096
#endif
4097
#endif
4098
4099
clean_ports:
4100
4101
ADC_DDR = TXD_MSK;
// all ADC-Pins Input
4102
ADC_PORT = TXD_VAL;
// all ADC outputs to Ground, keine Pull up
4103
R_DDR = 0;
// all resistor-outputs to Input
4104
R_PORT = 0;
// all resistor-outputs to Ground, no Pull up
4105
}
// end CheckPins()
4106
4107
/* -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- */
4108
4109
// Get residual current in reverse direction of a diode
4110
//=================================================================
4111
void
GetIr(uint8_t hipin, uint8_t lopin) {
4112
unsigned
int
u_res;
// reverse voltage at 470k
4113
unsigned
int
ir_nano;
4114
//unsigned int ir_micro;
4115
uint8_t LoPinR_L;
4116
uint8_t HiADC;
4117
4118
HiADC = pgm_read_byte(&PinADCtab[hipin]);
4119
ADC_PORT = HiADC | TXD_VAL;
// switch ADC port to high level
4120
ADC_DDR = HiADC | TXD_MSK;
// switch High Pin direct to VCC
4121
LoPinR_L = pgm_read_byte(&PinRLtab[lopin]);
// R_L mask for LowPin R_L load
4122
R_PORT = 0;
// switch R-Port to GND
4123
R_DDR = LoPinR_L + LoPinR_L;
// switch R_H port for LowPin to output (GND)
4124
4125
u_res = W5msReadADC(lopin);
// read voltage
4126
if
(u_res == 0)
return
;
// no Output, if no current in reverse direction
4127
4128
#ifdef NOK5110
4129
lcd_line4();
4130
#endif
4131
#ifdef LCD2004
4132
lcd_line4();
4133
#endif
4134
4135
lcd_fix_string(Ir_str);
// output text " Ir="
4136
4137
#ifdef WITH_IRMICRO
4138
if
(u_res < 2500) {
4139
#endif
4140
4141
// R_H_VAL has units of 10 Ohm, u_res has units of mV, ir_nano has units of nA
4142
ir_nano = (unsigned
long
)(u_res * 100000UL) / R_H_VAL;
4143
DisplayValue(ir_nano,-9,
'A'
,2);
// output two digits of current with nA units
4144
4145
#ifdef WITH_IRMICRO
4146
}
else
{
4147
R_DDR = LoPinR_L;
// switch R_L port for LowPin to output (GND)
4148
u_res = W5msReadADC(lopin);
// read voltage
4149
ir_nano = 0xffff;
// set to max
4150
// RR680MI has units of 0.1 Ohm, u_res has units of mV, ir_micro has units of uA
4151
ir_micro = (unsigned
long
)(u_res * 10000UL) / RR680MI;
4152
DisplayValue(ir_micro,-6,
'A'
,2);
// output two digits of current in uA units
4153
}
4154
#endif
4155
4156
ADC_DDR = TXD_MSK;
// switch off
4157
ADC_PORT = TXD_VAL;
// switch off
4158
R_DDR = 0;
// switch off current
4159
4160
return
;
4161
}
4162
4163
/* -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- */
4164
4165
/*
4166
extern struct ADCconfig_t{
4167
uint8_t Samples; // number of ADC samples to take
4168
uint8_t RefFlag; // save Reference type VCC of IntRef
4169
uint16_t U_Bandgap; // Reference Voltage in mV
4170
uint16_t U_AVCC; // Voltage of AVCC
4171
} ADCconfig;
4172
*/
4173
4174
#ifdef INHIBIT_SLEEP_MODE
4175
//#define StartADCwait() ADCSRA = (1<<ADSC) | (1<<ADEN) | (1<<ADIF) | AUTO_CLOCK_DIV; /* enable ADC and start */
4176
#define StartADCwait() ADCSRA = StartADCmsk; /* Start conversion */\
4177
while
(ADCSRA & (1 << ADSC))
/* wait until conversion is done */
4178
#else
4179
#define StartADCwait() ADCSRA = (1<<ADEN) | (1<<ADIF) | (1<<ADIE) | AUTO_CLOCK_DIV; /* enable ADC and Interrupt */\
4180
set_sleep_mode(SLEEP_MODE_ADC);\
4181
sleep_mode();
/* Start ADC, return, if ADC has finished */
4182
#endif
4183
4184
unsigned
int
ReadADC (uint8_t Probe) {
4185
unsigned
int
U;
// return value (mV)
4186
uint8_t Samples;
// loop counter
4187
unsigned
long
Value;
// ADC value
4188
Probe |= (1 << REFS0);
// use internal reference anyway
4189
4190
#ifdef AUTOSCALE_ADC
4191
sample:
4192
#endif
4193
4194
ADMUX = Probe;
// set input channel and U reference
4195
4196
#ifdef AUTOSCALE_ADC
4197
// if voltage reference changes, wait for voltage stabilization
4198
if
((Probe & (1 << REFS1)) != 0) {
4199
// switch to 1.1V Reference
4200
#ifdef NO_AREF_CAP
4201
wait100us();
// time for voltage stabilization
4202
#else
4203
wait_about10ms();
// time for voltage stabilization
4204
#endif
4205
}
4206
#endif
4207
4208
// allways do one dummy read of ADC, 112us
4209
StartADCwait();
// start ADC and wait
4210
4211
// sample ADC readings
4212
Value = 0UL;
// reset sampling variable
4213
Samples = 0;
// number of samples to take
4214
4215
while
(Samples < ADCconfig.Samples) {
// take samples
4216
StartADCwait();
// start ADC and wait
4217
Value += ADCW;
// add ADC reading
4218
4219
#ifdef AUTOSCALE_ADC
4220
// auto-switch voltage reference for low readings
4221
if
((Samples == 4) && (ADCconfig.U_Bandgap > 255) && ((uint16_t)Value < 1024) && !(Probe & (1 << REFS1))) {
4222
Probe |= (1 << REFS1);
// select internal bandgap reference
4223
4224
#if PROCESSOR_TYP == 1280
4225
Probe &= ~(1 << REFS0);
// ATmega640/1280/2560 1.1V Reference with REFS0=0
4226
#endif
4227
4228
goto
sample;
// re-run sampling
4229
}
4230
#endif
4231
4232
Samples++;
// one more done
4233
}
4234
4235
#ifdef AUTOSCALE_ADC
4236
// convert ADC reading to voltage - single sample: U = ADC reading * U_ref / 1024
4237
// get voltage of reference used
4238
if
(Probe & (1 << REFS1)) U = ADCconfig.U_Bandgap;
// bandgap reference
4239
else
U = ADCconfig.U_AVCC;
// Vcc reference
4240
#else
4241
U = ADCconfig.U_AVCC;
// Vcc reference
4242
#endif
4243
4244
// convert to voltage
4245
Value *= U;
// ADC readings * U_ref
4246
Value /= 1023;
// / 1024 for 10bit ADC
4247
4248
// de-sample to get average voltage
4249
Value /= ADCconfig.Samples;
4250
U = (unsigned
int
)Value;
4251
return
U;
4252
//return ((unsigned int)(Value / (1023 * (unsigned long)ADCconfig.Samples)));
4253
}
4254
4255
unsigned
int
W5msReadADC (uint8_t Probe) {
4256
wait_about5ms();
4257
return
(ReadADC(Probe));
4258
}
4259
4260
unsigned
int
W10msReadADC (uint8_t Probe) {
4261
wait_about10ms();
4262
return
(ReadADC(Probe));
4263
}
4264
4265
unsigned
int
W20msReadADC (uint8_t Probe) {
4266
wait_about20ms();
4267
return
(ReadADC(Probe));
4268
}
4269
4270
/* -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- */
4271
4272
// new code by K.-H. Kubbeler
4273
// ReadCapacity tries to find the value of a capacitor by measuring the load time.
4274
// first of all the capacitor is discharged.
4275
// Then a series of up to 500 load pulses with 10ms duration each is done across the R_L (680Ohm)
4276
// resistor.
4277
// After each load pulse the voltage of the capacitor is measured without any load current.
4278
// If voltage reaches a value of more than 300mV and is below 1.3V, the capacity can be
4279
// computed from load time and voltage by a interpolating a build in table.
4280
// If the voltage reaches a value of more than 1.3V with only one load pulse,
4281
// another measurement methode is used:
4282
// The build in 16bit counter can save the counter value at external events.
4283
// One of these events can be the output change of a build in comparator.
4284
// The comparator can compare the voltage of any of the ADC input pins with the voltage
4285
// of the internal reference (1.3V or 1.1V).
4286
// After setting up the comparator and counter properly, the load of capacitor is started
4287
// with connecting the positive pin with the R_H resistor (470kOhm) to VCC and immediately
4288
// the counter is started. By counting the overflow Events of the 16bit counter and watching
4289
// the counter event flag the total load time of the capacitor until reaching the internal
4290
// reference voltage can be measured.
4291
// If any of the tries to measure the load time is successful,
4292
// the following variables are set:
4293
// cap.cval = value of the capacitor
4294
// cap.cval_uncorrected = value of the capacitor uncorrected
4295
// cap.esr = serial resistance of capacitor, 0.01 Ohm units
4296
// cap.cpre = units of cap.cval (-12==pF, -9=nF, -6=uF)
4297
// ca = Pin number (0-2) of the LowPin
4298
// cb = Pin number (0-2) of the HighPin
4299
4300
//=================================================================
4301
void
ReadCapacity(uint8_t HighPin, uint8_t LowPin) {
4302
// check if capacitor and measure the capacity value
4303
unsigned
int
tmpint;
4304
unsigned
int
adcv[4];
4305
4306
#ifdef INHIBIT_SLEEP_MODE
4307
unsigned
int
ovcnt16;
4308
#endif
4309
4310
uint8_t HiPinR_L, HiPinR_H;
4311
uint8_t LoADC;
4312
uint8_t ii;
4313
4314
#if FLASHEND > 0x1fff
4315
unsigned
int
vloss;
// lost voltage after load pulse in 0.1%
4316
#endif
4317
4318
#ifdef AUTO_CAL
4319
pin_combination = (HighPin * 3) + LowPin - 1;
// coded Pin combination for capacity zero offset
4320
#endif
4321
4322
LoADC = pgm_read_byte(&PinADCtab[LowPin]) | TXD_MSK;
4323
HiPinR_L = pgm_read_byte(&PinRLtab[HighPin]);
// R_L mask for HighPin R_L load
4324
HiPinR_H = HiPinR_L + HiPinR_L;
// double for HighPin R_H load
4325
4326
#if DebugOut == 10
4327
lcd_line3();
4328
lcd_clear_line();
4329
lcd_line3();
4330
lcd_testpin(LowPin);
4331
lcd_data(
'C'
);
4332
lcd_testpin(HighPin);
4333
lcd_space();
4334
#endif
4335
4336
if
(PartFound == PART_RESISTOR) {
4337
4338
#if DebugOut == 10
4339
lcd_data(
'R'
);
4340
wait_about2s();
4341
#endif
4342
4343
return
;
// We have found a resistor already
4344
}
4345
4346
for
(ii=0;ii<NumOfDiodes;ii++) {
4347
if
((diodes[ii].Cathode == LowPin) && (diodes[ii].Anode == HighPin) && (diodes[ii].Voltage < 1500)) {
4348
4349
#if DebugOut == 10
4350
lcd_data(
'D'
);
4351
wait_about2s();
4352
#endif
4353
4354
return
;
4355
}
4356
}
4357
4358
#if FLASHEND > 0x1fff
4359
cap.esr = 0;
// set ESR of capacitor to zero
4360
vloss = 0;
// set lost voltage to zero
4361
#endif
4362
4363
cap.cval = 0;
// set capacity value to zero
4364
cap.cpre = -12;
// default unit is pF
4365
EntladePins();
// discharge capacitor
4366
4367
ADC_PORT = TXD_VAL;
// switch ADC-Port to GND
4368
R_PORT = 0;
// switch R-Port to GND
4369
ADC_DDR = LoADC;
// switch Low-Pin to output (GND)
4370
R_DDR = HiPinR_L;
// switch R_L port for HighPin to output (GND)
4371
adcv[0] = ReadADC(HighPin);
// voltage before any load
4372
4373
// ******** should adcv[0] be measured without current???
4374
adcv[2] = adcv[0];
// preset to prevent compiler warning
4375
4376
for
(ovcnt16=0; ovcnt16<500; ovcnt16++) {
4377
R_PORT = HiPinR_L;
// R_L to 1 (VCC)
4378
R_DDR = HiPinR_L;
// switch Pin to output, across R to GND or VCC
4379
wait10ms();
// wait exactly 10ms, do not sleep
4380
4381
R_DDR = 0;
// switch back to input
4382
R_PORT = 0;
// no Pull up
4383
wait500us();
// wait a little time
4384
4385
wdt_reset();
4386
4387
// read voltage without current, is already charged enough?
4388
adcv[2] = ReadADC(HighPin);
4389
4390
if
(adcv[2] > adcv[0]) {
4391
adcv[2] -= adcv[0];
// difference to beginning voltage
4392
}
else
{
4393
adcv[2] = 0;
// voltage is lower or same as beginning voltage
4394
}
4395
4396
if
((ovcnt16 == 126) && (adcv[2] < 75)) {
4397
// 300mV can not be reached well-timed
4398
break
;
// don't try to load any more
4399
}
4400
4401
if
(adcv[2] > 300) {
4402
break
;
// probably 100mF can be charged well-timed
4403
}
4404
}
4405
4406
// wait 5ms and read voltage again, does the capacitor keep the voltage?
4407
//adcv[1] = W5msReadADC(HighPin) - adcv[0];
4408
//wdt_reset();
4409
4410
#if DebugOut == 10
4411
DisplayValue(ovcnt16,0,
' '
,4);
4412
DisplayValue(adcv[2],-3,
'V'
,4);
4413
#endif
4414
4415
if
(adcv[2] < 301) {
4416
4417
#if DebugOut == 10
4418
lcd_data(
'K'
);
4419
lcd_space();
4420
wait1s();
4421
#endif
4422
4423
//if (NumOfDiodes != 0) goto messe_mit_rh;
4424
goto
keinC;
// was never charged enough, >100mF or shorted
4425
}
4426
4427
// voltage is rised properly and keeps the voltage enough
4428
if
((ovcnt16 == 0 ) && (adcv[2] > 1300)) {
4429
goto
messe_mit_rh;
// Voltage of more than 1300mV is reached in one pulse, too fast loaded
4430
}
4431
4432
// Capacity is more than about 50uF
4433
4434
#ifdef NO_CAP_HOLD_TIME
4435
ChargePin10ms(HiPinR_H,0);
// switch HighPin with R_H 10ms auf GND, then currentless
4436
adcv[3] = ReadADC(HighPin) - adcv[0];
// read voltage again, is discharged only a little bit ?
4437
4438
if
(adcv[3] > adcv[0]) {
4439
adcv[3] -= adcv[0];
// difference to beginning voltage
4440
}
else
{
4441
adcv[3] = 0;
// voltage is lower to beginning voltage
4442
}
4443
4444
#if DebugOut == 10
4445
lcd_data(
'U'
);
4446
lcd_data(
'3'
);
4447
lcd_data(
':'
);
4448
lcd_string(utoa(adcv[3],outval,10));
4449
lcd_space();
4450
wait_about2s();
4451
#endif
4452
4453
if
((adcv[3] + adcv[3]) < adcv[2]) {
4454
4455
#if DebugOut == 10
4456
lcd_data(
'H'
);
4457
lcd_space();
4458
wait_about1s();
4459
#endif
4460
4461
if
(ovcnt16 == 0 ) {
4462
goto
messe_mit_rh;
// Voltage of more than 1300mV is reached in one pulse, but not hold
4463
}
4464
4465
goto
keinC;
// implausible, not yet the half voltage
4466
}
4467
4468
cap.cval_uncorrected.dw = ovcnt16 + 1;
4469
cap.cval_uncorrected.dw *= getRLmultip(adcv[2]);
// get factor to convert time to capacity from table
4470
4471
#else
4472
// wait the half the time which was required for loading
4473
adcv[3] = adcv[2];
// preset to prevent compiler warning
4474
4475
for
(tmpint=0; tmpint<=ovcnt16; tmpint++) {
4476
wait5ms();
4477
adcv[3] = ReadADC(HighPin);
// read voltage again, is discharged only a little bit ?
4478
wdt_reset();
4479
}
4480
4481
if
(adcv[3] > adcv[0]) {
4482
adcv[3] -= adcv[0];
// difference to beginning voltage
4483
}
else
{
4484
adcv[3] = 0;
// voltage is lower or same as beginning voltage
4485
}
4486
4487
if
(adcv[2] > adcv[3]) {
4488
// build difference to load voltage
4489
adcv[3] = adcv[2] - adcv[3];
// lost voltage during load time wait
4490
}
else
{
4491
adcv[3] = 0;
// no lost voltage
4492
}
4493
4494
#if FLASHEND > 0x1fff
4495
// compute equivalent parallel resistance from voltage drop
4496
if
(adcv[3] > 0) {
4497
// there is any voltage drop (adcv[3]) !
4498
// adcv[2] is the loaded voltage.
4499
vloss = (unsigned
long
)(adcv[3] * 1000UL) / adcv[2];
4500
}
4501
#endif
4502
4503
if
(adcv[3] > 100) {
4504
// more than 100mV is lost during load time
4505
4506
#if DebugOut == 10
4507
lcd_data(
'L'
);
4508
lcd_space();
4509
wait_about1s();
4510
#endif
4511
4512
if
(ovcnt16 == 0 ) {
4513
goto
messe_mit_rh;
// Voltage of more than 1300mV is reached in one pulse, but not hold
4514
}
4515
4516
goto
keinC;
// capacitor does not keep the voltage about 5ms
4517
}
4518
4519
cap.cval_uncorrected.dw = ovcnt16 + 1;
4520
// compute factor with load voltage + lost voltage during the voltage load time
4521
cap.cval_uncorrected.dw *= getRLmultip(adcv[2]+adcv[3]);
// get factor to convert time to capacity from table
4522
#endif
4523
4524
cap.cval = cap.cval_uncorrected.dw;
// set result to uncorrected
4525
cap.cpre = -9;
// switch units to nF
4526
Scale_C_with_vcc();
4527
4528
// cap.cval for this type is at least 40000nF, so the last digit will be never shown
4529
cap.cval *= (1000 - C_H_KORR);
// correct with C_H_KORR with 0.1% resolution, but prevent overflow
4530
cap.cval /= 100;
4531
4532
#if DebugOut == 10
4533
lcd_line3();
4534
lcd_clear_line();
4535
lcd_line3();
4536
lcd_testpin(LowPin);
4537
lcd_data(
'C'
);
4538
lcd_testpin(HighPin);
4539
lcd_space();
4540
DisplayValue(cap.cval,cap.cpre,
'F'
,4);
4541
lcd_space();
4542
lcd_string(utoa(ovcnt16,outval,10));
4543
wait_about3s();
4544
#endif
4545
4546
goto
checkDiodes;
4547
4548
//==================================================================================
4549
// Measurement of little capacity values
4550
messe_mit_rh:
4551
// little capacity value, about < 50 uF
4552
EntladePins();
// discharge capacitor
4553
4554
// measure with the R_H (470kOhm) resistor
4555
R_PORT = 0;
// R_DDR ist HiPinR_L
4556
ADC_DDR = (1<<TP1) | (1<<TP2) | (1<<TP3) | (1<<TxD);
// switch all Pins to output
4557
ADC_PORT = TXD_VAL;
// switch all ADC Pins to GND
4558
R_DDR = HiPinR_H;
// switch R_H resistor port for HighPin to output (GND)
4559
4560
// setup Analog Comparator
4561
ADC_COMP_CONTROL = (1<<ACME);
// enable Analog Comparator Multiplexer
4562
ACSR = (1<<ACBG) | (1<<ACI) | (1<<ACIC);
// enable, 1.3V, no Interrupt, Connect to Timer1
4563
ADMUX = (1<<REFS0) | HighPin;
// switch Mux to High-Pin
4564
ADCSRA = (1<<ADIF) | AUTO_CLOCK_DIV;
// disable ADC
4565
wait200us();
// wait for bandgap to start up
4566
4567
// setup Counter1
4568
ovcnt16 = 0;
4569
TCCR1A = 0;
// set Counter1 to normal Mode
4570
TCNT1 = 0;
// set Counter to 0
4571
TI1_INT_FLAGS = (1<<ICF1) | (1<<OCF1B) | (1<<OCF1A) | (1<<TOV1);
// clear interrupt flags
4572
4573
#ifndef INHIBIT_SLEEP_MODE
4574
TIMSK1 = (1<<TOIE1) | (1<<ICIE1);
// enable Timer overflow interrupt and input capture interrupt
4575
unfinished = 1;
4576
#endif
4577
4578
R_PORT = HiPinR_H;
// switch R_H resistor port for HighPin to VCC
4579
4580
if
(PartFound == PART_FET) {
4581
// charge capacitor with R_H resistor
4582
TCCR1B = (1<<CS10);
//Start counter 1MHz or 8MHz
4583
ADC_DDR = (((1<<TP1) | (1<<TP2) | (1<<TP3) | TXD_MSK) & ~(1<<HighPin));
// release only HighPin ADC port
4584
}
else
{
4585
TCCR1B = (1<<CS10);
// start counter 1MHz or 8MHz
4586
ADC_DDR = LoADC;
// stay LoADC Pin switched to GND, charge capacitor with R_H slowly
4587
}
4588
4589
//******************************
4590
#ifdef INHIBIT_SLEEP_MODE
4591
while
(1) {
4592
// Wait, until Input Capture is set
4593
ii = TI1_INT_FLAGS;
// read Timer flags
4594
4595
if
(ii & (1<<ICF1)) {
4596
break
;
4597
}
4598
4599
if
((ii & (1<<TOV1))) {
// counter overflow, 65.536 ms @ 1MHz, 8.192ms @ 8MHz
4600
TI1_INT_FLAGS = (1<<TOV1);
// Reset OV Flag
4601
wdt_reset();
4602
ovcnt16++;
4603
4604
if
(ovcnt16 == (F_CPU/5000)) {
4605
break
;
// Timeout for Charging, above 12 s
4606
}
4607
}
4608
}
4609
4610
TCCR1B = (0<<ICNC1) | (0<<ICES1) | (0<<CS10);
// stop counter
4611
TI1_INT_FLAGS = (1<<ICF1);
// Reset Input Capture
4612
tmpint = ICR1;
// get previous Input Capture Counter flag
4613
4614
// check actual counter, if an additional overflow must be added
4615
if
((TCNT1 > tmpint) && (ii & (1<<TOV1))) {
4616
// this OV was not counted, but was before the Input Capture
4617
TI1_INT_FLAGS = (1<<TOV1);
// Reset OV Flag
4618
ovcnt16++;
4619
}
4620
4621
#else
4622
while
(unfinished) {
4623
set_sleep_mode(SLEEP_MODE_IDLE);
4624
sleep_mode();
// wait for interrupt
4625
wdt_reset();
4626
4627
if
(ovcnt16 == (F_CPU/5000)) {
4628
break
;
// Timeout for Charging, above 12 s
4629
}
4630
}
4631
4632
TCCR1B = (0<<ICNC1) | (0<<ICES1) | (0<<CS10);
// stop counter
4633
tmpint = ICR1;
// get previous Input Capture Counter flag
4634
TIMSK1 = (0<<TOIE1) | (0<<ICIE1);
// disable Timer overflow interrupt and input capture interrupt
4635
4636
if
(TCNT1 < tmpint) {
4637
ovcnt16--;
// one ov to much
4638
}
4639
#endif
4640
4641
//------------------------------------------------------------
4642
ADCSRA = (1<<ADEN) | (1<<ADIF) | AUTO_CLOCK_DIV;
// enable ADC
4643
R_DDR = 0;
// switch R_H resistor port for input
4644
R_PORT = 0;
// switch R_H resistor port pull up for HighPin off
4645
adcv[2] = ReadADC(HighPin);
// get loaded voltage
4646
load_diff = adcv[2] + REF_C_KORR - ref_mv;
// build difference of capacitor voltage to Reference Voltage
4647
//------------------------------------------------------------
4648
4649
if
(ovcnt16 >= (F_CPU/10000)) {
4650
4651
#if DebugOut == 10
4652
lcd_data(
'k'
);
4653
wait_about1s();
4654
#endif
4655
4656
goto
keinC;
// no normal end
4657
}
4658
4659
//cap.cval_uncorrected = CombineII2Long(ovcnt16, tmpint);
4660
cap.cval_uncorrected.w[1] = ovcnt16;
4661
cap.cval_uncorrected.w[0] = tmpint;
4662
4663
cap.cpre = -12;
// cap.cval unit is pF
4664
if
(ovcnt16 > 65) {
4665
cap.cval_uncorrected.dw /= 100;
// switch to next unit
4666
cap.cpre += 2;
// set unit, prevent overflow
4667
}
4668
4669
cap.cval_uncorrected.dw *= RHmultip;
// 708
4670
cap.cval_uncorrected.dw /= (F_CPU / 10000);
// divide by 100 (@ 1MHz clock), 800 (@ 8MHz clock)
4671
cap.cval = cap.cval_uncorrected.dw;
// set the corrected cap.cval
4672
Scale_C_with_vcc();
4673
4674
if
(cap.cpre == -12) {
4675
#if COMP_SLEW1 > COMP_SLEW2
4676
if
(cap.cval < COMP_SLEW1) {
4677
// add slew rate dependent offset
4678
cap.cval += (COMP_SLEW1 / (cap.cval+COMP_SLEW2 ));
4679
}
4680
#endif
4681
4682
#ifdef AUTO_CAL
4683
// auto calibration mode, cap_null can be updated in selftest section
4684
tmpint = eeprom_read_byte(&c_zero_tab[pin_combination]);
// read zero offset
4685
4686
if
(cap.cval > tmpint) {
4687
cap.cval -= tmpint;
// subtract zero offset (pF)
4688
}
else
{
4689
cap.cval = 0;
// unsigned long may not reach negativ value
4690
}
4691
4692
#else
4693
if
(HighPin == TP2) cap.cval += TP2_CAP_OFFSET;
// measurements with TP2 have 2pF less capacity
4694
4695
if
(cap.cval > C_NULL) {
4696
cap.cval -= C_NULL;
// subtract constant offset (pF)
4697
}
else
{
4698
cap.cval = 0;
// unsigned long may not reach negativ value
4699
}
4700
#endif
4701
}
4702
4703
#if DebugOut == 10
4704
R_DDR = 0;
// switch all resistor ports to input
4705
lcd_line4();
4706
lcd_clear_line();
4707
lcd_line4();
4708
lcd_testpin(LowPin);
4709
lcd_data(
'c'
);
4710
lcd_testpin(HighPin);
4711
lcd_space();
4712
DisplayValue(cap.cval,cap.cpre,
'F'
,4);
4713
wait_about3s();
4714
#endif
4715
4716
R_DDR = HiPinR_L;
// switch R_L for High-Pin to GND
4717
4718
#if F_CPU < 2000001
4719
if
(cap.cval < 50)
4720
#else
4721
if
(cap.cval < 25)
4722
#endif
4723
{
4724
// cap.cval can only be so little in pF unit, cap.cpre must not be testet!
4725
4726
#if DebugOut == 10
4727
lcd_data(
'<'
);
4728
lcd_space();
4729
wait_about1s();
4730
#endif
4731
4732
goto
keinC;
// capacity to low, < 50pF @1MHz (25pF @8MHz)
4733
}
4734
4735
// end low capacity
4736
4737
checkDiodes:
4738
4739
if
((NumOfDiodes > 0) && (PartFound != PART_FET)) {
4740
4741
#if DebugOut == 10
4742
lcd_data(
'D'
);
4743
lcd_space();
4744
wait_about1s();
4745
#endif
4746
4747
// nearly shure, that there is one or more diodes in reverse direction,
4748
// which would be wrongly detected as capacitor
4749
}
else
{
4750
PartFound = PART_CAPACITOR;
// capacitor is found
4751
4752
if
((cap.cpre > cap.cpre_max) || ((cap.cpre == cap.cpre_max) && (cap.cval > cap.cval_max))) {
4753
// we have found a greater one
4754
cap.cval_max = cap.cval;
4755
cap.cpre_max = cap.cpre;
4756
4757
#if FLASHEND > 0x1fff
4758
cap.v_loss = vloss;
// lost voltage in 0.01%
4759
#endif
4760
4761
cap.ca = LowPin;
// save LowPin
4762
cap.cb = HighPin;
// save HighPin
4763
}
4764
}
4765
4766
keinC:
4767
4768
// discharge capacitor again
4769
//EntladePins(); // discharge capacitors
4770
// ready
4771
// switch all ports to input
4772
ADC_DDR = TXD_MSK;
// switch all ADC ports to input
4773
ADC_PORT = TXD_VAL;
// switch all ADC outputs to GND, no pull up
4774
R_DDR = 0;
// switch all resistor ports to input
4775
R_PORT = 0;
// switch all resistor outputs to GND, no pull up
4776
4777
return
;
4778
}
// end ReadCapacity()
4779
4780
4781
unsigned
int
getRLmultip(unsigned
int
cvolt) {
4782
4783
// interpolate table RLtab corresponding to voltage cvolt
4784
// Widerstand 680 Ohm 300 325 350 375 400 425 450 475 500 525 550 575 600 625 650 675 700 725 750 775 800 825 850 875 900 925 950 975 1000 1025 1050 1075 1100 1125 1150 1175 1200 1225 1250 1275 1300 1325 1350 1375 1400 mV
4785
//uint16_t RLtab[] MEM_TEXT = {22447,20665,19138,17815,16657,15635,14727,13914,13182,12520,11918,11369,10865,10401, 9973, 9577, 9209, 8866, 8546, 8247, 7966, 7702, 7454, 7220, 6999, 6789, 6591, 6403, 6224, 6054, 5892, 5738, 5590, 5449, 5314, 5185, 5061, 4942, 4828, 4718, 4613, 4511, 4413, 4319, 4228};
4786
4787
#define RL_Tab_Abstand 25 // displacement of table 25mV
4788
#define RL_Tab_Beginn 300 // begin of table ist 300mV
4789
#define RL_Tab_Length 1100 // length of table is 1400-300
4790
4791
unsigned
int
uvolt;
4792
unsigned
int
y1, y2;
4793
uint8_t tabind;
4794
uint8_t tabres;
4795
4796
if
(cvolt >= RL_Tab_Beginn) {
4797
uvolt = cvolt - RL_Tab_Beginn;
4798
}
else
{
4799
uvolt = 0;
// limit to begin of table
4800
}
4801
4802
tabind = uvolt / RL_Tab_Abstand;
4803
tabres = uvolt % RL_Tab_Abstand;
4804
tabres = RL_Tab_Abstand - tabres;
4805
4806
if
(tabind > (RL_Tab_Length/RL_Tab_Abstand)) {
4807
tabind = (RL_Tab_Length/RL_Tab_Abstand);
// limit to end of table
4808
}
4809
4810
y1 = MEM_read_word(&RLtab[tabind]);
4811
y2 = MEM_read_word(&RLtab[tabind+1]);
4812
return
( ((y1 - y2) * tabres + (RL_Tab_Abstand/2)) / RL_Tab_Abstand + y2);
// interpolate table
4813
}
4814
4815
void
Scale_C_with_vcc(
void
) {
4816
4817
while
(cap.cval > 100000) {
4818
cap.cval /= 10;
4819
cap.cpre ++;
// prevent overflow
4820
}
4821
4822
cap.cval *= ADCconfig.U_AVCC;
// scale with measured voltage
4823
cap.cval /= U_VCC;
// Factors are computed for U_VCC
4824
}
4825
4826
#ifndef INHIBIT_SLEEP_MODE
4827
// Interrupt Service Routine for timer1 Overflow
4828
ISR(TIMER1_OVF_vect, ISR_BLOCK)
4829
{
4830
ovcnt16++;
// count overflow
4831
}
4832
4833
// Interrupt Service Routine for timer1 capture event (Comparator)
4834
ISR(TIMER1_CAPT_vect, ISR_BLOCK)
4835
{
4836
unfinished = 0;
// clear unfinished flag
4837
}
4838
#endif
4839
4840
/* -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- */
4841
4842
// new code by K.-H. Kubbeler
4843
// The 680 Ohm resistor (R_L_VAL) at the Lowpin will be used as current sensor
4844
// The current with a coil will with (1 - e**(-t*R/L)), where R is
4845
// the sum of Pin_RM , R_L_VAL , Resistance of coil and Pin_RP.
4846
// L in the inductance of the coil.
4847
4848
//=================================================================
4849
void
ReadInductance(
void
) {
4850
#if FLASHEND > 0x1fff
4851
4852
// check if inductor and measure the inductance value
4853
unsigned
int
tmpint;
4854
unsigned
int
umax;
4855
unsigned
int
total_r;
// total resistance of current loop
4856
unsigned
int
mess_r;
// value of resistor used for current measurement
4857
unsigned
long
inductance[4];
// four inductance values for different measurements
4858
4859
union t_combi{
4860
unsigned
long
dw;
// time_constant
4861
uint16_t w[2];
4862
} timeconstant;
4863
4864
uint16_t per_ref1,per_ref2;
// percentage
4865
uint8_t LoPinR_L;
// Mask for switching R_L resistor of low pin
4866
uint8_t HiADC;
// Mask for switching the high pin direct to VCC
4867
uint8_t ii;
4868
uint8_t count;
// counter for the different measurements
4869
4870
//uint8_t found; // variable used for searching resistors
4871
#define found 0
4872
4873
uint8_t cnt_diff;
// resistance dependent offset
4874
uint8_t LowPin;
// number of pin with low voltage
4875
uint8_t HighPin;
// number of pin with high voltage
4876
int8_t ukorr;
// correction of comparator voltage
4877
uint8_t nr_pol1;
// number of successfull inductance measurement with polarity 1
4878
uint8_t nr_pol2;
// number of successfull inductance measurement with polarity 2
4879
4880
if
(PartFound != PART_RESISTOR) {
4881
return
;
// We have found no resistor
4882
}
4883
4884
if
(ResistorsFound != 1) {
4885
return
;
// do not search for inductance, more than 1 resistor
4886
}
4887
4888
//for (found=0;found<ResistorsFound;found++) {
4889
// if (resis[found].rx > 21000) continue;
4890
4891
if
(resis[found].rx > 21000)
return
;
4892
// we can check for Inductance, if resistance is below 2100 Ohm
4893
4894
for
(count=0; count<4; count++) {
4895
// Try four times (different direction and with delayed counter start)
4896
4897
if
(count < 2) {
4898
// first and second pass, direction 1
4899
LowPin = resis[found].ra;
4900
HighPin = resis[found].rb;
4901
}
else
{
4902
// third and fourth pass, direction 2
4903
LowPin = resis[found].rb;
4904
HighPin = resis[found].ra;
4905
}
4906
4907
HiADC = pgm_read_byte(&PinADCtab[HighPin]);
4908
LoPinR_L = pgm_read_byte(&PinRLtab[LowPin]);
// R_L mask for HighPin R_L load
4909
4910
//==================================================================================
4911
// Measurement of Inductance values
4912
R_PORT = 0;
// switch R port to GND
4913
ADC_PORT = TXD_VAL;
// switch ADC-Port to GND
4914
4915
if
((resis[found].rx < 240) && ((count & 0x01) == 0)) {
4916
// we can use PinR_L for measurement
4917
mess_r = RR680MI - R_L_VAL;
// use only pin output resistance
4918
ADC_DDR = HiADC | (1<<LowPin) | TXD_MSK;
// switch HiADC and Low Pin to GND,
4919
}
else
{
4920
R_DDR = LoPinR_L;
// switch R_L resistor port for LowPin to output (GND)
4921
ADC_DDR = HiADC | TXD_MSK;
// switch HiADC Pin to GND
4922
mess_r = RR680MI;
// use 680 Ohm and PinR_L for current measurement
4923
}
4924
4925
// Look, if we can detect any current
4926
for
(ii=0;ii<20;ii++) {
4927
// wait for current is near zero
4928
umax = W10msReadADC(LowPin);
4929
total_r = ReadADC(HighPin);
4930
if
((umax < 2) && (total_r < 2))
break
;
// low current detected
4931
}
4932
4933
// setup Analog Comparator
4934
ADC_COMP_CONTROL = (1<<ACME);
// enable Analog Comparator Multiplexer
4935
ACSR = (1<<ACBG) | (1<<ACI) | (1<<ACIC);
// enable, 1.3V, no Interrupt, Connect to Timer1
4936
ADMUX = (1<<REFS0) | LowPin;
// switch Mux to Low-Pin
4937
ADCSRA = (1<<ADIF) | AUTO_CLOCK_DIV;
// disable ADC
4938
4939
// setup Counter1
4940
timeconstant.w[1] = 0;
// set ov counter to 0
4941
TCCR1A = 0;
// set Counter1 to normal Mode
4942
TCNT1 = 0;
// set Counter to 0
4943
TI1_INT_FLAGS = (1<<ICF1) | (1<<OCF1B) | (1<<OCF1A) | (1<<TOV1);
// reset TIFR or TIFR1
4944
HiADC |= TXD_VAL;
4945
wait200us();
// wait for bandgap to start up
4946
4947
if
((count & 0x01) == 0 ) {
4948
// first start counter, then start current
4949
TCCR1B = (1<<ICNC1) | (0<<ICES1) | (1<<CS10);
// start counter 1MHz or 8MHz
4950
ADC_PORT = HiADC;
// switch ADC-Port to VCC
4951
}
else
{
4952
// first start current, then start counter with delay
4953
// parasitic capacity of coil can cause high current at the beginning
4954
ADC_PORT = HiADC;
// switch ADC-Port to VCC
4955
4956
#if F_CPU >= 8000000UL
4957
wait3us();
// ignore current peak from capacity
4958
#else
4959
wdt_reset();
// delay
4960
wdt_reset();
// delay
4961
#endif
4962
4963
TI1_INT_FLAGS = (1<<ICF1);
// Reset Input Capture
4964
TCCR1B = (1<<ICNC1) | (0<<ICES1) | (1<<CS10);
// start counter 1MHz or 8MHz
4965
}
4966
4967
//******************************
4968
while
(1) {
4969
// Wait, until Input Capture is set
4970
ii = TI1_INT_FLAGS;
// read Timer flags
4971
4972
if
(ii & (1<<ICF1)) {
4973
break
;
4974
}
4975
4976
if
((ii & (1<<TOV1))) {
// counter overflow, 65.536 ms @ 1MHz, 8.192ms @ 8MHz
4977
TI1_INT_FLAGS = (1<<TOV1);
// Reset OV Flag
4978
wdt_reset();
4979
timeconstant.w[1]++;
// count one OV
4980
4981
if
(timeconstant.w[1] == (F_CPU/100000UL)) {
4982
break
;
// Timeout for Charging, above 0.13 s
4983
}
4984
}
4985
}
4986
4987
TCCR1B = (0<<ICNC1) | (0<<ICES1) | (0<<CS10);
// stop counter
4988
TI1_INT_FLAGS = (1<<ICF1);
// Reset Input Capture
4989
timeconstant.w[0] = ICR1;
// get previous Input Capture Counter flag
4990
4991
// check actual counter, if an additional overflow must be added
4992
if
((TCNT1 > timeconstant.w[0]) && (ii & (1<<TOV1))) {
4993
// this OV was not counted, but was before the Input Capture
4994
TI1_INT_FLAGS = (1<<TOV1);
// Reset OV Flag
4995
timeconstant.w[1]++;
// count one additional OV
4996
}
4997
4998
ADC_PORT = TXD_VAL;
// switch ADC-Port to GND
4999
ADCSRA = (1<<ADEN) | (1<<ADIF) | AUTO_CLOCK_DIV;
// enable ADC
5000
5001
for
(ii=0;ii<20;ii++) {
5002
// wait for current is near zero
5003
umax = W10msReadADC(LowPin);
5004
total_r = ReadADC(HighPin);
5005
5006
if
((umax < 2) && (total_r < 2))
break
;
// low current detected
5007
}
5008
5009
#define CNT_ZERO_42 6
5010
#define CNT_ZERO_720 7
5011
5012
//#if F_CPU == 16000000UL
5013
// #undef CNT_ZERO_42
5014
// #undef CNT_ZERO_720
5015
// #define CNT_ZERO_42 7
5016
// #define CNT_ZERO_720 10
5017
//#endif
5018
5019
total_r = (mess_r + resis[found].rx + RRpinMI);
5020
5021
//cnt_diff = 0;
5022
//if (total_r > 7000) cnt_diff = 1;
5023
//if (total_r > 14000) cnt_diff = 2;
5024
5025
cnt_diff = total_r / ((14000UL * 8) / (F_CPU/1000000UL));
5026
// Voltage of comparator in % of umax
5027
5028
#ifdef AUTO_CAL
5029
tmpint = (ref_mv + (int16_t)eeprom_read_word((uint16_t *)(&ref_offset))) ;
5030
#else
5031
tmpint = (ref_mv + REF_C_KORR);
5032
#endif
5033
5034
if
(mess_r < R_L_VAL) {
5035
// measurement without 680 Ohm
5036
cnt_diff = CNT_ZERO_42;
5037
5038
if
(timeconstant.dw < 225) {
5039
ukorr = (timeconstant.w[0] / 5) - 20;
5040
}
else
{
5041
ukorr = 25;
5042
}
5043
5044
tmpint -= (((REF_L_KORR * 10) / 10) + ukorr);
5045
}
else
{
5046
// measurement with 680 Ohm resistor
5047
// if 680 Ohm resistor is used, use REF_L_KORR for correction
5048
cnt_diff += CNT_ZERO_720;
5049
tmpint += REF_L_KORR;
5050
}
5051
5052
if
(timeconstant.dw > cnt_diff) timeconstant.dw -= cnt_diff;
5053
else
timeconstant.dw = 0;
5054
5055
if
((count&0x01) == 1) {
5056
// second pass with delayed counter start
5057
timeconstant.dw += (3 * (F_CPU/1000000UL))+10;
5058
}
5059
5060
if
(timeconstant.w[1] >= (F_CPU/100000UL)) timeconstant.dw = 0;
// no transition found
5061
5062
if
(timeconstant.dw > 10) {
5063
timeconstant.dw -= 1;
5064
}
5065
5066
// compute the maximum Voltage umax with the Resistor of the coil
5067
umax = ((unsigned
long
)mess_r * (unsigned
long
)ADCconfig.U_AVCC) / total_r;
5068
per_ref1 = ((unsigned
long
)tmpint * 1000) / umax;
5069
//per_ref2 = (uint8_t)MEM2_read_byte(&LogTab[per_ref1]); // -log(1 - per_ref1/100)
5070
per_ref2 = get_log(per_ref1);
// -log(1 - per_ref1/1000)
5071
5072
//*********************************************************
5073
#if 0
5074
if
(count == 0) {
5075
lcd_line3();
5076
DisplayValue(count,0,
' '
,4);
5077
DisplayValue(timeconstant.dw,0,
'+'
,4);
5078
DisplayValue(cnt_diff,0,
' '
,4);
5079
DisplayValue(total_r,-1,
'r'
,4);
5080
lcd_space();
5081
DisplayValue(per_ref1,-1,
'%'
,4);
5082
lcd_line4();
5083
DisplayValue(tmpint,-3,
'V'
,4);
5084
lcd_space();
5085
DisplayValue(umax,-3,
'V'
,4);
5086
lcd_space();
5087
DisplayValue(per_ref2,-1,
'%'
,4);
5088
wait_about4s();
5089
wait_about2s();
5090
}
5091
#endif
5092
5093
//*********************************************************
5094
// lx in 0.01mH units, L = Tau * R
5095
per_ref1 = ((per_ref2 * (F_CPU/1000000UL)) + 5) / 10;
5096
inductance[count] = (timeconstant.dw * total_r ) / per_ref1;
5097
5098
if
(((count&0x01) == 0) && (timeconstant.dw > ((F_CPU/1000000UL)+3))) {
5099
// transition is found, measurement with delayed counter start is not necessary
5100
inductance[count+1] = inductance[count];
// set delayed measurement to same value
5101
count++;
// skip the delayed measurement
5102
}
5103
5104
wdt_reset();
5105
}
// end for count
5106
5107
ADC_PORT = TXD_VAL;
// switch ADC Port to GND
5108
wait_about20ms();
5109
5110
#if 0
5111
if
(inductance[1] > inductance[0]) {
5112
resis[found].lx = inductance[1];
// use value found with delayed counter start
5113
}
else
{
5114
resis[found].lx = inductance[0];
5115
}
5116
5117
if
(inductance[3] > inductance[2]) inductance[2] = inductance[3];
// other polarity, delayed start
5118
5119
if
(inductance[2] < resis[found].lx) resis[found].lx = inductance[2];
// use the other polarity
5120
5121
#else
5122
nr_pol1 = 0;
5123
if
(inductance[1] > inductance[0]) { nr_pol1 = 1; }
5124
5125
nr_pol2 = 2;
5126
if
(inductance[3] > inductance[2]) { nr_pol2 = 3; }
5127
5128
if
(inductance[nr_pol2] < inductance[nr_pol1]) nr_pol1 = nr_pol2;
5129
5130
resis[found].lx = inductance[nr_pol1];
5131
resis[found].lpre = -5;
// 10 uH units
5132
5133
if
(((nr_pol1 & 1) == 1) || (resis[found].rx >= 240)) {
5134
// with 680 Ohm resistor total_r is more than 7460
5135
resis[found].lpre = -4;
// 100 uH units
5136
resis[found].lx = (resis[found].lx + 5) / 10;
5137
}
5138
#endif
5139
5140
//} // end loop for all resistors
5141
5142
// switch all ports to input
5143
ADC_DDR = TXD_MSK;
// switch all ADC ports to input
5144
R_DDR = 0;
// switch all resistor ports to input
5145
5146
#endif
5147
return
;
5148
}
// end ReadInductance()
5149
5150
5151
#if FLASHEND > 0x1fff
5152
// get_log interpolate a table with the function -log(1 - (permil/1000))
5153
uint16_t get_log(uint16_t permil) {
5154
// for remember:
5155
// uint16_t LogTab[] PROGMEM = {0, 20, 41, 62, 83, 105, 128, 151, 174, 198, 223, 248, 274, 301, 329, 357, 386, 416, 446, 478, 511, 545, 580, 616, 654, 693, 734, 777, 821, 868, 916, 968, 1022, 1079, 1139, 1204, 1273, 1347, 1427, 1514, 1609, 1715, 1833, 1966, 2120, 2303, 2526 };
5156
5157
#define Log_Tab_Distance 20 // displacement of table is 20 mil
5158
5159
uint16_t y1, y2;
// table values
5160
uint16_t result;
// result of interpolation
5161
uint8_t tabind;
// index to table value
5162
uint8_t tabres;
// distance to lower table value, fraction of Log_Tab_Distance
5163
5164
tabind = permil / Log_Tab_Distance;
// index to table
5165
tabres = permil % Log_Tab_Distance;
// fraction of table distance
5166
5167
// interpolate the table of factors
5168
y1 = pgm_read_word(&LogTab[tabind]);
// get the lower table value
5169
y2 = pgm_read_word(&LogTab[tabind+1]);
// get the higher table value
5170
5171
result = ((y2 - y1) * tabres ) / Log_Tab_Distance + y1;
// interpolate
5172
return
(result);
5173
}
5174
#endif
5175
5176
/* -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- */
5177
5178
#define MAX_CNT 255
5179
5180
/* The sleep mode for ADC can be used. It is implemented for 8MHz and 16MHz operation */
5181
/* But the ESR result is allways higher than the results with wait mode. */
5182
/* The time of ESR measurement is higher with the sleep mode (checked with oszilloscope) */
5183
/* The reason for the different time is unknown, the start of the next ADC measurement */
5184
/* should be initiated before the next ADC-clock (8 us). One ADC takes 13 ADC clock + 1 clock setup. */
5185
/* The setting to sleep mode takes 10 clock tics, the wakeup takes about 24 clock tics, but 8us are 64 clock tics. */
5186
/* I have found no reason, why a reset of the ADC clock divider should occur during ESR measurement. */
5187
//#define ADC_Sleep_Mode
5188
5189
//#define ESR_DEBUG
5190
5191
#ifdef ADC_Sleep_Mode
5192
//#define StartADCwait() ADCSRA = (1<<ADEN) | (1<<ADIF) | (1<<ADIE) | AUTO_CLOCK_DIV; /* enable ADC and Interrupt */
5193
//#define StartADCwait() set_sleep_mode(SLEEP_MODE_ADC);
5194
//sleep_mode() /* Start ADC, return if ADC has finished */
5195
#define StartADCwait() sleep_cpu()
5196
#else
5197
//#define StartADCwait() ADCSRA = (1<<ADSC) | (1<<ADEN) | (1<<ADIF) | AUTO_CLOCK_DIV; /* enable ADC and start */
5198
#define StartADCwait() ADCSRA = StartADCmsk; /* Start conversion */\
5199
while
(ADCSRA & (1 << ADSC))
/* wait until conversion is done */
5200
#endif
5201
5202
/************************************************************************/
5203
/* Predefine the wait time for switch off the load current for big caps */
5204
/************************************************************************/
5205
// wdt_reset(); // with wdt_reset the timing can be adjusted,
5206
// when time is too short, voltage is down before SH of ADC
5207
// when time is too long, capacitor will be overloaded.
5208
// That will cause too high voltage without current.
5209
5210
#ifdef ADC_Sleep_Mode
5211
// Interrupt mode, big cap
5212
#if F_CPU == 8000000UL
5213
#define DelayBigCap() wait10us(); /* 2.5 ADC clocks = 20us */ \
5214
wait5us();
/* */
\
5215
wait2us();
/* with only 17 us delay the voltage goes down before SH */
\
5216
/* delay 17us + 3 clock tics (CALL instead of RCALL) = 17.375 us @ 8 MHz */
\
5217
/* + 21 clock tics delay from interrupt return, +2.625us = 20.0 */
\
5218
wdt_reset();
/* 20.125 us */
\
5219
wdt_reset()
/* 20.250 us */
5220
#endif
5221
#if F_CPU == 16000000UL
5222
#define DelayBigCap() us500delay(18); /* 2.5 ADC clocks = 20us */ \
5223
/* with only 18 us delay the voltage goes down before SH */
\
5224
/* delay 18us 500ns + 1 clock tics (CALL instead of RCALL) = 18.5625 us */
\
5225
/* + 21 clock tics delay from interrupt return, +1.3125us = 19.8750 */
\
5226
wdt_reset();
/* 19.9375 us */
\
5227
wdt_reset();
/* 20.0000 us */
\
5228
wdt_reset();
/* 20.0625 us */
\
5229
wdt_reset();
/* 20.1250 us */
\
5230
wdt_reset();
/* 20.1875 us */
\
5231
wdt_reset()
/* 20.2500 us */
5232
#endif
5233
#else
5234
// Polling mode, big cap
5235
#if F_CPU == 8000000UL
5236
#define DelayBigCap() wait10us(); /* 2.5 ADC clocks = 20us */ \
5237
wait5us();
/* */
\
5238
wait4us();
/* pulse length 19.375 us */
5239
/* delay 19us + 3 clock tics (CALL instead of RCALL) = 19.375 us @ 8 MHz */
5240
/* + 7 clock tics delay from while loop, +0.875us = 20.250 */
5241
// wdt_reset() /* 20.375 us + */
5242
#endif
5243
#if F_CPU == 16000000UL
5244
#define DelayBigCap() delayMicroseconds(20)
5245
// #define DelayBigCap() us500delay(19); /* 2.5 ADC clocks = 20us */ \
5246
// /* with only 18 us delay the voltage goes down before SH */ \
5247
// /* delay 19us 500ns + 1 clock tics (CALL instead of RCALL) = 19.5625 us */ \
5248
// /* + 7 clock tics delay from "while (ADCSRA&(1<<ADSC))" loop = 20.0000 */ \
5249
// wdt_reset(); /* 20.0625 us */ \
5250
// wdt_reset(); /* 20.1250 us */ \
5251
// wdt_reset(); /* 20.1875 us */ \
5252
// wdt_reset() /* 20.2500 us */
5253
#endif
5254
#endif
5255
5256
/**************************************************************************/
5257
/* Predefine the wait time for switch off the load current for small caps */
5258
/**************************************************************************/
5259
// SH at 2.5 ADC clocks behind start = 5 us
5260
#ifdef ADC_Sleep_Mode
5261
// Interrupt mode, small cap
5262
#if F_CPU == 8000000UL
5263
#define DelaySmallCap() wait2us(); /* with only 4 us delay the voltage goes down before SH */ \
5264
/* delay 2us + 1 clock tics (CALL instead of RCALL) = 2.125 us @ 8 MHz */
\
5265
/* + 21 clock tics delay from interrupt return, +2.625us = 4.75 */
\
5266
wdt_reset();
/* 4.875 us */
\
5267
wdt_reset();
/* 5.000 us */
\
5268
wdt_reset()
/* 5.125 us */
5269
#endif
5270
#if F_CPU == 16000000UL
5271
#define DelaySmallCap() us500delay(3); /* with only 18 us delay the voltage goes down before SH */ \
5272
/* delay 3us 500ns + 1 clock tics (CALL instead of RCALL) = 3.5625 us */
\
5273
/* + 21 clock tics delay from interrupt return, +1.3125us = 4.875 */
\
5274
wdt_reset();
/* 4.9375 us */
\
5275
wdt_reset();
/* 5.0000 us */
\
5276
wdt_reset();
/* 5.0625 us */
\
5277
wdt_reset()
/* 5.1250 us */
5278
#endif
5279
#else
5280
// Polling mode, small cap
5281
#if F_CPU == 8000000UL
5282
#define DelaySmallCap() wait4us(); /* with only 4 us delay the voltage goes down before SH */ \
5283
/* delay 4us + 1 clock tics (CALL instead of RCALL) = 4.125 us @ 8 MHz */
\
5284
/* + 7 clock tics delay from while loop, +0.875us = 5.000 */
\
5285
wdt_reset()
/* 5.125 us */
5286
#endif
5287
#if F_CPU == 16000000UL
5288
#define DelaySmallCap() us500delay(4); /* with only 4 us delay the voltage goes down before SH */ \
5289
/* delay 4us 500ns + 1 clock tics (CALL instead of RCALL) = 4.5625 us */
\
5290
/* + 7 clock tics delay from "while (ADCSRA&(1<<ADSC))" loop, +0.4375 = 5.0000 */
\
5291
wdt_reset();
/* 5.0625 us */
\
5292
wdt_reset()
/* 5.1250 us */
5293
#endif
5294
#endif
5295
5296
//=================================================================
5297
uint16_t GetESR(uint8_t hipin, uint8_t lopin) {
5298
#if FLASHEND > 0x1fff
5299
// measure the ESR value of capacitor
5300
unsigned
int
adcv[4];
// array for 4 ADC readings
5301
unsigned
long
sumvolt[4];
// array for 3 sums of ADC readings
5302
unsigned
long
cap_val_nF;
5303
uint16_t esrvalue;
5304
uint8_t HiPinR_L;
// used to switch 680 Ohm to HighPin
5305
uint8_t HiADC;
// used to switch Highpin directly to GND or VCC
5306
uint8_t LoPinR_L;
// used to switch 680 Ohm to LowPin
5307
uint8_t LoADC;
// used to switch Lowpin directly to GND or VCC
5308
uint8_t ii,jj;
// tempory values
5309
uint8_t StartADCmsk;
// Bit mask to start the ADC
5310
uint8_t SelectLowPin,SelectHighPin;
5311
uint8_t big_cap;
5312
int8_t esr0;
// used for ESR zero correction
5313
big_cap = 1;
5314
5315
if
(PartFound == PART_CAPACITOR) {
5316
ii = cap.cpre_max;
5317
cap_val_nF = cap.cval_max;
5318
5319
while
(ii < -9) {
// set cval to nF unit
5320
cap_val_nF /= 10;
// reduce value by factor ten
5321
ii++;
// take next decimal prefix
5322
}
5323
5324
if
(cap_val_nF < (1800/18))
return
(0xffff);
// capacity lower than 1.8 uF
5325
//if (cap_val_nF > (1800/18)) {
5326
5327
// normal ADC-speed, ADC-Clock 8us
5328
#ifdef ADC_Sleep_Mode
5329
StartADCmsk = (1<<ADEN) | (1<<ADIF) | (1<<ADIE) | AUTO_CLOCK_DIV;
// enable ADC and Interrupt
5330
ADCSRA = StartADCmsk;
// enable ADC and Interrupt
5331
#else
5332
StartADCmsk = (1<<ADSC) | (1<<ADEN) | (1<<ADIF) | AUTO_CLOCK_DIV;
// enable and start ADC
5333
#endif
5334
5335
//} else {
5336
5337
// fast ADC-speed, ADC-Clock 2us
5338
#ifdef ADC_Sleep_Mode
5339
//StartADCmsk = (1<<ADEN) | (1<<ADIF) | (1<<ADIE) | FAST_CLOCK_DIV; // enable ADC and Interrupt
5340
//ADCSRA = StartADCmsk; // enable ADC and Interrupt
5341
//SMCR = (1 << SM0) | (1 <<SE); // set ADC Noise Reduction and Sleep Enable
5342
#else
5343
//StartADCmsk = (1<<ADSC) | (1<<ADEN) | (1<<ADIF) | FAST_CLOCK_DIV; // enable and start ADC
5344
#endif
5345
5346
//big_cap = 0;
5347
//}
5348
}
5349
5350
LoADC = pgm_read_byte(&PinADCtab[lopin]) | TXD_MSK;
5351
HiADC = pgm_read_byte(&PinADCtab[hipin]) | TXD_MSK;
5352
LoPinR_L = pgm_read_byte(&PinRLtab[lopin]);
// R_L mask for LowPin R_L load
5353
HiPinR_L = pgm_read_byte(&PinRLtab[hipin]);
// R_L mask for HighPin R_L load
5354
5355
#if PROCESSOR_TYP == 1280
5356
// ATmega640/1280/2560 1.1V Reference with REFS0=0
5357
SelectLowPin = (lopin | (1<<REFS1) | (0<<REFS0));
// switch ADC to LowPin, Internal Ref.
5358
SelectHighPin = (hipin | (1<<REFS1) | (0<<REFS0));
// switch ADC to HighPin, Internal Ref.
5359
#else
5360
SelectLowPin = (lopin | (1<<REFS1) | (1<<REFS0));
// switch ADC to LowPin, Internal Ref.
5361
SelectHighPin = (hipin | (1<<REFS1) | (1<<REFS0));
// switch ADC to HighPin, Internal Ref.
5362
#endif
5363
5364
// Measurement of ESR of capacitors AC Mode
5365
sumvolt[0] = 1;
// set sum of LowPin voltage to 1 to prevent divide by zero
5366
sumvolt[2] = 1;
// clear sum of HighPin voltage with current
5367
// offset is about (x*10*200)/34000 in 0.01 Ohm units
5368
sumvolt[1] = 0;
// clear sum of HighPin voltage without current
5369
sumvolt[3] = 0;
// clear sum of HighPin voltage without current
5370
EntladePins();
// discharge capacitor
5371
ADC_PORT = TXD_VAL;
// switch ADC-Port to GND
5372
ADMUX = SelectLowPin;
// set Mux input and Voltage Reference to internal 1.1V
5373
5374
#ifdef NO_AREF_CAP
5375
wait100us();
// time for voltage stabilization
5376
#else
5377
wait_about10ms();
// time for voltage stabilization with 100nF
5378
#endif
5379
5380
// start voltage must be negativ
5381
ADC_DDR = HiADC;
// switch High Pin to GND
5382
R_PORT = LoPinR_L;
// switch R-Port to VCC
5383
R_DDR = LoPinR_L;
// switch R_L port for HighPin to output (VCC)
5384
wait10us();
5385
wait2us();
5386
R_DDR = 0;
// switch off current
5387
R_PORT = 0;
5388
StartADCwait();
// set ADCSRA Interrupt Mode, sleep
5389
5390
// Measurement frequency is given by sum of ADC-Reads < 680 Hz for normal ADC speed.
5391
// For fast ADC mode the frequency is below 2720 Hz (used for capacity value below 3.6 uF).
5392
// ADC Sample and Hold (SH) is done 1.5 ADC clock number after real start of conversion.
5393
// Real ADC-conversion is started with the next ADC-Clock (125kHz) after setting the ADSC bit.
5394
5395
for
(ii=0;ii<MAX_CNT;ii++) {
5396
ADC_DDR = LoADC;
// switch Low-Pin to output (GND)
5397
R_PORT = LoPinR_L;
// switch R-Port to VCC
5398
R_DDR = LoPinR_L;
// switch R_L port for LowPin to output (VCC)
5399
ADMUX = SelectLowPin;
5400
StartADCwait();
// set ADCSRA Interrupt Mode, sleep
5401
StartADCwait();
// set ADCSRA Interrupt Mode, sleep
5402
adcv[0] = ADCW;
// Voltage LowPin with current
5403
ADMUX = SelectHighPin;
5404
5405
//if (big_cap != 0) {
5406
5407
StartADCwait();
// ADCSRA = (1<<ADEN) | (1<<ADIF) | (1<<ADIE) | AUTO_CLOCK_DIV;
5408
ADCSRA = (1<<ADSC) | (1<<ADEN) | (1<<ADIF) | AUTO_CLOCK_DIV;
// enable ADC and start with ADSC
5409
wait4us();
5410
R_PORT = HiPinR_L;
// switch R-Port to VCC
5411
R_DDR = HiPinR_L;
// switch R_L port for HighPin to output (VCC)
5412
DelayBigCap();
// wait predefined time
5413
5414
//} else {
5415
// StartADCwait(); // ADCSRA = (1<<ADEN) | (1<<ADIF) | (1<<ADIE) | AUTO_CLOCK_DIV;
5416
// R_PORT = HiPinR_L; // switch R-Port to VCC
5417
// R_DDR = HiPinR_L; // switch R_L port for HighPin to output (VCC)
5418
// ADCSRA = (1<<ADSC) | (1<<ADEN) | (1<<ADIF) | FAST_CLOCK_DIV; // enable ADC and start with ADSC
5419
// // SH at 2.5 ADC clocks behind start = 5 us
5420
// DelaySmallCap(); // wait predefined time
5421
//}
5422
5423
R_DDR = 0;
// switch current off, SH is 1.5 ADC clock behind real start
5424
R_PORT = 0;
5425
while
(ADCSRA&(1<<ADSC));
// wait for conversion finished
5426
adcv[1] = ADCW;
// Voltage HighPin with current
5427
5428
#ifdef ADC_Sleep_Mode
5429
ADCSRA = StartADCmsk;
// enable ADC and Interrupt
5430
#endif
5431
5432
wdt_reset();
5433
5434
// ******** Reverse direction, connect High side with GND ********
5435
ADC_DDR = HiADC;
// switch High Pin to GND
5436
R_PORT = HiPinR_L;
// switch R-Port to VCC
5437
R_DDR = HiPinR_L;
// switch R_L port for HighPin to output (VCC)
5438
wdt_reset();
5439
ADMUX = SelectHighPin;
5440
StartADCwait();
// set ADCSRA Interrupt Mode, sleep
5441
StartADCwait();
// set ADCSRA Interrupt Mode, sleep
5442
adcv[2] = ADCW;
// Voltage HighPin with current
5443
ADMUX = SelectLowPin;
5444
5445
//if (big_cap != 0) {
5446
5447
StartADCwait();
// set ADCSRA Interrupt Mode, sleep
5448
ADCSRA = (1<<ADSC) | (1<<ADEN) | (1<<ADIF) | AUTO_CLOCK_DIV;
// enable ADC and start with ADSC
5449
wait4us();
5450
R_PORT = LoPinR_L;
5451
R_DDR = LoPinR_L;
// switch LowPin with 680 Ohm to VCC
5452
DelayBigCap();
// wait predefined time
5453
5454
//} else {
5455
// StartADCwait(); // set ADCSRA Interrupt Mode, sleep
5456
// R_PORT = LoPinR_L;
5457
// R_DDR = LoPinR_L; // switch LowPin with 680 Ohm to VCC
5458
// ADCSRA = (1<<ADSC) | (1<<ADEN) | (1<<ADIF) | FAST_CLOCK_DIV; // enable ADC and start with ADSC
5459
// // 2.5 ADC clocks = 5 us
5460
// DelaySmallCap(); // wait predefined time
5461
//}
5462
5463
R_DDR = 0;
// switch current off
5464
R_PORT = 0;
5465
5466
while
(ADCSRA&(1<<ADSC));
// wait for conversion finished
5467
adcv[3] = ADCW;
// Voltage LowPin with current
5468
5469
#ifdef ADC_Sleep_Mode
5470
ADCSRA = StartADCmsk;
// enable ADC and Interrupt
5471
#endif
5472
5473
sumvolt[0] += adcv[0];
// add sum of both LowPin voltages with current
5474
sumvolt[1] += adcv[1];
// add HighPin voltages with current
5475
sumvolt[2] += adcv[2];
// add LowPin voltages with current
5476
sumvolt[3] += adcv[3];
// add HighPin voltages with current
5477
}
// end for
5478
5479
sumvolt[0] += sumvolt[2];
5480
5481
#ifdef ESR_DEBUG
5482
lcd_testpin(hipin);
5483
lcd_testpin(lopin);
5484
lcd_data(
' '
);
5485
DisplayValue(sumvolt[0],0,
'L'
,4);
// LowPin 1
5486
lcd_line3();
5487
DisplayValue(sumvolt[1],0,
'h'
,4);
// HighPin 1
5488
lcd_data(
' '
);
5489
DisplayValue(sumvolt[3],0,
'H'
,4);
// LowPin 2
5490
lcd_line4();
5491
#endif
5492
5493
if
((sumvolt[1] + sumvolt[3]) > sumvolt[0]) {
5494
sumvolt[2] = (sumvolt[1] + sumvolt[3]) - sumvolt[0];
// difference HighPin - LowPin Voltage with current
5495
}
else
{
5496
sumvolt[2] = 0;
5497
}
5498
5499
if
(PartFound == PART_CAPACITOR) {
5500
sumvolt[2] -= (1745098UL*MAX_CNT) / (cap_val_nF * (cap_val_nF + 19));
5501
}
5502
5503
#ifdef ESR_DEBUG
5504
DisplayValue(sumvolt[2],0,
'd'
,4);
// HighPin - LowPin
5505
lcd_data(
' '
);
5506
#endif
5507
5508
esrvalue = (sumvolt[2] * 10 * (unsigned
long
)RRpinMI) / (sumvolt[0]+sumvolt[2]);
5509
esrvalue += esrvalue / 14;
// esrvalue + 7%
5510
esr0 = (int8_t)pgm_read_byte(&EE_ESR_ZEROtab[hipin+lopin]);
5511
5512
if
(esrvalue > esr0) {
5513
esrvalue -= esr0;
5514
}
else
{
5515
esrvalue = 0;
5516
}
5517
5518
#ifdef ADC_Sleep_Mode
5519
SMCR = (0 << SM0) | (0 << SE);
// clear ADC Noise Reduction and Sleep Enable
5520
#endif
5521
5522
return
(esrvalue);
5523
#else
5524
return
(0);
5525
#endif
5526
}
5527
5528
void
us500delay(unsigned
int
us)
// = delayMicroseconds(us) + 500ns
5529
{
5530
#if F_CPU >= 20000000L
5531
__asm__ __volatile__ (
5532
"nop"
"\n\t"
5533
"nop"
);
// just waiting 2 cycles
5534
if
(--us == 0)
return
;
5535
us = (us<<2) + us;
// x5 us
5536
5537
#elif F_CPU >= 16000000L
5538
if
(--us == 0)
return
;
5539
us <<= 2;
5540
#else
5541
if
(--us == 0)
return
;
5542
if
(--us == 0)
return
;
5543
us <<= 1;
5544
#endif
5545
__asm__ __volatile__ (
5546
"1: sbiw %0,1"
"\n\t"
// 2 cycles
5547
"brne 1b"
:
"=w"
(us) :
"0"
(us)
// 2 cycles
5548
);
5549
}
5550
5551
/* -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- */
5552
5553
// new code by K.-H. Kubbeler
5554
// ca = Pin number (0-2) of the LowPin
5555
// cb = Pin number (0-2) of the HighPin
5556
5557
//=================================================================
5558
void
GetVloss() {
5559
#if FLASHEND > 0x1fff
5560
// measure voltage drop after load pulse
5561
unsigned
int
tmpint;
5562
unsigned
int
adcv[4];
5563
5564
union t_combi{
5565
unsigned
long
dw;
// capacity value in 100nF units
5566
uint16_t w[2];
5567
} lval;
5568
5569
uint8_t ii;
5570
uint8_t HiPinR_L;
5571
uint8_t LoADC;
5572
5573
if
(cap.v_loss > 0)
return
;
// Voltage loss is already known
5574
5575
LoADC = pgm_read_byte(&PinADCtab[cap.ca]) | TXD_MSK;
5576
HiPinR_L = pgm_read_byte(&PinRLtab[cap.cb]);
// R_L mask for HighPin R_L load
5577
5578
EntladePins();
// discharge capacitor
5579
ADC_PORT = TXD_VAL;
// switch ADC-Port to GND
5580
R_PORT = 0;
// switch R-Port to GND
5581
ADC_DDR = LoADC;
// switch Low-Pin to output (GND)
5582
R_DDR = HiPinR_L;
// switch R_L port for HighPin to output (GND)
5583
adcv[0] = ReadADC(cap.cb);
// voltage before any load
5584
5585
// ******** should adcv[0] be measured without current???
5586
if
(cap.cpre_max > -9)
return
;
// too much capacity
5587
5588
lval.dw = cap.cval_max;
5589
//for (ii=cap.cpre_max+12;ii<5;ii++) {
5590
for
(ii=cap.cpre_max+12;ii<4;ii++) {
5591
lval.dw = (lval.dw + 5) / 10;
5592
}
5593
5594
//if ((lval.dw == 0) || (lval.dw > 500)) {
5595
if
((lval.dw == 0) || (lval.dw > 5000)) {
5596
// capacity more than 50uF, Voltage loss is already measured
5597
return
;
5598
}
5599
5600
R_PORT = HiPinR_L;
// R_L to 1 (VCC)
5601
R_DDR = HiPinR_L;
// switch Pin to output, across R to GND or VCC
5602
5603
for
(tmpint=0; tmpint<lval.w[0]; tmpint+=2) {
5604
//wait50us(); // wait exactly 50us
5605
wait5us();
// wait exactly 5us
5606
}
5607
5608
R_DDR = 0;
// switch back to input
5609
R_PORT = 0;
// no Pull up
5610
//wait10us(); // wait a little time
5611
wdt_reset();
5612
5613
// read voltage without current
5614
ADCconfig.Samples = 5;
// set ADC to only 5 samples
5615
adcv[2] = ReadADC(cap.cb);
5616
if
(adcv[2] > adcv[0]) {
5617
adcv[2] -= adcv[0];
// difference to beginning voltage
5618
}
else
{
5619
adcv[2] = 0;
// voltage is lower or same as beginning voltage
5620
}
5621
5622
// wait 2x the time which was required for loading
5623
for
(tmpint=0; tmpint<lval.w[0]; tmpint++) {
5624
//wait50us();
5625
wait5us();
5626
}
5627
5628
adcv[3] = ReadADC(cap.cb);
// read voltage again, is discharged only a little bit ?
5629
ADCconfig.Samples = ANZ_MESS;
// set ADC back to configured No. of samples
5630
wdt_reset();
5631
5632
if
(adcv[3] > adcv[0]) {
5633
adcv[3] -= adcv[0];
// difference to beginning voltage
5634
}
else
{
5635
adcv[3] = 0;
// voltage is lower or same as beginning voltage
5636
}
5637
5638
if
(adcv[2] > adcv[3]) {
5639
// build difference to load voltage
5640
adcv[1] = adcv[2] - adcv[3];
// lost voltage during load time wait
5641
}
else
{
5642
adcv[1] = 0;
// no lost voltage
5643
}
5644
5645
// compute voltage drop as part from loaded voltage
5646
if
(adcv[1] > 0) {
5647
// there is any voltage drop (adcv[1]) !
5648
// adcv[2] is the loaded voltage.
5649
cap.v_loss = (unsigned
long
)(adcv[1] * 500UL) / adcv[2];
5650
}
5651
5652
#if 0
5653
lcd_line3();
5654
DisplayValue(adcv[2],0,
' '
,4);
5655
DisplayValue(adcv[1],0,
' '
,4);
5656
lcd_line4();
5657
DisplayValue(lval.w[0],0,
'x'
,4);
5658
#endif
5659
5660
// discharge capacitor again
5661
EntladePins();
// discharge capacitors
5662
// ready
5663
// switch all ports to input
5664
5665
ADC_DDR = TXD_MSK;
// switch all ADC ports to input
5666
ADC_PORT = TXD_VAL;
// switch all ADC outputs to GND, no pull up
5667
R_DDR = 0;
// switch all resistor ports to input
5668
R_PORT = 0;
// switch all resistor outputs to GND, no pull up
5669
5670
#endif
5671
return
;
5672
}
// end GetVloss()
5673
5674
/* -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- */
5675
5676
void
Calibrate_UR(
void
) {
5677
// get reference voltage, calibrate VCC with external 2.5V and
5678
// get the port output resistance
5679
5680
#ifdef AUTO_CAL
5681
uint16_t sum_rm;
// sum of 3 Pin voltages with 680 Ohm load
5682
uint16_t sum_rp;
// sum of 3 Pin voltages with 680 Ohm load
5683
uint16_t u680;
// 3 * (Voltage at 680 Ohm)
5684
#endif
5685
5686
//--------------------------------------------
5687
ADCconfig.U_AVCC = U_VCC;
// set initial VCC Voltage
5688
ADCconfig.Samples = 190;
// set number of ADC reads near to maximum
5689
5690
#if FLASHEND > 0x1fff
5691
ADC_PORT = TXD_VAL;
// switch to 0V
5692
ADC_DDR = (1<<TPREF) | TXD_MSK;
// switch pin with 2.5V reference to GND
5693
wait1ms();
5694
ADC_DDR = TXD_MSK;
// switch pin with reference back to input
5695
trans.uBE[1] = W5msReadADC(TPREF);
// read voltage of 2.5V precision reference
5696
5697
if
((trans.uBE[1] > 2250) && (trans.uBE[1] < 2750)) {
5698
// precision voltage reference connected, update U_AVCC
5699
WithReference = 1;
5700
ADCconfig.U_AVCC = (unsigned
long
)((unsigned
long
)ADCconfig.U_AVCC * 2495) / trans.uBE[1];
5701
}
5702
#endif
5703
5704
#ifdef WITH_AUTO_REF
5705
(
void
) ReadADC(MUX_INT_REF);
// read reference voltage
5706
ref_mv = W5msReadADC(MUX_INT_REF);
// read reference voltage
5707
RefVoltage();
// compute RHmultip = f(reference voltage)
5708
#else
5709
ref_mv = DEFAULT_BAND_GAP;
// set to default Reference Voltage
5710
#endif
5711
5712
ADCconfig.U_Bandgap = ADC_internal_reference;
// set internal reference voltage for ADC
5713
5714
//--------------------------------------------
5715
5716
#ifdef AUTO_CAL
5717
// measurement of internal resistance of the ADC port outputs switched to GND
5718
ADC_DDR = 1<<TP1 | TXD_MSK;
// ADC-Pin 1 to output 0V
5719
R_PORT = 1<<(TP1*2);
// R_L-PORT 1 to VCC
5720
R_DDR = 1<<(TP1*2);
// Pin 1 to output and over R_L to VCC
5721
sum_rm = W5msReadADC(TP1);
5722
5723
ADC_DDR = 1<<TP2 | TXD_MSK;
// ADC-Pin 2 to output 0V
5724
R_PORT = 1<<(TP2*2);
// R_L-PORT 2 to VCC
5725
R_DDR = 1<<(TP2*2);
// Pin 2 to output and over R_L to VCC
5726
sum_rm += W5msReadADC(TP2);
5727
5728
ADC_DDR = 1<<TP3 | TXD_MSK;
// ADC-Pin 3 to output 0V
5729
R_PORT = 1<<(TP3*2);
// R_L-PORT 3 to VCC
5730
R_DDR = 1<<(TP3*2);
// Pin 3 to output and over R_L to VCC
5731
sum_rm += W5msReadADC(TP3);
// add all three values
5732
5733
// measurement of internal resistance of the ADC port output switched to VCC
5734
R_PORT = 0;
// R-Ports to GND
5735
ADC_PORT = 1<<TP1 | TXD_VAL;
// ADC-Port 1 to VCC
5736
ADC_DDR = 1<<TP1 | TXD_MSK;
// ADC-Pin 1 to output 0V
5737
R_DDR = 1<<(TP1*2);
// Pin 1 to output and over R_L to GND
5738
sum_rp = ADCconfig.U_AVCC - W5msReadADC(TP1);
5739
5740
ADC_PORT = 1<<TP2 | TXD_VAL;
// ADC-Port 2 to VCC
5741
ADC_DDR = 1<<TP2 | TXD_MSK;
// ADC-Pin 2 to output 0V
5742
R_DDR = 1<<(TP2*2);
// Pin 2 to output and over R_L to GND
5743
sum_rp += ADCconfig.U_AVCC - W5msReadADC(TP2);
5744
5745
ADC_PORT = 1<<TP3 | TXD_VAL;
// ADC-Port 3 to VCC
5746
ADC_DDR = 1<<TP3 | TXD_MSK;
// ADC-Pin 3 to output 0V
5747
R_DDR = 1<<(TP3*2);
// Pin 3 to output and over R_L to GND
5748
sum_rp += ADCconfig.U_AVCC - W5msReadADC(TP3);
5749
5750
u680 = ((ADCconfig.U_AVCC * 3) - sum_rm - sum_rp);
// three times the voltage at the 680 Ohm
5751
pin_rmi = (unsigned
long
)((unsigned
long
)sum_rm * (unsigned
long
)R_L_VAL) / (unsigned
long
)u680;
5752
//adcmv[2] = pin_rm; // for last output in row 2
5753
pin_rpl = (unsigned
long
)((unsigned
long
)sum_rp * (unsigned
long
)R_L_VAL) / (unsigned
long
)u680;
5754
resis680pl = pin_rpl + R_L_VAL;
5755
resis680mi = pin_rmi + R_L_VAL;
5756
#endif
5757
5758
ADCconfig.Samples = ANZ_MESS;
// set to configured number of ADC samples
5759
}
5760
5761
/* -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- */
5762
5763
// Interfacing a HD44780 compatible LCD with 4-Bit-Interface mode
5764
5765
#ifdef STRIP_GRID_BOARD
5766
#warning "strip-grid-board layout selected!"
5767
#endif
5768
5769
void
lcd_set_cursor(uint8_t row, uint8_t col)
5770
{
5771
#ifdef LCD1602
5772
int
row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
5773
if
( row >= 2 ) {
5774
row = 1;
5775
}
5776
lcd.command(CMD_SetDDRAMAddress | (col + row_offsets[row]));
5777
#endif
5778
5779
#ifdef NOK5110
5780
lcd.setCursor(6*col, 10*row);
5781
#endif
5782
5783
uart_newline();
5784
}
5785
5786
void
lcd_string(
char
*data) {
5787
while
(*data) {
5788
lcd_data(*data);
5789
data++;
5790
}
5791
}
5792
5793
void
lcd_pgm_string(
const
unsigned
char
*data) {
5794
unsigned
char
cc;
5795
while
(1) {
5796
cc = pgm_read_byte(data);
5797
if
((cc == 0) || (cc == 128))
return
;
5798
lcd_data(cc);
5799
data++;
5800
}
5801
}
5802
5803
void
lcd_pgm_custom_char(uint8_t location,
const
unsigned
char
*chardata) {
5804
#ifdef LCD1602
5805
location &= 0x7;
5806
lcd.command(CMD_SetCGRAMAddress | (location << 3));
5807
for
(uint8_t i=0;i<8;i++) {
5808
lcd.write(pgm_read_byte(chardata));
5809
chardata++;
5810
}
5811
#endif
5812
}
5813
5814
// sends numeric character (Pin Number) to the LCD
5815
// from binary 0 we send ASCII 1
5816
void
lcd_testpin(unsigned
char
temp) {
5817
lcd_data(temp +
'1'
);
5818
}
5819
5820
// send space character to LCD
5821
void
lcd_space(
void
) {
5822
lcd_data(
' '
);
5823
}
5824
5825
void
lcd_fix_string(
const
unsigned
char
*data) {
5826
unsigned
char
cc;
5827
while
(1) {
5828
cc = MEM_read_byte(data);
5829
if
((cc == 0) || (cc == 128))
return
;
5830
lcd_data(cc);
5831
data++;
5832
}
5833
}
5834
5835
// sends data byte to the LCD
5836
void
lcd_data(unsigned
char
temp1) {
5837
#ifdef LCD1602
5838
lcd.write(temp1);
5839
#endif
5840
5841
#ifdef NOK5110
5842
lcd.write(temp1);
5843
#endif
5844
5845
#ifdef LCD2004
5846
lcd.write(temp1);
5847
#endif
5848
5849
switch
(temp1) {
5850
case
LCD_CHAR_DIODE1: {
5851
uart_putc(
'>'
); uart_putc(
'|'
);
break
;
5852
}
5853
case
LCD_CHAR_DIODE2: {
5854
uart_putc(
'|'
); uart_putc(
'<'
);
break
;
5855
}
5856
case
LCD_CHAR_CAP: {
5857
uart_putc(
'|'
); uart_putc(
'|'
);
break
;
5858
}
5859
case
LCD_CHAR_RESIS1:
5860
case
LCD_CHAR_RESIS2: {
5861
uart_putc(
'R'
);
break
;
5862
}
5863
case
LCD_CHAR_U: {
// micro
5864
uart_putc(
'u'
);
// ASCII u
5865
break
;
5866
}
5867
case
LCD_CHAR_OMEGA: {
// Omega
5868
uart_putc(
'o'
);
// "ohm"
5869
uart_putc(
'h'
);
5870
uart_putc(
'm'
);
break
;
5871
}
5872
default
: {
5873
uart_putc(temp1);
5874
}
5875
}
5876
}
5877
5878
void
lcd_clear(
void
) {
5879
#ifdef LCD1602
5880
lcd.clear();
5881
#endif
5882
5883
#ifdef LCD2004
5884
lcd.clear();
5885
#endif
5886
5887
#ifdef NOK5110
5888
lcd.clearDisplay();
5889
#endif
5890
5891
uart_newline();
5892
}
5893
5894
void
uart_putc(uint8_t data) {
5895
Serial
.write(data);
5896
delay(2);
5897
}
Благодарю! Завтра попробую
Все отлично работает, только сменил код модуля дисплея
Добрый день. Помогите пожалуста. Собрал tt108001 NANO V3.0 LCD1602A. Заливал скейчи с начала темы - Arduino1.6.12 выдаетошибки и с поста 115 пишет - ошибка компиляции для платы Arduino NANO. Подскажите ход действий, желательно подробней - я только начал пробовать изучать ардуино.
И подскажите как вставить снимок экрана - пробовал, неполучается - отправляет на внешний сервер.
С уважением!
Добрый день. Помогите пожалуста. Собрал tt108001 NANO V3.0 LCD1602A. Заливал скейчи с начала темы - Arduino1.6.12 выдаетошибки и с поста 115 пишет - ошибка компиляции для платы Arduino NANO. Подскажите ход действий, желательно подробней - я только начал пробовать изучать ардуино.
Не поленился, добавил себе Arduino IDE 1.6.12 - скетч tt108001 у меня компилируется без проблем:
Скетч использует 15 296 байт (49%) памяти устройства. Всего доступно 30 720 байт.
Глобальные переменные используют 383 байт (18%) динамической памяти, оставляя 1 665 байт для локальных переменных. Максимум: 2 048 байт.
Для подробного хода действий не хватает информации (на что ругается компилятор).
И подскажите как вставить снимок экрана - пробовал, неполучается - отправляет на внешний сервер.
http://arduino.ru/forum/obshchii/sokhranenie-kartinok-na-forume
Кто бы сомневался)))
ЗЫ nikolyalomaev включите в рацион творог
Какой такой творог?)
обычный, молочный продукт
Програмирую при помощи arduino 1.6.12 заливаю скейч tt108001, программа выдает ошибки. Естествено я их исправить не могу. Скоптровал скейч с поста 115, вставил в программу, нажал проверку - программа выдает сообщение - "ошибка компиляции для платы arduino nano" и снизу в окне куча текста на английском.
А если я Вам сброшу на почту снимки экрана, может быть Вы сможете мне помочь разобраться в этом поле информации?
С уважением Сергей.
Наконец-то получилось загрузить. Вот, что выдает программа, если я загружаю скейч с поста 115.
Вот, что выдает программа, если я загружаю скейч с поста 115.
Скорее всего, у вас не установлена библиотека LiquidCrystal_I2C (ссылка на неё дана в посте 110).
Скетч в посте 115 отредактирован ua6em (к нему все вопросы).
Спасибо за помощь, библиотеки скачал. Буду обращаться к ua6em.
Уважаемый ua6em, у меня на сей момент похожая ситуация, которую Вы описали в посте 109 - не совпадение выводов в скейче со схемой, схему прилагаю
Подскажите пожалуйста, что Вы делали, по возможности подробней, т.к. я совсем в этой теме зеленый. Заранее благодарен. Сергей
всем привет, у меня проблема, загрузил скетчи все которые только тут были, все компилируется но почему то не работает.... горят квадратики слабенько верхний ряд, проверял дисплей и конвертер i2c все работает, SDA и SCLдисплея подключать к А4, А5 или к SDA SCL дуины? перепробовал все варианты не было изменений, может я что-то делаю не так((
у меня проблема, загрузил скетчи все которые только тут были, все компилируется но почему то не работает.... горят квадратики слабенько верхний ряд, проверял дисплей и конвертер i2c все работает,
В скетче из поста 18 раскомментировали нужные строки?
SDA и SCL дисплея подключать к А4, А5 или к SDA SCL дуины?
Для Arduino Uno/Nano/ProMini это равнозначно, а на других Ардуинах (Mega, Leonardo) скетч не проверял.
у меня проблема, загрузил скетчи все которые только тут были, все компилируется но почему то не работает.... горят квадратики слабенько верхний ряд, проверял дисплей и конвертер i2c все работает,
В скетче из поста 18 раскомментировали нужные строки?
SDA и SCL дисплея подключать к А4, А5 или к SDA SCL дуины?
Для Arduino Uno/Nano/ProMini это равнозначно, а на других Ардуинах (Mega, Leonardo) скетч не проверял.
раскоментил 1602 i2c только одну же строку нужно раскоментить? из-за сопротивлений возможны глюки? когда нажимаю тест кнопку чуток притухает дсплей
не совпадение выводов в скейче со схемой, схему прилагаю
ArduTester07f
Подскажите пожалуйста, что Вы делали, по возможности подробней, т.к. я совсем в этой теме зеленый. Заранее благодарен. Сергей
Вы оказывается скетч ArduTester07f компилируете. Он в моих архивах только для примера приведён, так как автор его 3 года назад забросил. Компиляцию он проходит, но за работоспособность его не ручаюсь.
раскоментил 1602 i2c только одну же строку нужно раскоментить?
В посте 18 написано: Для дисплея LCD 1602 с I2C-интерфейсом комментарий снимается с двух строк: #define LCD1602 и #define LCD_I2C.
А #define NOK5110 нужно закомментировать.
раскоментил 1602 i2c только одну же строку нужно раскоментить?
В посте 18 написано: Для дисплея LCD 1602 с I2C-интерфейсом комментарий снимается с двух строк: #define LCD1602 и #define LCD_I2C.
А #define NOK5110 нужно закомментировать.
#define LCD1602
#define LCD_I2C
//#define NOK5110
вот так выставлено,но эфекта нет(((( у меня дисплей синий , в этом может быть дело?
у меня дисплей синий , в этом может быть дело?
Я так понимаю, что у синего просто подсветка по другому сделана.
А в Serial Monitor скетч что-нибудь выдаёт?
у меня дисплей синий , в этом может быть дело?
Я так понимаю, что у синего просто подсветка по другому сделана.
А в Serial Monitor скетч что-нибудь выдаёт?
TransistorTester
forArduino 1.08a
Ttester 1.08.2
testing...A
2-||-3 Vloss=1.6%
177.7uF ESR=21ohm
щас там стоит 100нан,без него тоже примерно такое же значение показывает
Спасибо за помощь, библиотеки скачал. Буду обращаться к ua6em.
Нужна билиотека I2C, без неё не заработает
щас там стоит 100нан,без него тоже примерно такое же значение показывает
Взял свой скетч из поста 18 (раскомментировал/закомментировал нужное), соединил детальки как описано в постах 2,3,5 и с конденсатором 100 нФ получил следующий результат:
Serial Monitor выдал аналогичное:
TransistorTester
forArduino 1.08a
Ttester 1.08.2
testing...
1-||-3 Vloss=1.0%
109.9nF ESR=16ohm
щас там стоит 100нан,без него тоже примерно такое же значение показывает
Взял свой скетч из поста 18 (раскомментировал/закомментировал нужное), соединил детальки как описано в постах 2,3,5 и с конденсатором 100 нФ получил следующий результат:
Serial Monitor выдал аналогичное:
TransistorTester
forArduino 1.08a
Ttester 1.08.2
testing...
1-||-3 Vloss=1.0%
109.9nF ESR=16ohm
я не сомневаюсь в работоспособности кода, если я подключу чисто дисплей без всех делителей чтобы проверить чисто дисплей он будет работать? или нужно обязательно все резисторы ставить?
будет!
По дисплею I2C
1. Залить программу определяющую адрес дисплея, смотрим в мониторинге порта
2. В коде инициализации дисплея подставляем этот адрес (скетча)
если я подключу чисто дисплей без всех делителей чтобы проверить чисто дисплей он будет работать? или нужно обязательно все резисторы ставить?
Ниже скетч, который выдаёт адреса для I2C-устройств (I2C_scanner):
01
#include <Wire.h>
02
03
void
setup
()
04
{
05
Wire.begin();
06
Serial
.begin(9600);
07
I2Cscanner();
08
}
09
10
void
loop
() {}
11
12
void
I2Cscanner()
13
{
14
byte
error, address;
15
int
nDevices;
16
17
Serial
.println(
"I2C Scanner"
);
18
19
nDevices = 0;
20
for
(address = 1; address < 127; address++)
21
{
22
Wire.beginTransmission(address);
23
error = Wire.endTransmission();
24
25
if
(error == 0)
26
{
27
Serial
.print(
"I2C device found at address 0x"
);
28
if
(address < 16)
29
Serial
.print(
"0"
);
30
Serial
.println(address,HEX);
31
32
nDevices++;
33
}
34
else
if
(error == 4)
35
{
36
Serial
.print(
"Unknow error at address 0x"
);
37
if
(address < 16)
38
Serial
.print(
"0"
);
39
Serial
.println(address,HEX);
40
}
41
}
42
43
if
(nDevices == 0)
44
Serial
.println(
"No I2C devices found"
);
45
else
{
46
Serial
.print(
"Found "
);
47
Serial
.print(nDevices);
48
Serial
.println(
" devices"
);
49
}
50
51
Serial
.println();
52
}
Полученный адрес вставляется в строку 1253 скетча tt108002.ino вместо 0x3F:
LiquidCrystal_I2C lcd(0x3F, 16, 2);
если я подключу чисто дисплей без всех делителей чтобы проверить чисто дисплей он будет работать? или нужно обязательно все резисторы ставить?
Ниже скетч, который выдаёт адреса для I2C-устройств (I2C_scanner):
01
#include <Wire.h>
02
03
void
setup
()
04
{
05
Wire.begin();
06
Serial
.begin(9600);
07
I2Cscanner();
08
}
09
10
void
loop
() {}
11
12
void
I2Cscanner()
13
{
14
byte
error, address;
15
int
nDevices;
16
17
Serial
.println(
"I2C Scanner"
);
18
19
nDevices = 0;
20
for
(address = 1; address < 127; address++)
21
{
22
Wire.beginTransmission(address);
23
error = Wire.endTransmission();
24
25
if
(error == 0)
26
{
27
Serial
.print(
"I2C device found at address 0x"
);
28
if
(address < 16)
29
Serial
.print(
"0"
);
30
Serial
.println(address,HEX);
31
32
nDevices++;
33
}
34
else
if
(error == 4)
35
{
36
Serial
.print(
"Unknow error at address 0x"
);
37
if
(address < 16)
38
Serial
.print(
"0"
);
39
Serial
.println(address,HEX);
40
}
41
}
42
43
if
(nDevices == 0)
44
Serial
.println(
"No I2C devices found"
);
45
else
{
46
Serial
.print(
"Found "
);
47
Serial
.print(nDevices);
48
Serial
.println(
" devices"
);
49
}
50
51
Serial
.println();
52
}
Полученный адрес вставляется в строку 1253 скетча tt108002.ino вместо 0x3F:
LiquidCrystal_I2C lcd(0x3F, 16, 2);
спасибо, вечером попробую
Р.S. все работает спасибо, но показания всеравно какие то не такие, подключил резистор на 10 кОм он пишет No unknown or damaged part, либо как будто конденсатор на 170vrA? это может быть связано с тем что собрано на макетке беспаячной?
показания всеравно какие то не такие, подключил резистор на 10 кОм он пишет No unknown or damaged part, либо как будто конденсатор на 170vrA? это может быть связано с тем что собрано на макетке беспаячной?
Возможно из-за плохого контакта на беспаечной макетной плате. Ещё светодиод на пине 13 иногда мешает.
Но я недолго с беспаечной макеткой экспериментировал. Как понял, что с 6 резисторами Ардуина может как транзистор-тестер работать, так сразу спаял плату, которую и показал в посте 3.
показания всеравно какие то не такие, подключил резистор на 10 кОм он пишет No unknown or damaged part, либо как будто конденсатор на 170vrA? это может быть связано с тем что собрано на макетке беспаячной?
Возможно из-за плохого контакта на беспаечной макетной плате. Ещё светодиод на пине 13 иногда мешает.
Но я недолго с беспаечной макеткой экспериментировал. Как понял, что с 6 резисторами Ардуина может как транзистор-тестер работать, так сразу спаял плату, которую и показал в посте 3.
))) понял, макетки под рукой нету, придется травить,спасибо за помощь
Интересно, а появится ли когда нибудь прошивка и программа к PC, что бы результаты измерений видеть не на экранчике, а на мониторе (там графичеких возможностей поболе)?
Интересно, а появится ли когда нибудь прошивка и программа к PC, что бы результаты измерений видеть не на экранчике, а на мониторе (там графичеких возможностей поболе)?
Скетчи выдают результаты также и в Serial Monitor, так что желающие могут сделать программу для PC и изображать измерения в любом удобном виде на мониторе.
Спасибо, кто откликнулся на мои просьбы! Схема была собрана на макетке, сегодня разобрал ее и снова собрал аналогично, как в посту 3. Скейч с 1 поста залился, но при включении яркость дисплея и надписи яркие, затем начинают тухнуть и становятся еле видными. Сейчас немного проветрюсь, займусь снова, но прогресс на лицо - это уже радует!!! Как отлажу, выложу фото.
Спасибо, кто откликнулся на мои просьбы! Схема была собрана на макетке, сегодня разобрал ее и снова собрал аналогично, как в посту 3. Скейч с 1 поста залился, но при включении яркость дисплея и надписи яркие, затем начинают тухнуть и становятся еле видными. Сейчас немного проветрюсь, займусь снова, но прогресс на лицо - это уже радует!!! Как отлажу, выложу фото.
если дисплей от нокии то у них помоему у большинства проблема с прилеганием резинок к плате... я такой выкинул так и не смог побороть такую как у тебя проблему
при включении яркость дисплея и надписи яркие, затем начинают тухнуть и становятся еле видными
В библиотеке LiquidCrystal-I2C есть команды для включения/отключения подсветки:
lcd.backlight();
lcd.noBacklight();
не машает ли ему на 13 пине светодиод дуинывский?
Не помню в каких случаях, но светодиод на 13 пине мне мешал, поэтому на Nano я его удалил (точнее удалил резистор к нему - о чём и написал в посте 3).