ATtiny13A 101 применение

Baks
Baks аватар
Offline
Зарегистрирован: 11.01.2016

вот как подключал.

https://yadi.sk/i/y4aNbfx33NXxBS

https://yadi.sk/i/vv-qCq773NXxG9

провода длиной до 30см, 

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

подключал так...
ардуинка <--> Attiny
10 - reset
11 - MOSI
12 - MISO
13 - SCK
vcc - vcc
GND - GND

 

.

Baks
Baks аватар
Offline
Зарегистрирован: 11.01.2016

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

+1 к использованию атиньки)))

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

Я шью эти мелкие тиньки через такую штуковину. Сделал отдельную плату, куда втыкается этот переходник. Можно его вытащить и воткнуть вместе с контроллером в макетку. Ещё рядом с этим "зажимом" размещены ДИП-кроватка (если тинька в ДИП) и светодиод, отключаемый джампером (можно контроллер проверять с пом. "блинк-а").
Можно шить USB ASP-ом через любой софт-оболочку над дудкой или напрямую из Atmel Studio.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Здравствуйте!

Вопрос к гуру по энергосбережению:

готовлю Attiny85 к работе как удаленный датчик со срабатыванием через каждый час,

используется WDT, через каждые 8 секунд прибавляется счетчик и соответственно через час основное действие.

замерил своим китайским мультиметром потребление в режиме WDT = 7 микроампер при 5 вольтах питания

это нормально?

#include <avr/sleep.h>
#include <avr/wdt.h>

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

#define PB0 0 // pin 5 - test led
#define PB1 1 // pin 6 - TX RF
#define PB2 2 // pin 7 - DS18B20
#define PB3 3 // pin 2
#define PB4 4 // pin 3

#define TimerCountSec 15 // delay start by sec
word CurrentTime = 0;

void ExecFunc() {
  // test LED on
  pinMode(PB0, OUTPUT);
  digitalWrite(PB0, HIGH);
  // exec real func
  // load current temp
  // send temp
  // end exec real func - off test led
  delay(100);
  digitalWrite(PB0, LOW);
  pinMode(PB0, INPUT); digitalWrite(PB0, LOW);
  // -
}

void CalcTimer() {
  ++CurrentTime;
  if (((CurrentTime + 1) * 8) >= TimerCountSec) {
    CurrentTime = 0;
    ExecFunc();
  }
}

ISR (WDT_vect)
{
  wdt_disable();  // disable watchdog
}

void setup () {
  // OFF unused pins
  pinMode(PB0, INPUT); digitalWrite(PB0, LOW);
  pinMode(PB1, INPUT); digitalWrite(PB1, LOW);
  pinMode(PB2, INPUT); digitalWrite(PB2, LOW);
  pinMode(PB3, INPUT); digitalWrite(PB3, LOW);
  pinMode(PB4, INPUT); digitalWrite(PB4, LOW);
  // first run
  ExecFunc();
}

void loop ()
{
  CalcTimer();
  cbi(ADCSRA, ADEN);                   // switch Analog to Digitalconverter OFF
  setup_watchdog(9);
  wdt_reset();  // pat the dog
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);
  noInterrupts ();           // timed sequence follows
  sleep_enable();
  interrupts ();             // guarantees next instruction executed
  sleep_cpu ();
  // cancel sleep as a precaution
  sleep_disable();
}

// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii) {
  byte bb; int ww;
  if (ii > 9 ) ii = 9;
  bb = ii & 7;
  if (ii > 7) bb |= (1 << 5);
  bb |= (1 << WDCE); ww = bb;
  MCUSR &= ~(1 << WDRF);
  // start timed sequence
  WDTCR |= (1 << WDCE) | (1 << WDE);
  // set new watchdog timeout value
  WDTCR = bb; WDTCR |= _BV(WDIE);
}

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

пробовал переводить все выходы в

pinMode(PB0, OUTPUT);

 - не помогло, энергопотребление не поменялось

sim31
sim31 аватар
Offline
Зарегистрирован: 26.07.2017

при 5 вольтах питания

От 5 вольт никто маломощную электронику не питает! Сделайте ему 1.8 вольта, в крайнем случае 3.3

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

в "бою" он будет работать от CR2032 3v

я думал что то я недостаточно прописал в скетче, т.к. в даташите написано что в спящем режиме 

● Power-down mode:
● 0.2μA at 2.7V

т.е. у меня сейчас почти в 35 раз больше при питании 5в.

ЗЫ. 7мкА тоже хорошо, т.е. если 200мА (CR2032) /7мкА = 28571 часов непрерывной работы

и даже если в реальности разделить на два - получается минимум 595 дней - меня устраивает.

Но вопрос остается.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

Attiny10 сильно отличается от Attiny13A в плане энергосбережения?

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Tomasina пишет:

Attiny10 сильно отличается от Attiny13A в плане энергосбережения?

даташит что говорит?

Speed Grade
– 0 – 4 MHz @ 1.8 – 5.5V
– 0 – 8 MHz @ 2.7 – 5.5V
– 0 – 12 MHz @ 4.5 – 5.5V
• Industrial Temperature Range
• Low Power Consumption
– Active Mode:
• 200μA at 1MHz and 1.8V
– Idle Mode:
• 25μA at 1MHz and 1.8V
– Power-down Mode:
• < 0.1μA at 1.8V
 
Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

А кто-нибудь пробовал подружить ее с Arduino? Уж очень её размеры (2х3 мм) нравятся.

Но там прошивка не стандартная SPI, а TPI.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Понадеялся что упадёт потребление attiny85 выключив BOD, добавил строку отключения - не помогло совсем, в даташите нашёл что данный функционал работает только с ревизии С и новее. Как узнать ревизию китайского МК купленного на Ali?

  MCUCR = MCUCR | _BV(BODS) | _BV(BODSE);

 

зря я наверное это вписал - смысла нет, т.к. я использую конфигурацию уже  с выключенным BOD

attiny85at1.name=ATtiny85 @ 1 MHz  (internal oscillator; BOD disabled)

как бы еще понизить потребление.....

NikitaS
Offline
Зарегистрирован: 22.10.2016

sim31 пишет:

при 5 вольтах питания

От 5 вольт никто маломощную электронику не питает! Сделайте ему 1.8 вольта, в крайнем случае 3.3

В первом сообщении этой темы написано: "ЗЫ для 5 В питания просто идеально подходит линейный стабилизатор 78L05, они просто созданы друг для друга"

Я в недоумении, кто прав? Автор темы или кто-то еще? Или, может, стабилизатор 78L05 понизит вольт до 1.8? Хотя, это же не понижающий трансформатор, а стабилизатор. То есть держит напряжение в заданных пределах. Я просто не знаю, что и думать. Сам хочу приступить к программированию тиньки, так что есть желание разобраться, как подключать к питанию этот МК.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

NikitaS пишет:

sim31 пишет:

при 5 вольтах питания

