Универсальный Ардуино пробник

svm
Offline
Зарегистрирован: 06.11.2016
Дело было вечером, делать было нечего. Оглядел все свои приборы и понял, что 
несмотря на то, что они могут достаточно много, а чаще всего используется простой тестер.
Но и у него есть недостатки. Во первых приходится щелкать переключателем, во вторых неудобно 
лазить щупами по мелким контактам и смотреть куда-то в сторну на прибор, рискуя 
устроить коротыш, ну и в третьих в постоянном бардаке на столе, в нужный момент его не 
всегда удается оперативно обнаружить. И вспомнил о старом добром пробнике.
Все умещается в самом щупе, необходимый минимум информации. Вот и решил сделать 
что-то подобное. В данном варианте пробник достаточно точно измеряет частоту до 8 Мгц, 
напряжения до 12 В, и сопротивления 1 ом-1МОм, при закороченных щупах или 
сопротивлении менее 1 ома пищит. Вывод информации на 4х разрядный 7 сегментный 
индикатор. Вот с индикацией пока проблема. 
Для напряжения и сопротивления 3х разрядов вроде хватает, четвертый показывает, что 
намерялось U R или F. При измерении резисторов если результат в омах, первый 
разряд показывает "o" или "r", если килоомы сверху еще черточка загорается. Вроде какая-то 
логика есть, а с частотой еще не придумал. Как возможный вариант - герцы нижний сегмент, 
килогерцы средний, мегагерцы верхний. Схема простейшая, никаких защит нет. Программа 
тоже не шедевр, особых навыков в программировании нет, собрана из нескольких 
разрозненных кусков. Ресурсов у контроллера еще много осталось, так что функционал можно 
расширять. Вывод на индикатор через серийный монитор, т.к. у меня индикатор на 
TM1650, который недостаточно распространен. Резисторы брались обычные, поэтому в программе корректировались под реальные значения.
Если у кого есть еще идеи, высказывайтесь. 


 #include <FreqCounter.h>
 unsigned long frq;
 long adc_buff;
 float u_del,u_izm,rez;
 byte ri;// режим измерения

//***************************************************************

void setup()
{
 Serial.begin(9600); 
}
void loop(){
start:

//****************************  ЧАСТОТОМЕР ******************************************
  ri=0;
  DDRB =  B00010000;         // 12 pin - out
  PORTB = B00010000;         // загрубляем вход (борьба с наводками)

 FreqCounter::f_comp=1050;   // Калибровочный коэффициент
 FreqCounter::start(1);   // 1ms Время пробного измерения
 while (FreqCounter::f_ready == 0) 
 frq=FreqCounter::f_freq;
 if (frq< 1)goto voltmeter;
 FreqCounter::start(1000);   // 1000ms Время измерения
 while (FreqCounter::f_ready == 0) 
 frq=FreqCounter::f_freq;
 rez=frq;
 goto vyv;
//**********************************************************************
//вольтметр
voltmeter:
   ri=1; 
  analogReference(INTERNAL);// включаем внутренний ИОН 1.1 В
  DDRB =  B00000100;         // 10 pin - out
  PORTB = B00000000;         // устанавливая его в 0(включаем нижний резистор делителя)
  delay(10);
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A3); }
adc_buff >>=4; // 16368 полная шкала 14bit
rez= (float)adc_buff/16368*12.335; //1.1*11.214 - реальный коэфф делителя
if (adc_buff > 15) goto vyv;   //если есть напряжения выводим - иначе измеряем сопротивление
//************************************************************************
rezist:
//#############################  4,7 kOm  ######################################
  analogReference(DEFAULT);// подключаем опорное 5 В
  ri=2;
  DDRB =  B00010000;         // 12 pin - out
  PORTB = B00010000;         // переводим его в 1 подключаем измерительный резистор 4.7 kOm
  delay(20);

// измеряем полное напряжение на делителе под нагрузкой
//**************************************************************
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A1); }
adc_buff >>=4; // 16368 full scale 14bit
u_del= (float)adc_buff/16368*5;

// измеряем напряжение на измеряемом резисторе
//**************************************************************
// сначала при опорном 5 В
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A3); }
adc_buff >>=4; // 16368 full scale 14bit
u_izm= (float)adc_buff/16368*5;
rez= float(u_izm*4710)/float(u_del-u_izm);// для 47 kOm
if (u_izm>=1.0) goto vyv;

//Если  точность не удовлетворяет переходим на опорное 1,1 В
analogReference(INTERNAL);// подключаем опорное 1.1 В
ri=3;
delay(20);
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A3); }
adc_buff >>=4; // 16368 full scale 14bit
u_izm= (float)adc_buff/16368*1.1;
rez= float(u_izm*4710)/float(u_del-u_izm);// для 4.7 kOm
if (u_izm> 0.1)goto vyv;
 
  //#############################  430 Om  ######################################
  analogReference(DEFAULT);// подключаем опорное 5 В
  ri=4;
  DDRB = B00001000;          // 11 pin - out
  PORTB = B00001000;         // переводим его в 1 подключаем измерительный резистор 470 Ом 
  delay(10);
// измеряем полное напряжение на делителе под нагрузкой
//**************************************************************
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A2); }
adc_buff >>=4; // 16368 full scale 14bit
u_del= (float)adc_buff/16368*5;

// измеряем напряжение на измеряемом резисторе
//**************************************************************
// сначала при опорном 5 В
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A3); }
adc_buff >>=4; // 16368 full scale 14bit
 u_izm= (float)adc_buff/16368*5;
rez= float(u_izm*433.8)/float(u_del-u_izm);// для 430 om
if (u_izm>=0.1) goto vyv;

//Если  точность не удовлетворяет переходим на опорное 1,1 В
analogReference(INTERNAL);// подключаем опорное 1.1 В
ri=5;
delay(10);
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A3); }
adc_buff >>=4; // 16368 full scale 14bit
u_izm= (float)adc_buff/16368*1.1;
(rez)= float(u_izm*433.8)/float(u_del-u_izm);// для 430 om
vyv:
if (ri==0){;
Serial.print(rez,1);
Serial.println(" - HZ");
goto start;
}
if (ri==1){;
Serial.print(rez,2);
Serial.println(" - Volt");
goto start;
}
if (rez> 999999){;     //Щуп в воздухе или сопроивление> 1 MOm
Serial.println("- ??? - ");
goto start;
}
if (rez< 1){;           //Щупы 3акорочены или сопроивление < 1 Om
pinMode(8, OUTPUT);     // выводим на 8 пин 0, подключаем спикер
digitalWrite(8,0);  
  Serial.println(" short ");
  delay(150);
goto start;
}
if (rez< 1000){;
Serial.print(rez,1);
Serial.println(" - OM");
goto start;
}
rez=rez/1000;
Serial.print(rez,1);
Serial.println(" - kOm");
goto start;
}

 

bwn
Offline
Зарегистрирован: 25.08.2014

Хм, интересненько, подпишусь. Тем более все собираюсь древний щуп реанимировать (еще Синклеры им отлаживал).

svm
Offline
Зарегистрирован: 06.11.2016

Сегодня собрал все на макетке и решил проверить все режимы. Вылез косяк при измерении частоты. Идея сначала бысьро и грубо измерить частоту, не проканала. Частомер показывает какую-то ахинею. Если вместо строк 21-30, вставить нормальный код частотомера

FreqCounter::f_comp=1050;   // Калибровочный коэффициент
 FreqCounter::start(1000);   // 1000 ms Время  измерения
 while (FreqCounter::f_ready == 0) 
 frq=FreqCounter::f_freq;
 rez=frq-1;
 if (frq>1)goto vyv;

то все работает нормально, но появляется секундная задержка. Для напряжений и сопротивлений это не критично и не ощущается, то в режиме прозвонки сильно раздражает. Может кто подскажет идею как быстро отловить наличие частоты хотя бы от 5 Герц. Снял небольшое видео работы концепта пробника

https://youtu.be/1FAHZERyiXc

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

svm пишет:

Может кто подскажет идею как быстро отловить наличие частоты хотя бы от 5 Герц.

А Вы определитесь, со скольки импульсов "отдельные импульсы" превращаются в "частоту".

Если с пяти штук, то для 5 Гц время измерения и будет 1 секунда.

svm
Offline
Зарегистрирован: 06.11.2016

Вот здесь собака и порылась. Хочется и чтобы частоту от 1 Гц показывал и время измерения сократить.

