вольтметр и милливольтметр одноврменно

maxvalin
Offline
Зарегистрирован: 22.02.2016

Добрый день! Понимаю что тема подымалас не единожды но тут ньюанс есть.

Есть мега и есть A5 и A10 нужно с одного канала измерять 0-110в с точностью без запятых даже.

А вот другой канал подключен паралельно стрелочному амперметру - там надо от 0 до 900 мВ . То что выкурил по форуму  и собрал чего то не ак работает! Поу помощи разобраться в этом впросе

Вот скетч (резисторы впсанные такие и есть в спайке)

#include <LiquidCrystal.h>

LiquidCrystal lcd(16, 17, 23, 25, 27, 29);

void setup()
{ 
  lcd.begin(16, 4);
  lcd.clear();
  analogReference(INTERNAL1V1);
  
 }
 
void loop()
{ 
  float Vbat = (analogRead(A5) * 1.1) / 1024.0;
  float Vin = Vbat / (8200.0 / (168000.0 + 8200.0)); // R2/(R1+R2)
  float Ibat = (analogRead(A10)* 1.1) / 1023.0-1.1;
  lcd.setCursor(0, 1);
  lcd.print("VOLT=");  
  lcd.print(Vin, 1);
  lcd.setCursor(0, 2);
  lcd.print("AMPER=");
  lcd.print(Ibat, 1);
  
  
 delay(200); 
}

"Не так" это вольты измеряет только до 36 а милливольты вообще не знаю как прописать правильно

maxvalin
Offline
Зарегистрирован: 22.02.2016

напряжение постоянное и пропуск букв (старый ноутбук шалит уже)извиняюсь .

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Даже не до 36, а 23, судя по написанному.

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

maxvalin
Offline
Зарегистрирован: 22.02.2016

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

1. для А10 картинку нарисуйте, с этой и так все понятно.

2. Про ЭТУ картинку: опорное напряжение 1.1, то есть внутренний источник.

Внимание вопрос: на сколько нужно поделить 110 В, чтобы результат был меньше 1.1В?

Калькулятор мне подсказывет, что на 100. удобнее будет на 101, используя резисторы на 1КОм и 100КОм.

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

Понятно, что делитель на 21.5 сделан для опорного +5 В.

=================

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

maxvalin
Offline
Зарегистрирован: 22.02.2016

епть... ))))

а ярезисторы заменил уже на R2=30кОм R1=670кОм

Дошло, после 10 перечитываний, сейчас резисторы подберу! нсколько я понял тогда лучше использовать 5 вольт опорных?  Чтоб диапазон шире был. Руководствовался подбору по онлайн калькулятору)

за А10 - нету картинки, я не делал делитель так как измерения ниже 5 вольт, усилителя нету((

просто GND и A10 и на него милливольты

п.с а не маловато будет для R2 1кОм?

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

1. (670+30)/30=23.33  ЭТО ОПЯТЬ НЕ 100! Блин!

Вы закон Ома понимаете, или в школе его проболели скарлатиной? я написал, 1 и 100 Ком, вот так и делайте. Вы не понимаете, почему два последовательных резистора делят напряжение?!

2. Нарисуйте картинку с амперметром, ардуиной и прроводом. Есть у меня подозрения, все более крепкие, что там не все в порядке. Что и куда Вы подключили.

Откуда Вы эти самые "милливольты" добыли?

maxvalin
Offline
Зарегистрирован: 22.02.2016

миливольты из шунта, это зарядка погрузчиков, там стрелочный амперметр. Закон ома я понимаю прекрасно, но я не понимаю что тут за порядок деления, никто толком не описывал и не объяснял что и как делается. Что должно быть меньше другого. и.т.д

два резистора потому что это делитель)) ну и стабилизатор (совсем неможко)

maxvalin
Offline
Зарегистрирован: 22.02.2016

di_mot
Offline
Зарегистрирован: 12.08.2016

maxvalin пишет:

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

Всё это прекрасно и многкратно описано в теории АЦП.

Это основа, которая на 100% применима и в Arduino.

Если кратко.

1. Максимальное напряжение на входе в АЦП (пина Arduino) не должно быть больше опороного напряжения.

2. Цена "деления" (шага, одно значение) АЦП = U/K.

Где U - опорное напряжение, K - разрядность АЦП (в Arduino=1024)

3. Входным делителем "приводим" напряжение которое нужно измерить к п.1.

Так что задачка в 3 действия. ;-)

maxvalin
Offline
Зарегистрирован: 22.02.2016

Я скажу очень доходчиво написали!

Спасибо !

собрал вот еще раз схемку с такими парметрами как в скетче