От 5 вольт никто маломощную электронику не питает! Сделайте ему 1.8 вольта, в крайнем случае 3.3

В первом сообщении этой темы написано: "ЗЫ для 5 В питания просто идеально подходит линейный стабилизатор 78L05, они просто созданы друг для друга"

Я в недоумении, кто прав? Автор темы или кто-то еще? Или, может, стабилизатор 78L05 понизит вольт до 1.8? Хотя, это же не понижающий трансформатор, а стабилизатор. То есть держит напряжение в заданных пределах. Я просто не знаю, что и думать. Сам хочу приступить к программированию тиньки, так что есть желание разобраться, как подключать к питанию этот МК.

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

Если например исполнительные устройства питаются от постоянных 12В то конечно для attiny придется понижать, а если у меня батарейка CR2032 то и нафиг ничего не надо.

NikitaS
Offline
Зарегистрирован: 22.10.2016

andycat, спасибо! Еще в сети встретил рекомендацию в обязательном порядке подключать конденсаторы, правильно ли пишут?: "Перед тем, как подать на микроконтроллер питающее напряжение, выполним правило, которое обязательно для всех цифровых микросхем: в непосредственной близости от выводов питания микросхемы должен быть керамический конденсатор емкостью 0,06 — 0,22 мкф. Обычно устанавливают конденсатор 0,1 мкф. Его часто называют блокировочным конденсатором.
В схему необходимо установить и электролитический конденсатор емкостью 4-10 мкф. Он также является блокировочным фильтром, но на менее высоких частотах.

Дело в том, что микроконтроллер (как и другие цифровые микросхемы) состоит из транзисторных ячеек, которые в процессе работы постоянно переключаются из открытого состояния в закрытое, и наоборот. При этом изменяется потребляемая транзисторными ячейками энергия. В линии питания возникают кратковременные «провалы» напряжения. Этих ячеек в микроконтроллере сотни тысяч (думаю, что сейчас уже миллионы!), поэтому по питающим проводам начинают гулять импульсные помехи с частотами от единиц до десятков тысяч Герц. Для предотвращения распространения этих помех по цепям схемы, да и самой микросхемы микроконтроллера, параллельно его выводам питания устанавливают такой блокировочный конденсатор. При этом на каждую микросхему необходимо устанавливать индивидуальный конденсатор.
 

Конденсатор для постоянного тока является изолятором. Но при установке конденсатора в цепи с непостоянным током он делается сопротивлением. Чем выше частота, тем меньшее сопротивление оказывает конденсатор. Следовательно, блокировочный конденсатор с малой емкостью пропускает через себя (шунтирует) высокочастотные сигналы (десятки и сотни Герц), а конденсатор с бОльшей емкостью — низкочастотные."

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

про конденсаторы - это в форум аппаратные вопросы.

я максимум с трудом помню курс физики и ТОЭиЭ института - так что не советчик.

тут где то пробегала картинка в PDF -типовые схемы подключения периферии/нагрузки к Arduino - не могу найти.

pittyalex
Offline
Зарегистрирован: 09.11.2016

Никита, все в Ваших цитатах правильно написано. Что Вам не понятно? Примите просто за правило, что на каждую цифровую микросхему нужен блокировочный конденсатор, керамический. Иногда можно поставить один на несколько корпусов если они стоят рядом и трассы питания имеют большую ширину дорожки а сами дорожки короткие. На входе схемы обычно ставят электролит или Тантал и в параллель ему ещё один дополнительный керамический на 0,1 - 0,5 мкФ. Если хотите более подробно, то надо читать даташите на конкретные чипы. Кстати, на современные АРМ чипы ставят уже до десяти блокировочных ёмкостей.

sim31
sim31 аватар
Offline
Зарегистрирован: 26.07.2017

NikitaS пишет:

Я в недоумении, кто прав? Автор темы или кто-то еще? Или, может, стабилизатор 78L05 понизит вольт до 1.8? Хотя, это же не понижающий трансформатор, а стабилизатор. То есть держит напряжение в заданных пределах. Я просто не знаю, что и думать. Сам хочу приступить к программированию тиньки, так что есть желание разобраться, как подключать к питанию этот МК.

 

Я прав )) И все правы. Просто тут у человека всплыл вопрос о потреблении тока всего в 7 мкА, это очень специфическое требование к микроконтроллеру. Еще более снизить потребление можно снижая напряжение питания, чем ниже, тем лучше. Если потребление в 7 мкА устраивает то можно работать с 5В.

Для сравнения на Atmega328 у меня не получилось снизить потребление менее 200 мкА в режиме Idle, но и так устройство работает год от батарейки.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

sim31 пишет:

NikitaS пишет:

Я в недоумении, кто прав? Автор темы или кто-то еще? Или, может, стабилизатор 78L05 понизит вольт до 1.8? Хотя, это же не понижающий трансформатор, а стабилизатор. То есть держит напряжение в заданных пределах. Я просто не знаю, что и думать. Сам хочу приступить к программированию тиньки, так что есть желание разобраться, как подключать к питанию этот МК.

 

Я прав )) И все правы. Просто тут у человека всплыл вопрос о потреблении тока всего в 7 мкА, это очень специфическое требование к микроконтроллеру. Еще более снизить потребление можно снижая напряжение питания, чем ниже, тем лучше. Если потребление в 7 мкА устраивает то можно работать с 5В.

Для сравнения на Atmega328 у меня не получилось снизить потребление менее 200 мкА в режиме Idle, но и так устройство работает год от батарейки.

мне уже не интересно понизить потребление ниже 7мкА, т.к. когда посчитал что датчик температуры +

передатчик каждые 47 минут  = основные потребители. В итоге зимой при отрицательных температурах

батарейки CR2032 мне хватит максимум на 2 месяца. Впрочем сейчас дождусь детали из Ali - проверим на 

практике расчеты.

Zahar
Zahar аватар
Offline
Зарегистрирован: 16.11.2013

Уважаемые гуру.

Собрал тестовую платку, Attiny13+WS2812B.

К моему удивлению всё заработало. Вот только мой гавнокод мне не нравиться.

Помогите пожалуйста оптимизировать код.

 

//Attiny13 freq=9.6MHz
#include <avr/io.h>
#include <util/delay.h> // нужна для функции _delay_ms();
//#define led 3
#define RGB 4
void L(){
  PORTB |= (1<<RGB); // устанавливаем высокий уровень  
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
  PORTB &= ~(1<<RGB); // устанавливаем низкий уровень
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
}
void H(){
  PORTB |= (1<<RGB); // устанавливаем высокий уровень  
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
  PORTB &= ~(1<<RGB); // устанавливаем низкий уровень
}
void res(){
  PORTB &= ~(1<<RGB); // устанавливаем низкий уровень
  asm volatile ("nop");
  asm volatile ("nop");
}

