Защита от глубокого разряда на ATtiny13A

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Давно хотелось сделать собственную защиту для свинцового акума, и сделал такую. Работает, но напряжение срабатывание колеблется постоянно от температуры да и хочется как бы своё запрограммировать и по паять... Прочитал интересную тему - почему бы и нет? Набросал тут немного, комментировал:









int V = 0; // обнулим, мало ли ;)
void setup(){
 pinMode(3, INPUT); // вольтметр, делитель из 62 кОм и 15 кОм(земля), значение в 1023 это будет 24.35 В.
 pinMode(4, OUTPUT); // релюха
 pinMode(5, OUTPUT); // 1-й светодиод 100% заряда - 12.5 В.
 pinMode(6, OUTPUT); // 2-й светодиод 60% заряда - 11.7 В.
 pinMode(7, OUTPUT); // 3-й светодиод 30% заряда - 11.1 В.
}
void loop()
{
  int V = analogRead(3); //если потолок 24.35 В, тогда 10.5 будет: (1023/24.35)*10.5 = 441
  if(V > 441) digitalWrite(4, HIGH); // если 10.5 В можно врубить реле
  else digitalWrite(4, LOW);
  if(V > 525 ) digitalWrite(5, HIGH); // 1-й светодиод 100%  - 12.5 В.
  else digitalWrite(5, LOW);
  if(V > 492 ) digitalWrite(6, HIGH); // 2-й светодиод 60% заряда - 11.7 В.
  else digitalWrite(6, LOW);
  if(V > 466 ) digitalWrite(7, HIGH); // 3-й светодиод 30% заряда - 11.1 В.
  else digitalWrite(7, LOW);
  delay (1000);  // ждём 1 сек
}

Как видите всё просто, так как шить тайни буду UNO то памяти в моём распоряжении было немного, но тем не менее больше и не нужно. Релюху буду брать на 12 В ампер так на 10 + транзистор, думаю КТ817 подойдёт. Светодиоды само собой на резисторах будут сидеть. МК буду кормить через 78L05. Позже нарисую схемку...

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

Snubist
Offline
Зарегистрирован: 18.02.2013

Интересно, схемку накидай, выложи.

step962
Offline
Зарегистрирован: 23.05.2011

Я бы сделал немного по другому:









int V = 0; // обнулим, мало ли ;)
void setup(){
 pinMode(3, INPUT); // вольтметр, делитель из 62 кОм и 15 кОм(земля), значение в 1023 это будет 24.35 В.
 pinMode(4, OUTPUT); // релюха
 pinMode(5, OUTPUT); // 1-й светодиод 100% заряда - 12.5 В.
 pinMode(6, OUTPUT); // 2-й светодиод 60% заряда - 11.7 В.
 pinMode(7, OUTPUT); // 3-й светодиод 30% заряда - 11.1 В.
}
void loop()
{
  int V = analogRead(3); //если потолок 24.35 В, тогда 10.5 будет: (1023/24.35)*10.5 = 441
  digitalWrite(5, HIGH);
  digitalWrite(6, HIGH);
  digitalWrite(7, HIGH);
  if(V > 441) digitalWrite(4, HIGH); // если 10.5 В можно врубить реле
  else digitalWrite(4, LOW);
  if(V < 525 ) digitalWrite(5, LOW);
  if(V < 492 ) digitalWrite(6, LOW);
  if(V < 466 ) digitalWrite(7, LOW);
  delay (1000);  // ждём 1 сек
}

Сэкономите несколько программных слов, что, - как вы уже заметили, - для 13-й тиньки весьма актуально.

Войдя во вкус экономии памяти, можно заняться гораздо более сытными кусками (правда, тут потребуются кое-какие знания о внутренностях микроконтроллера):
- Еще, наверное, полсотни этих самых слов можно сэкономить, если вместо digitalWrite использовать прямую запись в порт.
- То же самое относится к pinMode и Delay.
- Даже analogRead поддается оптимизации (идею можно почерпнуть, например, отсюда).

 

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

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

 

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 В то резисторы на светодиоды не нужно будет, так как напряжение будет заниженное на них, соответственно по закону ома и ток аналогично.

ЗЫ ещё думаю использовать мосфет ключи для подачи на ретюху питания...