Если на входе есть некий меандр и частотомер отключен, то пробник по очереди показывает 4.8 В (логическая "1") и 20 Оm (логический "0" или сопротивление открытого транзистора ) и так где-то до 15 Гц. Дальше начинается цветомузыка. Если скважность сильно отличается от 50%, тоже показания хаотичные.

Поэтому и прихордится сначала проверять нет-ли изменений сигнала в момент измерений. Ну а насчет 5Гц и одной секунды, это вы немного переборщили. их и за 0,1 сек отловить можно. Скорее всего придется изменить алгоритм измерения частоты, но ввиду того, что сей девайс делался в дни защитников Отечества голова соображала достаточно туго.

bwn
Offline
Зарегистрирован: 25.08.2014

Как вариант визуально, имеется смена уровней на входе дублируем ее на какие нибудь сегменты индикатора. Видим мигание или непонятное свечение, задержали щуп измерили частоту. Те же 5Гц уже легко отслеживаются, 1-2 и меньше можно и прозевать.

svm
Offline
Зарегистрирован: 06.11.2016

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

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

интересненькая тема... будем следить

svm
Offline
Зарегистрирован: 06.11.2016

Лучше не только следить, а еще и идеи подкидывать.

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

svm пишет:

 Может кто подскажет идею как быстро отловить наличие частоты хотя бы от 5 Герц.

Для пробника частоты ниже 10 Гц особо и нет смысла измерять IMHO. Удобнее вывести например светодиод, который будет показывать наличие лог.1 и соответссно мигать, если на входе частота. Кстати и частотометр можно сделать полностью "фоновым", и не ожидать секунду тормозя всю программу, пока он измерит. Не знаю, можно ли в той библе так сделать, но без библы легко -как тут например.

svm
Offline
Зарегистрирован: 06.11.2016

dimax пишет:

svm пишет:

 Может кто подскажет идею как быстро отловить наличие частоты хотя бы от 5 Герц.

 Кстати и частотометр можно сделать полностью "фоновым", и не ожидать секунду тормозя всю программу, пока он измерит. Не знаю, можно ли в той библе так сделать, но без библы легко -как тут например.

Полностью согласен с Вашими высказываниями, но задача не в том чтобы измерить частоту-она решаема многими способами, а в том чтобы быстро определить есть-ли периодический сигнал с частотой более 10-15 Гц. До этих значений пробник показывает то напряжение то сопротивление в зависимости от логического уровня сигнала. Может быть и до более высоких частот , просто глаз уже не реагирует.

А измерение в фоновом режиме создаст ситуацию как в том анекдоте " А мужики- то и не знают" или басне "Лебедь рак и щука".

Частотомер в фоновом режиме измеряет частоту, а вольтметр или омметр (кому повезет) пытаются свое измерить. 

Вы достаточно свободно обращаетесь с таймерами, может нарисуете небольшую процедурку, которая за 50-100 мс определит что есть импульсы и не стоит измерять напряжение или сопртивление, а стоит померять частоту. А то старому больному пенсионеру, с кучей вредных привычек придется долго вникать и еще больше гробить здоровье.

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

svm пишет:

 может нарисуете небольшую процедурку, которая за 50-100 мс определит что есть импульсы и не стоит измерять напряжение или сопртивление, а стоит померять частоту.

Так у вас же это уже сделано в начале скетча, разве нет? Моё мнение что не стоит тратить время на определение частоты, всё равно будут вносить глюки помехи в момент касания с измеряемой точкой. Так что на полное устаканивание контакта и измерение нужно хотя бы секунды 2. А любое ожидание в режиме обычной прозвонки будет бесить.  Как вариант можно взять oled дисплей 128x32, и выводить на него все измеренные параметры одновременно.

svm
Offline
Зарегистрирован: 06.11.2016

dimax пишет:

  Как вариант можно взять oled дисплей 128x32, и выводить на него все измеренные параметры одновременно.

А как быть с габаритами? Прбник должен быть максимум в габаритах крупного маркера,  макимально информативен и легко читаем, а дисплей или будет очень большим, или нечитаемым без микроскопа, что все преимущества пробника сведет на нет.  Заняться этим проектом, я решил после того как сделал пультоскоп. С некоторыми допущениями он удовлетворяет вашему предложению и его можно использовать как пробник, но габариты дисплея делают его "несколько" неудобным. Да и чтобы считать информацию и правильно её интерпретировать нужно уже напрягаться.

А кусок в начале скетча работает очень странно, хотя и не тормозит. Основной частотомер начинает врать безбожно, после отработки тестового. Без тестового все нормально. Возможно есть конфликт с библиотекой I2C , она обслуживает дисплей на двух ТМ1650

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

svm, да не должно быть конфликтов, впрочем я ту библу не использовал, так что не знаю её особенностей. У меня есть пример частотометра попроще, с остановкой для измерения. Т.е. как в вашем сейчас. Можно поставить любую паузу,и  вычислить частоту. Только перед паузой нужно обнулить переменные int_tic и TCNT1, а то первое измерение будет неправильным.

svm
Offline
Зарегистрирован: 06.11.2016

Вечером попробую. Время измерения в 15 строке?

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Да. Если будет не секунда, то нужно будет соответственно умножить результат.

svm
Offline
Зарегистрирован: 06.11.2016

dimax пишет:

 У меня есть пример частотометра попроще,

Спасибо! Заработало и даже лучше чем ожидал. Тормозов практически нет (а если сам тормоз то и не заметишь)  измеряет от 1 Гц до 4 мГц (больше на Вашем генераторе не было).

                                                        Вот что в итоге получилось:


 // Входом частотомера является пин цифровой пин 5
 #include <Wire.h>
  volatile unsigned int int_tic=0; 
 volatile unsigned long tic; 

 long adc_buff,rezd;
 float u_del,u_izm,rez;
 byte ri;// режим измерения

//***************************************************************

void setup()
{
 Serial.begin(9600); 
 Wire.begin();
 TCCR1A=0; TIMSK1 = 1<<TOIE1; //прерывание по переполнению
 }
ISR (TIMER1_OVF_vect){ int_tic++; }

void loop(){
start:
  //****************************  ЧАСТОТОМЕР ******************************************
  ri=0;
  DDRB =  B00010000;         // 12 pin - out
  PORTB = B00000000;         // загрубляем вход (борьба с наводками)

pinMode (5,INPUT); // вход сигнала T1 (only для atmega328)
TCCR1B = (1<<CS10)|(1<<CS11)|(1<<CS12);//тактировани от входа Т1
delay(50);// Тестовый замер (срабатывает> 5 Гц 10 устойчиво)
TCCR1B=0;
tic= ((uint32_t)int_tic<<16) | TCNT1; //сложить что натикало
int_tic=0; TCNT1 = 0; 
rez=tic;
if (tic<1)goto voltmeter;
int_tic=0; TCNT1 = 0;
TCCR1B = (1<<CS10)|(1<<CS11)|(1<<CS12);//тактировани от входа Т1
delay(1000);// Время измерения
TCCR1B=0;
tic= ((uint32_t)int_tic<<16) | TCNT1; //сложить что натикало
//int_tic=0; TCNT1 = 0; 
rez=tic; goto vyv;
//**********************************************************************
//вольтметр
voltmeter:
   ri=1; 
  analogReference(INTERNAL);// включаем внутренний ИОН 1.1 В
  DDRB =  B00000100;         // 10 pin - out
  PORTB = B00000000;         // устанавливая его в 0(включаем нижний резистор делителя)
  delay(2);
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A3); }
adc_buff >>=4; // 16368 полная шкала 14bit
rez= (float)adc_buff/16368.0*12.335; //1.1*11.214 - реальный коэфф делителя
if (adc_buff > 15) goto vyv;   //если есть напряжения выводим - иначе измеряем сопротивление
//************************************************************************
rezist:
//#############################  4,7 kOm  ######################################
  analogReference(DEFAULT);// подключаем опорное 5 В
  ri=2;
  DDRB =  B00010000;         // 12 pin - out
  PORTB = B00010000;         // переводим его в 1 подключаем измерительный резистор 4.7 kOm
  delay(2);

// измеряем полное напряжение на делителе под нагрузкой
//**************************************************************
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A1); }
adc_buff >>=4; // 16368 full scale 14bit
u_del= (float)adc_buff/16368*5;