void PixelColor(int r,int g, int b){
  boolean green;
  boolean red;
  boolean blue;
  for(byte i=0;i<8;i++){
    green=bitRead(g, i);
    if (green) H();
    if (!green) L();
  }
  for(byte i=0;i<8;i++){
    red=bitRead(r, i);
    if (red) H();
    if (!red) L();
  }
  for(byte i=0;i<8;i++){
    blue=bitRead(b, i);
    if (blue) H();
    if (!blue) L();
  }
}
int main( void )
{    
  DDRB |= (1<<RGB); // устанавливаем вывод PBx как выход
  OSCCAL=0x7F;// калибровка частоты. Частота завышена!!!
  res();
  while(1){ // вечный цыкл, тоже самое что и void loop(){
    int r=0;
    int g=0;
    int b=0;
    for(r=0;r<256;r=r+5){
      for(g=0;g<256;g=g+5){
        for(b=0;b<256;b=b+5){
          PixelColor(r,g,b);
          _delay_ms(10);
          res();
        }
      }
    }
  } // конец вечного цикла
  return 0;
}

Функцию PixelColor(), наверника можно написать иначе.

sim31
sim31 аватар
Offline
Зарегистрирован: 26.07.2017

andycat пишет:
батарейки CR2032 мне хватит максимум на 2 месяца. Впрочем сейчас дождусь детали из Ali - проверим на практике расчеты.

А что мешает поставить батарейку типа 18650 на 3500 мач? Там есть вариант Литий-железных батареек, что работают до -30, да и обычные работают, только емкость падает. Зачем такая минитюаризация для уличного датчика...

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

Zahar пишет:
Функцию PixelColor(), наверника можно написать иначе.

Как-нибудь так - 


void PixelColor(int r,int g, int b){
for(byte i=0;i<8;i++){
    (bitRead(g, i)) ? (H()) : (L());
 }

for(byte i=0;i<8;i++){
    (bitRead(r, i)) ? (H()) : (L());
 }

for(byte i=0;i<8;i++){
    (bitRead(b, i)) ? (H()) : (L());
 }
}

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

sim31 пишет:

andycat пишет:
батарейки CR2032 мне хватит максимум на 2 месяца. Впрочем сейчас дождусь детали из Ali - проверим на практике расчеты.

А что мешает поставить батарейку типа 18650 на 3500 мач? Там есть вариант Литий-железных батареек, что работают до -30, да и обычные работают, только емкость падает. Зачем такая минитюаризация для уличного датчика...

просто уже в заказе и уже едут CR2032 с прочей приблудой :)

соберу/потестирую - не устроит - переделаю на аккумуляторы 18650

NikitaS
Offline
Зарегистрирован: 22.10.2016

То есть можно от 5 вольт со стабилизатором питать attiny13a? Меня ввели в заблуждение Ваши слова с восклицательным знаком, выражающим, как бы, категорическую уверенность:

sim31 пишет:

От 5 вольт никто маломощную электронику не питает!

Zahar
Zahar аватар
Offline
Зарегистрирован: 16.11.2013

OlegK пишет:

Как-нибудь так - 


void PixelColor(int r,int g, int b){
for(byte i=0;i<8;i++){
    (bitRead(g, i)) ? (H()) : (L());
 }

for(byte i=0;i<8;i++){
    (bitRead(r, i)) ? (H()) : (L());
 }

for(byte i=0;i<8;i++){
    (bitRead(b, i)) ? (H()) : (L());
 }
}

 

Спасибо, так красивее :)

pittyalex
Offline
Зарегистрирован: 09.11.2016

А колличество норов Вас не смущает?
Например, читал у кого-то из известных авторов по программированию, что использование таких bitRead(g, i)) ? (H()) : (L()) конструкций не добавляет прозрачности коду, особенно, когда наблюдается их нагромождение.
Я бы на Вашем месте от ногодрыга абстрагировался бы функцией sendByte(b byte), весь ногодрыг был бы в ней. Это позволит в дальнейшем легко задействовать какой нибудь сдвиговый регистр, если таковой появится (аппаратный SPI например). Большие выдержки лучше делать вызовом подпрограммы и сразу возвратом из нее.
На крайний случай безусловным коротким переходом на следующий оператор.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Продолжил эксперименты над ATtiny85, добился от спящего режима <=1мкА (точнее мой тестер не показывает)

и оказалось что WDT "кушает" минимум 6 мкА

#include <avr/sleep.h>
#include <avr/interrupt.h>

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

// PB0 pin 5 - SDA
#define PB0_OUT sbi(DDRB,PB0)
#define PB0_IN cbi(DDRB,PB0)
#define PB0_HIGH sbi(PORTB,PB0)
#define PB0_LOW cbi(PORTB,PB0)
// PB1 pin 6 - WakeUp KEY
#define PB1_OUT sbi(DDRB,PB1)
#define PB1_IN cbi(DDRB,PB1)
#define PB1_HIGH sbi(PORTB,PB1)
#define PB1_LOW cbi(PORTB,PB1)
#define PB1_READ bitRead(PINB,PB1)
// PB2 pin 7 - SCL
#define PB2_OUT sbi(DDRB,PB2)
#define PB2_IN cbi(DDRB,PB2)
#define PB2_HIGH sbi(PORTB,PB2)
#define PB2_LOW cbi(PORTB,PB2)
// PB3 pin 2
#define PB3_OUT sbi(DDRB,PB3)
#define PB3_IN cbi(DDRB,PB3)
#define PB3_HIGH sbi(PORTB,PB3)
#define PB3_LOW cbi(PORTB,PB3)
// PB4 pin 3 - test led
#define PB4_OUT sbi(DDRB,PB4)
#define PB4_IN cbi(DDRB,PB4)
#define PB4_HIGH sbi(PORTB,PB4)
#define PB4_LOW cbi(PORTB,PB4)

ISR(PCINT0_vect) {
  if (PB1_READ == 0) { // LOW level KEY
    sleep_disable();
    cbi(GIMSK, PCIE);
    cbi(PCMSK, PCINT1);
  }
}

void toSleep() {
  // pins mode
  PB0_OUT; PB0_LOW;
  PB1_IN; PB1_HIGH;
  PB2_OUT; PB2_LOW;
  PB3_OUT; PB3_LOW;
  PB4_OUT; PB4_LOW;
  // sleep
  cbi(ADCSRA, ADEN);
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sbi(GIMSK, PCIE);
  sbi(PCMSK, PCINT1);
  sleep_mode();
}

void setup () {
}

void loop () {
  toSleep();
  // test led ON
  PB4_HIGH;
  // work
  // test led OFF
  delay(5000);
  PB4_LOW;
}

 

sim31
sim31 аватар
Offline
Зарегистрирован: 26.07.2017

NikitaS пишет:

То есть можно от 5 вольт со стабилизатором питать attiny13a? Меня ввели в заблуждение Ваши слова с восклицательным знаком, выражающим, как бы, категорическую уверенность:

Только типичный стабилизатор сам потребляет до 2000 мкА, особо экономичные еще поискать нужно, те могут потреблять 100 мкА и 10 мкА, чем ниже потребление, тем слабее стабилизатор и неожиданно его может не хватить чтобы помигать лампочкой.

pittyalex
Offline
Зарегистрирован: 09.11.2016

sim31 пишет:

NikitaS пишет:

То есть можно от 5 вольт со стабилизатором питать attiny13a? Меня ввели в заблуждение Ваши слова с восклицательным знаком, выражающим, как бы, категорическую уверенность:

Только типичный стабилизатор сам потребляет до 2000 мкА, особо экономичные еще поискать нужно, те могут потреблять 100 мкА и 10 мкА, чем ниже потребление, тем слабее стабилизатор и неожиданно его может не хватить чтобы помигать лампочкой.

А почему нельзя сделать включение стабилизатора через полевой транзистор, а при выключенном транзисторе камень питается напрямую от батареи, например, через несколько диодов (или стабилитрон) или резистивный делитель. Да хоть даже от конденсатора, предварительно заряженного до 2х вольт. По хорошему, этого должно хватить на несколько часов в режиме сна.

sim31
sim31 аватар
Offline
Зарегистрирован: 26.07.2017

Можно так сделать. Но это какое-то аналоговое шаманство. Резистивный делитель, например, ограничивает ток потребляемый, вдруг МК проснется и потребует 2 мА, а через делитель протекает всего 3 мкА, будет проблема, или глюк или перезагрузка. С конденсатором еще интереснее, можно неуспеть зарядить его и будет так же трудно уловимый сбой, с порчей памяти. Но можно, я тоже о таком думал, только с периодически пробуждением МК, раз в секунду на несколько микросекунд, МК проверяет напряжение на конденсаторе засыпает далее, сам себе стабилизатор програмный. Но поставить стабилизатор специальный на 3.3 В мне было проще.

И откуда у вас 5 Вольт в устройстве с низким потреблением? Обычно в таком случае питание идет от батарейки, а это 2.7-3.4 Вольта. Если на стабилизаторе падает хотя бы 0.3 В, получаем напряжение питания не более 2.4В. Если напряжение питания 5В, обычно это от блока питания и экономия не нужна.

NikitaS
Offline
Зарегистрирован: 22.10.2016

sim31, насколько я понял из Вашего диалога с pittyalex, при питании Attiny13 от батарейки 2.7-3.4 Вольта стабилизатор не нужен?

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

При питании от 1,8 до 5,1 В стабилизатор не нужен.

sim31
sim31 аватар
Offline
Зарегистрирован: 26.07.2017

Не нужен. Но можно поставить на 1.8 Вольт стабилизатор, если высокие тактовые частоты не нужны, помоему на частоте 1 МГц можно 1.8 Вольт давать.

Еще есть тема встроенный Broun out детектор, проверяет, достаточное ли напряжение для работы, но потребляет 70 мкА, можно в даташите уточнить. Мне не требовался.

Стабилизаторы использую типа таких

https://ru.aliexpress.com/item/Free-Shipping-50pcs-XC6206P332MR-662K-3-3...

Потребление 1 мкА всего.

Описание тут

http://www.alldatasheet.com/datasheet-pdf/pdf/243854/TOREX/XC6206P332MR....

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Я вот такие планирую использовать для питания от cr2032 МК и периферии, кто нибудь использовал?

DC-DC 0.8-3.3 В до 3.3 В Step Up Повышение Мощность модуль для Arduino Напряжение конвертер мини модуль для arduino
http://s.aliexpress.com/NJB7NJjm
(from AliExpress Android)

sim31
sim31 аватар
Offline
Зарегистрирован: 26.07.2017

DC-DC 0.8-3.3 В до 3.3 В Step Up

У этого модуля ток собственного потребления не указан, возможно что 1-2 мА, он достаточно мощный.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Sim31, спасибо, буду думать.....

sav13
sav13 аватар
Offline
Зарегистрирован: 17.06.2013

sim31 пишет:

Только типичный стабилизатор сам потребляет до 2000 мкА, особо экономичные еще поискать нужно, те могут потреблять 100 мкА и 10 мкА, чем ниже потребление, тем слабее стабилизатор и неожиданно его может не хватить чтобы помигать лампочкой.

Есть такой хороший стабилизатор BL8530/33/50

Повышает от 0.8В до 3.0/3.3/5.0
Выходной ток до 200мА
Ток покоя 12мк

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

 

pittyalex
Offline
Зарегистрирован: 09.11.2016

andycat пишет:
Я вот такие планирую использовать для питания от cr2032 МК и периферии, кто нибудь использовал? DC-DC 0.8-3.3 В до 3.3 В Step Up Повышение Мощность модуль для Arduino Напряжение конвертер мини модуль

Во-первых, зачем Вам повышать напряжение при питании от 3В батарейки? Вы используете максимальные частоты МК? ТОгда может быть.

Во-вторых, любой повышающий модуль будет в покое (как в принципе любой DC/DC преобразователь) потреблять достаточно приличный ток, тем более такой мощный, как этот.

Если Вы не будете на время простоя отключать преобразователь, тогда есть большая вероятность, что батарейки хватит не больше двух-трёх суток. Предполагаю, ток ХХ этого преобразователя около 1-5 мА.

Да. если Вы их уже получили, посмотрите, что у них на оборотной стороне за микросхема? Ну или измерьте ток потребления на ХХ.

Могу предложить вариант того, что уже предлагал выше: преобразователь подключается с помощью транзистора на время использования периферии, а на время PowerDown преобразователь отключать и питать контроллер через стабилитрон (должен быть тоже маломощным) или последовательно включенные несколько диодов в прямом направлении. Для питания контроллера в режиме POWERDOWN можно задаться током потребления в пару десятков микроампер (для расчёта), при этом блокировочного конденсатора должно хватить для начального момента пробуждения и раскачки входного транзистора и запуска преобразователя. Надо только проверить ток утечки выхода самого преобразователя, а то он может оказаться также порядка нескольких десятков микроампер. 

Микроамперные схемы - та ещё наука.

pittyalex
Offline
Зарегистрирован: 09.11.2016

sav13 пишет:

sim31 пишет:

Только типичный стабилизатор сам потребляет до 2000 мкА, особо экономичные еще поискать нужно, те могут потреблять 100 мкА и 10 мкА, чем ниже потребление, тем слабее стабилизатор и неожиданно его может не хватить чтобы помигать лампочкой.

Есть такой хороший стабилизатор BL8530/33/50

Повышает от 0.8В до 3.0/3.3/5.0
Выходной ток до 200мА
Ток покоя 12мк

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

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

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

pittyalex пишет:

andycat пишет:
Я вот такие планирую использовать для питания от cr2032 МК и периферии, кто нибудь использовал? DC-DC 0.8-3.3 В до 3.3 В Step Up Повышение Мощность модуль для Arduino Напряжение конвертер мини модуль