step962
Offline
Зарегистрирован: 23.05.2011

HWman пишет:

Тоесть если я подам на неё не 5 вольт а 1.8 она будет работать на частоте 0 – 4 MHz, 

Не будет. Частота работы контроллера определяется подключенным к нему резонатором (в режиме работы от внешнего осциллятора) и соответствующей настройкой фьюзов. Без резонатора работать придется от внутреннего осциллятора - на одной из частот 128 кГц, 4.8 МГц, 9.6 МГц и опять таки для этого необходима правильная настройка фьюзов.

В любом случае снижение напряжения не приводит к снижению частоты его работы. Максимум, чего можно при этом добиться - нестабильности работы микроконтроллера.

 

toc
Offline
Зарегистрирован: 09.02.2013

коллеги...

1. можно эту схему вставить в автомобиль отечественный? Бывает забываю, к примеру, фары выключить. И всё каюк, с прикуривателем побираюсь.

2. сколько эта схема сама по себе потребляет энергии?

3. по-моему, при включении стартёра напряжение может падать до 6 вольт

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Ясно, думаю для моих целей 128 кГц будет с лихвой.

Нарисовал схему в пеинте, довольно таки криво но думаю всё будет понятно.

схема

 

 

 

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

toc пишет:

коллеги...

1. можно эту схему вставить в автомобиль отечественный? Бывает забываю, к примеру, фары выключить. И всё каюк, с прикуривателем побираюсь.

2. сколько эта схема сама по себе потребляет энергии?

3. по-моему, при включении стартёра напряжение может падать до 6 вольт

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

Сам МК со светодиодами будет кушать 0.5 ватт.

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Вот дорисовал немного схемку:

схема

Добавил диод для защиты от переполюсовки, мне нужно ;)

Детали:

Диод любой на 30-40 В и ток в 0.1А

R1 15 кОм

R2 62 кОма

R3 хз какой, под транзистор

R4-R5 680 Ом

R6 10 кОм а можно и больше, это для того чтобы уменьшить потребление схемы когда батарея разрядиться до такой степени что уже релюшка не будет щёлкать.

VT1 Практически любой, в идеале мосфет транзистор.

Немного доработал скетч:







int V = 0; // обнулим, мало ли ;)
void setup(){
 pinMode(1, INPUT); // вольтметр, делитель из 62 кОм и 15 кОм(земля), значение в 1023 это будет 24.35 В.
 pinMode(2, OUTPUT); // релюха
 pinMode(3, INPUT); // кнопка, не тактовая 
 pinMode(5, OUTPUT); // 1-й светодиод 100% заряда - 12.5 В.
 pinMode(6, OUTPUT); // 2-й светодиод 60% заряда - 11.7 В.
 pinMode(7, OUTPUT); // 3-й светодиод 30% заряда - 11.1 В. Можно на него повесьть резистор большего номинала ведь он будет гореть постоянно, а я хочу уменьшить потребление даной схемки
}
void loop()
{
 int V = analogRead(1); //если потолок 24.35 В, тогда 10.5 будет: (1023/24.35)*10.5 = 441
   if (digitalRead(3) == HIGH) { // если кнопка зажата - приступаем 
      if(V > 441) digitalWrite(2, HIGH); // если 10.5 В можно врубить реле
        else digitalWrite(2, LOW);
      if(V > 525 ) digitalWrite(5, HIGH); // 1-й светодиод 100%  - 12.5 В.
        else digitalWrite(5, LOW);
      if(V > 492 ) digitalWrite(6, HIGH); // 2-й светодиод 60% заряда - 11.7 В.
        else digitalWrite(6, LOW);
      if(V > 466 ) digitalWrite(7, HIGH); // 3-й светодиод 30% заряда - 11.1 В.
        else digitalWrite(7, LOW);
   } 
     else { // если кнопка не зажата тогда хоть лопни с той кнопкой ;)
     digitalWrite(2, LOW); 
  }
  delay (1000);  // ждём 1 сек во избежания дребезжания контактов реле
}

А самое главное это размер:

1024 кило, вписался ;)

Правда у меня в списке невидно таньку 13-ю, выбрал 25-ю таньку, список скорей всего просто не помещается на дисплее, он у меня 18.5 дюймов.