#include <LiquidCrystal.h>
LiquidCrystal lcd(16, 17, 23, 25, 27, 29);
int analogInput = 5;
float vout = 0.0;
float vin = 0.0;
float R1 = 95000.0; // сопротивление R1 (100K)
float R2 = 3750.0; // сопротивление R2 (10K)
int value = 0;
void setup(){
   pinMode(analogInput, INPUT);
   lcd.begin(16, 2);
   lcd.print("DC VOLTMETER");
}
void loop(){
   // считывание аналогового значения
   value = analogRead(analogInput);
   vout = (value * 5) / 1024.0; //вместо пяти надо измерить истинное напряжение питания ардуины
   vin = vout / (R2/(R1+R2)); 
   if (vin<0.09) {
   vin=0.0;// обнуляем нежелательное значение
} 
lcd.setCursor(0, 1);
lcd.print("INPUT V= ");
lcd.print(vin);
delay(500);
}

как не измерял резисторы, один черт врет как собака, вместо 41.6в показывает 44 а батарейку занижает вместо 1.36 показывает 1.04. Понимаю что это в основном и за герлянды резисторов которые совсем не точные. Но на работе собрать лучше не выйдет.

А чтож тогда делать с измерением милливольт?! С округлением желательно, с ним примеры есть но с милливольтами не нашел(

аифметику можно в сетап вынести но не суть

maxvalin
Offline
Зарегистрирован: 22.02.2016

Кстати а есть ли модули для точного измерения допустим до 200 вольт постоянки? точного имел виду хотябы просто без десятых но правильный целых. чтоб еси 100вольт значт сто и показывал

ато накроется мой логер медным тазом(((

di_mot
Offline
Зарегистрирован: 12.08.2016

maxvalin пишет:

Кстати а есть ли модули для точного измерения допустим до 200 вольт постоянки?

Вот тебе тынц и не мучай Андрюшку. :-)

Ну или вот тынц, выбор разнообразный.

maxvalin
Offline
Зарегистрирован: 22.02.2016

Да что  вы ей Богу! 

у меня мультик есть могу и его подключть и каждый чаc подойти показания записать, суть ведь не в этом. Мучаю ардуино в целях самовоспитания (в свое время букварь скурил)  теперь за голву хватаюсь)))