Во-первых, зачем Вам повышать напряжение при питании от 3В батарейки? Вы используете максимальные частоты МК? ТОгда может быть.

Во-вторых, любой повышающий модуль 

Микроамперные схемы - та ещё наука.

Повышаю потому что rf модуль и ds18b20 работают от 3 вольт. Ещё пока стабилизаторы не заказывал - думаю выбираю. Попробую от cr2032 напрямую, уверен что будет работать, вопрос надолго ли и как в мороз будет.

pittyalex
Offline
Зарегистрирован: 09.11.2016

Если только RFмодуль (какой, кстати) и ds18, то наверное можно и от cr2032 напрямую (полностью заряженная 3.1-3.4 вольта.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

pittyalex пишет:

Если только RFмодуль (какой, кстати) и ds18, то наверное можно и от cr2032 напрямую (полностью заряженная 3.1-3.4 вольта.

можно, но если посмотреть на графики зависимости напряжения от минусовой температуры - на CR2032 при морозе сильно меньше 3 вольт.

заказал на Ali маломощный DC1.8-5V to 3.3 V  - придут - посмотрим как сильно меняется потребление с ним.

VetalST
Offline
Зарегистрирован: 29.12.2015

Я извеняюсь все не читал но вижу что andycat делает радиопередатчик температуры на ds18b20 и rf модуле. 

Я собрал на Attiny13 и rf модуле 433 , передает температуру с ds18b20 и замеры ацп. Принемает ардуина, проверял в железе все прекрасно работает. С спящим режимом пока не заморачивался. Передатчиков может быть пара десятков.

Скетч частичьно и идея взята с сайта  https://sohabr.net/habr/post/231041/ там есть и для ATtiny85, и есть конструктор для создания прошивки готового hex файла http://homes-smart.ru/index.php/oborudovanie/bez-provodov-433-315mgts/besprovodnoj-datchik-temperatury-i-vlazhnosti-na-baze-radiomodulej-433-315

Вот скетч передатчика Attiny13  9.6мгц

//               AtTity13
//                 ----
// ADC0 (D5) res 1|    |8 Vcc
// ADC3 (D3) PB3 2|    |7 PB2 (D2) ADC1
// ADC2 (D4) PB4 3|    |6 PB1 (D1) PWM1
//           GND 4|    |5 PB0 (D0) PWM0
//                 ----
/* Name: main.c
ds18b20
 */
#define timer 1 // время в секундах (умноженное на 5) опрос и отправка данных с датчика.
#define periodusec 400 // mcs
#define DS_BIT         4 // pin 3
#define RC_BIT         3 // pin 2
#define AC_BIT         1 // 7 PB2 (D2) ADC1 АЦП
#define keyT  11000

#include <avr/io.h>
#include <util/delay.h>     /* for _delay_us() */

void sendRC(unsigned long data) { // Отправка данных по радиоканалу RCswitch. Двоичный протокол

    DDRB |= _BV(RC_BIT);
    data |= 3L << 20; // ?
    unsigned short repeats = 1 << (((unsigned long)data >> 20) & 7);

    data = data & 0xfffff;

    unsigned long dataBase4 = 0; uint8_t i;

    for (i=0; i<20; i++) {
        dataBase4<<=1;
        dataBase4|=(data%2);
        data/=2;
    }

    unsigned short int j;
    for (j=0;j<repeats;j++) {

        data=dataBase4; uint8_t i;

        for (i=0; i<20; i++) {
            switch (data & 1) {

            case 0:
              
    PORTB |= _BV(RC_BIT);

    _delay_us(periodusec);

    PORTB &= ~_BV(RC_BIT);

    _delay_us(periodusec*3);
    
            break;

            case 1:
              
    PORTB |= _BV(RC_BIT);

    _delay_us(periodusec*3);

    PORTB &= ~_BV(RC_BIT);

    _delay_us(periodusec);
    
            break;

        }

        data>>=1;

    }

    PORTB |= _BV(RC_BIT);

    _delay_us(periodusec);

    PORTB &= ~_BV(RC_BIT);

    _delay_us(periodusec*31);
}
}

// OneWire функции:

void OneWireReset() 
{

     PORTB &= ~_BV(DS_BIT);
     DDRB |= _BV(DS_BIT);
     _delay_us(500);
     DDRB &= ~_BV(DS_BIT);
     _delay_us(500);
}

void OneWireOutByte(uint8_t d) 
{
   uint8_t n;

   for(n=8; n!=0; n--)
   {
      if ((d & 0x01) == 1) 
      {

     PORTB &= ~_BV(DS_BIT);
     DDRB |= _BV(DS_BIT);
         _delay_us(5);
     DDRB &= ~_BV(DS_BIT);
         _delay_us(60);
      }
      else
      {
     PORTB &= ~_BV(DS_BIT);
     DDRB |= _BV(DS_BIT);
         _delay_us(60);
     DDRB &= ~_BV(DS_BIT);
      }
      d=d>>1; 
   }
}


uint8_t OneWireInByte() 
{
    uint8_t d, n,b;

    for (n=0; n<8; n++)
    {
    PORTB &= ~_BV(DS_BIT);
    DDRB |= _BV(DS_BIT);
        _delay_us(5);
    DDRB &= ~_BV(DS_BIT);
        _delay_us(5);
    b = ((PINB & _BV(DS_BIT)) != 0);
        _delay_us(50);
        d = (d >> 1) | (b<<7);
    }
    return(d);
}

unsigned int analogRead_C(byte channel){ 
  ADMUX = channel; // 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;
}

//------------------------------------------------
//-----------------Main программа-----------------
//------------------------------------------------
int __attribute__((noreturn)) main(void)
{
  uint8_t delay_counter=0;


    // установка режима для ds
    DDRB |= _BV(DS_BIT);
    PORTB &= ~_BV(DS_BIT);
    DDRB &= ~_BV(DS_BIT);


    for(;;){                /* main event loop */


    _delay_ms(5000); 

    
    if (delay_counter==0) {

      delay_counter=timer;

   // ds              
       
  uint8_t SignBit;
  uint8_t DSdata[2];
  
  
     OneWireReset();
     OneWireOutByte(0xcc);
     OneWireOutByte(0x44);
     
       PORTB |= _BV(DS_BIT);
       DDRB |= _BV(DS_BIT);
       _delay_ms(1000); // если хотим ждать когда датчик посчитает температуру.
       DDRB &= ~_BV(DS_BIT);
       PORTB &= ~_BV(DS_BIT);
     
     
     OneWireReset();
     OneWireOutByte(0xcc);
     OneWireOutByte(0xbe);

     DSdata[0] = OneWireInByte(); 
     DSdata[1] = OneWireInByte();

  int T = analogRead_C(AC_BIT); // ацп
  
  int TReading = (int)(DSdata[1] << 8) + DSdata[0];
  
     SignBit = TReading & 0x8000; 
    if (SignBit) TReading = (TReading ^ 0xffff) + 1;
     
     sendRC(((6 * TReading) + TReading / 4)/10+500+keyT); // отправляем данные

     sendRC(T+keyT+1000); // отправляем данные
     
     //Как передать другие более простые переменные ?
     //Для отправки НЕотрицательного значения мы можем упустить прибавления числа 500
     //Для отправки ЦЕЛОГО числа мы можем не умножать на 10 при передаче,а при приеме не делить на 10.. 

     

    }
        delay_counter--;
        
    }
}

 

 ID arduino-1.8.3
Скетч использует 704 байт (68%) памяти устройства. Всего доступно 1024 байт.
Глобальные переменные используют 0 байт (0%) динамической памяти, оставляя 64 байт для локальных переменных. Максимум: 64 байт.
 
Вот скетч приемника 
#include <RCSwitch.h>

RCSwitch mySwitch = RCSwitch();

float tempout=0;
int tempin=0;

#define key1  11000 // 1 датчик температуры
#define key1_1  12000 // 2 ацп

// можно добавить еще передатчиков с другими адресами
//#define key2  13000 // 1 датчик температуры
//#define key2_2  14000 // 2 ацп

//#define key3  15000 // 1 датчик температуры
//#define key3_3  16000 // 2 ацп
// и т.д


void setup() {
 Serial.begin(9600); 
 mySwitch.enableReceive(0);  // Receiver on inerrupt 0 => that is pin 2 // иницилизация.Используется вывод м/к с прерыванием под номером 0.
}
void loop() {
  
  if (mySwitch.available()) {
    
  long receivedCode =  mySwitch.getReceivedValue();
  
   if (receivedCode == 0) {
      // обработка:не верный формат данных
    } else {

  if (key1<=receivedCode && key1+999>receivedCode){  // принатая температура ds18b20
    tempout=(float)(receivedCode-key1-500)/10;      
  }
  else if (key1_1<=receivedCode && key1_1+999>receivedCode) { // принятые значения ацп
    tempin = receivedCode-key1_1;
  }
  // здесь так точьно и для других передатчиков заменив названия переменных на свои
  /*
  else if (key2<=receivedCode && key2+999>receivedCode) {
    tempin = receivedCode-key2;
  }
  else if (key2_2<=receivedCode && key2_2+999>receivedCode) {
    Hr = receivedCode-key2_2;
  }
  else if (key3<=receivedCode && key3+999>receivedCode){
    tempin=(float)(receivedCode-key3)/10;//пример для влажности
  }
  else if (key3_3<=receivedCode && key3_3+999>receivedCode){
    Hr=(float)(receivedCode-key3)/10;//пример для влажности
  }*/
// можно не делить на 10,если отправляем через езернет на компьютер- разделить можно там.
//Откуда взялось число 999 ? - это указание диапозона,в котором число будет воспринято 
//как данная температура в даипозоне -49.9 до +49.9    
//Как передать другие более простые переменные ?
//Для отправки НЕотрицательного значения мы можем упустить прибавления числа 500
//Для отправки ЦЕЛОГО числа мы можем не умножать на 10 при передаче,а при приеме не делить на 10..  
   Serial.print("Received ");
   Serial.print(receivedCode);
   Serial.print(" 1 ds18b20 : ");
   Serial.print( tempout ,1); 
   Serial.print("°С; АЦП : ");
   Serial.println( tempin );   
    } 
    mySwitch.resetAvailable(); // сброс данных.
  } // end available
  // тут могут выводится данные tempout и tempin на лсд экран или отправлятся через езернет.

}
 
И еще я подстраивал контур катушки на приемнике, крутил на пол оборота в лево или право следя за растоянием приема и по количеству принятых посылок в терминале. В моих скетчах получается 7 посилок но можно добавить или уменьшить поигравши с задержками передатчика. Сейчас через 2 стены метров на 40 на улице отличьно ловит, дальше не бегал. И при настройке не держите приемник в руках, а крутнув отойдите на метр и смотрите что принемает, уж очень ему не нравится наше близкое присутствие.
 
andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Возьму скетч за основу, спасибо. А то у меня передача всего метров на 6.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

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

#include <avr/sleep.h>
#include <avr/wdt.h>
#include <avr/io.h>
#include <util/delay.h>     /* for _delay_us() */

#define periodusec 400 // mcs
#define DS_BIT         4 // pin 3
#define RC_BIT         3 // pin 2
#define keyT  11000

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

// PB0 pin 5
#define PB0_OUT sbi(DDRB,PB0)
#define PB0_LOW cbi(PORTB,PB0)
// PB1 pin 6
#define PB1_OUT sbi(DDRB,PB1)
#define PB1_LOW cbi(PORTB,PB1)
// PB2 pin 7
#define PB2_OUT sbi(DDRB,PB2)
#define PB2_LOW cbi(PORTB,PB2)
// PB3 pin 2
#define PB3_OUT sbi(DDRB,PB3);
#define PB3_LOW cbi(PORTB,PB3);
// PB4 pin 3
#define PB4_OUT sbi(DDRB,PB4);
#define PB4_LOW cbi(PORTB,PB4);

#define TimerCountSec 15 // delay start by sec
word CurrentTime = 0;

void ExecFunc() {
  // установка режима для ds
  DDRB |= _BV(DS_BIT);
  PORTB &= ~_BV(DS_BIT);
  DDRB &= ~_BV(DS_BIT);
  // get temp and send
  int TReading = GetTemp();
  sendRC(((6 * TReading) + TReading / 4) / 10 + 500 + keyT); // отправляем данные
  // OFF pins
  PB0_OUT; PB0_LOW;
  PB1_OUT; PB1_LOW;
  PB2_OUT; PB2_LOW;
  PB3_OUT; PB3_LOW;
  PB4_OUT; PB4_LOW;
  // -
}

void CalcTimer() {
  ++CurrentTime;
  if (((CurrentTime + 1) * 8) >= TimerCountSec) {
    CurrentTime = 0;
    ExecFunc();
  }
}

ISR (WDT_vect)
{
  wdt_disable();  // disable watchdog
}

void setup () {
  // OFF pins
  PB0_OUT; PB0_LOW;
  PB1_OUT; PB1_LOW;
  PB2_OUT; PB2_LOW;
  PB3_OUT; PB3_LOW;
  PB4_OUT; PB4_LOW;
  // first run
  ExecFunc();
}

void loop ()
{
  CalcTimer();
  cbi(ADCSRA, ADEN); // switch Analog to Digitalconverter OFF
  setup_watchdog(9);
  wdt_reset();  // pat the dog
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);
  noInterrupts (); // timed sequence follows
  sleep_enable();
  // turn off brown-out enable in software
  sleep_bod_disable();
  //MCUCR = MCUCR | _BV(BODS) | _BV(BODSE);
  /*MCUCR = bit (BODS) | bit (BODSE);
    MCUCR = bit (BODS);*/
  // --
  interrupts ();  // guarantees next instruction executed
  sleep_cpu ();  // cancel sleep as a precaution
  sleep_disable();
}


// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii) {
  byte bb; int ww;
  if (ii > 9 ) ii = 9;
  bb = ii & 7;
  if (ii > 7) bb |= (1 << 5);
  bb |= (1 << WDCE); ww = bb;
  MCUSR &= ~(1 << WDRF);
  // start timed sequence
  WDTCR |= (1 << WDCE) | (1 << WDE);
  // set new watchdog timeout value
  WDTCR = bb; WDTCR |= _BV(WDIE);
}