Осталось купить всё и собрать :) 

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

step962 пишет:

Войдя во вкус экономии памяти, можно заняться гораздо более сытными кусками (правда, тут потребуются кое-какие знания о внутренностях микроконтроллера):
- Еще, наверное, полсотни этих самых слов можно сэкономить, если вместо digitalWrite использовать прямую запись в порт.
- То же самое относится к pinMode и Delay.
- Даже analogRead поддается оптимизации (идею можно почерпнуть, например, отсюда).

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

Думаю я начинаю понимать о чём Вы:







#include <util/delay.h>
int V = 0; // обнулим, мало ли ;)
void setup(){
 pinMode(1, INPUT); // вольтметр, делитель из 62 кОм и 15 кОм(земля), значение в 1023 это будет 24.35 В.
 pinMode(2, OUTPUT); // релюха
 pinMode(3, INPUT); // кнопка, не тактовая 
 pinMode(5, OUTPUT); // 1-й светодиод 100% заряда - 12.5 В.
 pinMode(6, OUTPUT); // 2-й светодиод 60% заряда - 11.7 В.
 pinMode(7, OUTPUT); // 3-й светодиод 30% заряда - 11.1 В. Можно на него повесьть резистор большего номинала ведь он будет гореть постоянно, а я хочу уменьшить потребление даной схемки
}
void loop()
{
 int V = analogRead(1); //если потолок 24.35 В, тогда 10.5 будет: (1023/24.35)*10.5 = 441
   if (digitalRead(3) == HIGH) { // если кнопка зажата - приступаем 
      if(V > 441) digitalWrite(2, HIGH); // если 10.5 В можно врубить реле
        else digitalWrite(2, LOW);
      if(V > 525 ) digitalWrite(5, HIGH); // 1-й светодиод 100%  - 12.5 В.
        else digitalWrite(5, LOW);
      if(V > 492 ) digitalWrite(6, HIGH); // 2-й светодиод 60% заряда - 11.7 В.
        else digitalWrite(6, LOW);
      if(V > 466 ) digitalWrite(7, HIGH); // 3-й светодиод 30% заряда - 11.1 В.
        else digitalWrite(7, LOW);
   } 
     else { 
     digitalWrite(2, LOW); 
  }
  _delay_ms(1000); // ждём 1 сек во избежания дребезжания контактов реле
}

850 байт всего если для 25-й таньки, против 1024-х, отлично!

Snubist
Offline
Зарегистрирован: 18.02.2013

я бы так сделал



#include <util/delay.h>
int V = 0; // обнулим, мало ли ;)
void setup(){
 pinMode(1, INPUT); // вольтметр, делитель из 62 кОм и 15 кОм(земля), значение в 1023 это будет 24.35 В.
 pinMode(2, OUTPUT); // релюха
 pinMode(3, INPUT); // кнопка, не тактовая 
 pinMode(5, OUTPUT); // 1-й светодиод 100% заряда - 12.5 В.
 pinMode(6, OUTPUT); // 2-й светодиод 60% заряда - 11.7 В.
 pinMode(7, OUTPUT); // 3-й светодиод 30% заряда - 11.1 В. Можно на него повесьть резистор большего номинала ведь он будет гореть постоянно, а я хочу уменьшить потребление даной схемки
}
void loop()
{
 int V = analogRead(1); //если потолок 24.35 В, тогда 10.5 будет: (1023/24.35)*10.5 = 441
  // 
      if(V > 441 && digitalRead(3) == HIGH) digitalWrite(2, HIGH ); //если кнопка зажата   и если 10.5 В можно врубить реле
        else digitalWrite(2, LOW);
      if(V > 525 ) digitalWrite(5, HIGH); // 1-й светодиод 100%  - 12.5 В.
        else digitalWrite(5, LOW);
      if(V > 492 ) digitalWrite(6, HIGH); // 2-й светодиод 60% заряда - 11.7 В.
        else digitalWrite(6, LOW);
      if(V > 466 ) digitalWrite(7, HIGH); // 3-й светодиод 30% заряда - 11.1 В.
        else digitalWrite(7, LOW);


  _delay_ms(1000); // ждём 1 сек во избежания дребезжания контактов реле
}

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

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Snubist пишет:

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