// измеряем напряжение на измеряемом резисторе
//**************************************************************
// сначала при опорном 5 В
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A3); }
adc_buff >>=4; // 16368 full scale 14bit
u_izm= (float)adc_buff/16368*5;
rez= float(u_izm*4710)/float(u_del-u_izm);// для 47 kOm
if (u_izm>=1.0) goto vyv;

//Если  точность не удовлетворяет переходим на опорное 1,1 В
analogReference(INTERNAL);// подключаем опорное 1.1 В
ri=3;
delay(2);
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A3); }
adc_buff >>=4; // 16368 full scale 14bit
u_izm= (float)adc_buff/16368*1.1;
rez= float(u_izm*4710)/float(u_del-u_izm);// для 4.7 kOm
if (u_izm> 0.1)goto vyv;
 
  //#############################  430 Om  ######################################
  analogReference(DEFAULT);// подключаем опорное 5 В
  ri=4;
  DDRB = B00001000;          // 11 pin - out
  PORTB = B00001000;         // переводим его в 1 подключаем измерительный резистор 470 Ом 
  delay(2);
// измеряем полное напряжение на делителе под нагрузкой
//**************************************************************
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A2); }
adc_buff >>=4; // 16368 full scale 14bit
u_del= (float)adc_buff/16368*5;

// измеряем напряжение на измеряемом резисторе
//**************************************************************
// сначала при опорном 5 В
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A3); }
adc_buff >>=4; // 16368 full scale 14bit
 u_izm= (float)adc_buff/16368*5;
rez= float(u_izm*433.8)/float(u_del-u_izm);// для 430 om
if (u_izm>=0.1) goto vyv;

//Если  точность не удовлетворяет переходим на опорное 1,1 В
analogReference(INTERNAL);// подключаем опорное 1.1 В
ri=5;
delay(2);
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A3); }
adc_buff >>=4; // 16368 full scale 14bit
u_izm= (float)adc_buff/16368*1.1;
(rez)= float(u_izm*433.8)/float(u_del-u_izm);// для 430 om
vyv:
vdspl();// Вывод на 7 сегментный дисплей
if (ri==0){;
Serial.print(rez,1);
Serial.println(" - HZ");
goto start;
}
if (ri==1){;
Serial.print(rez,5);
Serial.println(" - Volt");
goto start;
}
if (rez> 7999999){;     //Щуп в воздухе или сопроивление> 1 MOm
Serial.println("- ??? - ");
goto start;
}
if (rez< 1){;           //Щупы 3акорочены или сопроивление < 1 Om
pinMode(8, OUTPUT);     // выводим на 8 пин 0, подключаем спикер
digitalWrite(8,1);  
  Serial.println(" short ");
  delay(250);
goto start;
}
if (rez< 1000){;
Serial.print(rez,1);
Serial.println(" - OM");
goto start;
}
rez=rez/1000;
Serial.print(ri);
Serial.println(" - ri");
Serial.print(rez,1);
Serial.println(" - kOm");
goto start;
}

Вывод на дисплей наверное не стоит показывать, он достаточно большой, корявый и не очень понятный. У меня используются два дисплея на ТМ1650 плюс два транзистора для переключения I2C шины. Да и дисплеи не имеют десятичных точек,а только двоеточие. Откуда и заморочки.

Спикер активный, включается в 148 строке.

Ну и снова вопрос - что еще можно добавить малой кровью?

Напрягаем фантазию.

arduinec
Offline
Зарегистрирован: 01.09.2015

svm пишет:

Ну и снова вопрос - что еще можно добавить?

Измерение ESR без выпаивания конденсатора, по аналогии с такими:
http://www.joyta.ru/4139-esr-metr-kondensatorov-svoimi-rukami/
http://radio-konst.narod.ru/moi_konstrukcii/per_ESR/per_ESR.htm

А ещё лучше: сделать аналог электронного пинцета для измерения у элементов на плате R, C, L.

svm
Offline
Зарегистрирован: 06.11.2016

arduinec пишет:

 

Измерение ESR без выпаивания конденсатора.
А ещё лучше: сделать аналог электронного пинцета для измерения у элементов на плате R, C, L.

Это уже несколько другой уровень. Я больше планировал пробник для поиска неисправностей в платах на Ардуино, и питаться от них же. А для пинцета желательно автономное питание. Хотя в принципе если не гнаться за высокой точностью, то можно и ESR померять. Хотя-бы оценочно -рабочий кондюк или в мусорку. В принципе измерение ESR это тоже измерение сопротивления, но не на постоянке, а на достаточно низких частотах. 

Соберу в корпус сделаю нормальные щупы и попробую. Сейчас достаточно сильно влияют наводки и показания в младших разрядач плавают. скорее всего придется экранировать. Может быть стоит на аналоговых входах небольшие кондючки поставить. Да и скетч нужно проанализировать и причесать.

svm
Offline
Зарегистрирован: 06.11.2016

Вылез еще один косяк.  Настроил делитель напряжения и коэффициенты для измерительных резисторов, вывод делал на терминал. Все удовлетворяло. Подключил дисплей из 8 индикаторов и все полетело к чертям. Мало того, что показания (особенно омметра) сильно не соответствуют действительности да еще и прыгают два, а то и три разряда.  Для контроля запустил измерение напряжения питания. Оказалось , что оно прыгает от 4,8 до 5,16 вольта, хотя тестер показывает строго 4,95 В. При отключении дисплея, показания стабильны. Возможно неудачный монтаж на макетке, возможно USB не тянет. Придется разбираться с питанием.

svm
Offline
Зарегистрирован: 06.11.2016

С питанием раэобрался. Виновник всего дисплей. При выводе информации по питанию идет мусор около 1 вольта.

От него удалось избавиться поставив на входе питания индикаторов  дроссель  и конденсатор на 1000 мкф.

После этого мусор по питанию исчез и стало возможно использовать фактическое значение напряжения питания, вместо абстрактных опорных 5 вольт при измерениях. На работу вольтметра и частотомера зто никак не повлияло,а измерение сопротивлений стало более адекватным. 

Но влияние индикатора при питании от USB все равно заметно. При включенной индикации напряжение питания просаживается на 0,3 - 0,5 вольта в зависимости от количества горящих разрядов.

При использовании 5 амперного БП, это зффект практически  не наблюдается. Полностью избавиться от влияния индикатора удалось только запретом работы индикатора на время измерения сопртивлений. Но в зтом случае индикатор подмаргивает.

Кардинально от этого избавиться можно только раздельными стабилизаторами питания измерительной части и индикации.

 

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

svm - нубский вопрос. На вашей схеме нет второго щупа. Куда он сажается - на GND?

svm
Offline
Зарегистрирован: 06.11.2016

b707 пишет:

svm - нубский вопрос. На вашей схеме нет второго щупа. Куда он сажается - на GND?

Да, все измерения относительно земли.

bwn
Offline
Зарегистрирован: 25.08.2014

svm пишет:

Но влияние индикатора при питании от USB все равно заметно. При включенной индикации напряжение питания просаживается на 0,3 - 0,5 вольта в зависимости от количества горящих разрядов.

Специально не проверял, но мне кажется это очень сильная просадка. Попробуйте более толстый провод по питанию или раздельные к дисплею и МК.

 

svm
Offline
Зарегистрирован: 06.11.2016

bwn пишет:

svm пишет:

Но влияние индикатора при питании от USB все равно заметно. При включенной индикации напряжение питания просаживается на 0,3 - 0,5 вольта в зависимости от количества горящих разрядов.

Специально не проверял, но мне кажется это очень сильная просадка. Попробуйте более толстый провод по питанию или раздельные к дисплею и МК.

 

Сейчас пмтается от USB, точишко там небольшой поэтому и просадка такая. Да и индикатор потребляет немало. Восемь разрядов по семь сегментов это уже 56 светодиодов. Если по 10 мА - то уже почти 600 мА.

svm
Offline
Зарегистрирован: 06.11.2016

Сегодня немного изменил схему (для удобства навесного монтажа голой  328)

Соответственно и скетч пришлось подкорректировать.


 
 // Входом частотомера является пин цифровой пин 5
 #include <Wire.h>
  volatile unsigned int int_tic=0; 
 volatile unsigned long tic; 

 long adc_buff,rezd;
 float u_del,u_izm,rez;
 byte ri;// режим измерения

//***************************************************************

void setup()
{
 Serial.begin(9600); 
 Wire.begin();
 TCCR1A=0; TIMSK1 = 1<<TOIE1; //прерывание по переполнению
 }
ISR (TIMER1_OVF_vect){ int_tic++; }