Я логгер с этого сделаю а потом после и самоотключение зарядки, собирал уже схемки но с аналоговым затык, еще не разобрался вот(((

самое страшное- взять нормальные показатели!

 

По сути вопроса пожалуйста ответьте по милливольтам

di_mot
Offline
Зарегистрирован: 12.08.2016

maxvalin пишет:

как не измерял резисторы, один черт врет как собака, вместо 41.6в показывает 44 а батарейку занижает вместо 1.36 показывает 1.04.

Вот только сочинять не надо, да...

R1 = 9500.0

R2 = 3750.0

Это не делитель "на 25", а на 26.33333...

Вот и врет приборчик, хотя он в этом не виноват. :-)

А поставить в делитель подстроечный резистор и им "вывести" показания прибора в норму - ни как?

Ну раз расчитать делитель не получается. И за одно этим подстроечником выбрать погрешность резисторов делителя.

Выставить, что бы он показывал тоже значение, что и эталонный прибор.

А затем проверить в разных точка диапазона, вверху и внизу.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Отходил двигло собирать.... весь в масле, чорт побери!

Картинка правильная. Чтобы посчитать ток нужно знать сопротивление шунта. Его нужно точно померить. Ток равен отношению измеренного напряжения (А10 *1.1/1023) к сопротивлению шунта Rш (обычно десятые или сотые доли Ома, мерить очень непросто, если не разберетесь — подскажу как).

 

Чтобы измерения напряжения не «врали», нужно в расчетах в программе использовать не номиналы резисторов, которые нанесены полосками, а померить их тестером и использовать эти значения.

Теперь про делитель:

по закону Ома падение напряжения на резисторе = ток умножить на сопротивление.

Ток Вы задаете суммой двух сопротивлений резисторов, включенных последовательно. Теперь Вам нужно взять меньшее значение напряжения, так? Вы его снимаете с МЕНЬШЕГО резистора, понятно?

Чтобы сделать делитель на 100 нужно чтобы один резистор был 99 частей, а меньший — 1 часть, вместе 100 частей, пропорции в школе ведь тоже учили?

Для Вашего случая удобно взять 1 КОм и 99 Ком, но 99 — не бывает, берем 100. Коэффициент делителя равен отношению сопротивления того резистора, с которого снимаем показания к сумме сопротивлений. Снимаем с 1КОм, получаем делитель 1 к (1+100=101) — 1/101. Но в программе желательно использовать числа не 1.0 и 101.0, а ТОЧНЫЕ значения сопротивлений, измеренные тестером.

maxvalin
Offline
Зарегистрирован: 22.02.2016

не  вру! )

опять неправильно сделал(

на пальцах дураку надо тыкать... дожился(((

дак я так и мерял- тестером! и просто вписал в програму показания, но гляжу этого мало. Ладн дома продолжу бой!

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Раз у Вас есть мультиметр, то Rш Вы легко посчитаете. Измерьте напряжение на шунте мультиметром, без ардуинки, и поделите на ток, который показывает стрелочный амперметр.

Сделайте 4-5 или даже 10 таких измерений в разных ситуациях и возьмите среднее значение.

И все равно в программе придется уточнять коэффициенты, при настройке. Добейтесь соответствия показаний Ардуинки и мультика.

nik182
Offline
Зарегистрирован: 04.05.2015

Я дико извиняюсь, но в меге есть усилитель на 10 и на 200. Специально к АЦП приделан. Для шунта самое то,если шунт на землю.

maxvalin
Offline
Зарегистрирован: 22.02.2016

насчет шунта:

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

вопрос как снять миливольты? делитель то не нужен? 

maxvalin
Offline
Зарегистрирован: 22.02.2016

di_mot пишет:

maxvalin пишет:

как не измерял резисторы, один черт врет как собака, вместо 41.6в показывает 44 а батарейку занижает вместо 1.36 показывает 1.04.

А поставить в делитель подстроечный резистор и им "вывести" показания прибора в норму - ни как?

вот это я завтра и сделаю)) Так как это легче полнять чем все эти формулы. Вместо R2 подстоечник.

 

maxvalin
Offline
Зарегистрирован: 22.02.2016

nik182 пишет:

Я дико извиняюсь, но в меге есть усилитель на 10 и на 200. Специально к АЦП приделан. Для шунта самое то,если шунт на землю.

Да , шунт на земле входом а выходом на A10, висит он на минусовом кабеле. На картинке мож недорисовал, а что за вариант? 

maxvalin
Offline
Зарегистрирован: 22.02.2016

wdrakula пишет:

 

Для Вашего случая удобно взять 1 КОм и 99 Ком, но 99 — не бывает, берем 100. Коэффициент делителя равен отношению сопротивления того резистора, с которого снимаем показания к сумме сопротивлений. Снимаем с 1КОм, получаем делитель 1 к (1+100=101) — 1/101. Но в программе желательно использовать числа не 1.0 и 101.0, а ТОЧНЫЕ значения сопротивлений, измеренные тестером.

судя по http://bsvi.ru/kalkulyator-delitelya-na-rezistorax/ этот делитель вы подсказали для опорного 1.1в.

Вообще чем больше я читаю тему тем больше захожу в ступор. Указывать точные показания я уже пробовал, это не правильно.

<span style="font-size:14.4px;font-weight:bold;line-height:12px;">di_mot</span> пишет:

Это не делитель "на 25", а на 26.33333...

 

ааааа, ну почему Вы сказали что это делитель не на 25?! почему он должен быть на 25?!!!

Товарищи! Я признаю свою полную некомпетентность в даном вопросе так как не могу все камни сложить воедино.  Пошлите меня куда нить где есть этот АЦП во всех формулах или пример чтоб глядя на строчки скетча можно было понять почему подобраны именно так резисторы и делитель.

Извините за много постие но опции уж очень ущемлены на этом форуме(((

 

di_mot
Offline
Зарегистрирован: 12.08.2016

maxvalin пишет:

ааааа, ну почему Вы сказали что это делитель не на 25?! почему он должен быть на 25?!!!

Хороший вопрос. :-)

Потому что так проще для понимания что же происходит на самом деле.

Проще сопоставить что на входе, что увидели на выходе и понять по коду и/или формуле - в чем ошибка.

Делить (в уме, на калькуляторе) на 10, 100 или 25 проще, чем на 26.33333.

И при дробных числа еще получим еще "пулю" на округлениях.

А судя по вопросу, весь "расчёт" строился на том, что:

- Всуну что ни попадя, подставлю в программу и процессор сам мне всё расчитает ПРАВИЛЬНО.

Типа цифирки показаний "на входе" и "на выходе" - совпадут как бы сами собой.

И Андрюша, судя по примерам выше, рассчитал ПРАВИЛЬНО. Но результатом кто-то был удивлён. ;-)

Попутно к коду. Реплика в сторону, как в театре.

 - За чем и зачем заставлять процессор при каждом измерении(!) "расчитывать" делитель из резисторов заново?

Типа процессор железный - вот пусть и работает?

Стоит заменить на константу. Расчитанную на бумашке по точным значениям резисторов. Тогда бы и сразу бросилась в глаза несуразица, с точки зрения человека, делителя "абы на каких-нить резюках". ;-)

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

Извинюсь за некий философизм в посте. :-)

maxvalin пишет:
Пошлите меня куда нить где есть этот АЦП во всех формулах или пример чтоб глядя на строчки скетча можно было понять почему подобраны именно так резисторы и делитель.

Послать - дело не долгое. ;-)

Но очень часто это явно не отражено в коде.

Формула АЦП проста как 3 копейки.

1. "Показания АЦП" = I * цену деления АЦП.

Где:

I - число считанное как значение АЦП.

Цена деления АЦП - опорное напряжение деленое на максимальное кол-во "шагов" АЦП.

Это делает строка №15 в первом посте.

2. Полученное число надо умножить на K (коэф. деления входного делителя).

Это делает строка №16 там же.

Значит строки №15 и №16 можно объеденить усложнив понимание.

Типа такого:

(analogRead(A5) * 1.1) / 10.23;

Где:

1.1 величина опорного напряжения;

10.23 - это N=1023 АЦП уже деленное на K=100 входного делителя. :-)