Спасибо за подсказку, но стоит ли? Моя целью - сделать всё это как можно энергоэффективней.

Вот смотрите, я использую батарею от упса как дополнительный буфер для моего ноутбука, конечно заряжаю бук через инвертор 12 В - 20 В. Именно потому что использую инвертор и задумался о создании подобной защиты, так как инвертор уверено работает от 8-ми вольт, что равноценно убийству акума без суда и следствия. Так  вот, когда танька отключит нагрузку от акума, пусть она жрёт минимум энергии, ведь аккумулятор сел уже незачем его дальше мучить. Я ведь сипользую линейный стабилизатор для питания а у него КПД и без того небольшое...

step962
Offline
Зарегистрирован: 23.05.2011

HWman пишет:

850 байт всего если для 25-й таньки, против 1024-х, отлично!

Это вы delay на _delay_ms заменили?

Теперь вместо

      if(V > 441) digitalWrite(2, HIGH); // если 10.5 В можно врубить реле
        else digitalWrite(2, LOW);
      if(V > 525 ) digitalWrite(5, HIGH); // 1-й светодиод 100%  - 12.5 В.
        else digitalWrite(5, LOW);
      if(V > 492 ) digitalWrite(6, HIGH); // 2-й светодиод 60% заряда - 11.7 В.
        else digitalWrite(6, LOW);
      if(V > 466 ) digitalWrite(7, HIGH); // 3-й светодиод 30% заряда - 11.1 В.
        else digitalWrite(7, LOW);

напишите

      PORTD &= B00011011; // тушим диоды 7,6,5 и размыкаем реле (2)
      if(V > 441) digitalWrite(2, HIGH); // если 10.5 В можно врубить реле
      if(V > 525 ) digitalWrite(5, HIGH); // 1-й светодиод 100%  - 12.5 В.
      if(V > 492 ) digitalWrite(6, HIGH); // 2-й светодиод 60% заряда - 11.7 В.
      if(V > 466 ) digitalWrite(7, HIGH); // 3-й светодиод 30% заряда - 11.1 В.
 

Еще два десятка байтов сэкономите.

А если так:

   PORTD &= B00011011; // тушим диоды 7,6,5 и размыкаем реле (2)
   if(V > 441)  PORTD |= B00000100; // если 10.5 В можно врубить реле
   if(V > 525 ) PORTD |= B00100000; // 1-й светодиод 100%  - 12.5 В.
   if(V > 492 ) PORTD |= B01000000; // 2-й светодиод 60% заряда - 11.7 В.
   if(V > 466 ) PORTD |= B10000000; // 3-й светодиод 30% заряда - 11.1 В.

то экономия составит 236 байт (при условии, что и в других местах избавитесь от вызова функции digitalWrite)

А если в setup заменить

pinMode(1, INPUT); // вольтметр, делитель из 62 кОм и 15 кОм(земля), значение в 1023 это будет 24.35 В.
 pinMode(2, OUTPUT); // релюха
 pinMode(3, INPUT); // кнопка, не тактовая 
 pinMode(5, OUTPUT); // 1-й светодиод 100% заряда - 12.5 В.
 pinMode(6, OUTPUT); // 2-й светодиод 60% заряда - 11.7 В.
 pinMode(7, OUTPUT); // 3-й светодиод 30% заряда - 11.1 В. Можно на него повесьть резистор большего номинала ведь он будет гореть постоянно, а я хочу уменьшить потребление даной схемки

на

DDRD = B11100100;

то общая экономия составит около 420 байт.

При той же функциональности.

Но, конечно, необходимо кое-что почитать, кроме книжек типа "Arduino - это просто"...

Snubist
Offline
Зарегистрирован: 18.02.2013

Ясно.

toc
Offline
Зарегистрирован: 09.02.2013

>> всё зависит от реле.

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

Snubist
Offline
Зарегистрирован: 18.02.2013

Тогда бы я изменил схему включения реле и кнопки

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

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Snubist а если у нас будет там мощная нагрузка? Это негуманно по отношению к маленькой кнопке, быстро выйдет из строя - пройдены этап, пускай лучше таня себе постоянно курит в ожидании, пока нажму на зажимную кнопку.

toc нет, реле при одном положении контактов - не будут ничего кушать, при втором - будут несколько десятков миллиампер.