void loop(){
start:
pinMode(2, INPUT);// 2 пин высокий импеданс
pinMode(3, INPUT);// 3 пин высокий импеданс
pinMode(4, INPUT);// 4 пин высокий импеданс
pinMode(8, OUTPUT);     // выводим на 8 пин 0, выключаем спикер
digitalWrite(8,0); 
  
  //****************************  ЧАСТОТОМЕР ******************************************
  ri=0;
pinMode(4, OUTPUT);        // выводим на 4 пин 0
digitalWrite(4,0);         // загрубляем вход (борьба с наводками)

pinMode (5,INPUT); // вход сигнала T1 (only для atmega328)
TCCR1B = (1<<CS10)|(1<<CS11)|(1<<CS12);//тактировани от входа Т1
delay(50);// Тестовый замер (срабатывает> 5 Гц 10 устойчиво)
TCCR1B=0;
tic= ((uint32_t)int_tic<<16) | TCNT1; //сложить что натикало
//int_tic=0; TCNT1 = 0; 
rez=tic;
if (tic<1)goto voltmeter;
int_tic=0; TCNT1 = 0;
TCCR1B = (1<<CS10)|(1<<CS11)|(1<<CS12);//тактировани от входа Т1
delay(1000);// Время измерения
TCCR1B=0;
tic= ((uint32_t)int_tic<<16) | TCNT1; //сложить что натикало
//int_tic=0; TCNT1 = 0; 
rez=tic; goto vyv;
//**********************************************************************
//вольтметр
voltmeter:
   ri=1; 
  analogReference(INTERNAL);// включаем внутренний ИОН 1.1 В
pinMode(4, OUTPUT);        // выводим на 4 пин 0
digitalWrite(4,0);         // устанавливая его в 0(включаем нижний резистор делителя)
  delay(2);
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A0); }
adc_buff >>=4; // 16368 полная шкала 14bit
rez= (float)adc_buff/16368.0*12.335; //1.1*11.214 - реальный коэфф делителя
if (adc_buff > 150) goto vyv;   //если есть напряжения выводим - иначе измеряем сопротивление
//************************************************************************
rezist:
// ---------------ВЫКЛЮЧЕНИЕ ДИСПЛЕЕВ---------------------
// для устранения просадки питания при измерениях
pinMode(7, OUTPUT);     // выводим на 7 пин 1, разрешаем обмен с 1 дисплеем
digitalWrite(7,1); 
pinMode(6, OUTPUT);     // выводим на 6 пин 1, разрешаем обмен с 2 дисплеем
digitalWrite(6,1);
Wire.beginTransmission(0x24);      //обращаемся к любому порту 0х24-0х27
   Wire.write(0b0000000);//         режим, отображение дисплеев ОFF
Wire.endTransmission();            // закрываем сессию

//#############################  4,7 kOm  ######################################
  analogReference(DEFAULT);// подключаем опорное 5 В
  ri=2;
pinMode(4, INPUT);         // 4 пин высокий импеданс
pinMode(3, OUTPUT);        // 3 пин выход
digitalWrite(3,1);         // переводим его в 1 подключаем измерительный резистор 4.7 kOm
  delay(3);

// измеряем полное напряжение на делителе под нагрузкой
//**************************************************************
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A1); }
adc_buff >>=4; // 16368 full scale 14bit
u_del= (float)adc_buff/16368*readVcc();

// измеряем напряжение на измеряемом резисторе
//**************************************************************
// сначала при опорном 5 В
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A0); }
adc_buff >>=4; // 16368 full scale 14bit
u_izm= (float)adc_buff/16368*readVcc();
rez= float(u_izm*4710)/float(u_del-u_izm);// для 4,7 kOm
if (u_izm>=0.99) goto vyv;

//Если  точность не удовлетворяет переходим на опорное 1,1 В
analogReference(INTERNAL);// подключаем опорное 1.1 В
ri=3;
delay(3);
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A0); }
adc_buff >>=4; // 16368 full scale 14bit
u_izm= (float)adc_buff/16368*1.1;
rez= float(u_izm*4710)/float(u_del-u_izm);// для 4.7 kOm
if (u_izm> 0.1)goto vyv;
 
  //#############################  430 Om  ######################################
  analogReference(DEFAULT);// подключаем опорное 5 В
  ri=4;
pinMode(3, INPUT);         // 3 пин высокий импеданс
pinMode(2, OUTPUT);        // 2 пин выход
digitalWrite(2,1);         // переводим его в 1 подключаем измерительный резистор 470 Ом 
  delay(2);
// измеряем полное напряжение на делителе под нагрузкой
//**************************************************************
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A2); }
adc_buff >>=4; // 16368 full scale 14bit
u_del= (float)adc_buff/16368*readVcc();

// измеряем напряжение на измеряемом резисторе
//**************************************************************
// сначала при опорном 5 В
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A0); }
adc_buff >>=4; // 16368 full scale 14bit
 u_izm= (float)adc_buff/16368*readVcc();
rez= float(u_izm*433.8)/float(u_del-u_izm);// для 430 om
if (u_izm>=0.99) goto vyv;

//Если  точность не удовлетворяет переходим на опорное 1,1 В
analogReference(INTERNAL);// подключаем опорное 1.1 В
ri=5;
delay(2);
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A0); }
adc_buff >>=4; // 16368 full scale 14bit
u_izm= (float)adc_buff/16368*1.1;
(rez)= float(u_izm*433.8)/float(u_del-u_izm);// для 430 om
vyv:
/////////////////////////////////////////////////////////////////////////

pinMode(2, INPUT);// 2 пин высокий импеданс
pinMode(3, INPUT);// 3 пин высокий импеданс
pinMode(4, INPUT);// 4 пин высокий импеданс
vdspl();// Вывод на 7 сегментный дисплей !!!! закомментировать или написать свой вывод
Serial.print(rez,5);
Serial.println(" - Out Data");

Serial.print(readVcc());// фактическое напряжение питания
Serial.println(" - Ucc");

goto start;//!!!!!!!!!!!!!! закомментировать если нужен вывод в серийный монитор
Serial.print(ri);
Serial.println(" - REJIM)");
if (ri==0){;
Serial.print(rez,1);
Serial.println(" - HZ");
goto start;
}
if (ri==1){;
Serial.print(rez,5);
Serial.println(" - Volt");
goto start;
}
if (rez> 7999999){;     //Щуп в воздухе или сопроивление> 1 MOm
Serial.println("- ??? - ");
goto start;
}
if (rez >=0 && rez < 1){;           //Щупы 3акорочены или сопроивление < 1 Om
pinMode(8, OUTPUT);     // выводим на 8 пин 0, подключаем спикер
digitalWrite(8,1);  
  Serial.print(rez,5);
  Serial.println(" short ");
  delay(100);
goto start;
}
if (rez< 1000){;
Serial.print(rez,1);
Serial.println(" - OM");
goto start;
}
rez=rez/1000;
Serial.print(ri);
Serial.println(" - ri");
Serial.print(rez,1);
Serial.println(" - kOm");
goto start;
}
long readVcc() {
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  result = (1100L * 1023)/result;
  result=result/1000;
  return result;
}
yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

Занятный девайс получился. Для компактности можно думаю экранчик прикрутить 0.91 дюймов OLED 128х32. Извеняюсь если уже предлогали.
Тогда можно и простенький осциллограф прикрутить. Ещё думаю нужна защита входов от перенапряжния.

svm
Offline
Зарегистрирован: 06.11.2016

Я навеное ограничусь, тем что есть. Сейчас уже печатается корпус. Так, что менять уже поздно. Да и экранчик в моем возрасте уже сложно разглядеть. А семисегментные индикаторы еще вижу и пищалку пока слышу. Но возможности программной модернизации я предусмотрел. В торце кроме питания выведены RX,TX и DTR/

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

С Вашего разрешения предложу немного оптимизированный код

Повторяющуюся часть кода вынес в отдельную функцию, которая принимает номер аналогового входа и возвращает значение в 14бит

int adc14BitRead(byte Ain){
  adc_buff=0;
  for (int n=0; n<=255; n++ ) {
    adc_buff+= analogRead(Ain); 
  }
  return  adc_buff >>=4; // 16368 полная шкала 14bit
}

Код похудел на 466 байт.

Полный код



// Входом частотомера является пин цифровой пин 5
#include <Wire.h>
volatile unsigned int int_tic=0; 
volatile unsigned long tic; 