Итого: Имеем измеритель от 0 до 110 с шагом в 0,1075.

 

maxvalin
Offline
Зарегистрирован: 22.02.2016

di_mot пишет:

maxvalin пишет:

ааааа, ну почему Вы сказали что это делитель не на 25?! почему он должен быть на 25?!!!

А судя по вопросу, весь "расчёт" строился на том, что:

- Всуну что ни попадя, подставлю в программу и процессор сам мне всё расчитает ПРАВИЛЬНО.

вот именно)) вот так я и думал при первом-пятом посроении скетча

[/quote]

 - За чем и зачем заставлять процессор при каждом измерении(!) "расчитывать" делитель из резисторов заново?

Типа процессор железный - вот пусть и работает?

[/quote]

знал что это замечание вылезет))) несогласен с этим и я! по этому добавил ниже - что это пример и арифметику конечно надо вынести в сетап 

maxvalin
Offline
Зарегистрирован: 22.02.2016
#include <LiquidCrystal.h>

LiquidCrystal lcd(16, 17, 23, 25, 27, 29);

void setup()
{ 
  lcd.begin(16, 4);
  lcd.clear();
  analogReference(INTERNAL1V1);
  
 }
 
void loop()
{ 
  float Vin = (analogRead(A5) * 1.1) / 10.23;
  
  lcd.setCursor(0, 1);
  lcd.print("VOLT=");  
  lcd.print(Vin, 1);
  lcd.setCursor(0, 2);
  lcd.print("AMPER=");
  //lcd.print(Ibat, 1);
  
  
 delay(200); 
}

Считает правильно! 41.1 =41.1 мультиметру

(хотя батарейку занижает на 0.3в пробовал паралельным тестом, но мне от 40 до 100 надо))

емае.... как же надо было до это дойти так тернисто...

К слову: установил DEFAULT и подставил 5ку измерять стал криво, вместо 41.1 = 39в.. вот так (реальное питание дуинки 5.00в)

своими словами (поправьте сразу если не так)

(analogRead(A5) * 1.1) / 10.23;

float переменная = (читаем нужный аналоговый вход, умножаем на опорное напряжение) делим на коефициент делителя

 

так теперь с милливолтами)))

maxvalin
Offline
Зарегистрирован: 22.02.2016

Все , добил ардуинку!((

Надо бло стбилизатор паралельно R2 ставить( 5вольтовый 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Нанку не жалко, заказывйте их сразу штук по 10, так они по 120-130 рублей получаются. Это расходный материал.

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

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

maxvalin
Offline
Зарегистрирован: 22.02.2016

сжог флеш, загружает 1-процентные скетчи, все что больше зависает на этапе загрузки(

У меня уже с такими симптомами лежит на запчасти

П.С сжог мегу)))  благо, было не мало

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

для Вашей задачи Мега - крутовато, ИМХО. ;)

maxvalin
Offline
Зарегистрирован: 22.02.2016

во всех проэктах так мне говорили)))

ну нет у меня ничего другого а меги были и бесплатно))

maxvalin
Offline
Зарегистрирован: 22.02.2016

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

по сути дела: чего мне с милливольтами делать?

замерил на амперметре при зарядке батареи, 33mВ равны 45A реальным. Возможно как-то просто мапировать показания, без вычесления шунта и всего прочего? как писал выше

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

что вы замерили????? я все написал выше. НАПРЯЖЕНИЕ на шунте померить надо мультиметром, при известном токе. Ардуинка же, напряжение мерить будет.

maxvalin
Offline
Зарегистрирован: 22.02.2016

Ну дак замерял  я на шунте! 33mВ при 45A . Там амперметр стреолочный висит еще на этом шунте - вот и написал я так что замерил на амперметре)

nik182
Offline
Зарегистрирован: 04.05.2015