step962 спасибо за оптимизацыю кода, но я там пока ещё не сильно разбираюсь в этом С, может Вы мне поможете полностью перенести мою роботу, которую я делаю итак по примерам, на микропроцессорный С? Тогда повторить смогут не только ардуинщики но и обычные AVR-шики. Буду крайне признателен. 

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

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

step962 пишет:
Без резонатора работать придется от внутреннего осциллятора - на одной из частот 128 кГц, 4.8 МГц, 9.6 МГц и опять таки для этого необходима правильная настройка фьюзов.

А как настроить правильно фюзы?

в файле boards.txt что лежит по адресу "C:\Users\Я\Documents\Arduino\hardware\attiny"  изменить 















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

 

attiny13.build.f_cpu=9600000L на attiny13.build.f_cpu=192000L

И всё?

 

Я тут доделал схемку по маленькой, на паре делать нечего было...

фотка схемы

Нововведение заключается в том  что добавил пищалку на второй контакт реле и ещё диод VD2 который защищает порт от переполюсовки, но тут нужно уже менять немного скетч, так как диод имеет тоже своё сопротивление, это скажется на значении аналогового входа(1). Короче ещё нужно доработать и протестировать.

ЗЫ подскажите пожалуйста в каком софте лучше рисовать схемы, а если можно было бы полностью смоделировать и посмотреть как она работает так было бы вообще клас.
 

toc
Offline
Зарегистрирован: 09.02.2013

про три светодиода...

если тини имеет резисторы на портах, как, к примеру, атмега328, то можно убрать R4, R5, R6, но при этом порты нужно оставить в режиме INPUT.

Snubist
Offline
Зарегистрирован: 18.02.2013

Хорошая программа - multisim. 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Моделировать можно в Proteus, в т.ч. подсовывая ему скетч.

 

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

Через что у Вас планируется подавать плюс на обмотку реле?

maksim
Offline
Зарегистрирован: 12.02.2012

step962 пишет:
Без резонатора работать придется от внутреннего осциллятора - на одной из частот 128 кГц, 4.8 МГц, 9.6 МГц и опять таки для этого необходима правильная настройка фьюзов.
Так же не забываем про бит CKDIV8, который даст еще 3 частоты работы МК - 1.2 МГц, 600 кГц и 16 кГц.
То есть полный ряд частот, на которых может работать тини13 от внутреннего осциллятора - 

16 кГц, 128 кГц, 600 кГц, 1.2 МГц, 4.8 МГц, 9.6 МГц.

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Andrey_Y_Ostan рисовал по памяти, недосмотрел, там второй контакт реле идёт не в  землю а к "+ in", спасибо за замечание.

Старнно что никто не посоветовал использовать мосфет вместо реле... хотя я хочу сделать полностью гальваническую развязку но при этом не используя оптопару или ещё что там... Если реле разомкнуто то ни капли не протечёт не тока, не напряжения.

toc надо бы попробовать... времени как такого нету всё прошить и собрать...

maksim какую частоту посоветуете выставить для как можно меньшего энергопотребления? Ведь просто так тормозить камень тож как-то не хочется. 

А можно через #define задать частоту в IDE ?

maksim
Offline
Зарегистрирован: 12.02.2012

 

HWman пишет:

Какую частоту посоветуете выставить для как можно меньшего энергопотребления?

Никакую. Снижение частоты не влияет на энергосбережение. Снижение частоты приводит к снижению минимального рабочего пряжения, НО снижение частоты приведет и к дольшему выполнению программы. То есть какая разница что МК в течении 10 секунд будет потреблять 10 мА или 5 мА в течении 20 секунд. Для энергосбережения нужно использовать режимы энергосбережения, например powerdown.
HWman пишет:

А можно както через #define задать частоту в IDE ?

Нельзя.

step962
Offline
Зарегистрирован: 23.05.2011

maksim пишет:

 

HWman пишет:

Какую частоту посоветуете выставить для как можно меньшего энергопотребления?

Никакую. Снижение частоты не влияет на энергосбережение. 

График зависимости потребляемого ATTiny13 тока в зависимости от частоты тактирования. Другие микроконтроллеры ведут себя подобным же образом.

 

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

