RSS блога
Подписка
Самодельный вольтметр для батареек
- Цена: $2.35 + доставка
- Перейти в магазин
В сегодняшнем занятии мы рассмотрим вариант изготовления самодельного цифрового вольтметра для измерения напряжения на одиночном элементе питания. Пределы измерения напряжения 1-4.5 Вольт. Внешнее дополнительное питание, кроме измеряемого, не требуется.
25 лет назад у меня был кассетный плеер. Питал я его Ni-Cd аккумуляторами НКГЦ-0.45 ёмкостью 450мА/ч. Чтобы в дороге определять какие аккумуляторы уже сели, а какие ещё поработают было сделано простое устройство.
Батарейно-аккумуляторный диагностическо-измерительный комплекс.
Он собран по схеме преобразователя напряжения на двух транзисторах. На выход включен светодиод. Параллельно входу, подключаемому к аккумулятору включен резистор, намотанный из нихрома. Таким образом, если аккумулятор способен отдавать около 200мА, то светодиод загорается.
Из недостатков — размеры контактов жестко выгнуты на длину АА элемента, все прочие типоразмеры подключать не удобно. Ну и напряжение не видно. Поэтому в век цифровых технологий захотелось сделать более высокотехнологичное устройство. И конечно на микроконтроллере, куда без него :)
Итак, схема проектируемого устройства.
Используемые детали:
1. OLED дисплей с диагональю 0.91 дюйм и разрешением 128x32 (около $3)
2. Микроконтроллер ATtiny85 в корпусе SOIC (около $1)
3. Boost DC/DC Converter LT1308 от компании Linear Technology. ($2.74 за 5 штук) LT1308 manual
4. Конденсаторы керамические, выпаяны из неисправной видеокарты.
5. Индуктивность COILTRONICS CTX5-1 или COILCRAFT DO3316-472.
6. Диод Шоттки, я использовал MBR0520 (0.5A, 20V)
Обещают 300мА 3.3В с одного элемента NiCd, нам подходит. Выходное напряжение устанавливается делителем, резисторы 330кОм и 120кОм, при указанных номиналах выходное напряжение преобразователя получается около 4.5В. Выходное напряжение выбиралось достаточным для питания контроллера и дисплея, чуть выше максимального измеряемого напряжения на литиевом аккумуляторе.
Для раскрытия всего потенциала преобразователя напряжения нужна индуктивность, которой у меня нет (см. пункт 5 выше), поэтому собираемый мной преобразователь имеет заведомо худшие параметры. Но и нагрузка у меня совсем небольшая. При подключении реальной нагрузки из микроконтроллера и OLED дисплея получается такая нагрузочная таблица.
Прекрасно, идём дальше.
Т.е. предполагается, что напряжение питания строго 5В. Если напряжение питания микроконтроллера изменится, то измеренное напряжение тоже изменится. Поэтому нам нужно узнать точное значение напряжения питания!
Многие чипы AVR включая серию ATmega и ATtiny обеспечивают средства для измерения внутреннего опорного напряжения. Путем измерения внутреннего опорного напряжения, мы можем определить значение Vcc. Вот как:
Из чего следует:
На просторах интернета была найдена функция для измерения напряжения питания контроллера:
Для вывода на экран используется библиотека Tiny4kOLED с включенным шрифтом 16х32. Из шрифта, для уменьшения размера библиотеки, удалены 2 не используемых символа (, и -) и нарисована отсутствующая буква «В». Код библиотеки соответственно изменен.
Так-же для стабилизации выводимых измерений использована функция с форума ардуино, спасибо автору dimax, работает хорошо.
Код я отлаживал на платке Digispark в среде arduino IDE. После чего ATtiny85 была выпаяна и припаяна на макетку. Собираем макетную плату, подстроечным резистором выставляем напряжение на выходе преобразователя (сначала я выставлял на выходе 5В, при этом ток на входе преобразователя был под 170мА, уменьшил напряжение до 4.5В, ток снизился до 100мА). Когда ATtiny85 припаяна на макетку код приходится заливать с помощью программатора, у меня обычный USBash ISP.
Как упоминалось выше, в контроллерах есть внутренний источник опорного напряжения 1.1В. Он стабильный, но не точный. Поэтому его реальное напряжение скорее всего отличается от 1.1В. Чтобы узнать, сколько на самом деле, необходимо провести калибровку:
* Ставим #define NASTROYKA 1
* Компилируем, заливаем код, запускаем, запоминаем значение на дисплее, например 5741
* Измеряем мультиметром реальное напряжение на выходе преобразователя, например 4979 (это в мВ)
* Считаем (4979/5741)*1.1=0.953997 — это реальное напряжение источника опорного напряжения
* Считаем 0.953997*1023*1000 = 975939
* Записываем результат в строку 100 в виде result = 975939L;
* Ставим #define NASTROYKA 0
* Компилируем, заливаем код, запускаем, готово.
В программе DipTrace разводим плату, размером с OLED дисплей 37х12мм
Полчаса нелюбимого занятия ЛУТом.
Припаиваем. SMD индуктивность 4,7мкГн была мне любезно предоставлена SS_SerG, большое спасибо, Сергей.
Собираем бутерброд из платы и экрана. На концах проводов я припаял небольшие магниты, вольтметр сам прищелкивается к измеряемому аккумулятору. Неодимовые магниты при нагреве выше 80 градусов теряют магнитные свойства, поэтому паять нужно легкоплавким сплавом Вуда или Розе очень быстро. Еще раз проводим калибровку и проверяем точность измерения:
Код программы, библиотеку OLED дисплея и печатную плату можно скачать ПО ССЫЛКЕ
Спасибо за внимание, всем добра.
25 лет назад у меня был кассетный плеер. Питал я его Ni-Cd аккумуляторами НКГЦ-0.45 ёмкостью 450мА/ч. Чтобы в дороге определять какие аккумуляторы уже сели, а какие ещё поработают было сделано простое устройство.
Батарейно-аккумуляторный диагностическо-измерительный комплекс.
Он собран по схеме преобразователя напряжения на двух транзисторах. На выход включен светодиод. Параллельно входу, подключаемому к аккумулятору включен резистор, намотанный из нихрома. Таким образом, если аккумулятор способен отдавать около 200мА, то светодиод загорается.
Из недостатков — размеры контактов жестко выгнуты на длину АА элемента, все прочие типоразмеры подключать не удобно. Ну и напряжение не видно. Поэтому в век цифровых технологий захотелось сделать более высокотехнологичное устройство. И конечно на микроконтроллере, куда без него :)
Итак, схема проектируемого устройства.
Используемые детали:
1. OLED дисплей с диагональю 0.91 дюйм и разрешением 128x32 (около $3)
2. Микроконтроллер ATtiny85 в корпусе SOIC (около $1)
3. Boost DC/DC Converter LT1308 от компании Linear Technology. ($2.74 за 5 штук) LT1308 manual
4. Конденсаторы керамические, выпаяны из неисправной видеокарты.
5. Индуктивность COILTRONICS CTX5-1 или COILCRAFT DO3316-472.
6. Диод Шоттки, я использовал MBR0520 (0.5A, 20V)
Преобразователь напряжения LT1308
Характеристики из описания LT1308:Обещают 300мА 3.3В с одного элемента NiCd, нам подходит. Выходное напряжение устанавливается делителем, резисторы 330кОм и 120кОм, при указанных номиналах выходное напряжение преобразователя получается около 4.5В. Выходное напряжение выбиралось достаточным для питания контроллера и дисплея, чуть выше максимального измеряемого напряжения на литиевом аккумуляторе.
Для раскрытия всего потенциала преобразователя напряжения нужна индуктивность, которой у меня нет (см. пункт 5 выше), поэтому собираемый мной преобразователь имеет заведомо худшие параметры. Но и нагрузка у меня совсем небольшая. При подключении реальной нагрузки из микроконтроллера и OLED дисплея получается такая нагрузочная таблица.
Прекрасно, идём дальше.
Особенности измерения напряжения микроконтроллером
Микроконтроллер ATtiny85 имеет АЦП разрядностью 10 бит. Поэтому считываемый уровень лежит в диапазоне 0-1023 (2^10 ). Для перевода в напряжение используется код:float Vcc = 5.0;
int value = analogRead(4); / читаем показания с А2
float volt = (value / 1023.0) * Vcc;
Т.е. предполагается, что напряжение питания строго 5В. Если напряжение питания микроконтроллера изменится, то измеренное напряжение тоже изменится. Поэтому нам нужно узнать точное значение напряжения питания!
Многие чипы AVR включая серию ATmega и ATtiny обеспечивают средства для измерения внутреннего опорного напряжения. Путем измерения внутреннего опорного напряжения, мы можем определить значение Vcc. Вот как:
- Установить источник опорного напряжения analogReference(INTERNAL).
- Снять показания АЦП для внутреннего источника 1.1 В.
- Расчитать значение Vcc основываясь на измерении 1.1 В по формуле:
Vcc * (Показания АЦП) / 1023 = 1.1 В
Из чего следует:
Vcc = 1.1 В * 1023 / (Показания АЦП)
На просторах интернета была найдена функция для измерения напряжения питания контроллера:
Функция readVcc()
long readVcc() {
// Read 1.1V reference against AVcc
// set the reference to Vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADMUX = _BV(MUX3) | _BV(MUX2);
#else
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
delay(75); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA,ADSC)); // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
long result = (high<<8) | low;
result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
return result; // Vcc in millivolts
}
Для вывода на экран используется библиотека Tiny4kOLED с включенным шрифтом 16х32. Из шрифта, для уменьшения размера библиотеки, удалены 2 не используемых символа (, и -) и нарисована отсутствующая буква «В». Код библиотеки соответственно изменен.
Так-же для стабилизации выводимых измерений использована функция с форума ардуино, спасибо автору dimax, работает хорошо.
Код я отлаживал на платке Digispark в среде arduino IDE. После чего ATtiny85 была выпаяна и припаяна на макетку. Собираем макетную плату, подстроечным резистором выставляем напряжение на выходе преобразователя (сначала я выставлял на выходе 5В, при этом ток на входе преобразователя был под 170мА, уменьшил напряжение до 4.5В, ток снизился до 100мА). Когда ATtiny85 припаяна на макетку код приходится заливать с помощью программатора, у меня обычный USBash ISP.
Код программы
// НАСТРОЙКА
/*
* Ставим #define NASTROYKA 1
* Компилируем, заливаем код, запускаем, запоминаем значение на дисплее, например 5741
* Измеряем мультиметром реальное напряжение на выходе преобразователя, например 4979 (это в мВ)
* Считаем (4979/5741)*1.1=0.953997
* Считаем 0.953997*1023*1000 = 975939
* Записываем результат в строку 100 в виде result = 975939L
* Ставим #define NASTROYKA 0
* Компилируем, заливаем код, запускаем, готово.
*/
#define NASTROYKA 0
#include <Tiny4kOLED.h>
#include <TinyWireM.h>
long Vcc;
float Vbat;
// тонкая настройка алгоритма сглаживания shumodav()
#define ts 5 // *table size* количество строк массива для хранения данных , для девиации ± 2 отсчёта оптимально 4 строки и одна в запас.
#define ns 25 // *number samples*, от 10..до 50 максимальное количество выборок для анализа 1й части алгоритма
#define ain A2 // какой аналоговый вход читать (А2 это P4)
#define mw 50 // *max wait* от 15..до 200 ms ожидать повтора отсчёта для 2 части алгоритма
unsigned int myArray[ts][2], aread, firstsample, oldfirstsample, numbersamples, rezult;
unsigned long prevmillis = 0;
boolean waitbegin = false; //флаг включённого счётчика ожидания повтора отсчёта
void setup() {
oled.begin();
oled.clear();
oled.on();
oled.setFont(FONT16X32_sega);
}
void loop() {
for (byte i = 0; i < 5; i++) {
Vcc += readVcc();
}
Vcc /= 5;
shumodav();
Vbat = ((rezult / 1023.0) * Vcc) / 1000;
if (Vbat >= 0.95) {
oled.setCursor(16, 0);#if NASTROYKA
oled.print(rezult);
#else
oled.print(Vbat, 2);
oled.print("/");
#endif
}
Vcc = 0;
}
long readVcc() { // чтение реального напряжения питания
// Read 1.1V reference against AVcc
// set the reference to Vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADMUX = _BV(MUX3) | _BV(MUX2);
#else
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
delay(75); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA, ADSC)); // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
long result = (high << 8) | low;
// result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
// индикатор показывал 4990, вольтметр 4576мВ (4576/4990)*1.1=1.008737
result = 1031938L / result; // Calculate Vcc (in mV); 1031938 = 1.008737*1023*1000
return result; // Vcc in millivolts
}
void shumodav() { // главная функция
//заполнить таблицу нолями в начале цикла
for (int s = 0; s < ts; s++ ) {
for (int e = 0; e < 2; e++) {
myArray[s][e] = 0;
}
}
// основной цикл накопления данных
for (numbersamples = 0; numbersamples < ns; numbersamples++) {
#if NASTROYKA
aread = readVcc();
#else
aread = analogRead(ain);
#endif
// уходим работать с таблицей////
tablework();
}
// заполнен массив, вычисляем максимально повторяющееся значение
int max1 = 0; // временная переменная для хранения максимумов
for (byte n = 0; n < ts ; n++) {
if (myArray[n][1] > max1) { //перебор 2-х элементов строк
max1 = myArray[n][1]; // запомним куда больше всего попало
firstsample = myArray[n][0]; // его 1 элемент = промежуточный результат.
}
}
//*****вторая фаза алгоритма *********/////
// если старый отсчёт не равен новому,
//и флага включения счёта времени небыло, то
if (oldfirstsample != firstsample && waitbegin == false) {
prevmillis = millis(); // скидываем счётчик времени на начало
waitbegin = true;
} // активируем флаг ожидания
// если до истечения лимита времени отсчёт сравнялся
//со старым, то снимаем флаг
if (waitbegin == true && oldfirstsample == firstsample) {
waitbegin = false;
rezult = firstsample;
}
// если всё таки отсчёт не сравнялся, а время ожидания вышло
if (waitbegin == true && millis() - prevmillis >= mw) {
oldfirstsample = firstsample;
waitbegin = false;
rezult = firstsample;
} //то признаём новый отсчёт конечным результатом функции.
} // конец главной функции
void tablework() { // функция внесения данных в таблицу
// если в таблице совпадает отсчёт, то инкрименировать
//его счётчик во втором элементе
for (byte n = 0; n < ts; n++) {
if (myArray[n][0] == aread) {
myArray[n][1] ++; return;
}
}
// перебираем ячейки что б записать значение aread в таблицу
for (byte n = 0; n < ts; n++) {
if (myArray[n][0] == 0) { //если есть пустая строка
myArray[n][0] = aread; return;
}
}
// если вдруг вся таблица заполнена раньше чем кончился цикл,
numbersamples = ns;
} // то счётчик циклов на максимум
Как упоминалось выше, в контроллерах есть внутренний источник опорного напряжения 1.1В. Он стабильный, но не точный. Поэтому его реальное напряжение скорее всего отличается от 1.1В. Чтобы узнать, сколько на самом деле, необходимо провести калибровку:
* Ставим #define NASTROYKA 1
* Компилируем, заливаем код, запускаем, запоминаем значение на дисплее, например 5741
* Измеряем мультиметром реальное напряжение на выходе преобразователя, например 4979 (это в мВ)
* Считаем (4979/5741)*1.1=0.953997 — это реальное напряжение источника опорного напряжения
* Считаем 0.953997*1023*1000 = 975939
* Записываем результат в строку 100 в виде result = 975939L;
* Ставим #define NASTROYKA 0
* Компилируем, заливаем код, запускаем, готово.
В программе DipTrace разводим плату, размером с OLED дисплей 37х12мм
Полчаса нелюбимого занятия ЛУТом.
Найдите 10 отличий
Первый раз я облажался и протравил зеркальную плату, причем заметил это только когда начал паять элементы.
Припаиваем. SMD индуктивность 4,7мкГн была мне любезно предоставлена SS_SerG, большое спасибо, Сергей.
Собираем бутерброд из платы и экрана. На концах проводов я припаял небольшие магниты, вольтметр сам прищелкивается к измеряемому аккумулятору. Неодимовые магниты при нагреве выше 80 градусов теряют магнитные свойства, поэтому паять нужно легкоплавким сплавом Вуда или Розе очень быстро. Еще раз проводим калибровку и проверяем точность измерения:
Бонус
Обманул, бонуса нет, простите.
Предвидя комментарии, что устройство с подобным и даже лучшим функционалом можно купить на Али сразу соглашусь без торговли. Вот оно, ищется по названию BT-168D. Стоит около $4.
Предвидя комментарии, что устройство с подобным и даже лучшим функционалом можно купить на Али сразу соглашусь без торговли. Вот оно, ищется по названию BT-168D. Стоит около $4.
Код программы, библиотеку OLED дисплея и печатную плату можно скачать ПО ССЫЛКЕ
Спасибо за внимание, всем добра.
Самые обсуждаемые обзоры
+60 |
1294
42
|
+41 |
2845
68
|
+49 |
2316
33
|
А за прямые руки +
Чем не устроил простой вольтметр за 1-1.5 доллара? Цвет цифр на дисплее можно выбрать
И точность даже на краях измеряемого диапазона разбегается на пару десятых вольта.
А, ну и пожалуйста за индуктивность ))) у меня в закромах всяко найти можно )))
ebay.com/itm/272458874791
Но у меня вылазит еще 2,36 за доставку — а это уже больше 5 баксов…
стрелочный ещё дешевле
лет этак 25 назад делал…
только я не лампочку ставил, а резистор. Вернее два один достаточно большой, а второй подключался кнопочкой.
И еще поставил диод — в результате шкала стала не от 0В до 1.5В, а от 0.8В до 1.5В
т.е. стало лучше видно сколько там в батарейке.
Пользуюсь до сих пор.
Кстати ток нагрузки при 1,5 В — 40 мА.
по причине отсутствия нагрузки на батаерйку в процессе измерения.
Ситуация аккурат трехдневной давности, с парой не новых литиевых 3-вольтовых батареек.
Тестером намерили у одной 3,12В, у второй 2,96В. Угадайте, какую в итоге вставили в пульт?
В пульт поставили ту, что на тестере показала себя хуже (2,96В).
потому что при замере тестером батареек на ней остались 2,94 вольта, а якобы хорошая «просела» до 2,1 вольта.
Провел замеры на лабораторном БП. Работать начинает примерно на 0.8 вольтах, но показывает при этом 0.6В При понижении напряжения расхождение увеличивается и при 0.3 В на тестере 0. В обратную сторону при повышении напряжения расхождение уменьшается, при 1.5 В совпадает с реальным а затем наоборот начинает завышать.
Как показометр — пойдёт. Точности нет и ниже 0.8в просто не включится.
Провел замеры на лабораторном БП. Работать начинает примерно на 0.8 вольтах, но показывает при этом 0.6В При понижении напряжения расхождение увеличивается и при 0.3 В на тестере 0. В обратную сторону при повышении напряжения расхождение уменьшается, при 1.5 В совпадает с реальным а затем наоборот начинает завышать.
После статьи Надежина, с тестом самых дешевых батареек из ашана и етс в сравнении с дорогими, я стал покупать в ашане — 4штуки ААА стоят 19рублей.
в пульты и етс самое то.
Знакомый покупает без малого дюраселы, а потом жалится что через 2 года у него пульт умер от того что батарейка потекла )
На сколько? Икеи рядом нет, но для A91 лучше дюрасела может быть только выдранный OEM Duracel из Microsoft'овских беспроводных комплектов.
соль очень эффективна в (недолговечных) детских игрушках, особенно C или D))
Делал тоже так кеммы для зарядки аккумуляторов.
Он полностью и не размагничивается, но магнитная сила заметно снижается. Чем больше по размеру магнит — тем менее заметно размагничивание.
отсюда совет: не использовать магнитики худенькие & с одной парой полюсов)
Я вот свои китайские(десятками) паяю ортофосфорной кислотой жалом паяльника разогретого до 300С(быстро 2-3 сек).
Ещё ни один магнит не испортился.Магнитную силу проверял ДО и ПОСЛЕ пайки-никакой разницы НЕ обнаружено.Паял и «худенькие» кругляши ф8мм х1мм.
У нас разный неодим или разные китайцы?
Или очередные мифы вашего городка?
Просто если уж используешь контроллер, сделай ему и задачу, например измерить внутреннее сопротивление батареи.
пусть это будет просто красивая учебная задача;)
^ или хотя бы качественной оценки: «у вас отличный аккум aaa или дохлая солевая d»
Я уж не говорю про то, что имеет 26 GPIO в этих 4x4мм, на борту 32КБ флеша, DMA, ЦАП, 3 таймера (2 по 16бит), нормальную отладку и программирование по 4м проводам, изменение настроек на лету, а не через какие то фьюзы и т.д. И стоит… (барабанная дробь)… тот же бакс на али. Не понимаю как при этом можно выбирать атмелы :).
кстати, корпус, — что, сделан из слюдяного конденсатора? класс!
да лаадно, а шелкография откуда взялась?)
при случае, допишите в сам обзор, какой получился объём прошивки (и каковы планы на v2.0:)
и соглашусь с Kruzo: stm8s стоит (стоило?) заметно меньше $1, в виде готового изделия^ — всё равно придётся их когда-нибудь изучать…
^ только «правой» половины схемы, ессно
Ещё раз посмотрел свои фото, шелкографию рассмотрел только на покупном OLED дисплее.
Корпус — прозрачная термоусадка :)
Обязательно должна быть кнопка, чтобы подключать нагрузку прямо во время измерения, чтобы оценить просадку напряжения. Это — главная характеристика «свежести» батарейки.
— Нет, это Бадик!
#else
^~~~
Battary_tester_:70:2: error: #endif without #if
#endif
^~~~~
exit status 1
#else without #if
Подскажите как решить, версию IDE, ссылку на платы для IDE… Заранее спасибо.