void sendRC(unsigned long data) { // Отправка данных по радиоканалу RCswitch. Двоичный протокол
  DDRB |= _BV(RC_BIT);
  data |= 3L << 20; // ?
  unsigned short repeats = 1 << (((unsigned long)data >> 20) & 7);
  data = data & 0xfffff;
  unsigned long dataBase4 = 0; uint8_t i;
  for (i = 0; i < 20; i++) {
    dataBase4 <<= 1;
    dataBase4 |= (data % 2);
    data /= 2;
  }
  unsigned short int j;
  for (j = 0; j < repeats; j++) {
    data = dataBase4; uint8_t i;
    for (i = 0; i < 20; i++) {
      switch (data & 1) {
        case 0:
          PORTB |= _BV(RC_BIT);
          _delay_us(periodusec);
          PORTB &= ~_BV(RC_BIT);
          _delay_us(periodusec * 3);
          break;
        case 1:
          PORTB |= _BV(RC_BIT);
          _delay_us(periodusec * 3);
          PORTB &= ~_BV(RC_BIT);
          _delay_us(periodusec);
          break;
      }
      data >>= 1;
    }
    PORTB |= _BV(RC_BIT);
    _delay_us(periodusec);
    PORTB &= ~_BV(RC_BIT);
    _delay_us(periodusec * 31);
  }
}