А как использовать режимы энергосбережения, наверное есть какая-то функция которая усыпляет МК ? У меня стоит задержка в 1 сек, тогда пускай спит себе лучше вместо того чтобы просто ждать. Скетч довольно простой, мне кажется даже минимально возможной частоты в 16 кГц будет хватать более чем.

maksim
Offline
Зарегистрирован: 12.02.2012

Попробуйте так:

#include <avr/wdt.h> // здесь организована работа с ватчдогом
#include <avr/sleep.h> // здесь описаны режимы сна
#include <avr/interrupt.h> // работа с прерываниями


ISR (WDT_vect) // прерывания по ватчдогу
{ 
  wdt_disable(); // отключаем ватчдог
}

void setup()
{
  pinMode(0, OUTPUT);  
}


void loop()
{
  digitalWrite(0, HIGH);   // set the LED on
  Sleep(WDTO_1S);
  digitalWrite(0, LOW);    // set the LED off
  Sleep(WDTO_1S);
}

void Sleep(byte time){   
  ADCSRA &= ~(1 << ADEN);  // отключаем АЦП
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // если спать - то на полную
  wdt_enable(time); // разрешаем ватчдог mсек
  WDTCSR |= 1<<WDIE; // разрешаем прерывания по ватчдогу. Иначе будет резет.
  sei(); // разрешаем прерывания
  sleep_enable(); // разрешаем сон
  sleep_cpu(); // спать!
   //спим
   // проснулись
  sleep_disable(); // запрещаем сон
  ADCSRA &= 1 << ADEN;  // включаем АЦП
}

Так же отключается АЦП на время сна ,только писал я это для тини24 ,так что если что-то не заработает, то курим даташит.

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Что-то неполучается смоделировать зашиту в Proteus 7 Professional, меняю название ног на PB0-PB4 в скетче, все подключаю соответственно и ничего не происходит. Такое впечатление что АЦП неработает, пробовал использовать другие ноги, всё тоже самое.

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

схема