long adc_buff,rezd;
float u_del,u_izm,rez;
byte ri;// режим измерения

//***************************************************************

void setup()
{
  Serial.begin(9600); 
  Wire.begin();
  TCCR1A=0; 
  TIMSK1 = 1<<TOIE1; //прерывание по переполнению
}
ISR (TIMER1_OVF_vect){ 
  int_tic++; 
}

//функция чтения с АЦП в 14 бит 
int adc14BitRead(byte Ain){
  adc_buff=0;
  for (int n=0; n<=255; n++ ) {
    adc_buff+= analogRead(Ain); 
  }
  return  adc_buff >>=4; // 16368 полная шкала 14bit
}

void loop(){
start:
  pinMode(2, INPUT);// 2 пин высокий импеданс
  pinMode(3, INPUT);// 3 пин высокий импеданс
  pinMode(4, INPUT);// 4 пин высокий импеданс
  pinMode(8, OUTPUT);     // выводим на 8 пин 0, выключаем спикер
  digitalWrite(8,0); 

  //****************************  ЧАСТОТОМЕР ******************************************
  ri=0;
  pinMode(4, OUTPUT);        // выводим на 4 пин 0
  digitalWrite(4,0);         // загрубляем вход (борьба с наводками)

  pinMode (5,INPUT); // вход сигнала T1 (only для atmega328)
  TCCR1B = (1<<CS10)|(1<<CS11)|(1<<CS12);//тактировани от входа Т1
  delay(50);// Тестовый замер (срабатывает> 5 Гц 10 устойчиво)
  TCCR1B=0;
  tic= ((uint32_t)int_tic<<16) | TCNT1; //сложить что натикало
  //int_tic=0; TCNT1 = 0; 
  rez=tic;
  if (tic<1)goto voltmeter;
  int_tic=0; 
  TCNT1 = 0;
  TCCR1B = (1<<CS10)|(1<<CS11)|(1<<CS12);//тактировани от входа Т1
  delay(1000);// Время измерения
  TCCR1B=0;
  tic= ((uint32_t)int_tic<<16) | TCNT1; //сложить что натикало
  //int_tic=0; TCNT1 = 0; 
  rez=tic; 
  goto vyv;
  //**********************************************************************
  //вольтметр
voltmeter:
  ri=1; 
  analogReference(INTERNAL);// включаем внутренний ИОН 1.1 В
  pinMode(4, OUTPUT);        // выводим на 4 пин 0
  digitalWrite(4,0);         // устанавливая его в 0(включаем нижний резистор делителя)
  delay(2);
  adc_buff=adc14BitRead(A0);//чтение с аналогового входа с разрешением 14 бит
  rez= (float)adc_buff/16368.0*12.335; //1.1*11.214 - реальный коэфф делителя
  if (adc_buff > 150) goto vyv;   //если есть напряжения выводим - иначе измеряем сопротивление
  //************************************************************************
rezist:
  // ---------------ВЫКЛЮЧЕНИЕ ДИСПЛЕЕВ---------------------
  // для устранения просадки питания при измерениях
  pinMode(7, OUTPUT);     // выводим на 7 пин 1, разрешаем обмен с 1 дисплеем
  digitalWrite(7,1); 
  pinMode(6, OUTPUT);     // выводим на 6 пин 1, разрешаем обмен с 2 дисплеем
  digitalWrite(6,1);
  Wire.beginTransmission(0x24);      //обращаемся к любому порту 0х24-0х27
  Wire.write(0b0000000);//         режим, отображение дисплеев ОFF
  Wire.endTransmission();            // закрываем сессию

  //#############################  4,7 kOm  ######################################
  analogReference(DEFAULT);// подключаем опорное 5 В
  ri=2;
  pinMode(4, INPUT);         // 4 пин высокий импеданс
  pinMode(3, OUTPUT);        // 3 пин выход
  digitalWrite(3,1);         // переводим его в 1 подключаем измерительный резистор 4.7 kOm
  delay(3);

  // измеряем полное напряжение на делителе под нагрузкой
  //**************************************************************
  adc_buff=adc14BitRead(A1);
  u_del= (float)adc_buff/16368*readVcc();

  // измеряем напряжение на измеряемом резисторе
  //**************************************************************
  // сначала при опорном 5 В
  adc_buff=adc14BitRead(A0);
  u_izm= (float)adc_buff/16368*readVcc();
  rez= float(u_izm*4710)/float(u_del-u_izm);// для 4,7 kOm
  if (u_izm>=0.99) goto vyv;

  //Если  точность не удовлетворяет переходим на опорное 1,1 В
  analogReference(INTERNAL);// подключаем опорное 1.1 В
  ri=3;
  delay(3);
  adc_buff=adc14BitRead(A0);
  u_izm= (float)adc_buff/16368*1.1;
  rez= float(u_izm*4710)/float(u_del-u_izm);// для 4.7 kOm
  if (u_izm> 0.1)goto vyv;

  //#############################  430 Om  ######################################
  analogReference(DEFAULT);// подключаем опорное 5 В
  ri=4;
  pinMode(3, INPUT);         // 3 пин высокий импеданс
  pinMode(2, OUTPUT);        // 2 пин выход
  digitalWrite(2,1);         // переводим его в 1 подключаем измерительный резистор 470 Ом 
  delay(2);
  // измеряем полное напряжение на делителе под нагрузкой
  //**************************************************************
  adc_buff=adc14BitRead(A2);
  u_del= (float)adc_buff/16368*readVcc();

  // измеряем напряжение на измеряемом резисторе
  //**************************************************************
  // сначала при опорном 5 В
  adc_buff=adc14BitRead(A0);
  u_izm= (float)adc_buff/16368*readVcc();
  rez= float(u_izm*433.8)/float(u_del-u_izm);// для 430 om
  if (u_izm>=0.99) goto vyv;

  //Если  точность не удовлетворяет переходим на опорное 1,1 В
  analogReference(INTERNAL);// подключаем опорное 1.1 В
  ri=5;
  delay(2);
  adc_buff=adc14BitRead(A0);
  u_izm= (float)adc_buff/16368*1.1;
  (rez)= float(u_izm*433.8)/float(u_del-u_izm);// для 430 om
vyv:
  /////////////////////////////////////////////////////////////////////////

  pinMode(2, INPUT);// 2 пин высокий импеданс
  pinMode(3, INPUT);// 3 пин высокий импеданс
  pinMode(4, INPUT);// 4 пин высокий импеданс
  //vdspl();// Вывод на 7 сегментный дисплей !!!! закомментировать или написать свой вывод
  Serial.print(rez,5);
  Serial.println(" - Out Data");

  Serial.print(readVcc());// фактическое напряжение питания
  Serial.println(" - Ucc");

  goto start;//!!!!!!!!!!!!!! закомментировать если нужен вывод в серийный монитор
  Serial.print(ri);
  Serial.println(" - REJIM)");
  if (ri==0){
    ;
    Serial.print(rez,1);
    Serial.println(" - HZ");
    goto start;
  }
  if (ri==1){
    ;
    Serial.print(rez,5);
    Serial.println(" - Volt");
    goto start;
  }
  if (rez> 7999999){
    ;     //Щуп в воздухе или сопроивление> 1 MOm
    Serial.println("- ??? - ");
    goto start;
  }
  if (rez >=0 && rez < 1){
    ;           //Щупы 3акорочены или сопроивление < 1 Om
    pinMode(8, OUTPUT);     // выводим на 8 пин 0, подключаем спикер
    digitalWrite(8,1);  
    Serial.print(rez,5);
    Serial.println(" short ");
    delay(100);
    goto start;
  }
  if (rez< 1000){
    ;
    Serial.print(rez,1);
    Serial.println(" - OM");
    goto start;
  }
  rez=rez/1000;
  Serial.print(ri);
  Serial.println(" - ri");
  Serial.print(rez,1);
  Serial.println(" - kOm");
  goto start;
}
long readVcc() {
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  result = (1100L * 1023)/result;
  result=result/1000;
  return result;
}





 

svm
Offline
Зарегистрирован: 06.11.2016

yul-i-an пишет:

С Вашего разрешения предложу немного оптимизированный код

Код похудел на 466 байт.

Спасибо, получилось гораздо красивее. Там еще много что оптимизировать можно. В первом варианте, когда переключение резисторов шло через прямое управление портами, код тоже был заметно короче и красивее , но т.к. с целью упрощения монтажа я поменял порты появилась возможность нарушить обмен вывода на терминал. В отработанной конструкции это будет не актуально и можно снова вернуться к прямому управлению. 

