Как заряжать NiMH AA аккумуляторы
Существует много способов зарядки NiMH аккумуляторов. Выбор используемого вами метода главным образом зависит от того, как быстро вы хотите зарядить аккумулятор. Скорость заряда измеряется по отношению к емкости батареи. Если ваша батарея обладает емкостью 2500 мАч, и вы заряжаете ее током 2500 мА, то вы заряжаете ее со скоростью 1C. Если вы заряжаете этот же аккумулятор током 250 мА, то вы заряжаете его со скоростью C/10.
Во время быстрой зарядки аккумулятора (со скоростью выше C/10), вам необходимо тщательно контролировать напряжение на батарее и ее температуру, чтобы не перезарядить ее. Это может серьезно повредить аккумулятор. Тем не менее, когда вы заряжаете аккумулятор медленно (со скоростью ниже C/10), у вас гораздо меньше шансов повредить батарею, если случайно перезарядите ее. Поэтому медленные методы зарядки, как правило, считаются более безопасными и помогут вам увеличить срок службы батареи. Поэтому в нашем самодельном зарядном устройстве мы будем использовать скорость заряда C/10.
Цепь заряда
Для данного зарядного устройства основой является схема для управления источником питания с помощью Arduino. Схема питается от источника напряжения 5 вольт, например, от адаптера переменного тока или компьютерного блока питания. Большинство USB портов не подходит для данного проекта из-за ограничений по току. Источник 5В заряжает батарею через мощный резистор 10 Ом и мощный MOSFET транзистор. MOSFET транзистор устанавливает величину тока, протекающего через батарею. Резистор добавлен как простой способ контроля тока. Контроль величины тока выполняется подключением каждого вывода резистора к аналоговым входным выводам Arduino и измерением напряжения с каждой стороны. MOSFET транзистор управляется выходным ШИМ выводом Arduino. Импульсы сигнала широтно-импульсной модуляции сглаживаются до постоянного напряжения фильтром на резисторе 1 МОм и конденсаторе 1 мкФ. Данная схема позволяет Arduino отслеживать и управлять током, протекающим через батарею.
Повышаем точность
Пока большие допуски внутреннего источника питания 1.1 В. значительно ограничивают точность измерений при использовании в серийном производстве, для индивидуальных проэктов мы можем добиться большей точности. Сделать это просто, просто измерив Vcc с помощью вольтметра и нашей функции readVcc(). Далее заменяем константу 1125300L новой переменной:
scale_constant = internal1.1Ref * 1023 * 1000
internal1.1Ref = 1.1 * Vcc1 (показания_вольтметра) / Vcc2 (показания_функции_readVcc())
Это калиброванное значение будет хорошим показателем для измерений AVR чипом, но может зависеть от изменений температуры. Не стесняйтесь экспериментировать с вашим собственным измерениям.
Вывод
С этой маленькой функцией можно сделать многее. Вы можете использовать стабильное опорное напряжение близкое к 5.0 В не имея на самом деле 5.0 В на Vcc. Вы можете измерять напряжение вашей батареи или даже увидеть на каком вы питание от батареи или от стационарного источника питания.
И наконец, код будет поддерживать все Arduino, включая новый Leonardo, а также чипы ATtinyX4 и ATtinyX5 серий.
Привет, Хабр! Сегодня хочу продолжить тему «скрещивания» arduino и android. В предыдущей публикации я рассказал про bluetooth машинку , а сегодня речь пойдет про DIY bluetooth вольтметр. Еще такой девайс можно назвать смарт вольтметр, «умный» вольтметр или просто умный вольтметр, без кавычек. Последнее название является неправильным с точки зрения грамматики русского языка, тем не менее частенько встречается в СМИ. Голосование на эту тему будет в конце статьи, а начать предлагаю с демонстрации работы устройства, чтобы понять о чем же пойдет речь в статье.
Скетч
int analogInput = A0;
float val = 0.0;
float voltage = 0.0;
float R1 = 100000.0; //Battery Vin-> 100K -> A0
float R2 = 10000.0; //Battery Gnd -> Arduino Gnd and Arduino Gnd -> 10K -> A0
int value = 0;
Void setup() {
Serial.begin(9600);
pinMode(analogInput, INPUT);
}
Void loop() {
value = analogRead(analogInput);
val = (value * 4.7) / 1024.0;
voltage = val / (R2/(R1+R2));
Serial.println(voltage);
delay(500);
}
Широкий интерес для любителей самодельных электронно-программируемых устройств представляют многофункциональные сборки Arduino, позволяющие воплощать в жизнь интересные задумки.
Основное преимущество готовых схем Arduino заключается в уникальном блочно-модульном принципе: каждая плата может быть добавлена дополнительными интерфейсами, бесконечно расширяя возможности для создания различных проектов.
Модули Arduino
построены на универсальном микроконтроллере с собственным загрузчиком, что позволяет легко прошивать его необходимым программным кодом, без использования дополнительных устройств. Программирование осуществляется на стандартном языке С++.
Одним из простейших примеров использования Arduino может стать реализация на базе этой сборки вольтметра постоянного напряжения повышенной точности с диапазоном измерения от 0 до 30 В.
Аналоговые входы Arduino предназначены для постоянного напряжения не более пяти вольт, поэтому, использование их при превышающих это значение напряжениях возможно с делителем напряжения.
Делитель напряжения состоит из двух последовательно соединенных сопротивлений. Расчет его производится по формуле:
Внешний USB-разъем в автомагнитоле
Корпус
Чтобы прибор имел презентабельный вид, для него был разработан алюминиевый корпус. Необходимые файлы проекта (Inkscape), шаблоны и трафареты также доступны в разделе загрузок.
На передней панели прибора расположены кнопки управления (выбор диапазона измерения, удержание показаний), разъемы для подключения тестовых щупов и ЖК-индикатор. Внешний вид передней панели прибора и расположение на ней кнопок, разъемов и индикатора изображено на Рисунке 6.
Рисунок 6. | Вариант передней панели и корпуса миллиомметра. |
Подключение ЖК-индикатора, разъемов и кнопок указано на Рисунке 7. На рисунке отмечено: 1 – печатная плата прибора, 2 – разъем внешнего питания, 3 – ЖК-индикатор, 4 –разъемы для тестовых щупов Кельвина, 5 –кнопки управления.
Рисунок 7. | Подключение кнопок управления, ЖК индикатора, тестовых щупов к разъемам на печатной плате миллиомметра. |
[46] Десульфатирующая зарядка своими руками на Arduino — бортжурнал Mitsubishi Lancer 1.5 MT ★ Silver Shark ★ 2009 года на DRIVE2
Вернувшись недавно из отпуска, первым делом я, конечно же, отправился проверять свою любимицу, шутка ли, машина простояла во дворе без движения почти три недели. Аккумулятор у меня стоит до сих пор «родной» а ему между тем исполнилось уже девять лет! Захотелось мне, проверить на нем напряжение после долго простоя. Картина была прямо таки удручающая, 11.
85 вольт, для современного акб это почти полный разряд. Более того, категорически не рекомендуется допускать падение напряжения ниже 12 вольт, так как после этого кальциевый аккумулятор очень быстро приходит в негодность. В общем, я тут же отправился сделать круг по КАДу что-бы подзарядить АКБ и в процессе обдумать, как продлить жизнь моего дедушки аккумулятора.
Полный размер
11.85 вольт для современного акб это почти полный разряд.
Таблица заряда аккумулятора
Хороших зарядных устройств ни у кого из знакомых не оказалось, а идею с покупкой нового я отмел сразу, поскольку нормальный зарядник стоит от трех тысяч рублей и выше, а мой бюджет и так был очень сильно подкошен прошедшим отпуском.
5 ампера2) DC-CC понижающий преобразователь до 9 ампер3) Цифровой Вольтметр/Амперметр4) Ардуино УНО совместимая плата Wemos D15) Пару ардуиновских реле6) LED дисплей, лампа на 5 ватт, резисторы и куча проводов.Подключил я всё это следующим образом.
Полный размер
Схема десульфирующего зарядника своими руками на Arduino
Суть предельно проста: напряжение с блока питания пускаем через преобразователь, настраиваем на выходе 14.4 вольта и до 4 ампер тока, для наглядности пропускаем всё это через вольтметр/амперметр и подключаем к аккумулятору через реле. Через второе реле вешаем на аккум лампочку. Плата Wemos управляет включением и выключением реле, так же к ней подключен LCD дисплей, кнопка включения, а к аналоговому пину A0 через делитель напряжения подведены провода напрямую с клемм акб для постоянного мониторинга напряжения во время зарядки.В скетче изначально я задал два режима:
1) Десульфикация – 3 секунды заряда током до 4 ампер, 3 секунды разряда током 0.4 ампера. Этот цикл заряда длится до повышения напряжения на клеммах до 14.4 вольт, далее автоматически переходит во второй режим.
2) В этом режиме зарядка происходит трёх секундными импульсами с паузами.
Перед зарядкой я так же промерил плотность электролита. В пяти банках она оказалась в пределах 1.20, а в первой к моему великому огорчению всего 1.175. А напряжение составило 12.3 вольта, что соответствует примерно 60% заряда.
Плотность в первой банке
Полный размер
Десульфирующая зарядка своими руками на Arduino
Первый цикл прошел достаточно быстро, всего около 8 часов, в начале заряда ток был около 4 ампер, а к концу цикла составлял всего чуть больше одного ампера. Во втором режиме зарядка проработала еще около двух часов, пока ток не упал до 0.4 ампера. Итого по грубым подсчетам за 10 часов в АКБ было влито всего около 10 ампер тока, явно маловато для 100% заряда, должно было влезть еще минимум 10!Зарядка в действииК этому я был готов заранее. Дело в том, что специфика современных кальциевых АКБ не позволяет зарядить их полностью привычным напряжением 14.4 вольта, им требуется от 15.8 до 16.1 вольта для 100% зарядки. Поэтому я тут же отрегулировал преобразователь на 15.8 вольт с максимальным током в 3 ампера. И поправил скетч в режим 2 секунды заряда, 4 секунды паузы.
Полный размер
Десульфирующая зарядка своими руками на Arduino
По итогу после ночного отстаивания АКБ показал напряжение 12.7 вольт. А вот с плотностью дела обстоят хуже, в пяти банках она поднялась до 1.25, а в первой составила всего 1.20.
Наверное, придётся в ближайшем будущем погонять акум в режиме заряд/разряд.
Всем добра!
Программа для вольтметра
Программа на языке C++ приведена на рисунке 2.
Рис. 2. Исходный код программы.
Для управления ЖК-индикатором решено было использовать порты с D2 по D7 платы ARDUINO UNO. В принципе, можно и другие порты, но я вот так, решил использовать именно эти.
Для того чтобы индикатор взаимодействовал с ARDUINO UNO нужно в программу загрузить подпрограмму для его управления. Такие подпрограммы называются «библиотеками», и в программном комплекте для ARDUINO UNO есть много разных «библиотек». Для работы с ЖК-индикатором на основе HD44780 нужна библиотека LiquidCrystal. Поэтому программа (таблица 1) начинается с загрузки этой библиотеки:
Эта строка дает команду загрузить в ARDUINO UNO данную библиотеку. Затем, нужно назначить порты ARDUINO UNO, которые будут работать с ЖК-индикатором. Я выбрал порты с D2 по D7. Можно выбрать другие. Эти порты назначены строкой:
LiquidCrystal led(2, 3, 4, 5, 6, 7);
После чего, программа переходит собственно к работе вольтметра. Для измерения напряжения решено было использовать аналоговые входы А1 и А2. Эти входы заданы в строках:
int analogInput=1;
int analogInput1=2;
Для чтения данных с аналоговых портов используется функция analogRead. Чтение данных с аналоговых портов происходит в строках:
vout=analogRead(analogInput);
voutl=analogRead(analoglnput1);
Затем, производится вычисление фактического напряжения с учетом коэффициента деления делителя входного напряжения:
volt=vout*5.0/1024.0/0.048 ;
volt1=vout1*5.0/1024.0/0.048;
В этих строках число 5.0 — это напряжение на выходе стабилизатора платы ARDUINO UNO. В идеале должно быть 5V, но для точной работы вольтметра это напряжение нужно предварительно измерить. Подключите источник питания и измерьте достаточно точным вольтметром напряжение +5V на разъеме POWER платы. Что будет, то и вводите в эти строки вместо 5.0, например, если будет 4.85V, строки будут выглядеть так:
volt=vout*4.85/1024.0/0.048;
volt1=vout1*4.85/1024.0/0.048;
На следующем этапе нужно будет измерить фактические сопротивления резисторов R1-R4 и определить коэффициенты К (указаны 0.048) для этих строк по формулам:
К1 = R3 / (R1+R3) и К2 = R4 / (R2+R4)
Допустим, К1 = 0.046, а К2 = 0.051, так и пишем:
volt=vout*4.85/1024.0/0.046 ;
volt1=vout1*4.85/1024.0/0.051;
Таким образом, в текст программы нужно внести изменения соответственно фактическому напряжению на выходе 5-воль-тового стабилизатора платы ARDUINO UNO и согласно фактическим коэффициентам деления резистивных делителей. После этого прибор будет работать точно и никакого налаживания или калибровки не потребует.
Изменив коэффициенты деления резистивных делителей (и, соответственно, коэффициенты «К») можно сделать другие пределы измерения, и совсем не обязательно одинаковые для обоих входов.
Каравкин В. РК-2017-01.
Литература:
- Каравкин В. — Ёлочная мигалка на ARDUINO как средство от боязни микроконтроллеров. РК-11-2016.
- Каравкин В. — Частотомер на ARDUINO. РК-12-2016.
Вольтметр
Я реализую простой вольтметр с одним диапазоном примерно 0 — 20в
Это замечанием важно, тк АЦП нашего контроллера имеет разрядность 10 бит (1024 дискретных значения), поэтому погрешность составит не менее 0.02 в (20 / 1024). Для реализации железно нам нужен аналоговый вход контроллера, делитель из пары резисторов и какой-нибудь вывод (дисплей в законченном варианте, для отладки можно последовательный порт)
Принцип измерения АЦП состоит в сравнении напряжения на аналоговом входе с опорным VRef. Выход АЦП всегда целый — 0 соответствует 0в, 1023 соответствует напряжению VRef. Измерение реализовано путем серии последовательных чтений напряжения и усреднения по периоду между обновлениями значения на экране. Выбор опорного напряжения важен, поскольку по умолчанию оно равно напряжению питания, которое может быть не стабильно. Это нам совершенно не подходит — за основу мы будем брать стабильный внутренний опорный источник напряжением 1.1в, инициализируя его вызовом analogReference(INTERNAL). Затем мы откалибруем его значение по показаниям мультиметра.
На схеме слева — вариант с прямым управлением дисплея (он просто управляется — смотрите стандартный скетч LiquidCrystal\HelloWorld). Справа — вариант с I2C, который я и буду использовать дальше. I2C позволяет сэкономить на проводах (коих в обычном варианте — 10, не считая подсветки). Но при этом необходим дополнительный модуль и более сложная инициализация. В любом случае, отображение символов на модуле надо сначала проверить и настроить контрастность — для этого надо просто вывести после инициализации любой текст. Контрастность настраивается резистором R1, либо аналогичным резистором I2C модуля.
Вход представляет собой делитель 1:19, который позволяет при Vref = 1.1 получить максимальное напряжение около 20в (обычно параллельно входу ставят конденсатор + стабилитрон для защиты, но нам пока это не важно). Резисторы имеют разброс, да и опорное Vref контроллера тоже, поэтому после сборки надо измерить напряжение (хотя бы питания) параллельно нашим устройством и эталонным мультиметром и подобрать Vref в коде до совпадения показания
Так же стоить отметить, что любой АЦП имеет напряжение смещения нуля (которое портит показания в начале диапазона), но мы пока не будем в это углубляться.
Также важным будет разделение питающей и измерительной «земли». Наш АЦП имеет разрешение чуть хуже 1мВ, что может создавать проблемы при неправильной разводке, особенно на макете. Поскольку разводка платы модуля уже сделана и нам остается только выбор пинов. «Земляных» пинов у модуля несколько, поэтому мы должны сделать так, чтобы питание в модуль заходило по одной «земле», а измерения по другой. Фактически для изменений я всегда использую «земляной» пин ближайший к аналоговым входам.
Для управление I2C используется вариант библиотеки LiquidCrystal_I2C — в моем случае указывается специфическая распиновка модуля I2C (китайцы производят модули с отличающимся управлением). Так же отмечу, что I2C в Arduino предполагает использование именно пинов A4, A5 — на плате Pro Mini они находятся не с краю, что неудобно для макетирования на BreadBoard.
Объяснение программы для Arduino
Полный код программы приведен в конце статьи, здесь же мы рассмотрим его основные фрагменты.
Цель функционирования программы – считать значения аналогового напряжения с контактов A3 и A4 и рассчитать напряжение, ток и мощность, а потом отобразить все это на экране ЖК дисплея.
Вначале программы нам необходимо инициализировать используемые контакты: A3 и A4 для измерения напряжения и тока соответственно, и цифровые контакты 3, 4, 8, 9, 10 и 11 для подключения ЖК дисплея.
Arduino
int Read_Voltage = A3;
int Read_Current = A4;
const int rs = 3, en = 4, d4 = 8, d5 = 9, d6 = 10, d7 = 11; //контакты для подключения ЖК дисплея
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
1 |
intRead_Voltage=A3; intRead_Current=A4; constintrs=3,en=4,d4=8,d5=9,d6=10,d7=11;//контакты для подключения ЖК дисплея LiquidCrystallcd(rs,en,d4,d5,d6,d7); |
Далее внутри функции setup мы инициализируем ЖК дисплей и показываем на нем приветственное сообщение “Arduino Wattmeter”, ждем 2 секунды, а потом очищаем экран дисплея.
Arduino
void setup() {
lcd.begin(16, 2); //инициализируем ЖК дисплей 16х2
lcd.print(» Arduino Wattmeter»); //приветственное сообщение на первой строчке
lcd.setCursor(0, 1);
lcd.print(«-Circuitdigest»); //приветственное сообщение на второй строчке
delay(2000);
lcd.clear();
}
1 |
voidsetup(){ lcd.begin(16,2);//инициализируем ЖК дисплей 16х2 lcd.print(» Arduino Wattmeter»);//приветственное сообщение на первой строчке lcd.setCursor(,1); lcd.print(«-Circuitdigest»);//приветственное сообщение на второй строчке delay(2000); lcd.clear(); } |
Внутри главной функции main мы будем использовать функцию analogread для считывания значений напряжения с аналоговых контактов A3 и A4. Плата Arduino имеет 10 битный АЦП (аналогово-цифровой преобразователь) поэтому на его выходе диапазон возможных значений составляет 0-1023. Это значение потом конвертируется в диапазон 0-5V с помощью его умножения на (5/1023). Поскольку в аппаратной части проекта мы преобразуем истинное значение напряжения из диапазона 0-24V в диапазон 0-5V и истинное значение тока из диапазона 0-1A в диапазон 0-5V. Поэтому в программе мы должны использовать умножитель чтобы конвертировать значения с выхода АЦП в истинные значения напряжения и тока. Коэффициенты для этого умножения можно теоретически рассчитать либо с помощью формул, описанных в разделе статьи «работа схемы», либо практически, зная значения измеряемых токов и напряжений. Второй подход представляется более точным, поэтому мы использовали именно его и у нас с его помощью получились коэффициенты умножения 6.46 и 0.239.
Arduino
float Voltage_Value = analogRead(Read_Voltage);
float Current_Value = analogRead(Read_Current);
Voltage_Value = Voltage_Value * (5.0/1023.0) * 6.46;
Current_Value = Current_Value * (5.0/1023.0) * 0.239;
1 |
floatVoltage_Value=analogRead(Read_Voltage); floatCurrent_Value=analogRead(Read_Current); Voltage_Value=Voltage_Value*(5.01023.0)*6.46; Current_Value=Current_Value*(5.01023.0)*0.239; |
Исходный код программы (скетча)
Код программы достаточно объемный, но по своей сути он достаточно простой, мы надеемся, что его понимание не вызовет у вас затруднений.
Arduino
#include<LiquidCrystal.h>
LiquidCrystal lcd(A5, A4, A3, A2, A1, A0);
#define serial
#define charge 3
#define freqIn 2
#define mode 10
#define Delay 15
double frequency, capacitance, inductance;
typedef struct
{
int flag: 1;
}Flag;
Flag Bit;
void setup()
{
#ifdef serial
Serial.begin(9600);
#endif
lcd.begin(16, 2);
pinMode(freqIn, INPUT);
pinMode(charge, OUTPUT);
pinMode(mode, INPUT_PULLUP);
lcd.print(» LC Meter Using «);
lcd.setCursor(0, 1);
lcd.print(» Arduino «);
delay(2000);
lcd.clear();
lcd.print(«Circuit Digest»);
delay(2000);
}
void loop()
{
for(int i=0;i<Delay;i++)
{
digitalWrite(charge, HIGH);
delayMicroseconds(100);
digitalWrite(charge, LOW);
delayMicroseconds(50);
double Pulse = pulseIn(freqIn, HIGH, 10000);
if (Pulse > 0.1)
frequency+= 1.E6 / (2 * Pulse);
delay(20);
}
frequency/=Delay;
#ifdef serial
Serial.print(«frequency:»);
Serial.print( frequency );
Serial.print(» Hz «);
#endif
lcd.setCursor(0, 0);
lcd.print(«freq:»);
lcd.print( frequency );
lcd.print(» Hz «);
if (Bit.flag)
{
inductance = 1.E-3;
capacitance = ((1. / (inductance * frequency * frequency * 4.*3.14159 * 3.14159)) * 1.E9);
if((int)capacitance < 0)
capacitance=0;
#ifdef serial
Serial.print(«Capacitance:»);
Serial.print( capacitance,6);
Serial.println(» uF «);
#endif
lcd.setCursor(0, 1);
lcd.print(«Cap: «);
if(capacitance > 47)
{
lcd.print( (capacitance/1000));
lcd.print(» uF «);
}
else
{
lcd.print(capacitance);
lcd.print(» nF «);
}
}
else
{
capacitance = 0.1E-6;
inductance = (1. / (capacitance * frequency * frequency * 4.*3.14159 * 3.14159)) * 1.E6;
#ifdef serial
Serial.print(«Ind:»);
if(inductance>=1000)
{
Serial.print( inductance/1000 );
Serial.println(» mH»);
}
else
{
Serial.print( inductance );
Serial.println(» uH»);
}
#endif
lcd.setCursor(0, 1);
lcd.print(«Ind:»);
if(inductance>=1000)
{
lcd.print( inductance/1000 );
lcd.print(» mH «);
}
else
{
lcd.print( inductance );
lcd.print(» uH «);
}
}
if (digitalRead(mode) == LOW)
{
Bit.flag = !Bit.flag;
delay(1000);
while (digitalRead(mode) == LOW);
}
delay(50);
}
1 |
#include<LiquidCrystal.h> LiquidCrystallcd(A5,A4,A3,A2,A1,A0); #define serial doublefrequency,capacitance,inductance; typedefstruct { intflag1; }Flag; FlagBit; voidsetup() { Serial.begin(9600); #endif lcd.begin(16,2); pinMode(freqIn,INPUT); pinMode(charge,OUTPUT); pinMode(mode,INPUT_PULLUP); lcd.print(» LC Meter Using «); lcd.setCursor(,1); lcd.print(» Arduino «); delay(2000); lcd.clear(); lcd.print(«Circuit Digest»); delay(2000); } voidloop() { for(inti=;i<Delay;i++) { digitalWrite(charge,HIGH); delayMicroseconds(100); digitalWrite(charge,LOW); delayMicroseconds(50); doublePulse=pulseIn(freqIn,HIGH,10000); if(Pulse>0.1) frequency+=1.E6(2*Pulse); delay(20); } frequency/=Delay; #ifdef serial Serial.print(«frequency:»); Serial.print(frequency); Serial.print(» Hz «); #endif lcd.setCursor(,); lcd.print(«freq:»); lcd.print(frequency); lcd.print(» Hz «); if(Bit.flag) { inductance=1.E-3; capacitance=((1.(inductance*frequency*frequency*4.*3.14159*3.14159))*1.E9); if((int)capacitance<) capacitance=; #ifdef serial Serial.print(«Capacitance:»); Serial.print(capacitance,6); Serial.println(» uF «); #endif lcd.setCursor(,1); lcd.print(«Cap: «); if(capacitance>47) { lcd.print((capacitance1000)); lcd.print(» uF «); } else { lcd.print(capacitance); lcd.print(» nF «); } } else { capacitance=0.1E-6; inductance=(1.(capacitance*frequency*frequency*4.*3.14159*3.14159))*1.E6; #ifdef serial Serial.print(«Ind:»); if(inductance>=1000) { Serial.print(inductance1000); Serial.println(» mH»); } else { Serial.print(inductance); Serial.println(» uH»); } #endif lcd.setCursor(,1); lcd.print(«Ind:»); if(inductance>=1000) { lcd.print(inductance1000); lcd.print(» mH «); } else { lcd.print(inductance); lcd.print(» uH «); } } if(digitalRead(mode)==LOW) { Bit.flag=!Bit.flag; delay(1000); while(digitalRead(mode)==LOW); } delay(50); } |
Шаг 4. Наша схема
У нас был SPI OLED, который валялся без дела, поэтому мы преобразовали его в I2C и использовали. Если вы хотите узнать, как преобразовать SPI в OLED, то мы обязательно это разберем в ближайших уроках.
Схему проекта смотрите выше. И вот как работает эта схема. Сначала Arduino измеряет падение напряжения, создаваемое резистором 10 Ом, если выше 4,3 В, тогда она отключит высокое напряжение дисплея MOSFET, если оно меньше 2,9 В, оно отображает низкое напряжение и выключает MOSFET, а если находится между 4,3 В и 2,9 В, то она включит MOSFET. Батарея начнет разряжаться через резистор, начнется измерение тока, используя закон Ома. Ардуино также использует функцию Миллиса для измерения времени, а произведение тока и времени дает нам пропускную способность.
Мотивация
Есть, по крайней
мере, две причины
для измерения
напряжения, питающего
наш
Arduino
(Vcc). Одним из них является наш проект, питающийся от батареи, если мы хотим следить за уровнем напряжения батареи. Кроме того, когда питание от батареи (Vcc) не может быть 5,0 вольт(например питание от 3-х элементов 1.5 В), а мы хотим сделать аналоговые измерения более точными — мы должны использовать либо внутренний источник опорного напряжения 1,1 В либо внешний источник опорного напряжения. Почему?
Обычно предполагают при использовании analogRead () то, что аналоговое напряжение питания контроллера составляет 5.0 вольт, когда в действительности это может быть совсем не так(например питание от 3-х элементов 1.5 В). Официальная документация Arduino даже может привести нас к этому неправильному предположению. Дело в том, что питание не обязательно 5,0 вольт, независимо от текущего уровня это питание подано на Vcc чипа. Если наше питание не стабилизировано или если мы работаем от аккумулятора, это напряжение может меняться совсем немного. Вот пример кода, иллюстрирующий эту проблему:
Double Vcc = 5.0; // не обязательно правда
int value = analogRead(0); / читаем показания с А0
double volt = (value / 1023.0) * Vcc; // верно только если Vcc = 5.0 вольт
Для того чтобы измерить напряжение точно, необходимо точное опорное напряжение. Большинство чипов AVR обеспечивает три источника опорного напряжения:
1,1 в от внутреннего источника, в документации он проходит как bandgap reference (некоторые из них 2,56 В, например ATMega 2560). Выбор осуществляется функцией analogReference() с параметром INTERNAL : analogReference(INTERNAL) ;
внешний источник опорного наптяжения, на ардуинке подписан AREF. Выбор: analogReference(EXTERNAL);
Vcc — источник питания самого контроллера. Выбор: analogReference(DEFAULT).
В Arduino нельзя просто взять и подключить Vcc к аналоговому пину напрямую — по умолчанию AREF связан с Vcc и вы всегда будете получать максимальное значение 1023, от какого бы напряжения вы не питались. Спасает подключение к AREF источника напряжения с заранее известным, стабильным напряжением, но это — лишний элемент в схеме.
Еще можно соединить Vcc с AREF через диод
: падение напряжение на диоде заранее известно, поэтому вычислить Vcc не составит труда. Однако, при такой схеме через диод постоянно протекает ток
, сокращая жизнь батареи, что тоже не очень удачно.
Источник внешнего опорного напряжения является наиболее точным, но требует дополнительных аппаратных средств. Внутренний ИОН стабильным, но не точен + / — 10% отклонение. Vcc является абсолютно ненадежен в большинстве случаев. Выбор внутреннего источника опорного напряжения является недорогим и стабильным, но большую часть времени, мы хотели бы измеряет большее напряжение чем 1.1 В, так что использование Vcc является наиболее практичным, но потенциально наименее точным. В некоторых случаях оно может быть очень ненадежным!