А зачем вычислять шунт в программе? Зачем в программе умножение на 1.1?

У вас Ардуино измеряет напряжение. Вам нужно вывести значение на дисплей с каким то коэффициентом. Т.е. просто пишете в скече analogRead(A5) * ku и analogRead(A10) * ki. В начале работы калибруем - устанавливаем в сетапе ku и ki равными 1.0. Измеряем тестером напряжение и ток (напряжение на шунте :-) и смотрим на показания ардуины. Расчитываем ku,ki=показания вольтметра/показания ардуины. Вписываем в сетап. Ненужно подбирать резисторы и ставить переменники. На A10 можно включить усилитель на 10 или 200. Если 33мВ умножить на 10 и использовать внутренний опорник 1.1 то получим измеритель до 150 А с точностью 0.15 А.

maxvalin
Offline
Зарегистрирован: 22.02.2016

аааа. .. Не так все просто! нужно ставить перемнники, здесь два канала измерения один от 0-100В  второй от 0- 100мВ. 

Или я не правильно Вас понял)))

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

кстати сопротивление шунта у меня выходит 0.001 Ом  во как!!

maxvalin
Offline
Зарегистрирован: 22.02.2016

ничего не понимаю, сделал "Delete the folder C:\Users\uyoyo\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc

Restart the Arduino IDE

The problem should now be fixed"

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

nik182
Offline
Зарегистрирован: 04.05.2015
#include <LiquidCrystal.h>

LiquidCrystal lcd(16, 17, 23, 25, 27, 29);

float Vu,Vi,ku,ki;
uint16_t V,l,h;
uint8_t i;

void setup()
{ 
  lcd.begin(16, 4);
  lcd.clear();
  ku=1.0;
  ki=1.0;
  
 }
 
void loop()
{ 
  ADCSRB =0; 
  ADMUX = 0x85;
  for(i=0;i<100;i++);    
  ADCSRA=B11000111;
  while (ADCSRA & (1 << ADSC));
  l=ADCL;
  h=ADCH;   
  V=(h << 8) + l;
  Vu=ku*V;

  ADCSRB = 0x1 << MUX5; 
  ADMUX = 0x8D;
  for(i=0;i<100;i++); 
  ADCSRA=B11000111;
  while (ADCSRA & (1 << ADSC));
  l=ADCL;
  h=ADCH;   
  V=(h << 8) + l -511;
  Vi=ki*V;
 
  lcd.setCursor(0, 1);
  lcd.print("VOLT=");  
  lcd.print(Vu, 1);
  lcd.print("      ");  
  lcd.setCursor(0, 2);
  lcd.print("AMPER=");
  lcd.print(Vi, 1);
  lcd.print("      ");  
  
  delay(200); 
}

 

Где то так. Подключение как в посте 8. Только еще ножку А11 надо заземлить! А лучше 10 заземлить, а подать сигнал напряжения на 11. Никаких переменников не надо. Надо обеспечить напряжение меньше одного вольта  с помощью резистивного делителя на ноге A5. И меньше 100мВ на ноге А10. После запуска показания тока и напряжения будут в диапазоне 0 - 1023. После измерения тестером реальных значений рассчитать ku ki и переписать строки 13,14 - вместо 1.0 вписать полученные рассчитанные значения. 

maxvalin
Offline
Зарегистрирован: 22.02.2016

мда... до написания такого кода еще асти лет 10..

Спасибо ! сейчас буду пробовать!

Извиняюсь, но как изменить порт вместо A10?

не в 31-ой строке?

Потому что вольтаж выставил а ток не реагирует на милливольты. думаю поменять порт.

Сейчас на амперах при  ki=0.01; показывает 650.4 и мертво.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

nik182 пишет:

Где то так. Подключение как в посте 8. Только еще ножку А11 надо заземлить! А лучше 10 заземлить, а подать сигнал напряжения на 11.

nik182! Так, как Вы написали, сигнал именно на А11 подавать нужно, а А10 - на землю, потому как 101101 это код для позитивного 11 и негативного 10 входов. Иначе нужно не 0x8D, а 0x8E в строке 31.

Если наоборот подать, то я, честно говоря, просто не знаю, что посчитает АЦП. Не пробовал.

maxvalin
Offline
Зарегистрирован: 22.02.2016

wdrakula пишет:

Раз у Вас есть мультиметр, то Rш Вы легко посчитаете. Измерьте напряжение на шунте мультиметром, без ардуинки, и поделите на ток, который показывает стрелочный амперметр.

тогда получается сопротивление шунта 0.000757575.. Ом 

чето маловато совсем.

33A стрелочный амперметр показывает когда на шунте 25мВ

maxvalin
Offline
Зарегистрирован: 22.02.2016

wdrakula пишет:

nik182 пишет:

Где то так. Подключение как в посте 8. Только еще ножку А11 надо заземлить! А лучше 10 заземлить, а подать сигнал напряжения на 11.

nik182! Так, как Вы написали, сигнал именно на А11 подавать нужно, а А10 - на землю, потому как 101101 это код для позитивного 11 и негативного 10 входов. Иначе нужно не 0x8D, а 0x8E в строке 31.

Если наоборот подать, то я, честно говоря, просто не знаю, что посчитает АЦП. Не пробовал.

плохо посчитает... я пробовал тольо что

maxvalin
Offline
Зарегистрирован: 22.02.2016

в общих чертах:

пошол пока что по первичному варианту 

#include <LiquidCrystal.h>

LiquidCrystal lcd(16, 17, 23, 25, 27, 29);

#include <SD.h>

File myFile;
float outputAmper = 0;


void setup()
{ 
  lcd.begin(16, 4);
  lcd.clear();
  lcd.setCursor(0, 1);
  lcd.print("   PROVER UROVEN ");
  lcd.setCursor(3, 2);
  lcd.print("      DISTILATA! ");
  delay(4000);
  lcd.clear();
  analogReference(INTERNAL1V1);
  pinMode(53, OUTPUT);
  Serial.begin(9600);
  while (!Serial) {
    ; //Ждём инициализации серийного порта. Нужно для Leonardo
  }

  Serial.print("Initializing SD card...");
  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  analogReference(INTERNAL1V1);
  
}

void loop()
{ 
  
  float Vin = (analogRead(A5) * 1.1) / 10.23;
  lcd.setCursor(0, 0);
  lcd.print("VOLT=");  
  lcd.print(Vin, 1);
  float Uin = (analogRead(A10) *1.1/1023)/0.00075;
  //outputAmper = map(Uin, 0, 1023, 0, 80);
  lcd.setCursor(0, 1);
  lcd.print("AMPER=");
  lcd.print(Uin,1);
  lcd.print("      ");
  delay(200);
  
    myFile = SD.open("LOG1.txt", FILE_WRITE);

  // Если файл открылся, пишем в него:
  if (myFile) {
    
    Serial.print("amper3");
    myFile.println("amper3");
    // Закрываем файл:
    myFile.close();
    Serial.println("done.");
  } else {
    // если файл не открылся, сообщает об ошибке:
    Serial.println("error opening test.txt");
  }

  // открываем файл только для чтения
  myFile = SD.open("LOG1.txt");
  if (myFile) {
    Serial.println("log.txt:");

    // читаем файл посимвольно до конца:
    while (myFile.available()) {
      Serial.write(myFile.read());
    }
    // закрываем файл:
    myFile.close();
  } 
  else {
    // если файл не открылся, сообщает об ошибке:
    Serial.println("error opening log.txt");
  }
  delay(500);
}

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

П.С емае- шунт же заводской! на нем надпись 80А 60мВ, что подтверждает мои измерения! И почему я сразу не полез туда с фонариком?!)))

nik182
Offline
Зарегистрирован: 04.05.2015

wdrakula пишет:

nik182! Так, как Вы написали, сигнал именно на А11 подавать нужно, а А10 - на землю, потому как 101101 это код для позитивного 11 и негативного 10 входов. Иначе нужно не 0x8D, а 0x8E в строке 31.

Если наоборот подать, то я, честно говоря, просто не знаю, что посчитает АЦП. Не пробовал.

0x8E Это код для балансировки усиления 200х. С ним вообще мерить не будет. В идеале нужно запустить с кодом 0х8С  - балансировка 10х - полученный код вписать в строку 37 вместо 511. Если оставить вход А10 то код при увеличении напряжения будет меняться от 511 (ну или от кода балансировки)  до 0. Соответственно строка должна выглядеть

V=511- ((h << 8) + l);

wdrakula пишет:

плохо посчитает... я пробовал тольо что

 Нет у меня меги. Есть леонардо. Там тоже усилитель. Пробовал на нем. Всё работает штатно. Если использовать analogRead() то точность измерения тока будет чуть лучше чем 2А. Если этого достаточно, то заморачиваться на увеличения точности через применение усилителя можно не надо.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

1. nik182. Точно! Мой косяк.Все правильно. А10 на землю и убрать "-511" при вычислении.

2. maxvalin. У Вас стандартный шунт на 100А. Делайте, как написал nik182. Это самый простой путь. Реф - интернал 1.1, делитель на 100, как я показал, от шунта - как написал ник182, задействуйте А10 и А11 с усилителем. Обратите внимание, как ник182 написал определить коэффициенты.

maxvalin
Offline
Зарегистрирован: 22.02.2016