Как я понял, Вы не только оптимизировали код но и реально попробовали этот пробничек?

svm
Offline
Зарегистрирован: 06.11.2016

Сделал пробный вариант корпуса. Делал на "вырост" в ширину взял 21мм, чтобы две пальчиковые батарейки или аккумуляторы влезли. Глубину продиктовал спикер. Монтаж навесной. Но мне кажется в такие габариты корпуса влезут многие платки ардуино, просто у меня еще штук 5 голых 328 осталось и еще 20 на подходе. После того как вставил пробник в корпус увидел, что там много свободного места. И появилась мысль часы  туда запихнуть. Пусть вместо пустого табло время показывает.

Ну и пара фоток - пробник снаружи и изнутри и монтаж спереди и сзади.

 

bwn
Offline
Зарегистрирован: 25.08.2014

svm пишет:

 

Жестокий, грубый человек.))) Так бедной Атмеге лапки заплести.))))

svm
Offline
Зарегистрирован: 06.11.2016

bwn пишет:

 

Жестокий, грубый человек.))) Так бедной Атмеге лапки заплести.))))

Дык, она-ж Китаянка. Они могут и не такие позы принимать. Главное, что ей это нравится раз  она выполняет  все мои прихоти!

Зато мне гемморою нет: берешь паяльник ЭПСН-60,  канифоль сосновую, проводочки цветные, кучку радиодеталей и все это лепишь к чуду иноземному. Никакого ЛУТу, фоторезисту и прочей хрени нужной в массовом производстве

Но снаружи-то все вполне пристойно?)))

bwn
Offline
Зарегистрирован: 25.08.2014

Штука действительно неплохая получилась, до реанимации своего доберусь, на печатке буду делать.

cray
Offline
Зарегистрирован: 25.01.2018

Еле нашел понравившийся мне 10 лет назад простой пробник на атмеге8 - http://radiokot.ru/circuit/digital/measure/12/

Одна проблемка - доступен только hex прошивки.

bwn
Offline
Зарегистрирован: 25.08.2014

Ну наверно еще и стабик или супрессор на вход будет не лишним, мало ли ткнешь не туда. Правда режим сопротивлений и пробник придется подкорректировать.

Novice User
Offline
Зарегистрирован: 25.09.2017

Сложно ли переделать под SSD1306?

            Заинтересовало... )))

Можно еще генератор добавить,индикатор  лог 0 и лог 1

Буду пока разводить платку...

svm
Offline
Зарегистрирован: 06.11.2016

Novice User пишет:

Сложно ли переделать под SSD1306?

Можно еще генератор добавить,индикатор  лог 0 и лог 1

1. Я специально не приводил скетч вывода на индикатор, а только в монитор, как говорят: "В каждой избушке - свои погремушки". Закомментируйте или удалите вывод в монитор и выводите на свой дисплей. Или ждите пока кто-то не сделает и выложит готовый скетч. Кстати в программе есть места , которые отвечают конкретно за мои индикаторы (отключение индикации на время измерения сопротивлений). которые многим могут не понадобиться. А они занимают два пина D6, D7 для переключения шины I2C на два моих дисплея с одинаковыми адресами.

2. Можно все, только придется добавить элементы управления, а насчет логического "0" или "1" вопрос неоднозначный. Еденицу можно отловить по напряжению (скажем от 3В и выше) , а с нолем есть небольшая проблема. Если выход нагружен на высокоомную нагрузку, то "0" определяется как 19-23 Ома если низкоомная- то напряжение от 0 с небольшим до 1 вольта. И что взять за "0" ?????

Novice User
Offline
Зарегистрирован: 25.09.2017

1.Понятно,сам не подумал что исходник открытый

2.Спаяю,посмотрю что можно сделать

контакт "щуп F,U,R" соединяется только с 4 резисторами и все?

прошу простить меня за глупые вопросы...

svm
Offline
Зарегистрирован: 06.11.2016

Novice User пишет:

контакт "щуп F,U,R" соединяется только с 4 резисторами и все?

Да.

Novice User
Offline
Зарегистрирован: 25.09.2017

Платку нарисовал,предусмотрел зарядник и цепь вкл/выкл из схемы транзистотестера  https://img.mysku-st.ru/uploads/images/02/55/13/2014/07/29/6a7ae4.jpg  ,начну травить/паять,а там разберемся...

 

svm
Offline
Зарегистрирован: 06.11.2016

Да с питанием есть проблемы. При питании от USB на разных компьютерах показания не сильно, но отличаются. Особенно при измерении сопротивлений ниже 20 Ом. Пробовал поставить диод защиты от переполюсовки, врать начинает безбожно. Нужно или питать от большего напряжения и стабилизатор или преобразователь STEP UP.  И еще неплохо-бы отдельный стабилизатор на опорное напряжение около 5 В. Но в принципе для пробника и так сойдет. Это для тех кто не спеша отработает и схему и код. У меня уже в корпусе и заклеен китайскими соплями. Так что есть возможность только программной доработки. 

Вот небольшой видео ролик по крайней версии:

https://youtu.be/BC9ahA5oUQw

А это предыдущая:

https://youtu.be/1FAHZERyiXc

 

Novice User
Offline
Зарегистрирован: 25.09.2017

можно последнюю версию скетча?

svm
Offline
Зарегистрирован: 06.11.2016


 // Входом частотомера является пин цифровой пин 5
 #include <Wire.h>
  volatile unsigned int int_tic=0; 
 volatile unsigned long tic; 

 long adc_buff,rezd;
 float u_del,u_izm,rez;
 byte ri;// режим измерения

//***************************************************************

void setup()
{
 Serial.begin(9600); 
 Wire.begin();
 TCCR1A=0; TIMSK1 = 1<<TOIE1; //прерывание по переполнению
 }
ISR (TIMER1_OVF_vect){ int_tic++; }

void loop(){
start:
pinMode(2, INPUT);// 2 пин высокий импеданс
pinMode(3, INPUT);// 3 пин высокий импеданс
pinMode(4, INPUT);// 4 пин высокий импеданс
pinMode(8, OUTPUT);     // выводим на 8 пин 0, выключаем спикер
digitalWrite(8,0); 
  
  //****************************  ЧАСТОТОМЕР ******************************************
  ri=0;
pinMode(4, OUTPUT);        // выводим на 4 пин 0
digitalWrite(4,0);         // загрубляем вход (борьба с наводками)

pinMode (5,INPUT); // вход сигнала T1 (only для atmega328)
TCCR1B = (1<<CS10)|(1<<CS11)|(1<<CS12);//тактировани от входа Т1
delay(50);// Тестовый замер (срабатывает> 5 Гц 10 устойчиво)
TCCR1B=0;
tic= ((uint32_t)int_tic<<16) | TCNT1; //сложить что натикало
//int_tic=0; TCNT1 = 0; 
rez=tic;
if (tic<1)goto voltmeter;
int_tic=0; TCNT1 = 0;
TCCR1B = (1<<CS10)|(1<<CS11)|(1<<CS12);//тактировани от входа Т1
delay(1000);// Время измерения
TCCR1B=0;
tic= ((uint32_t)int_tic<<16) | TCNT1; //сложить что натикало
//int_tic=0; TCNT1 = 0; 
rez=tic; goto vyv;
//**********************************************************************
//вольтметр
voltmeter:
   ri=1; 
  analogReference(INTERNAL);// включаем внутренний ИОН 1.1 В
pinMode(4, OUTPUT);        // выводим на 4 пин 0
digitalWrite(4,0);         // устанавливая его в 0(включаем нижний резистор делителя)
  delay(2);
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A0); }
adc_buff >>=4; // 16368 полная шкала 14bit
rez= (float)adc_buff/16368.0*6.133;//12.335; //1.1*11.214 - реальный коэфф делителя
if (adc_buff > 150) goto vyv;   //если есть напряжения выводим - иначе измеряем сопротивление
//************************************************************************
rezist:
// ---------------ВЫКЛЮЧЕНИЕ ДИСПЛЕЕВ---------------------
// для устранения просадки питания при измерениях
pinMode(7, OUTPUT);     // выводим на 7 пин 1, разрешаем обмен с 1 дисплеем
digitalWrite(7,1); 
pinMode(6, OUTPUT);     // выводим на 6 пин 1, разрешаем обмен с 2 дисплеем
digitalWrite(6,1);
Wire.beginTransmission(0x24);      //обращаемся к любому порту 0х24-0х27
   Wire.write(0b0000000);//         режим, отображение дисплеев ОFF
