Делитель напряжения и АЦП
- Войдите на сайт для отправки комментариев
Пнд, 23/01/2017 - 10:36
Подскажите какое максимальное сопротивление в делителе можно исполльзовать для уверенной работы АЦП у Atmega8a? Нужно замерять напряжение 2-х литиевых банок (7.2В), хочу сделать делитель в 2 раза. 10к к 10к знаю точно будет работать, но при этом ток будет слишком большой. В идеале хотелось бы 100к к 100к, но будет ли работать правильно, какое сопротивление на входе в АЦП? Или я что-то не правильно понимаю в работе АЦП?
Частота какая? Если никакой, просто одноразово замерять - до мегаома спокойно ставьте, т.к. сопротивление входа - 100МОм. Если хотите часто мерять, то в даташите написано, что импеданс источника - 10К, т.е. Ваши резисторы должны давать 10К при параллельном соединении.
Собственно будет примерно такой код:
// Цифровые порты #define PWR_MC 4 // Питание МК горит пока МК включен #define PWR_BAT1 2 // Исправность и готовность батареи 1 #define PWR_BAT2 3 // Исправность и готовность батареи 2 #define B1_conn 6 // Выход включения батареи 1 #define B2_conn 7 // Выход включения батареи 2 // Аналоговые порты #define V1 A0 #define V2 A1 #define V3 A2 #define V4 A3 #define V5 A4 #define V6 A5 #define I_detect A7 #define V_corr A6 // Пороги отключения батареи #define B_min 650 float corr = 1.0; int U1 = 0; int U2 = 0; int U3 = 0; int U4 = 0; int U5 = 0; int U6 = 0; int I = 0; bool B1_ok = true; bool B2_ok = true; byte B_conn = 1; void setup() { pinMode(B1_conn, OUTPUT); digitalWrite(B1_conn, LOW); pinMode(B2_conn, OUTPUT); digitalWrite(B2_conn, LOW); pinMode(PWR_MC, OUTPUT); digitalWrite(PWR_MC, HIGH); pinMode(PWR_BAT1, OUTPUT); digitalWrite(PWR_BAT1, LOW); pinMode(PWR_BAT2, OUTPUT); digitalWrite(PWR_BAT2, LOW); // pinMode(V1, INPUT); // pinMode(V2, INPUT); // pinMode(V3, INPUT); // pinMode(V4, INPUT); // pinMode(V5, INPUT); // pinMode(V6, INPUT); // pinMode(I_detect, INPUT); // pinMode(V_corr, INPUT); corr = 512.0 / analogRead(V_corr); U1 = analogRead(V1); U2 = analogRead(V2); U3 = analogRead(V3); U4 = analogRead(V4); U5 = analogRead(V5); U6 = analogRead(V6); // Напряжение 1-й банки - corr * U1 // Напряжение 2-й банки - corr * (2*U2 - U1) // Напряжение 3-й банки - corr * (3*U3 - 2*U2) // Напряжение 4-й банки - corr * U4 // Напряжение 5-й банки - corr * (2*U5 - U4) // Напряжение 6-й банки - corr * (3*U6 - 2*U5) if ((corr * U1) <= B_min) {B1_ok = false;} if ((corr * (2*U2 - U1)) <= B_min) {B1_ok = false;} if ((corr * (3*U3 - 2*U2)) <= B_min) {B1_ok = false;} if ((corr * U4) <= B_min) {B2_ok = false;} if ((corr * (2*U5 - U4)) <= B_min) {B2_ok = false;} if ((corr * (3*U6 - 2*U5)) <= B_min) {B2_ok = false;} if (B1_ok) { digitalWrite(PWR_BAT1, HIGH); digitalWrite(B1_conn, HIGH); B_conn = 1; } if (B2_ok) { digitalWrite(PWR_BAT2, HIGH); if (!B1_ok) { digitalWrite(B2_conn, HIGH); B_conn = 2; } } } void loop() { if (B1_ok || B2_ok) { corr = 512.0 / analogRead(V_corr); if (B1_ok) { U1 = analogRead(V1); U2 = analogRead(V2); U3 = analogRead(V3); if ((corr * U1) <= B_min) {B1_ok = false;} if ((corr * (2*U2 - U1)) <= B_min) {B1_ok = false;} if ((corr * (3*U3 - 2*U2)) <= B_min) {B1_ok = false;} if (!B1_ok) { digitalWrite(PWR_BAT1, LOW); digitalWrite(B1_conn, LOW); delay(100); if (B2_ok) { digitalWrite(B2_conn, HIGH); B_conn = 2; } } } if (B2_ok) { U4 = analogRead(V4); U5 = analogRead(V5); U6 = analogRead(V6); if ((corr * U4) <= B_min) {B2_ok = false;} if ((corr * (2*U5 - U4)) <= B_min) {B2_ok = false;} if ((corr * (3*U6 - 2*U5)) <= B_min) {B2_ok = false;} if (!B2_ok) { digitalWrite(PWR_BAT2, LOW); digitalWrite(B2_conn, LOW); B_conn = 0; } } if ((corr * analogRead(I_detect)) > 900) { switch (B_conn) { case 1: digitalWrite(B1_conn, LOW); delay(3000); digitalWrite(B1_conn, HIGH); case 2: digitalWrite(B2_conn, LOW); delay(3000); digitalWrite(B2_conn, HIGH); } } } }Он еще правда в стадии доработки, думаю опрос самих аккумуляторов будет с периодичностью 0.1с, на ток будет непрерывный опрос.
На делеи не смотрите - специфика программы допускает остановку на указанное время (оно именно остановкой и должно быть).
Нужно так подобрать делитель, чтобы при максимально возможном измеряемом напряжении сигнал на входе Arduino был максимально возможным (по диапазону измерения)
Тогда точность измерения будет максимальной.
Мне не требуется здесь огромная точность. Нужно поймать напряжение на банке 3.1В +- 0.05В, что вполне дает и прямое подключение банки. Делитель в 2 раза делает одну банку из 2-х. Если почитаете скетч, то поймете что считаю напряжение каждой банки и сравниваю с минимальным. Максимальное разрешение 5В/1024=0.0049В и даже в случае бегания показаний на 10 единиц я получу необходимую точность замера. Для того чтобы не думать какое там реальное напряжение на входе (примерно 5В) считывается показание эталона tl431 в минимальной обвязке - 2.5В и вычисляется коэффициент.
nevkon, может вы и так знаете -но на всякий случай скажу -делате вы изначально плохо. В проффесиональной схемотехнике что бы измерить напряжение каждой из n-последовательно соединённых батарей берут n дифф.усилителей. Взяв схему какого-нибудь зарядника типа Imax тыц подобный вариант мы и увидим. Причём это ещё экономили, и сделали из "говна и палок" В идеале нужно использовать инструментальный усилитель, и непотребуется обвешивать о.у. точными резисторами. Благодаря применению дифф усилителей обеспечивается большой входной и минимальный выходной импенданс, т.е. попутно получаем грамотное согласование с ацп как того требует даташит, и не создаётся побочная нагрузка на аккумулятор как хотите вы. Один минус -готовые инструментальные дифф усилители довольно дорогие :), либо как по ссылке "лоу каст" - по 5 точных резисторов обвеса на каждый оу и обычный лм324.
dimax, согласен что это не совсем корректное решение (думаю вы видели схему в другой теме и поняли что это все связано). Но здесь есть одно "но" - проект уже превысил 3 стоимости того шурика что восстанавливается (вернее уже почти достиг 4-х стоимостей). Поэтому по феншую ну совсем не хочется делать, это будет совсем нерентабельно. Мне главное запустить валяющийся иструмент.