Уже написал, уже проверил)) усе работает! (правда с первым вариантом, так как его код я вообще не смог понять уж слишком сложно для меня)  

вишу теперь над тем как ограничить время! Мне надо чтоб показания на дисплее обновлялись раз в 1000 мс а запись велась на карту раз в 300000мс.  начал мутить через флаг и милис и немного повис, так как наткнулся на библиотеку SimpleTimer. и поехало все в сторону..

 

#include <LiquidCrystal.h>

LiquidCrystal lcd(16, 17, 23, 25, 27, 29);

#include <SD.h>
long previousMillis = 0; // время последнего задействования
long zapuskflag = 10000;
long stopflag = 10000;
boolean zapusk = false; // флаг для запуска записи на карту
File myFile;
float outputAmper = 0;


void setup()
{ 
  lcd.begin(16, 4);
  lcd.clear();
  lcd.setCursor(0, 1);
  lcd.print("   PROVER UROVEN ");
  lcd.setCursor(3, 2);
  lcd.print("      DISTILATA! ");
  delay(4000);
  lcd.clear();
  analogReference(INTERNAL1V1);
  pinMode(53, OUTPUT);
  Serial.begin(115200);
  while (!Serial) {
    ; //Ждём инициализации серийного порта. Нужно для Leonardo
  }

  Serial.print("Initializing SD card...");
  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  
}

void loop()
{ 
  
    float Vin = (analogRead(A5) * 1.1) / 10.23;
    lcd.setCursor(0, 0);
    lcd.print("VOLT=");  
    lcd.print(Vin, 1);
    float Uin = (analogRead(A10) *1.1/1023)/0.00075;
    lcd.setCursor(0, 1);
    lcd.print("AMPER=");
    lcd.print(Uin,1);
    lcd.print("      ");
    unsigned long currentMillis = millis();
  if(currentMillis - previousMillis >= zapuskflag)
  
    {
     previousMillis = currentMillis; 
     zapusk = true;  
    }
   else if(currentMillis - previousMillis >= stopflag)
    {
     previousMillis = currentMillis; 
     zapusk = false;  
    }
   
  if (zapusk == true)
     myFile = SD.open("LOG1.txt", FILE_WRITE);

     // Если файл открылся, пишем в него:
  if (myFile) 
    {
     Serial.print("Напряжение = ");
     Serial.println(Vin);
     myFile.print("Напряжение = ");
     myFile.println(Vin);
     Serial.print("Ток заряда = ");
     Serial.println(Uin);
     myFile.print("Ток заряда = ");
     myFile.println(Uin);
     // Закрываем файл:
     myFile.close();
     Serial.println("done.");
     } 
   else 
     {
     // если файл не открылся, сообщает об ошибке:
     Serial.println("error opening test.txt");
     }

      // открываем файл только для чтения
      myFile = SD.open("LOG1.txt");
  if (myFile) 
     {
      Serial.println("LOG1.txt:");
      // читаем файл посимвольно до конца:
  while (myFile.available()) 
     {
      Serial.write(myFile.read());
     }
     // закрываем файл:
     myFile.close();
     } 
  else 
     {
     // если файл не открылся, сообщает об ошибке:
     Serial.println("error opening log.txt");
     }
 
}

 

nik182
Offline
Зарегистрирован: 04.05.2015

wdrakula пишет:

1. nik182. Точно! Мой косяк.Все правильно. А10 на землю и убрать "-511" при вычислении.

 В диф. режиме при равенстве входов выдает 511 - от этой величины верх положительные коды, вниз отрицательные. Имеется в виду, если на на отрицательном входе напряжение больше чем на положительном, то выдаваемый код будет меньше 511-ти. Если заземлим отрицательный, при нулевом положительном выходной код будет 511( или где то рядом - для точного значения нужна калибровка)  поэтому положительные значения напряжения на положительном входе имеют коды от 511 до 1023. Поэтому нужно вычитать 511 в дифф режиме для измерений от нуля до референс напряжения. Разрядность только 9 бит будет.   

di_mot
Offline
Зарегистрирован: 12.08.2016

maxvalin пишет:

 Мне надо чтоб показания на дисплее обновлялись раз в 1000 мс а запись велась на карту раз в 300000мс. 

Пока - делай как проще для своего понимания.

Что-то типа (эскиз):

int Cnt_Loop; // Счетчик кол-ва циклов в Loop;

void setup() {
Cnt_Loop=0;
}