Wire.endTransmission();            // закрываем сессию

//#############################  4,7 kOm  ######################################
  analogReference(DEFAULT);// подключаем опорное 5 В
  ri=2;
pinMode(4, INPUT);         // 4 пин высокий импеданс
pinMode(3, OUTPUT);        // 3 пин выход
digitalWrite(3,1);         // переводим его в 1 подключаем измерительный резистор 4.7 kOm
  delay(3);

// измеряем полное напряжение на делителе под нагрузкой
//**************************************************************
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A1); }
adc_buff >>=4; // 16368 full scale 14bit
u_del= (float)adc_buff/16368*readVcc();

// измеряем напряжение на измеряемом резисторе
//**************************************************************
// сначала при опорном 5 В
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A0); }
adc_buff >>=4; // 16368 full scale 14bit
u_izm= (float)adc_buff/16368*readVcc();
rez= float(u_izm*4710)/float(u_del-u_izm);// для 4,7 kOm
if (u_izm>0.99) goto vyv;

//Если  точность не удовлетворяет переходим на опорное 1,1 В
analogReference(INTERNAL);// подключаем опорное 1.1 В
ri=3;
delay(3);
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A0); }
adc_buff >>=4; // 16368 full scale 14bit
u_izm= (float)adc_buff/16368*1.1;
rez= float(u_izm*4710)/float(u_del-u_izm);// для 4.7 kOm
Serial.print(u_izm);
Serial.println(" -222    REJIM)");

if (u_izm> 0.1)goto vyv;
 
  //#############################  430 Om  ######################################
  analogReference(DEFAULT);// подключаем опорное 5 В
  ri=4;
pinMode(3, INPUT);         // 3 пин высокий импеданс
pinMode(2, OUTPUT);        // 2 пин выход
digitalWrite(2,1);         // переводим его в 1 подключаем измерительный резистор 470 Ом 
  delay(2);
// измеряем полное напряжение на делителе под нагрузкой
//**************************************************************
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A2); }
adc_buff >>=4; // 16368 full scale 14bit
u_del= (float)adc_buff/16368*readVcc();

// измеряем напряжение на измеряемом резисторе
//**************************************************************
// сначала при опорном 5 В
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A0); }
adc_buff >>=4; // 16368 full scale 14bit
 u_izm= (float)adc_buff/16368*readVcc();
rez= float(u_izm*705)/float(u_del-u_izm);// для 430 om
if (u_izm>=0.99) goto vyv;

//Если  точность не удовлетворяет переходим на опорное 1,1 В
analogReference(INTERNAL);// подключаем опорное 1.1 В
ri=5;
delay(2);
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A0); }
adc_buff >>=4; // 16368 full scale 14bit
u_izm= (float)adc_buff/16368*1.1;
(rez)= float(u_izm*767)/float(u_del-u_izm);// для 430 om
vyv:
/////////////////////////////////////////////////////////////////////////

pinMode(2, INPUT);// 2 пин высокий импеданс
pinMode(3, INPUT);// 3 пин высокий импеданс
pinMode(4, INPUT);// 4 пин высокий импеданс
vdspl();// Вывод на 7 сегментный дисплей !!!! закомментировать или написать свой вывод
Serial.print(rez,5);
Serial.println(" - Out Data");

Serial.print(readVcc());// фактическое напряжение питания
Serial.println(" - Ucc");

//goto start;//!!!!!!!!!!!!!! закомментировать если не нужен вывод в серийный монитор
Serial.print(ri);
Serial.println(" - REJIM)");
if (ri==0){;
Serial.print(rez,1);
Serial.println(" - HZ");
goto start;
}
if (ri==1){;
Serial.print(rez,5);
Serial.println(" - Volt");
goto start;
}
if (rez> 7999999){;     //Щуп в воздухе или сопроивление> 1 MOm
Serial.println("- ??? - ");
goto start;
}
if (rez >=0 && rez < 1){;           //Щупы 3акорочены или сопроивление < 1 Om
pinMode(8, OUTPUT);     // выводим на 8 пин 0, подключаем спикер
digitalWrite(8,1);  
  Serial.print(rez,5);
  Serial.println(" short ");
  delay(100);
goto start;
}
if (rez< 1000){;
Serial.print(rez,1);
Serial.println(" - OM");
goto start;
}
rez=rez/1000;
Serial.print(ri);
Serial.println(" - ri");
Serial.print(rez,1);
Serial.println(" - kOm");
goto start;
}
long readVcc() {
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  result = (1100L * 1023)/result;
  return result/1000;
}

В принципе скетч не менялся, возможно только номиналы резисторов, т.к. я их брал со старых плат и особо не заморачивался с номиналами +- 20%.

Novice User
Offline
Зарегистрирован: 25.09.2017

спасибо!я уже вытравил платку,буду паять,а потом изучать ардуино среду,я почти ноль в нем...

Novice User
Offline
Зарегистрирован: 25.09.2017

спаял,мой скетч

// Входом частотомера является пин цифровой пин 5
#include <OLED_I2C.h>
#include <Wire.h>
OLED  myOLED(SDA, SCL, 8);

extern uint8_t SmallFont[];
extern uint8_t MediumNumbers[];
extern uint8_t BigNumbers[];


  volatile unsigned int int_tic=0; 
 volatile unsigned long tic; 

 long adc_buff,rezd;
 float u_del,u_izm,rez;
 byte ri;// режим измерения

//***************************************************************

void setup()
{
 myOLED.begin();
  myOLED.setFont(SmallFont); 
 Serial.begin(9600); 
 Wire.begin();
 TCCR1A=0; TIMSK1 = 1<<TOIE1; //прерывание по переполнению
 }
ISR (TIMER1_OVF_vect){ int_tic++; }

void loop(){
start:
pinMode(2, INPUT);// 2 пин высокий импеданс
pinMode(3, INPUT);// 3 пин высокий импеданс
pinMode(4, INPUT);// 4 пин высокий импеданс
pinMode(8, OUTPUT);     // выводим на 8 пин 0, выключаем спикер
digitalWrite(8,0); 
  
  //****************************  ЧАСТОТОМЕР ******************************************
  ri=0;
pinMode(4, OUTPUT);        // выводим на 4 пин 0
digitalWrite(4,0);         // загрубляем вход (борьба с наводками)

pinMode (5,INPUT); // вход сигнала T1 (only для atmega328)
TCCR1B = (1<<CS10)|(1<<CS11)|(1<<CS12);//тактировани от входа Т1
delay(50);// Тестовый замер (срабатывает> 5 Гц 10 устойчиво)
TCCR1B=0;
tic= ((uint32_t)int_tic<<16) | TCNT1; //сложить что натикало
//int_tic=0; TCNT1 = 0; 
rez=tic;
if (tic<1)goto voltmeter;
int_tic=0; TCNT1 = 0;
TCCR1B = (1<<CS10)|(1<<CS11)|(1<<CS12);//тактировани от входа Т1
delay(1000);// Время измерения
TCCR1B=0;
tic= ((uint32_t)int_tic<<16) | TCNT1; //сложить что натикало
//int_tic=0; TCNT1 = 0; 
rez=tic; goto vyv;
//**********************************************************************
//вольтметр
voltmeter:
   ri=1; 
  analogReference(INTERNAL);// включаем внутренний ИОН 1.1 В
pinMode(4, OUTPUT);        // выводим на 4 пин 0
digitalWrite(4,0);         // устанавливая его в 0(включаем нижний резистор делителя)
  delay(2);
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A0); }
adc_buff >>=4; // 16368 полная шкала 14bit
rez= (float)adc_buff/16368.0*6.133;//12.335; //1.1*11.214 - реальный коэфф делителя
if (adc_buff > 150) goto vyv;   //если есть напряжения выводим - иначе измеряем сопротивление
//************************************************************************
rezist:
// ---------------ВЫКЛЮЧЕНИЕ ДИСПЛЕЕВ---------------------
// для устранения просадки питания при измерениях
pinMode(7, OUTPUT);     // выводим на 7 пин 1, разрешаем обмен с 1 дисплеем
digitalWrite(7,1); 
pinMode(6, OUTPUT);     // выводим на 6 пин 1, разрешаем обмен с 2 дисплеем
digitalWrite(6,1);
Wire.beginTransmission(0x24);      //обращаемся к любому порту 0х24-0х27
   Wire.write(0b0000000);//         режим, отображение дисплеев ОFF