// OneWire функции:

void OneWireReset()
{
  PORTB &= ~_BV(DS_BIT);
  DDRB |= _BV(DS_BIT);
  _delay_us(500);
  DDRB &= ~_BV(DS_BIT);
  _delay_us(500);
}

void OneWireOutByte(uint8_t d)
{
  uint8_t n;
  for (n = 8; n != 0; n--)
  {
    if ((d & 0x01) == 1)
    {
      PORTB &= ~_BV(DS_BIT);
      DDRB |= _BV(DS_BIT);
      _delay_us(5);
      DDRB &= ~_BV(DS_BIT);
      _delay_us(60);
    }
    else
    {
      PORTB &= ~_BV(DS_BIT);
      DDRB |= _BV(DS_BIT);
      _delay_us(60);
      DDRB &= ~_BV(DS_BIT);
    }
    d = d >> 1;
  }
}


uint8_t OneWireInByte()
{
  uint8_t d, n, b;
  for (n = 0; n < 8; n++)
  {
    PORTB &= ~_BV(DS_BIT);
    DDRB |= _BV(DS_BIT);
    _delay_us(5);
    DDRB &= ~_BV(DS_BIT);
    _delay_us(5);
    b = ((PINB & _BV(DS_BIT)) != 0);
    _delay_us(50);
    d = (d >> 1) | (b << 7);
  }
  return (d);
}


int GetTemp() {
  uint8_t SignBit;
  uint8_t DSdata[2];
  OneWireReset();
  OneWireOutByte(0xcc);
  OneWireOutByte(0x44);
  PORTB |= _BV(DS_BIT);
  DDRB |= _BV(DS_BIT);
  _delay_ms(1000); // если хотим ждать когда датчик посчитает температуру.
  DDRB &= ~_BV(DS_BIT);
  PORTB &= ~_BV(DS_BIT);
  OneWireReset();
  OneWireOutByte(0xcc);
  OneWireOutByte(0xbe);
  DSdata[0] = OneWireInByte();
  DSdata[1] = OneWireInByte();
  int TReading = (int)(DSdata[1] << 8) + DSdata[0];
  SignBit = TReading & 0x8000;
  if (SignBit) TReading = (TReading ^ 0xffff) + 1;
  return TReading;
}

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

плохое потребление получилось при питании от 5 Вольт: Спящий режим - 1.07 мА.

много, буду дальше бороться

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

исправил скетч - потребление в спящем режиме = 10мкА

отличный результат, осталось спаять это на макетке и запитать от батарейки CR2032

#include <avr/sleep.h>
#include <avr/wdt.h>
#include <avr/io.h>
#include <util/delay.h>     /* for _delay_us() */

#define periodusec 400 // mcs
#define DS_BIT         4 // pin 3
#define RC_BIT         3 // pin 2
#define keyT  11000

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

// PB0 pin 5
#define PB0_OUT sbi(DDRB,PB0)
#define PB0_LOW cbi(PORTB,PB0)
// PB1 pin 6
#define PB1_OUT sbi(DDRB,PB1)
#define PB1_LOW cbi(PORTB,PB1)
// PB2 pin 7
#define PB2_OUT sbi(DDRB,PB2)
#define PB2_LOW cbi(PORTB,PB2)
// PB3 pin 2
#define PB3_OUT sbi(DDRB,PB3);
#define PB3_LOW cbi(PORTB,PB3);
// PB4 pin 3
#define PB4_OUT sbi(DDRB,PB4)
#define PB4_IN cbi(DDRB,PB4)
#define PB4_HIGH sbi(PORTB,PB4)
#define PB4_LOW cbi(PORTB,PB4)

#define TimerCountSec 15 // delay start by sec
word CurrentTime = 0;

void ExecFunc() {
  // установка режима для ds
  DDRB |= _BV(DS_BIT);
  PORTB &= ~_BV(DS_BIT);
  DDRB &= ~_BV(DS_BIT);
  // get temp and send
  int TReading = GetTemp();
  sendRC(((6 * TReading) + TReading / 4) / 10 + 500 + keyT); // отправляем данные
  // OFF pins
  OneWireReset();
  PB0_OUT; PB0_LOW;
  PB1_OUT; PB1_LOW;
  PB2_OUT; PB2_LOW;
  PB3_OUT; PB3_LOW;
  //PB4_OUT; PB4_LOW;
  PB4_IN; PB4_LOW;
  // -
  //delay(3000); // for test power
}

void CalcTimer() {
  ++CurrentTime;
  if (((CurrentTime + 1) * 8) >= TimerCountSec) {
    CurrentTime = 0;
    ExecFunc();
  }
}

ISR (WDT_vect)
{
  wdt_disable();  // disable watchdog
}

void setup () {
  // OFF pins
  PB0_OUT; PB0_LOW;
  PB1_OUT; PB1_LOW;
  PB2_OUT; PB2_LOW;
  PB3_OUT; PB3_LOW;
  PB4_OUT; PB4_LOW;
  // first run
  ExecFunc();
}