Уже второй день мучаюсь с этим моделированием в Proteus 7 Professional, неработает :( при подачи питания тупо включается реле и всё, на изменение напряжения не реагирует.

Вот архив с всеми файлами.

 

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

HWman пишет:

Уже второй день мучаюсь с этим моделированием в Proteus 7 Professional, неработает :( при подачи питания тупо включается реле и всё, на изменение напряжения не реагирует.

Мосфет пробило статикой при включении модели. :) Попробуйте оборвать линию, идущую от МК на затвор мосфета...

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Так я вроде для того поставил резистор R6 чтобы полевик не открывался сам по себе. Если убрать проводок с 2 ноги, то сигнал от таньки всё равно идёт а реле разомкнуто...

maksim
Offline
Зарегистрирован: 12.02.2012

Попробуйте подтянуть ресет к VCC, и вы проверяли пример блинк он работает?

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

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

maksim
Offline
Зарегистрирован: 12.02.2012

Вообще-то PB5 это RESET и пока не установить фьюз, который его отключает он так и будет ресетом.
Могу предположить, что на тине13 не работает дуиновская функция analogRead()
, поэтому воспользуйтесь ссылкой от step962 и даташитом на тини13.

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Пробовал сегодня варить всё это дело, зашил блинк и релюха щёлкала каждую секунду.

Без бредборда тяжеловато, приходится паять всё...

Вот тут качал файлы для таньки, пишут что можно... хм...

maksim
Offline
Зарегистрирован: 12.02.2012

Протэус может глючить ,попробуйте на настоящей микрухе.

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

На днях закончу.

Кстати, я не планирую останавливаться, есть у меня ещё идеек пару... например прибор для восстановления засульфатированных свинцовых аккумов... тоже на таньке, удобная она, и жрет мало. 

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Что только не делал, неработает, как в протеусе.

Вот немного отшлифовал скетч



//#include <util/delay.h> // уменьшим вес прошивки
int V = 0; // обнулим, мало ли ;)
void setup(){
   pinMode(A3, INPUT);      // вольтметр, делитель из 5 кОм и 1 кОм(земля), значение в 1023 это будет 24.35 В.
   pinMode(4, OUTPUT);     // релюха
   pinMode(0, OUTPUT);     // 1-й светодиод 100% заряда - 12.5 В.
   pinMode(1, OUTPUT);     // 2-й светодиод 65% заряда - 11.7 В.
   pinMode(2, OUTPUT);     // 3-й светодиод 35% заряда - 11.1 В.
   // диагностика:   
   digitalWrite(0, HIGH); delay(1000); digitalWrite(0, LOW); delay(1000);   
   digitalWrite(1, HIGH); delay(1000); digitalWrite(1, LOW); delay(1000);  
   digitalWrite(2, HIGH); delay(1000); digitalWrite(2, LOW); delay(1000);
   digitalWrite(4, HIGH); delay(1000); digitalWrite(4, LOW);
   // всё работает?
}
void loop()
{
    digitalWrite(0, LOW); 
    digitalWrite(1, LOW); 
    digitalWrite(2, LOW);    //тушим диоды 100/65/35
    int V = analogRead(A3);   
        if(V >= 441) { { digitalWrite(4, HIGH); }  // если 10.5 В можно врубить реле
        if(V <= 525 ) { digitalWrite(0, HIGH); }  // 1-й светодиод 100% заряда - 12.5 В.
        if(V <= 492 ) { digitalWrite(1, HIGH); }  // 2-й светодиод 65% заряда - 11.7 В.
        if(V <= 466 ) { digitalWrite(2, HIGH); } }  // 3-й светодиод 35% заряда - 11.1 В.    
    else { digitalWrite(4, LOW); }
delay(1000);   // ждём 1 сек во избежания дребезжания контактов реле
}

592 байта. Использовал файлы отсюда

Вот видео тестового скетча аля блинк, сорри за качество.

http://www.youtube.com/watch?v=QwNxW14ne64&feature=youtu.be

Как видете что-то работает но то что нужно...

Пол дня возился и нечего, обидно как-то даже :(

toc
Offline
Зарегистрирован: 09.02.2013

HWman,

1. что будет делать ваша програма если напряжение равно 10.4 вольт ?

2. что будет делать ваша програма если напряжение равно 12.6 вольт ?

3. уверен, что вы измерили резисторы в делителе мультиметром. Я плохо разбираюсь в маркировке, вероятно у вас резисторы с точностью 1% или 5%.

4. вы питаете мк от стабилизированного источника? померили напряжение?

5. если нет, то как вариант: можно измерить внутренний стабильный источник 1.1 В относительно А3. Стоп. Не знаю есть ли он в тини, в атмега328 есть.

6. Индикация "заряд включён" не предусмотрена?

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

1 Ничего не должно произойти.

2 При 12.6 должны гореть три диода и быть включенная релюха.

3 Замерял тестером, на порту 2.56 В что должно быть больше значения в 512.

4 Был линейный стаб 78L05, но он перегорел, не так припаял я его, пока питаю от юсб

5 хз а как это сделать? мой скетч выше, аппаратно что-то изменить уже будет сложно, всё припаяно уже

6 Нет, нету ног сводных...

 

Ещё наблюдения, при подачи питания, после диагностики реле сразу срабатывает и в таком состоянии может оставатся вечно. Если отсоединить клёмы от аккума то реле отключается, ещё бы, оно ведь питается от 12 В и горят все три диода...

maksim
Offline
Зарегистрирован: 12.02.2012

И так. Как вам уже рекомендовал step962 отказывайтесь от дуиновских функций! Попробуйте так:

#define L100_ON PORTB|=1<<PB0  // 1-й светодиод 100% заряда - 12.5 В
#define L65_ON  PORTB|=1<<PB1  // 2-й светодиод 65% заряда - 11.7 В.
#define L35_ON  PORTB|=1<<PB2  // 3-й светодиод 35% заряда - 11.1 В.
#define RELE_ON PORTB|=1<<PB4  // релюха
#define L100_OFF PORTB&=~(1<<PB0)
#define L65_OFF  PORTB&=~(1<<PB1)
#define L35_OFF  PORTB&=~(1<<PB2)
#define RELE_OFF PORTB&=~(1<<PB4)

void setup()
{
  DDRB = 0b10111;
  // диагностика:   
  for(byte i = 0; i < 3; i++)
  {
    PORTB = 1<<i;
    delay(1000);
  }
  PORTB = 0;
  RELE_ON; 
  delay(1000);
  RELE_OFF;
  delay(1000);
}

void loop()
{
  int V = ADC_READ();   
  if(V >= 441) 
  {  
    RELE_ON;                        // если 10.5 В можно врубить реле
    V <= 525 ? L100_ON : L100_OFF;  // 1-й светодиод 100% заряда - 12.5 В.
    V <= 492 ? L65_ON : L65_OFF;    // 2-й светодиод 65% заряда - 11.7 В.
    V <= 466 ? L35_ON : L35_OFF;    // 3-й светодиод 35% заряда - 11.1 В.    
  }
  else RELE_OFF; 
  delay(1000);                      // ждём 1 сек во избежания дребезжания контактов реле
}

int ADC_READ()
{
  ADMUX = 3; // ADC pin
  ADCSRA |= 1<<ADEN;
  ADCSRA |= 1<<ADSC;
  while(!(ADCSRA & (1<<ADIF)));
  ADCSRA |= 1<<ADIF; 
  byte low  = ADCL;
  byte high = ADCH;
  ADCSRA &= ~(1 << ADEN);  // отключаем АЦП
  return (high << 8) | low;
}

 

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013
sketch_mar20a.ino: In function 'void setup()':
sketch_mar20a:13: error: 'B10111' was not declared in this scope

Гуглил... пробовал подключить библиотеку #include<avr/io.h> всё тоже самое.

maksim
Offline
Зарегистрирован: 12.02.2012

замените на 

DDRB = 0b10111;

 

toc
Offline
Зарегистрирован: 09.02.2013

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

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

maksim спасибо большое за переделку кода, всё работает в протэусе, позже прошью микруху и посмотрю как железо будет себя вести.

toc спасибо за поправку, сделал логическую ошибку, как-то стыдно за себя...

 Для тонкой подстройки добавил подстроечник на 500 Ом последовательно к резистору в 1 кОм(реально он имеет 0.89 кОм замерял мультиметром) что позволяет мне поднимать напряжение которое на АЦП, тоесть менять потолок по измерению с 30 В до 21.75 В. Кстати  делитель напряжения теперь из 5 кОм и 1кОм(земля). 

Ну а мигание при зарядке реализовать сложновато, тут есть только один путь, следить за напряжением, если оно растёт тогда можно мигать... Мне это реализовать пока не по зубам, как видите.

Есть ещё куча нюансов, например, когда аккум сдохнет то у него напряжение не будет держатся на уровне 10.5 а будет расти, что естественно для свинцовых аккумов, тут нужно сделать какую то паузу в минут так 10-15... а может и вообще завершить исполнение цикла... Сейчас чёт мозги не варят всё это предусматривать, потом обязательно как-то реализую.

Собственно вот схема:

Почти на 80% завершена, нужно ещё некоторые нюансы учесть, о них ниже:

Есть пара вопросов по ней, нужно защитить от дурака схемку, всякое бывает, люблю я не так подсоединить проводки, тоесть от переполюсовки? Ну, перед входом стаба поставить диод - это понятно, но а как быть с ногой PB3 ? Ей ничего не будет при переполюсовке?

Rimidalw
Offline
Зарегистрирован: 04.04.2012

Извините за глупый вопрос, но что нужно сделать с Arduino IDE 1.0.3 что бы этот проект вообще скомпилировался. Я добавил нужные строки из поста #17, но все равно не компилируется.

In file included from sketch_mar21a.ino:10:
C:\Arduino\arduino-1.0.3\hardware\arduino\cores\arduino/Arduino.h:213:26: error: pins_arduino.h: No such file or directory

 

maksim
Offline
Зарегистрирован: 12.02.2012

Качаете архив, распаковываете его в \Дуина\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) и компилируете.

Rimidalw
Offline
Зарегистрирован: 04.04.2012

maksim пишет:

Качаете архив, распаковываете его в \Дуина\arduino-1.0.3\hardware\, после чего открываете файл \Дуина\arduino-1.0.3\hardware\attiny\boards.txt и добавляете в него строки...........

Спасибо, все заработало!

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Всё корректно работает? 

toc
Offline
Зарегистрирован: 09.02.2013

поставил протеус. 
хотел попробовать.
тут ничего нет :( ...

всё хорошо.