Давно хотелось сделать собственную защиту для свинцового акума, и сделал такую. Работает, но напряжение срабатывание колеблется постоянно от температуры да и хочется как бы своё запрограммировать и по паять... Прочитал интересную тему - почему бы и нет? Набросал тут немного, комментировал:
11 | int V = analogRead(3); |
12 | if (V > 441) digitalWrite(4, HIGH); |
13 | else digitalWrite(4, LOW); |
14 | if (V > 525 ) digitalWrite(5, HIGH); |
15 | else digitalWrite(5, LOW); |
16 | if (V > 492 ) digitalWrite(6, HIGH); |
17 | else digitalWrite(6, LOW); |
18 | if (V > 466 ) digitalWrite(7, HIGH); |
19 | else digitalWrite(7, LOW); |
Как видите всё просто, так как шить тайни буду UNO то памяти в моём распоряжении было немного, но тем не менее больше и не нужно. Релюху буду брать на 12 В ампер так на 10 + транзистор, думаю КТ817 подойдёт. Светодиоды само собой на резисторах будут сидеть. МК буду кормить через 78L05. Позже нарисую схемку...
Возможно названиями пинов немного ошибся, я просто ещё не имел опыта с тайни, как будет, тогда ещё поправлю если что-то не так назвал.
Интересно, схемку накидай, выложи.
Я бы сделал немного по другому:
01
int
V = 0;
// обнулим, мало ли ;)
02
void
setup
(){
03
pinMode(3, INPUT);
// вольтметр, делитель из 62 кОм и 15 кОм(земля), значение в 1023 это будет 24.35 В.
04
pinMode(4, OUTPUT);
// релюха
05
pinMode(5, OUTPUT);
// 1-й светодиод 100% заряда - 12.5 В.
06
pinMode(6, OUTPUT);
// 2-й светодиод 60% заряда - 11.7 В.
07
pinMode(7, OUTPUT);
// 3-й светодиод 30% заряда - 11.1 В.
08
}
09
void
loop
()
10
{
11
int
V = analogRead(3);
//если потолок 24.35 В, тогда 10.5 будет: (1023/24.35)*10.5 = 441
12
digitalWrite(5, HIGH);
13
digitalWrite(6, HIGH);
14
digitalWrite(7, HIGH);
15
if
(V > 441) digitalWrite(4, HIGH);
// если 10.5 В можно врубить реле
16
else
digitalWrite(4, LOW);
17
if
(V < 525 ) digitalWrite(5, LOW);
18
if
(V < 492 ) digitalWrite(6, LOW);
19
if
(V < 466 ) digitalWrite(7, LOW);
20
delay (1000);
// ждём 1 сек
21
}
Сэкономите несколько программных слов, что, - как вы уже заметили, - для 13-й тиньки весьма актуально.
Войдя во вкус экономии памяти, можно заняться гораздо более сытными кусками (правда, тут потребуются кое-какие знания о внутренностях микроконтроллера):
- Еще, наверное, полсотни этих самых слов можно сэкономить, если вместо digitalWrite использовать прямую запись в порт.
- То же самое относится к pinMode и Delay.
- Даже analogRead поддается оптимизации (идею можно почерпнуть, например, отсюда).
В результате код может оказаться раза в два-три короче - ненамного длиннее ассемблеровского. А, стало быть, появится шанс сделать устройство еще более умным - в тех же 1024 байтах программной памяти.
step962 спасибо за оптимизацию кода. Перешёл по Вашей сылке, прочёл и почти ничего не понял, видимо ещё нет тех знаний которые нужны.
Посмотрел даташит таньки, там есть интересная информация:
Low Power Consumption
– Active Mode:
• 190 μA at 1.8 V and 1 MHz
– Idle Mode:
• 24 μA at 1.8 V and 1 MHz
Тоесть если я подам на неё не 5 вольт а 1.8 она будет работать на частоте 0 – 4 MHz, чего для моих целей достаточно, и кушать будет 190 мкА. Ведь когда защита отрубит аккум от нагрузки она буде кушать что-то, так пускай кушает минимум.
Прикинул, у меня будет ещё одна нога свободная, так почему бы не неё не повесить собственно пуск релюхи? Тоесть если кнопка(не тактовая) не зажата то МК простаивает, если же зажата тогда всё это дело работает...
У меня есть вопрос, когда МК ждёт, тоесть delay (1000); это ведь будет простой верно?
И ещё вопрос, если я подам питание на МК в 1.8 В то резисторы на светодиоды не нужно будет, так как напряжение будет заниженное на них, соответственно по закону ома и ток аналогично.
ЗЫ ещё думаю использовать мосфет ключи для подачи на ретюху питания...
Тоесть если я подам на неё не 5 вольт а 1.8 она будет работать на частоте 0 – 4 MHz,
Не будет. Частота работы контроллера определяется подключенным к нему резонатором (в режиме работы от внешнего осциллятора) и соответствующей настройкой фьюзов. Без резонатора работать придется от внутреннего осциллятора - на одной из частот 128 кГц, 4.8 МГц, 9.6 МГц и опять таки для этого необходима правильная настройка фьюзов.
В любом случае снижение напряжения не приводит к снижению частоты его работы. Максимум, чего можно при этом добиться - нестабильности работы микроконтроллера.
коллеги...
1. можно эту схему вставить в автомобиль отечественный? Бывает забываю, к примеру, фары выключить. И всё каюк, с прикуривателем побираюсь.
2. сколько эта схема сама по себе потребляет энергии?
3. по-моему, при включении стартёра напряжение может падать до 6 вольт
Ясно, думаю для моих целей 128 кГц будет с лихвой.
Нарисовал схему в пеинте, довольно таки криво но думаю всё будет понятно.
коллеги...
1. можно эту схему вставить в автомобиль отечественный? Бывает забываю, к примеру, фары выключить. И всё каюк, с прикуривателем побираюсь.
2. сколько эта схема сама по себе потребляет энергии?
3. по-моему, при включении стартёра напряжение может падать до 6 вольт
2. Если всё сделаю правильно то автомобильный аккумулятор протянет её несколько лет, несколько ватта думаю это макс, всё зависит от реле.
Сам МК со светодиодами будет кушать 0.5 ватт.
Вот дорисовал немного схемку:
Добавил диод для защиты от переполюсовки, мне нужно ;)
Детали:
Диод любой на 30-40 В и ток в 0.1А
R1 15 кОм
R2 62 кОма
R3 хз какой, под транзистор
R4-R5 680 Ом
R6 10 кОм а можно и больше, это для того чтобы уменьшить потребление схемы когда батарея разрядиться до такой степени что уже релюшка не будет щёлкать.
VT1 Практически любой, в идеале мосфет транзистор.
Немного доработал скетч:
01
int
V = 0;
// обнулим, мало ли ;)
02
void
setup
(){
03
pinMode(1, INPUT);
// вольтметр, делитель из 62 кОм и 15 кОм(земля), значение в 1023 это будет 24.35 В.
04
pinMode(2, OUTPUT);
// релюха
05
pinMode(3, INPUT);
// кнопка, не тактовая
06
pinMode(5, OUTPUT);
// 1-й светодиод 100% заряда - 12.5 В.
07
pinMode(6, OUTPUT);
// 2-й светодиод 60% заряда - 11.7 В.
08
pinMode(7, OUTPUT);
// 3-й светодиод 30% заряда - 11.1 В. Можно на него повесьть резистор большего номинала ведь он будет гореть постоянно, а я хочу уменьшить потребление даной схемки
09
}
10
void
loop
()
11
{
12
int
V = analogRead(1);
//если потолок 24.35 В, тогда 10.5 будет: (1023/24.35)*10.5 = 441
13
if
(digitalRead(3) == HIGH) {
// если кнопка зажата - приступаем
14
if
(V > 441) digitalWrite(2, HIGH);
// если 10.5 В можно врубить реле
15
else
digitalWrite(2, LOW);
16
if
(V > 525 ) digitalWrite(5, HIGH);
// 1-й светодиод 100% - 12.5 В.
17
else
digitalWrite(5, LOW);
18
if
(V > 492 ) digitalWrite(6, HIGH);
// 2-й светодиод 60% заряда - 11.7 В.
19
else
digitalWrite(6, LOW);
20
if
(V > 466 ) digitalWrite(7, HIGH);
// 3-й светодиод 30% заряда - 11.1 В.
21
else
digitalWrite(7, LOW);
22
}
23
else
{
// если кнопка не зажата тогда хоть лопни с той кнопкой ;)
24
digitalWrite(2, LOW);
25
}
26
delay (1000);
// ждём 1 сек во избежания дребезжания контактов реле
27
}
А самое главное это размер:
Правда у меня в списке невидно таньку 13-ю, выбрал 25-ю таньку, список скорей всего просто не помещается на дисплее, он у меня 18.5 дюймов.
Осталось купить всё и собрать :)
Войдя во вкус экономии памяти, можно заняться гораздо более сытными кусками (правда, тут потребуются кое-какие знания о внутренностях микроконтроллера):
- Еще, наверное, полсотни этих самых слов можно сэкономить, если вместо digitalWrite использовать прямую запись в порт.
- То же самое относится к pinMode и Delay.
- Даже analogRead поддается оптимизации (идею можно почерпнуть, например, отсюда).
В результате код может оказаться раза в два-три короче - ненамного длиннее ассемблеровского. А, стало быть, появится шанс сделать устройство еще более умным - в тех же 1024 байтах программной памяти.
Думаю я начинаю понимать о чём Вы:
01
#include <util/delay.h>
02
int
V = 0;
// обнулим, мало ли ;)
03
void
setup
(){
04
pinMode(1, INPUT);
// вольтметр, делитель из 62 кОм и 15 кОм(земля), значение в 1023 это будет 24.35 В.
05
pinMode(2, OUTPUT);
// релюха
06
pinMode(3, INPUT);
// кнопка, не тактовая
07
pinMode(5, OUTPUT);
// 1-й светодиод 100% заряда - 12.5 В.
08
pinMode(6, OUTPUT);
// 2-й светодиод 60% заряда - 11.7 В.
09
pinMode(7, OUTPUT);
// 3-й светодиод 30% заряда - 11.1 В. Можно на него повесьть резистор большего номинала ведь он будет гореть постоянно, а я хочу уменьшить потребление даной схемки
10
}
11
void
loop
()
12
{
13
int
V = analogRead(1);
//если потолок 24.35 В, тогда 10.5 будет: (1023/24.35)*10.5 = 441
14
if
(digitalRead(3) == HIGH) {
// если кнопка зажата - приступаем
15
if
(V > 441) digitalWrite(2, HIGH);
// если 10.5 В можно врубить реле
16
else
digitalWrite(2, LOW);
17
if
(V > 525 ) digitalWrite(5, HIGH);
// 1-й светодиод 100% - 12.5 В.
18
else
digitalWrite(5, LOW);
19
if
(V > 492 ) digitalWrite(6, HIGH);
// 2-й светодиод 60% заряда - 11.7 В.
20
else
digitalWrite(6, LOW);
21
if
(V > 466 ) digitalWrite(7, HIGH);
// 3-й светодиод 30% заряда - 11.1 В.
22
else
digitalWrite(7, LOW);
23
}
24
else
{
25
digitalWrite(2, LOW);
26
}
27
_delay_ms(1000);
// ждём 1 сек во избежания дребезжания контактов реле
28
}
850 байт всего если для 25-й таньки, против 1024-х, отлично!
я бы так сделал
01
#include <util/delay.h>
02
int
V = 0;
// обнулим, мало ли ;)
03
void
setup
(){
04
pinMode(1, INPUT);
// вольтметр, делитель из 62 кОм и 15 кОм(земля), значение в 1023 это будет 24.35 В.
05
pinMode(2, OUTPUT);
// релюха
06
pinMode(3, INPUT);
// кнопка, не тактовая
07
pinMode(5, OUTPUT);
// 1-й светодиод 100% заряда - 12.5 В.
08
pinMode(6, OUTPUT);
// 2-й светодиод 60% заряда - 11.7 В.
09
pinMode(7, OUTPUT);
// 3-й светодиод 30% заряда - 11.1 В. Можно на него повесьть резистор большего номинала ведь он будет гореть постоянно, а я хочу уменьшить потребление даной схемки
10
}
11
void
loop
()
12
{
13
int
V = analogRead(1);
//если потолок 24.35 В, тогда 10.5 будет: (1023/24.35)*10.5 = 441
14
//
15
if
(V > 441 && digitalRead(3) == HIGH) digitalWrite(2, HIGH );
//если кнопка зажата и если 10.5 В можно врубить реле
16
else
digitalWrite(2, LOW);
17
if
(V > 525 ) digitalWrite(5, HIGH);
// 1-й светодиод 100% - 12.5 В.
18
else
digitalWrite(5, LOW);
19
if
(V > 492 ) digitalWrite(6, HIGH);
// 2-й светодиод 60% заряда - 11.7 В.
20
else
digitalWrite(6, LOW);
21
if
(V > 466 ) digitalWrite(7, HIGH);
// 3-й светодиод 30% заряда - 11.1 В.
22
else
digitalWrite(7, LOW);
23
24
25
_delay_ms(1000);
// ждём 1 сек во избежания дребезжания контактов реле
26
}
так светодиоды всегда будут отображать уровень напряжения, а не только когда тумблер включен
так светодиоды всегда будут отображать уровень напряжения, а не только когда тумблер включен
Спасибо за подсказку, но стоит ли? Моя целью - сделать всё это как можно энергоэффективней.
Вот смотрите, я использую батарею от упса как дополнительный буфер для моего ноутбука, конечно заряжаю бук через инвертор 12 В - 20 В. Именно потому что использую инвертор и задумался о создании подобной защиты, так как инвертор уверено работает от 8-ми вольт, что равноценно убийству акума без суда и следствия. Так вот, когда танька отключит нагрузку от акума, пусть она жрёт минимум энергии, ведь аккумулятор сел уже незачем его дальше мучить. Я ведь сипользую линейный стабилизатор для питания а у него КПД и без того небольшое...
850 байт всего если для 25-й таньки, против 1024-х, отлично!
Это вы delay на _delay_ms заменили?
Теперь вместо
1
if
(V > 441) digitalWrite(2, HIGH);
// если 10.5 В можно врубить реле
2
else
digitalWrite(2, LOW);
3
if
(V > 525 ) digitalWrite(5, HIGH);
// 1-й светодиод 100% - 12.5 В.
4
else
digitalWrite(5, LOW);
5
if
(V > 492 ) digitalWrite(6, HIGH);
// 2-й светодиод 60% заряда - 11.7 В.
6
else
digitalWrite(6, LOW);
7
if
(V > 466 ) digitalWrite(7, HIGH);
// 3-й светодиод 30% заряда - 11.1 В.
8
else
digitalWrite(7, LOW);
напишите
1
PORTD &= B00011011;
// тушим диоды 7,6,5 и размыкаем реле (2)
2
if
(V > 441) digitalWrite(2, HIGH);
// если 10.5 В можно врубить реле
3
if
(V > 525 ) digitalWrite(5, HIGH);
// 1-й светодиод 100% - 12.5 В.
4
if
(V > 492 ) digitalWrite(6, HIGH);
// 2-й светодиод 60% заряда - 11.7 В.
5
if
(V > 466 ) digitalWrite(7, HIGH);
// 3-й светодиод 30% заряда - 11.1 В.
Еще два десятка байтов сэкономите.
А если так:
1
PORTD &= B00011011;
// тушим диоды 7,6,5 и размыкаем реле (2)
2
if
(V > 441) PORTD |= B00000100;
// если 10.5 В можно врубить реле
3
if
(V > 525 ) PORTD |= B00100000;
// 1-й светодиод 100% - 12.5 В.
4
if
(V > 492 ) PORTD |= B01000000;
// 2-й светодиод 60% заряда - 11.7 В.
5
if
(V > 466 ) PORTD |= B10000000;
// 3-й светодиод 30% заряда - 11.1 В.
то экономия составит 236 байт (при условии, что и в других местах избавитесь от вызова функции digitalWrite)
А если в setup заменить
1
pinMode(1, INPUT);
// вольтметр, делитель из 62 кОм и 15 кОм(земля), значение в 1023 это будет 24.35 В.
2
pinMode(2, OUTPUT);
// релюха
3
pinMode(3, INPUT);
// кнопка, не тактовая
4
pinMode(5, OUTPUT);
// 1-й светодиод 100% заряда - 12.5 В.
5
pinMode(6, OUTPUT);
// 2-й светодиод 60% заряда - 11.7 В.
6
pinMode(7, OUTPUT);
// 3-й светодиод 30% заряда - 11.1 В. Можно на него повесьть резистор большего номинала ведь он будет гореть постоянно, а я хочу уменьшить потребление даной схемки
на
DDRD = B11100100;
то общая экономия составит около 420 байт.
При той же функциональности.
Но, конечно, необходимо кое-что почитать, кроме книжек типа "Arduino - это просто"...
Ясно.
>> всё зависит от реле.
вроде бывают реле с двумя устойчивыми положениями. Они потребляют только в момент переключения.
Тогда бы я изменил схему включения реле и кнопки
Реле бы поставил до схемы с нормально разомкнутым контактом, и кнопку без фиксации на запуск. Тогда после падения напряжения отключится вся нагрузк включая мк.
Snubist а если у нас будет там мощная нагрузка? Это негуманно по отношению к маленькой кнопке, быстро выйдет из строя - пройдены этап, пускай лучше таня себе постоянно курит в ожидании, пока нажму на зажимную кнопку.
toc нет, реле при одном положении контактов - не будут ничего кушать, при втором - будут несколько десятков миллиампер.
step962 спасибо за оптимизацыю кода, но я там пока ещё не сильно разбираюсь в этом С, может Вы мне поможете полностью перенести мою роботу, которую я делаю итак по примерам, на микропроцессорный С? Тогда повторить смогут не только ардуинщики но и обычные AVR-шики. Буду крайне признателен.
Я вот думаю что ещё было бы неплохо что бы защита ещё при достижении низкого уровня напряжения начала дико кричать в спикер, типо всё батарея сдохла, как упс, но как? ведь всё ноги занятые...
А как настроить правильно фюзы?
в файле boards.txt что лежит по адресу "C:\Users\Я\Documents\Arduino\hardware\attiny" изменить
1
attiny13.name=ATtiny13 (
internal
9.6 MHz clock)
2
attiny13.bootloader.low_fuses=0x7a
3
attiny13.bootloader.high_fuses=0xff
4
attiny13.upload.maximum_size=1024
5
attiny13.build.mcu=attiny13
6
attiny13.build.f_cpu=9600000L
7
attiny13.build.core=arduino:arduino
8
attiny13.build.variant=tiny8
attiny13.build.f_cpu=9600000L на attiny13.build.f_cpu=192000L
И всё?
Я тут доделал схемку по маленькой, на паре делать нечего было...
Нововведение заключается в том что добавил пищалку на второй контакт реле и ещё диод VD2 который защищает порт от переполюсовки, но тут нужно уже менять немного скетч, так как диод имеет тоже своё сопротивление, это скажется на значении аналогового входа(1). Короче ещё нужно доработать и протестировать.
ЗЫ подскажите пожалуйста в каком софте лучше рисовать схемы, а если можно было бы полностью смоделировать и посмотреть как она работает так было бы вообще клас.
про три светодиода...
если тини имеет резисторы на портах, как, к примеру, атмега328, то можно убрать R4, R5, R6, но при этом порты нужно оставить в режиме INPUT.
Хорошая программа - multisim.
Моделировать можно в Proteus, в т.ч. подсовывая ему скетч.
Через что у Вас планируется подавать плюс на обмотку реле?
То есть полный ряд частот, на которых может работать тини13 от внутреннего осциллятора -
16 кГц, 128 кГц, 600 кГц, 1.2 МГц, 4.8 МГц, 9.6 МГц.
Andrey_Y_Ostan рисовал по памяти, недосмотрел, там второй контакт реле идёт не в землю а к "+ in", спасибо за замечание.
Старнно что никто не посоветовал использовать мосфет вместо реле... хотя я хочу сделать полностью гальваническую развязку но при этом не используя оптопару или ещё что там... Если реле разомкнуто то ни капли не протечёт не тока, не напряжения.
toc надо бы попробовать... времени как такого нету всё прошить и собрать...
maksim какую частоту посоветуете выставить для как можно меньшего энергопотребления? Ведь просто так тормозить камень тож как-то не хочется.
А можно через #define задать частоту в IDE ?
Какую частоту посоветуете выставить для как можно меньшего энергопотребления?
А можно както через #define задать частоту в IDE ?
Какую частоту посоветуете выставить для как можно меньшего энергопотребления?
График зависимости потребляемого ATTiny13 тока в зависимости от частоты тактирования. Другие микроконтроллеры ведут себя подобным же образом.
А как использовать режимы энергосбережения, наверное есть какая-то функция которая усыпляет МК ? У меня стоит задержка в 1 сек, тогда пускай спит себе лучше вместо того чтобы просто ждать. Скетч довольно простой, мне кажется даже минимально возможной частоты в 16 кГц будет хватать более чем.
Попробуйте так:
01
#include <avr/wdt.h> // здесь организована работа с ватчдогом
02
#include <avr/sleep.h> // здесь описаны режимы сна
03
#include <avr/interrupt.h> // работа с прерываниями
04
05
06
ISR (WDT_vect)
// прерывания по ватчдогу
07
{
08
wdt_disable();
// отключаем ватчдог
09
}
10
11
void
setup
()
12
{
13
pinMode(0, OUTPUT);
14
}
15
16
17
void
loop
()
18
{
19
digitalWrite(0, HIGH);
// set the LED on
20
Sleep(WDTO_1S);
21
digitalWrite(0, LOW);
// set the LED off
22
Sleep(WDTO_1S);
23
}
24
25
void
Sleep(
byte
time){
26
ADCSRA &= ~(1 << ADEN);
// отключаем АЦП
27
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
// если спать - то на полную
28
wdt_enable(time);
// разрешаем ватчдог mсек
29
WDTCSR |= 1<<WDIE;
// разрешаем прерывания по ватчдогу. Иначе будет резет.
30
sei();
// разрешаем прерывания
31
sleep_enable();
// разрешаем сон
32
sleep_cpu();
// спать!
33
//спим
34
// проснулись
35
sleep_disable();
// запрещаем сон
36
ADCSRA &= 1 << ADEN;
// включаем АЦП
37
}
Так же отключается АЦП на время сна ,только писал я это для тини24 ,так что если что-то не заработает, то курим даташит.
Что-то неполучается смоделировать зашиту в Proteus 7 Professional, меняю название ног на PB0-PB4 в скетче, все подключаю соответственно и ничего не происходит. Такое впечатление что АЦП неработает, пробовал использовать другие ноги, всё тоже самое.
Уже второй день мучаюсь с этим моделированием в Proteus 7 Professional, неработает :( при подачи питания тупо включается реле и всё, на изменение напряжения не реагирует.
Вот архив с всеми файлами.
Уже второй день мучаюсь с этим моделированием в Proteus 7 Professional, неработает :( при подачи питания тупо включается реле и всё, на изменение напряжения не реагирует.
Мосфет пробило статикой при включении модели. :) Попробуйте оборвать линию, идущую от МК на затвор мосфета...
Так я вроде для того поставил резистор R6 чтобы полевик не открывался сам по себе. Если убрать проводок с 2 ноги, то сигнал от таньки всё равно идёт а реле разомкнуто...
Попробуйте подтянуть ресет к VCC, и вы проверяли пример блинк он работает?
да, написал скетч чтобы все порты мигали, все мигали как надо, последовательно но кроме PB5 походу его не удастся использовать...
Вообще-то PB5 это RESET и пока не установить фьюз, который его отключает он так и будет ресетом.
Могу предположить, что на тине13 не работает дуиновская функция analogRead(), поэтому воспользуйтесь ссылкой от step962 и даташитом на тини13.
Пробовал сегодня варить всё это дело, зашил блинк и релюха щёлкала каждую секунду.
Без бредборда тяжеловато, приходится паять всё...
Вот тут качал файлы для таньки, пишут что можно... хм...
Протэус может глючить ,попробуйте на настоящей микрухе.
На днях закончу.
Кстати, я не планирую останавливаться, есть у меня ещё идеек пару... например прибор для восстановления засульфатированных свинцовых аккумов... тоже на таньке, удобная она, и жрет мало.
Что только не делал, неработает, как в протеусе.
Вот немного отшлифовал скетч
01
//#include <util/delay.h> // уменьшим вес прошивки
02
int
V = 0;
// обнулим, мало ли ;)
03
void
setup
(){
04
pinMode(A3, INPUT);
// вольтметр, делитель из 5 кОм и 1 кОм(земля), значение в 1023 это будет 24.35 В.
05
pinMode(4, OUTPUT);
// релюха
06
pinMode(0, OUTPUT);
// 1-й светодиод 100% заряда - 12.5 В.
07
pinMode(1, OUTPUT);
// 2-й светодиод 65% заряда - 11.7 В.
08
pinMode(2, OUTPUT);
// 3-й светодиод 35% заряда - 11.1 В.
09
// диагностика:
10
digitalWrite(0, HIGH); delay(1000); digitalWrite(0, LOW); delay(1000);
11
digitalWrite(1, HIGH); delay(1000); digitalWrite(1, LOW); delay(1000);
12
digitalWrite(2, HIGH); delay(1000); digitalWrite(2, LOW); delay(1000);
13
digitalWrite(4, HIGH); delay(1000); digitalWrite(4, LOW);
14
// всё работает?
15
}
16
void
loop
()
17
{
18
digitalWrite(0, LOW);
19
digitalWrite(1, LOW);
20
digitalWrite(2, LOW);
//тушим диоды 100/65/35
21
int
V = analogRead(A3);
22
if
(V >= 441) { { digitalWrite(4, HIGH); }
// если 10.5 В можно врубить реле
23
if
(V <= 525 ) { digitalWrite(0, HIGH); }
// 1-й светодиод 100% заряда - 12.5 В.
24
if
(V <= 492 ) { digitalWrite(1, HIGH); }
// 2-й светодиод 65% заряда - 11.7 В.
25
if
(V <= 466 ) { digitalWrite(2, HIGH); } }
// 3-й светодиод 35% заряда - 11.1 В.
26
else
{ digitalWrite(4, LOW); }
27
delay(1000);
// ждём 1 сек во избежания дребезжания контактов реле
28
}
592 байта. Использовал файлы отсюда
Вот видео тестового скетча аля блинк, сорри за качество.
http://www.youtube.com/watch?v=QwNxW14ne64&feature=youtu.be
Как видете что-то работает но то что нужно...
Пол дня возился и нечего, обидно как-то даже :(
HWman,
1. что будет делать ваша програма если напряжение равно 10.4 вольт ?
2. что будет делать ваша програма если напряжение равно 12.6 вольт ?
3. уверен, что вы измерили резисторы в делителе мультиметром. Я плохо разбираюсь в маркировке, вероятно у вас резисторы с точностью 1% или 5%.
4. вы питаете мк от стабилизированного источника? померили напряжение?
5. если нет, то как вариант: можно измерить внутренний стабильный источник 1.1 В относительно А3. Стоп. Не знаю есть ли он в тини, в атмега328 есть.
6. Индикация "заряд включён" не предусмотрена?
1 Ничего не должно произойти.
2 При 12.6 должны гореть три диода и быть включенная релюха.
3 Замерял тестером, на порту 2.56 В что должно быть больше значения в 512.
4 Был линейный стаб 78L05, но он перегорел, не так припаял я его, пока питаю от юсб
5 хз а как это сделать? мой скетч выше, аппаратно что-то изменить уже будет сложно, всё припаяно уже
6 Нет, нету ног сводных...
Ещё наблюдения, при подачи питания, после диагностики реле сразу срабатывает и в таком состоянии может оставатся вечно. Если отсоединить клёмы от аккума то реле отключается, ещё бы, оно ведь питается от 12 В и горят все три диода...
И так. Как вам уже рекомендовал step962 отказывайтесь от дуиновских функций! Попробуйте так:
01
#define L100_ON PORTB|=1<<PB0 // 1-й светодиод 100% заряда - 12.5 В
02
#define L65_ON PORTB|=1<<PB1 // 2-й светодиод 65% заряда - 11.7 В.
03
#define L35_ON PORTB|=1<<PB2 // 3-й светодиод 35% заряда - 11.1 В.
04
#define RELE_ON PORTB|=1<<PB4 // релюха
05
#define L100_OFF PORTB&=~(1<<PB0)
06
#define L65_OFF PORTB&=~(1<<PB1)
07
#define L35_OFF PORTB&=~(1<<PB2)
08
#define RELE_OFF PORTB&=~(1<<PB4)
09
10
void
setup
()
11
{
12
DDRB = 0b10111;
13
// диагностика:
14
for
(
byte
i = 0; i < 3; i++)
15
{
16
PORTB = 1<<i;
17
delay(1000);
18
}
19
PORTB = 0;
20
RELE_ON;
21
delay(1000);
22
RELE_OFF;
23
delay(1000);
24
}
25
26
void
loop
()
27
{
28
int
V = ADC_READ();
29
if
(V >= 441)
30
{
31
RELE_ON;
// если 10.5 В можно врубить реле
32
V <= 525 ? L100_ON : L100_OFF;
// 1-й светодиод 100% заряда - 12.5 В.
33
V <= 492 ? L65_ON : L65_OFF;
// 2-й светодиод 65% заряда - 11.7 В.
34
V <= 466 ? L35_ON : L35_OFF;
// 3-й светодиод 35% заряда - 11.1 В.
35
}
36
else
RELE_OFF;
37
delay(1000);
// ждём 1 сек во избежания дребезжания контактов реле
38
}
39
40
int
ADC_READ()
41
{
42
ADMUX = 3;
// ADC pin
43
ADCSRA |= 1<<ADEN;
44
ADCSRA |= 1<<ADSC;
45
while
(!(ADCSRA & (1<<ADIF)));
46
ADCSRA |= 1<<ADIF;
47
byte
low = ADCL;
48
byte
high = ADCH;
49
ADCSRA &= ~(1 << ADEN);
// отключаем АЦП
50
return
(high << 8) | low;
51
}
1
sketch_mar20a.ino: In function
'void setup()'
:
2
sketch_mar20a:13: error:
'B10111'
was not declared
in
this
scope
Гуглил... пробовал подключить библиотеку #include<avr/io.h> всё тоже самое.
замените на
1
DDRB = 0b10111;
HWman,
1,2. Я всё никак не пойму... Я считаю аккумулятор полностью заряженным, если его напряжение больше или равно 12.5 вольт. Вы согласны? Почему у вас в строке 23 написано: если напряжение меньше или равно 525 то включить лампочку 《100%》?
3. Я имел в виду, что ваш резистор 5к может быть на самом деле 5.2к. Вы расчитывали константы для ифов с учётом фактического сопротивления резисторов?
4. МК измеряет А3 относительно напряжения питания VCC. Если оно 4.5 вольта - ваши константы станут неточными.
5. Поищите скетч "измерение vcc без использования ног". Позже дам ссылку. В вашем случае без ног не получится, вероятно.
6. Как вариант: когда идёт зарядка пусть мигает диод, надпись на котором ближе всего к текущему напряжению.
7. 'B10111' - забейте в скетч руками. Может там "В" русская.
UPD 2: 5. гуглить arduino secret voltmeter
maksim спасибо большое за переделку кода, всё работает в протэусе, позже прошью микруху и посмотрю как железо будет себя вести.
toc спасибо за поправку, сделал логическую ошибку, как-то стыдно за себя...
Для тонкой подстройки добавил подстроечник на 500 Ом последовательно к резистору в 1 кОм(реально он имеет 0.89 кОм замерял мультиметром) что позволяет мне поднимать напряжение которое на АЦП, тоесть менять потолок по измерению с 30 В до 21.75 В. Кстати делитель напряжения теперь из 5 кОм и 1кОм(земля).
Ну а мигание при зарядке реализовать сложновато, тут есть только один путь, следить за напряжением, если оно растёт тогда можно мигать... Мне это реализовать пока не по зубам, как видите.
Есть ещё куча нюансов, например, когда аккум сдохнет то у него напряжение не будет держатся на уровне 10.5 а будет расти, что естественно для свинцовых аккумов, тут нужно сделать какую то паузу в минут так 10-15... а может и вообще завершить исполнение цикла... Сейчас чёт мозги не варят всё это предусматривать, потом обязательно как-то реализую.
Собственно вот схема:
Почти на 80% завершена, нужно ещё некоторые нюансы учесть, о них ниже:
Есть пара вопросов по ней, нужно защитить от дурака схемку, всякое бывает, люблю я не так подсоединить проводки, тоесть от переполюсовки? Ну, перед входом стаба поставить диод - это понятно, но а как быть с ногой PB3 ? Ей ничего не будет при переполюсовке?
Извините за глупый вопрос, но что нужно сделать с Arduino IDE 1.0.3 что бы этот проект вообще скомпилировался. Я добавил нужные строки из поста #17, но все равно не компилируется.
1
In file included from sketch_mar21a.ino:10:
2
C:\Arduino\arduino-1.0.3\hardware\arduino\cores\arduino/Arduino.h:213:26: error: pins_arduino.h: No such file or directory
Качаете архив, распаковываете его в \Дуина\arduino-1.0.3\hardware\, после чего открываете файл \Дуина\arduino-1.0.3\hardware\attiny\boards.txt и добавляете в него строки:
attiny13.name=ATtiny13 (
internal
9.6 MHz clock)
attiny13.bootloader.low_fuses=0x7a
attiny13.bootloader.high_fuses=0xff
attiny13.upload.maximum_size=1024
attiny13.build.mcu=attiny13
attiny13.build.f_cpu=9600000L
attiny13.build.core=arduino:arduino
attiny13.build.variant=tiny8
запускаете IDE и в меню Сервис -> Плата выбираете ATtiny13 (internal 9.6 MHz clock) и компилируете.
Качаете архив, распаковываете его в \Дуина\arduino-1.0.3\hardware\, после чего открываете файл \Дуина\arduino-1.0.3\hardware\attiny\boards.txt и добавляете в него строки...........
Спасибо, все заработало!
Всё корректно работает?
поставил протеус.
хотел попробовать.
тут ничего нет :( ...Вот архив с всеми файлами.
всё хорошо.