void loop() {
int time_Start = millis();

//Тут обрабатываешь
// показания вольтемтра и амперметра
// и показываешь их на дисплей.

if (Cnt_Loop==299) {
//  Тут пишешь в лог...
}

Cnt_Loop++; //  в каждом цикле увеличиваем счетчик на 1:
if (Cnt_Loop==300){Cnt_Loop=0;} //  сбрасываешь счетчик:                   

int tm_Wait=1000-(millis()-time_Start); // Замеряешь сколько по времени заняли все операции и корректируешь это значение для  Delay
if (tm_Wait<0){tm_Wait=0;}                 // На всякий.

delay(tm_Wait);
}
maxvalin
Offline
Зарегистрирован: 22.02.2016

Пока что дошел до этого)))



#include <LiquidCrystal.h>

LiquidCrystal lcd(16, 17, 23, 25, 27, 29);
long ekran = 2000;
long zapuskflag = 10000;
long previousMillis = 0; // время последнего задействования
float Vin = 0;
float Uin = 0;
#include <SD.h>
File myFile;
float outputAmper = 0;


void setup()
{ 
  lcd.begin(16, 4);
  lcd.clear();
  lcd.setCursor(0, 1);
  lcd.print("   PROVER UROVEN ");
  lcd.setCursor(3, 2);
  lcd.print("      DISTILATA! ");
  delay(4000);
  lcd.clear();
  analogReference(INTERNAL1V1);
  pinMode(53, OUTPUT);
  Serial.begin(9600);
  while (!Serial) {
    ; //Ждём инициализации серийного порта. Нужно для Leonardo
  }

  Serial.print("Initializing SD card...");
  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  
}

void loop()
{ 
    float Vin = (analogRead(A5) * 1.1) / 10.23;
    lcd.setCursor(0, 0);
    lcd.print("VOLT=");  
    lcd.print(Vin, 1);
    float Uin = (analogRead(A10) *1.1/1023)/0.00075;
    lcd.setCursor(0, 1);
    lcd.print("AMPER=");
    lcd.print(Uin,1);
    lcd.print("      ");
    delay(1000);
  
    unsigned long currentMillis = millis();
    if(currentMillis - previousMillis >= zapuskflag)
     {
      previousMillis = currentMillis;
      myFile = SD.open("LOG1.csv", FILE_WRITE); 
      if (myFile)       // Если файл открылся, пишем в него:
    { 
     Serial.print("Напряжение = ");
     Serial.println(Vin);
     myFile.print("Напряжение = ");
     myFile.println(Vin);
     Serial.print("Ток заряда = ");
     Serial.println(Uin);
     myFile.print("Ток заряда = ");
     myFile.println(Uin);
     // Закрываем файл:
     myFile.close();
     Serial.println("done.");
     } 
   else 
     {
     // если файл не открылся, сообщает об ошибке:
     Serial.println("error opening LOG1.csv");
     }

      // открываем файл только для чтения
      myFile = SD.open("LOG1.csv");
  if (myFile) 
     {
      Serial.println("LOG1.csv:");
      // читаем файл посимвольно до конца:
  while (myFile.available()) 
     {
      Serial.write(myFile.read());
     }
     // закрываем файл:
     myFile.close();
     } 
  else 
     {
     // если файл не открылся, сообщает об ошибке:
     Serial.println("error opening LOG1.csv");
     //delay(1000);
     }
     }

                    
  
 
}

Тоже работает;)  

Теперь хочу разобраться с усреднением данных, прыганье сгладить.  допустим 5 замеров за секунду и средне-арифметичесское на показ.

а также как график в екселе построить из этих показаний.

С  .csv разобрался, создает, но надо знать как правильно заполнить ее чтоб exel его потом понял. 

di_mot
Offline
Зарегистрирован: 12.08.2016

maxvalin пишет:

Тоже работает;)  

Вопрос в том - Как ЭТО работает? ;-)

По коду получается, что:

1. Сделал замеры Вольт и Ампер.

2. Отправил процессор на перекур на целую секунду! Задлянакуда - не понятно.

3. Занялся файликом.

4. Вернулся к п.1.

А теперь вопрос (на засыпку): - С какой периоичностью снимаются показания Вольт и Ампер? ;-)

Ответ: 1 сек (время по п.2) + время по п.1 + время по п.3.

То тебе измерять каждую секунду и писать в лог каждые 300 сек.

То устраивает не известно как часто измеряешь и писать через не определенное время (но явно чаще чем раз в 300 сек)  в лог.

nik182
Offline
Зарегистрирован: 04.05.2015

С усреднением совсем просто. Вводим две переменных для усреднённого значения и по простой формуле усредняем. 15 и 16 это глубина усреднения (N и N-1). Чем больше N тем лучше усредняется,но тем медленнее реакция. Начать эксперементы с усреднением можно с 4 (3 и 4 вместо 15 и 16)

float VinOld,VinSmooth;
.....
    Vin = (analogRead(A5) * 1.1) / 10.23;
    VinOld=VinSmooth;
    VinSmooth=(15.0*VinOld+Vin)/16.0;