void loop ()
{
  CalcTimer();
  cbi(ADCSRA, ADEN); // switch Analog to Digitalconverter OFF
  setup_watchdog(9);
  wdt_reset();  // pat the dog
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);
  noInterrupts (); // timed sequence follows
  sleep_enable();
  // turn off brown-out enable in software
  sleep_bod_disable();
  //MCUCR = MCUCR | _BV(BODS) | _BV(BODSE);
  /*MCUCR = bit (BODS) | bit (BODSE);
    MCUCR = bit (BODS);*/
  // --
  interrupts ();  // guarantees next instruction executed
  sleep_cpu ();  // cancel sleep as a precaution
  sleep_disable();
}


// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii) {
  byte bb; int ww;
  if (ii > 9 ) ii = 9;
  bb = ii & 7;
  if (ii > 7) bb |= (1 << 5);
  bb |= (1 << WDCE); ww = bb;
  MCUSR &= ~(1 << WDRF);
  // start timed sequence
  WDTCR |= (1 << WDCE) | (1 << WDE);
  // set new watchdog timeout value
  WDTCR = bb; WDTCR |= _BV(WDIE);
}


void sendRC(unsigned long data) { // Отправка данных по радиоканалу RCswitch. Двоичный протокол
  DDRB |= _BV(RC_BIT);
  data |= 3L << 20; // ?
  unsigned short repeats = 1 << (((unsigned long)data >> 20) & 7);
  data = data & 0xfffff;
  unsigned long dataBase4 = 0; uint8_t i;
  for (i = 0; i < 20; i++) {
    dataBase4 <<= 1;
    dataBase4 |= (data % 2);
    data /= 2;
  }
  unsigned short int j;
  for (j = 0; j < repeats; j++) {
    data = dataBase4; uint8_t i;
    for (i = 0; i < 20; i++) {
      switch (data & 1) {
        case 0:
          PORTB |= _BV(RC_BIT);
          _delay_us(periodusec);
          PORTB &= ~_BV(RC_BIT);
          _delay_us(periodusec * 3);
          break;
        case 1:
          PORTB |= _BV(RC_BIT);
          _delay_us(periodusec * 3);
          PORTB &= ~_BV(RC_BIT);
          _delay_us(periodusec);
          break;
      }
      data >>= 1;
    }
    PORTB |= _BV(RC_BIT);
    _delay_us(periodusec);
    PORTB &= ~_BV(RC_BIT);
    _delay_us(periodusec * 31);
  }
}

// OneWire функции:

void OneWireReset()
{
  PORTB &= ~_BV(DS_BIT);
  DDRB |= _BV(DS_BIT);
  _delay_us(500);
  DDRB &= ~_BV(DS_BIT);
  _delay_us(500);
}

void OneWireOutByte(uint8_t d)
{
  uint8_t n;
  for (n = 8; n != 0; n--)
  {
    if ((d & 0x01) == 1)
    {
      PORTB &= ~_BV(DS_BIT);
      DDRB |= _BV(DS_BIT);
      _delay_us(5);
      DDRB &= ~_BV(DS_BIT);
      _delay_us(60);
    }
    else
    {
      PORTB &= ~_BV(DS_BIT);
      DDRB |= _BV(DS_BIT);
      _delay_us(60);
      DDRB &= ~_BV(DS_BIT);
    }
    d = d >> 1;
  }
}


uint8_t OneWireInByte()
{
  uint8_t d, n, b;
  for (n = 0; n < 8; n++)
  {
    PORTB &= ~_BV(DS_BIT);
    DDRB |= _BV(DS_BIT);
    _delay_us(5);
    DDRB &= ~_BV(DS_BIT);
    _delay_us(5);
    b = ((PINB & _BV(DS_BIT)) != 0);
    _delay_us(50);
    d = (d >> 1) | (b << 7);
  }
  return (d);
}


int GetTemp() {
  uint8_t SignBit;
  uint8_t DSdata[2];
  OneWireReset();
  OneWireOutByte(0xcc);
  OneWireOutByte(0x44);
  PORTB |= _BV(DS_BIT);
  DDRB |= _BV(DS_BIT);
  _delay_ms(1000); // если хотим ждать когда датчик посчитает температуру.
  DDRB &= ~_BV(DS_BIT);
  PORTB &= ~_BV(DS_BIT);
  OneWireReset();
  OneWireOutByte(0xcc);
  OneWireOutByte(0xbe);
  DSdata[0] = OneWireInByte();
  DSdata[1] = OneWireInByte();
  int TReading = (int)(DSdata[1] << 8) + DSdata[0];
  SignBit = TReading & 0x8000;
  if (SignBit) TReading = (TReading ^ 0xffff) + 1;
  return TReading;
}

 

NikitaS
Offline
Зарегистрирован: 22.10.2016

andycat пишет:

исправил скетч...

Вы на стабилизатор конденсаторы ставите? В сети встретил упоминание о необходимости подключения конденсаторов для 78L05, упомянутого в первом сообщении: "Чтобы стабилизатор работал правильно (нормально стабилизировал и не генерировал пульсации) стабилизатора на вход и выход необходимо подключить конденсаторы. Причем их номиналы не должны быть меньше 0,33 мкФ и 0,1 мкФ соответственно.".

С этим понятно. А вот дальше не очень понятно: "Если стабилизатор питается выпрямленным напряжением частотой 50Гц, то входной конденсатор приходиться увеличивать, ставить электролитический у которого не маленькое последовательное сопротивление. Поэтому в данном случае к электролитическому конденсатору в параллель нужно поставить керамический."

Почему говорится, что нужно ставить электролитический, и поэтому нужно поставить керамический?

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

NikitaS пишет:

andycat пишет:

исправил скетч...

Вы на стабилизатор конденсаторы ставите? 

у меня и стабилизатора то нет - я питаю от Arduino UNO китайской as ISP.

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

и я вообще буду от батарейки питать, нафиг там конденсаторы? 

максимальное потребление которое я замерил своим китайским прибором <5мА в активном режиме.

NikitaS
Offline
Зарегистрирован: 22.10.2016

andycat пишет:

у меня и стабилизатора то нет - я питаю от Arduino UNO китайской as ISP.

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

и я вообще буду от батарейки питать, нафиг там конденсаторы? 

максимальное потребление которое я замерил своим китайским прибором <5мА в активном режиме.

Тогда переадресую вопрос к тем, кто питает МК от выпрямленного тока 5 В, например, от зарядки мобильника.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

NikitaS пишет:

Тогда переадресую вопрос к тем, кто питает МК от выпрямленного тока 5 В, например, от зарядки мобильника.

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

ЗЫ. В деревне на тераске стоит в коробке блок управления освещением, питается от преобразователя какого то дешевого с Ali, никаких конденсаторов не ставил вообще, а сеть в деревне ужасная и по напряжению и по качеству, вот уже несколько месяцев - все отлично работает.