Wire.endTransmission();            // закрываем сессию

//#############################  4,7 kOm  ######################################
  analogReference(DEFAULT);// подключаем опорное 5 В
  ri=2;
pinMode(4, INPUT);         // 4 пин высокий импеданс
pinMode(3, OUTPUT);        // 3 пин выход
digitalWrite(3,1);         // переводим его в 1 подключаем измерительный резистор 4.7 kOm
  delay(3);

// измеряем полное напряжение на делителе под нагрузкой
//**************************************************************
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A1); }
adc_buff >>=4; // 16368 full scale 14bit
u_del= (float)adc_buff/16368*readVcc();

// измеряем напряжение на измеряемом резисторе
//**************************************************************
// сначала при опорном 5 В
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A0); }
adc_buff >>=4; // 16368 full scale 14bit
u_izm= (float)adc_buff/16368*readVcc();
rez= float(u_izm*4710)/float(u_del-u_izm);// для 4,7 kOm
if (u_izm>0.99) goto vyv;

//Если  точность не удовлетворяет переходим на опорное 1,1 В
analogReference(INTERNAL);// подключаем опорное 1.1 В
ri=3;
delay(3);
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A0); }
adc_buff >>=4; // 16368 full scale 14bit
u_izm= (float)adc_buff/16368*1.1;
rez= float(u_izm*4710)/float(u_del-u_izm);// для 4.7 kOm
Serial.print(u_izm);
Serial.println(" -222    REJIM)");

if (u_izm> 0.1)goto vyv;
 
  //#############################  430 Om  ######################################
  analogReference(DEFAULT);// подключаем опорное 5 В
  ri=4;
pinMode(3, INPUT);         // 3 пин высокий импеданс
pinMode(2, OUTPUT);        // 2 пин выход
digitalWrite(2,1);         // переводим его в 1 подключаем измерительный резистор 470 Ом 
  delay(2);
// измеряем полное напряжение на делителе под нагрузкой
//**************************************************************
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A2); }
adc_buff >>=4; // 16368 full scale 14bit
u_del= (float)adc_buff/16368*readVcc();

// измеряем напряжение на измеряемом резисторе
//**************************************************************
// сначала при опорном 5 В
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A0); }
adc_buff >>=4; // 16368 full scale 14bit
 u_izm= (float)adc_buff/16368*readVcc();
rez= float(u_izm*705)/float(u_del-u_izm);// для 430 om
if (u_izm>=0.99) goto vyv;

//Если  точность не удовлетворяет переходим на опорное 1,1 В
analogReference(INTERNAL);// подключаем опорное 1.1 В
ri=5;
delay(2);
adc_buff=0;
for (int n=0; n<=255; n++ ) {
adc_buff+= analogRead(A0); }
adc_buff >>=4; // 16368 full scale 14bit
u_izm= (float)adc_buff/16368*1.1;
(rez)= float(u_izm*767)/float(u_del-u_izm);// для 430 om
vyv:
/////////////////////////////////////////////////////////////////////////

pinMode(2, INPUT);// 2 пин высокий импеданс
pinMode(3, INPUT);// 3 пин высокий импеданс
pinMode(4, INPUT);// 4 пин высокий импеданс
//vdspl();// Вывод на 7 сегментный дисплей !!!! закомментировать или написать свой вывод
Serial.println(" - Out Data");
Serial.print(rez,5);

  // 
Serial.println(" - Ucc");
Serial.print(readVcc());// фактическое напряжение питания

//goto start;//!!!!!!!!!!!!!! закомментировать если не нужен вывод в серийный монитор
Serial.print(ri);
Serial.println(" - REJIM)");
myOLED.clrScr();
if (ri==0){;
Serial.print(rez,1);
myOLED.setFont(BigNumbers);
myOLED.printNumI(rez,LEFT, 10);
myOLED.update();
Serial.println(" - HZ");
myOLED.setFont(SmallFont);
myOLED.print(" - HZ", LEFT, 0);
myOLED.update();
goto start;
}
if (ri==1){;
Serial.print(rez,5);
myOLED.setFont(BigNumbers);
myOLED.printNumI(rez,LEFT, 10);
myOLED.update();
Serial.println(" - Volt");
myOLED.setFont(SmallFont);
myOLED.print(" - Volt", LEFT, 0);
myOLED.update();
goto start;
}
if (rez> 7999999){;     //Щуп в воздухе или сопроивление> 1 MOm
Serial.println("- ??? - ");
myOLED.setFont(SmallFont);
myOLED.print("- ??? - ", LEFT, 0);
myOLED.update();
goto start;
}
if (rez >=0 && rez < 1){;           //Щупы 3акорочены или сопроивление < 1 Om
pinMode(8, OUTPUT);     // выводим на 8 пин 0, подключаем спикер
digitalWrite(8,1);  
  Serial.print(rez,5);
  myOLED.setFont(BigNumbers);
  myOLED.printNumI(rez,LEFT, 10);
  myOLED.update();
  Serial.println(" short ");
  myOLED.setFont(SmallFont);
  myOLED.print(" short ", LEFT, 0);
  myOLED.update();
  delay(100);
goto start;
}
if (rez< 1000){;
Serial.print(rez,1);
myOLED.setFont(BigNumbers);
myOLED.printNumI(rez,LEFT, 10);
myOLED.update();
myOLED.setFont(SmallFont);
myOLED.print(" - OM", LEFT, 0);
myOLED.update();
Serial.println(" - OM");
goto start;
}
rez=rez/1000;
Serial.print(ri);
myOLED.setFont(BigNumbers);
myOLED.printNumI(ri,LEFT, 10);
myOLED.update();
myOLED.setFont(SmallFont);
myOLED.print(" - ri", LEFT, 0);
myOLED.update();
Serial.println(" - ri");
Serial.print(rez,1);
myOLED.setFont(BigNumbers);
myOLED.printNumI(rez,LEFT, 10);
myOLED.update();
myOLED.setFont(SmallFont);
myOLED.print(" - kOm", LEFT, 0);
myOLED.update();
Serial.println(" - kOm");
goto start;
}
long readVcc() {
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  result = (1100L * 1023)/result;
  return result/1000;
}

 

Novice User
Offline
Зарегистрирован: 25.09.2017

что должно быть при разомкнутых щупах?у меня меняется -???- и "ОМ" и аж восьмизначное число

 

частотомер измеряет довольно точно до 4 МГц,выше не проверял

svm
Offline
Зарегистрирован: 06.11.2016

Novice User пишет:

что должно быть при разомкнутых щупах?у меня меняется -???- и "ОМ" и аж восьмизначное число

 

частотомер измеряет довольно точно до 4 МГц,выше не проверял

В терминале у меня то-же самое, а на дисплей вывод блокируется , уходит в спячку. и ждет реальных данных.

Сейчас пытался окончательно выставить значения измерительных резисторов, оказалось что по сравнению с начальным скетчем работает некорректно. Виновао измерение собственного U питания. измеряет нормально, но при делении отбрасывается дробная часть. Отсюда и вранье.  В общем надо разбираться. сейчас везде втыкаю вывод на монитор промежуточных результатов и пытаюсь с этим бороться. Скорее всего нужно убрать в прцедуре измерения питания деление на 1000 и все просчиталь в милливольтах а не в вольтах. и изменить условия для смены диапазонов измерения.

Novice User
Offline
Зарегистрирован: 25.09.2017

с частотомером все нормально,сделал вывод в гц при частоте до 1000 гц в формате ХХХХ.ХХХ при большей частоте,измеряет замечательно,с вольтметром беда-всегда показывает 6,13 в...

снимал на телефон,качество так себе...

разобрался,замыкание D3 и D4

svm
Offline
Зарегистрирован: 06.11.2016

Novice User пишет:

с частотомером все нормально,сделал вывод в гц при частоте до 1000 гц в формате ХХХХ.ХХХ при большей частоте,измеряет замечательно,с вольтметром беда-всегда показывает 6,13 в...

 

разобрался,замыкание D3 и D4

Вольтметр должен работать без всяких заморочек. Только нужно ввести правильные данные делителя. 

У Вас в 70 строке вместо 6.133 свое значение. 

Судя по фотографии с вашим дисплейчиком вполне компактная конструкция получается.

Novice User
Offline
Зарегистрирован: 25.09.2017

Это выставил ,все норм,получилось 12,07