Автономные устройства на базе Atmega328

Westwood
Offline
Зарегистрирован: 17.03.2020

Добрый вечер! Есть устройство на базе меги328. Ключевое то - что оно автономное, подразумевается питание от батарейки типа cr2450 или 77. Работает все как надо, как только становится возможным, сразу же уходит в крепкий сон, потребляя меньше 1 мка. Как уже стало ясно, мега питается от 3-х вольт, в результате чего снижена тактовая частота до 8 Мгц. Ход работы устройства такой: работает без перерыва в активном режиме, потребляя со всей нагрузкой 7 мА. Из них 3 мА уходят на работу самого микроконтроллера. Если трогать его перестали - сразу же спать. Но вот в чем вопрос. При таком потреблении такой батарейки в лучшем случае хватит на 140 часов непрерывной работы(активный режим). Частоту меньше 8 МГц не сделать, так как скетч немаленький, и занимается выводом времени за сегментный индикатор с помощью динамической индикации, которая ниже 8 Мгц начинает заметно моргать + есть датчики, которые должны все же опрашиваться как можно быстрее, чтобы не пропустить ничего. В перспективе, заменить сегментный LED индикатор на сегментный LCD приведет к потреблению в районе 3.5 мА (если 3 под мегу остаются). Но вот эти вот 3.5 мА от самого микроконтроллера - как ножом по сердцу. Есть ли пути с этим как-то бороться? Может другие модели из линейки avr (dip-8 не пойдет, портов мало)? Я лично имел дело только с 328, собственно к вам и обращаюсь, может что подскажете. По поводу LCD тоже хотел бы услышать от вас. Есть ли шанс его запустить стабильно, использую скажем частоту в 1 МГц у микроконтроллера. В таком случае тут уже не будет той динамической индикации, для которой важно быстро обновляться. Опять же, допускаю, что глупый вопрос, однако у меня с LCD первый опыт знакомства, нету еще на руках, чтобы проверить самостоятельно, только едет. А прикинуть надо. Хочется услышать ваше мнение. Спасибо.

 

b707
Offline
Зарегистрирован: 26.05.2017

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

Если управлять сегментами через сдвиговые регистры, а ардуину отправлять в сон - ток можно уменьшить примерно раз в 10

Green
Offline
Зарегистрирован: 01.10.2015

1 мка!? Это в книгу рекордов Гиннеса. Невозможность динамической индикации при 1 мгц? 1 МИЛЛИОН операций в секунду... Как всё запущено.

Westwood
Offline
Зарегистрирован: 17.03.2020

Green, наверное, раз ты отвечаешь, ты должен знать, что в режиме сна можно добиться потребления в районе 0.1 мкА. Не понятно, чем тебя удивляет 1 мкА. По поводу индикации. В коде ведь не только динамическая индикация. Как я уже писал, также происходит опрос датчиков. Более того, есть примитивное меню выбора на двух кнопках, которое также тратит на себя время выполнения. Вот в связи со всем этим при 1 МГц экран начинает мерцать очень заметно. Хочется услышать предложения полезные

Westwood
Offline
Зарегистрирован: 17.03.2020

B707, а можно немного подробнее. Сегментные LCD ведь и так по-иному управляются. Вот у меня должно выводиться время, причём частота обновления должна быть равна 1 сотой секунды, так как сотые как раз самый младший разряд для вывода. То есть ты предлагаешь делать так: записывать в драйвер LCD команду вывести время, допустим, 01.25 (секунды.десятые/сотые), и ложимся спать на 10 миллисекунд? А далее выводим 01.26 и опять повторяем?

b707
Offline
Зарегистрирован: 26.05.2017

Westwood пишет:
Green, наверное, раз ты отвечаешь, ты должен знать, что в режиме сна можно добиться потребления в районе 0.1 мкА. Не понятно, чем тебя удивляет 1 мкА.

Грин прав. Цифра 0.1 просто показывает, что вы абсолютно не в теме. Смотрим табличку ниже. Да, там есть строчка со значением 0.1 мкA Но это дипслип с полностью выключенной периферией. А просыпаться вы как будете? Для вашего случая абсолютный предел - вторая снизу строчка, 4 мкА. Так что никаких 1 мкА у вас быть не может.

Цитата:
По поводу индикации. В коде ведь не только динамическая индикация. Как я уже писал, также происходит опрос датчиков. Более того, есть примитивное меню выбора на двух кнопках, которое также тратит на себя время выполнения. Вот в связи со всем этим при 1 МГц экран начинает мерцать очень заметно. Хочется услышать предложения полезные

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

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

Westwood пишет:
Хочется услышать предложения полезные

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

b707
Offline
Зарегистрирован: 26.05.2017

Westwood пишет:
B707, а можно немного подробнее. Сегментные LCD ведь и так по-иному управляются. Вот у меня должно выводиться время, причём частота обновления должна быть равна 1 сотой секунды, так как сотые как раз самый младший разряд для вывода. То есть ты предлагаешь делать так: записывать в драйвер LCD команду вывести время, допустим, 01.25 (секунды.десятые/сотые), и ложимся спать на 10 миллисекунд? А далее выводим 01.26 и опять повторяем?

если вы делаете секундомер с выводом сотых, то думаю никакой сон ни на каком дисплее вам не поможет.С другой стороны, непонятно, разве для секундомера 140 часов работы от батарейки - мало? Даже в знаменитой гонке Ле ман всего 24 часа. что вы там собрались отсчитывать с такой точностью?

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Минимум, который мне удалось получить. Всё отключено, кроме WDT, частота 8 Мгц от внутреннего RC, питание один 18650

b707
Offline
Зарегистрирован: 26.05.2017

ТС кудат пропал,  опять не так помогаем :)))

Westwood
Offline
Зарегистрирован: 17.03.2020

TC никуда не пропал! Просто нету возможности постоянно присутствовать на форуме. По поводу навыков и опыта я ни на что не претендую! Фактически, эта вещь - мой первый немаленький проект. И, что естественно, говорить о полностью оптимизированном коде пока что не приходится. Поэтому и обращаюсь к вам. А теперь по делу.

Ключевым у устройства все равно остаётся достижение наибольшего времени автономной работы. Спрашивали про 140 часов - это конечно неплохо, но вот 500 - было бы просто превосходно. Теперь про потребление в режиме сна: естественно, режим Power-Down mode + отключение АЦП+отключение BOD. Выход из сна с помощью прерывания по кнопке. При прямом измерении амперметром показывает меньше одного микроампера. А вот, кому интересно, видео для демонстрации, начиная с 10:30 по ссылке https://www.youtube.com/watch?v=urLSDi7SD8M&list=PL0JWuCHXfJ2zjHiHtHUO2AjGQ1pP4Bzab&index=3&t=798s&ab_channel=KevinDarrah . Я ваши советы буду пробовать учесть. Поиграюсь с динамической индикацией, как вы сказали, которой 1 МГц будет более чем предостаточно. В случае неудачи отпишусь, приложу код и выслушаю ваши наставления. Спасибо.

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

Westwood, вы наверное не поняли, зачем мерять что то 140 или 500 часов я могу понять, но автономное устройство которое меняет это в никуда - зачем? Никто не будет смотреть на дисплей час или два......

Westwood
Offline
Зарегистрирован: 17.03.2020

Andycat, я вас пытаюсь понять. Но дело в том, что вот это вот ключевое у этого устройства. Просто есть таймер четырехразрядный, измеряющий время между двумя срабатываниями датчиков, и вот просто необходимо сделать так, чтобы этот таймер в режиме вывода цифр на экран работал как можно дольше. Возможно, вам кажется это совершенно бесполезным. Но стоит одна цель: Оптимизировать так,чтобы его непрерывная работа была максимально долгой. 

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

Rtc + МК, срабатывает от двух импульсов и прекрасно измеряет время между ними. Отображение в момент импульсов. Все.....при умелой реализации на пол года батарейки точно хватит. Но тема не раскрыта : нахрена отображать время таймера в течении кучи часов?

b707
Offline
Зарегистрирован: 26.05.2017

Westwood пишет:

Теперь про потребление в режиме сна: естественно, режим Power-Down mode + отключение АЦП+отключение BOD. Выход из сна с помощью прерывания по кнопке. При прямом измерении амперметром показывает меньше одного микроампера.

это все замечательно, но если МК просыпается по кнопке - каким образом вы собрались обеспечить обновление картинки на экране с частотой 100 Гц ? Сон с периодическим просыпанием, насколько я знаю - можно организовать только через WDT - а это, возвращаемся к таблице выше - потребление 4 мкА,

Именно об этом я и писал вам ранее - режим с потреблением менее 1 мкА есть, но задествовать вы его не сможете, для вашего случая минимум - это 4 мкА

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

Westwood
Offline
Зарегистрирован: 17.03.2020

Andycat, тем временем благодаря вашим советам и советам уважаемого b707 мне удалось добиться небольшого успеха. За что вам спасибо. Согласен, глаз у меня еще не набит. Неправильно игрался я с понижением частоты. Теперь понизил до 1 Мгц, по итогу получил полное потребление всего устройства в среднем 2 мА (так как на LED индикатор постоянно выводятся разные цифры, в зависимости от того, сколько сегментов зажжено). Появилось паразитное свечение сегментов, но удалось справится корректировкой кода. Теперь, используя cr2077, например, можно надеяться на 400-450 часов думаю. Надо проверить на практике. Говоря о том, что вас так сильно неймёт, а именно о том, зачем надо столько работать таймеру, отвечаю: задача в том, чтобы как можно дольше это устройство функционировало без замены элемента питания, вот и все. Никто не собирается на него смотреть по 10 часов каждый день. Условно в день по часу применения по назначению, и тогда хватит на год. Это ли не здорово.

VladimirTsibrov
Offline
Зарегистрирован: 05.03.2019

b707 пишет:

это все замечательно, но если МК просыпается по кнопке - каким образом вы собрались обеспечить обновление картинки на экране с частотой 100 Гц ? Сон с периодическим просыпанием, насколько я знаю - можно организовать только через WDT - а это, возвращаемся к таблице выше - потребление 4 мкА,

Я так понял, что устройство спит с выключенным wdt до нажатия кнопки. Потребляет при этом меньше 1мкА - ок. А вот после пробуждения начинается активный режим работы устройства и речь об уходе в сон уже не идёт, потому что надо опрашивать какие-то датчики и обновлять дисплей.

Если уйти от динамического обновления индикаторов, то можно попробовать уводить МК в сон на 16мс и просыпаться по WDT. Устроит ли ТС такая частота опроса датчиков? Но в любом случае МК жрет 3мА из общих 7, т.е. серьезно сэкономить на нем не получится.

Westwood
Offline
Зарегистрирован: 17.03.2020

b707, возможно мы с вами друг друга не поняли. Дисплей работает только тогда, когда устройство не спит, как бы это было неочевидно. То есть, скажем, таймер отсчитывает время и выводит на экран - то устройство в сон не уходит в этом процессе. Затем остановили таймер, через 15 секунд он сам уйдет в сон до следующего пробуждения по кнопке с помощью прерывания. А про это я уже выше сказал, как удалось добиться меньше 1 мка, и даже видео привёл.

Westwood
Offline
Зарегистрирован: 17.03.2020

VladimirTsibrov, спасибо за совет! Но вот выше вашего сообщения разместил новые показания. Всё же удалось добиться в среднем потребления 2 мА.

b707
Offline
Зарегистрирован: 26.05.2017

Westwood пишет:

b707, возможно мы с вами друг друга не поняли. Дисплей работает только тогда, когда устройство не спит, как бы это было неочевидно. То есть, скажем, таймер отсчитывает время и выводит на экран - то устройство в сон не уходит в этом процессе. Затем остановили таймер, через 15 секунд он сам уйдет в сон до следующего пробуждения по кнопке с помощью прерывания.

нафига тогда сон, если устройство не нужно? - выключайте его и все

Westwood
Offline
Зарегистрирован: 17.03.2020

Избавиться от лишних кнопок. Одной достаточно, которая для управления. 

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Westwood пишет:

Избавиться от лишних кнопок. Одной достаточно, которая для управления. 

Tак и питание включать можно этой же кнопкой.

Westwood
Offline
Зарегистрирован: 17.03.2020

Установлена тактовая кнопка, с помощью которой осуществляется управление секундомером. А также на ней висит функция ухода в сон. Под включением питания вы имеете в виду замыкание цепи это кнопкой?

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Под включением я имею ввиду включение МК по нажатию этой кнопкой. Ею так же можно управлять секундомером и выключать МК если там есть пара независимых контактов. Ну еще потребуется транзистор и несколько резисторов.

 

Westwood
Offline
Зарегистрирован: 17.03.2020

Asam, спасибо за идею! Но тем не менее, насколько эффективнее может быть ваша реализация? Токи утечки присутствуют в любом транзисторе, и в принципе любой новый электронный прибор будет увеличивать токопотребление. Не понятно насколько они будут меньше, чем в данном режиме сейчас при токе во сне примерно в 0.3 мкА. 

Westwood
Offline
Зарегистрирован: 17.03.2020

Уважаемые господа, тем не менее, появился к Вам новый вопрос. Ниже приведен код данного устройства. Я постарался максимально все подписать комментариями. Вопрос вот в чем. Некорректно работает функция micros. При выставлении длительности одной сотой секунды (переменная TIME_2) по какой-то причине первые 60 секунд отсчитываются быстрее, чем все следующее время. То есть в сравнении с эталонным временем на первых 60 секундах данный таймер ускоряется, обгоняя эталонное время на 5 секунд, а затем, когда начинается заполнение минут, начинает отставать примерно на 5 секунд за каждую минуту. Атмега тактируется 1 МГц внутрений RC-генератор. Питание 3 В. Смущает такое странное поведение, что сначала ускорение, а затем замедление. Понятно, что при понижении частоты уменьшается и точность работы. Хотелось бы услышать ваше мнение,с чем это может быть связано. Спасибо!

 

PS один из первых больших кодов, поэтому буду рад принять уважительную критику, без наездов. Спасибо!



const byte SENSOR_0 = A0; 
const byte SENSOR_1 = A1; 
const byte BUTTON = 2;

const byte SYNHRO = 7;
const byte LATCH = 6;
const byte DATA = 5;

const byte ZERO = 11;
const byte FIRST = 10;
const byte SECOND = 9;
const byte THIRD = 8;


byte all_off = 0b00000000; 
byte figures[] = {0b11111100, 0b01100000, 0b11011010, 0b11110010, 0b01100110, 0b10110110, 0b10111110, 0b11100000, 0b11111110, 0b11110110};      // байт числа 0-9 для сегментного идикатора
byte figures_DP[] = {0b11111101, 0b01100001, 0b11011011, 0b11110011, 0b01100111, 0b10110111, 0b10111111, 0b11100001, 0b11111111, 0b11110111};   // байт числа 0-9 + точка(dp) для сегментного идикатора 


unsigned long CURRENT;

long TIME_1 = 104;              // время работы одного разряда сегментного 4-хразрядного индикатора (динамическая индикация)
unsigned long PREVIOUS_1;       

long TIME_2 = 6400;             // должна быть 0.01 секунда
unsigned long PREVIOUS_2;

long zero_digit;              // 4 переменные, привязанные к каждому разряду индикатора; равны числам, которые будут выводится на соответсвующий им разряд
long first_digit;
long second_digit;
long third_digit;             

int n;                        // секунды с точностью до сотых (то есть максимальное значение до 5999)
int minute;                   // минуты (от 0 до 100, далее сброс минут в 0)

byte k;                       // номер разряда индикатора (0-3)

boolean val_0;                // переменная первого датчика (секундомер измеряет время между срабатыванием датчиков)
boolean val_1;                // переменная второго датчика
boolean button;               // переменная для кнопки

int state;

long counter;                 // переменная для отсчета времени, остающегося до ухода в сон (Power-down)
long beforeSleep = 4000;      // время до ухода в сон (просто отсчёт количества тактов)

// THE BEGINNING OF THE CODE

 void myFunction()            // функция обработчика прерывания
 {
  counter = 0;                // обнуляет время до ухода в сон
 }

void setup()
{
  pinMode(0, OUTPUT);         // все свободные пины на выход для повышения энергосбережения
  pinMode(1, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
  pinMode(16, OUTPUT);
  pinMode(17, OUTPUT);
  pinMode(18, OUTPUT);
  pinMode(19, OUTPUT);

  
  pinMode(SYNHRO, OUTPUT);
  pinMode(LATCH, OUTPUT);
  pinMode(DATA, OUTPUT);
  pinMode(ZERO, OUTPUT);
  pinMode(FIRST, OUTPUT);
  pinMode(SECOND, OUTPUT);
  pinMode(THIRD, OUTPUT);
  pinMode(SENSOR_1, INPUT);
  pinMode(SENSOR_0, INPUT);
  pinMode(BUTTON, INPUT_PULLUP);

  attachInterrupt(digitalPinToInterrupt(2), myFunction, FALLING);  // объявление прерывания
}




void sleepMode()              // функция, зададающая параметры ухода в сон
{
  ADCSRA &= ~(1<<7);          // выключаем АЦП

 SMCR|=(1<<2);                // выбираем режим сна
 SMCR|=1;                     // разрешаем сон

 MCUCR |= (3<<5);             // отключаем BOD
 MCUCR = (MCUCR & ~(1<<5)) | (1<<6);
 __asm__ __volatile__ ("sleep");  // уходим в сон
}


void shift (byte v)           // функция занимается записью байта "v" информации в сдвиговый регистр
{
 for (int i=0; i<8; i++)
 {
  digitalWrite(SYNHRO, LOW);
  digitalWrite(DATA, v & (1<<i));
  digitalWrite(SYNHRO, HIGH);
 }
 digitalWrite(LATCH, HIGH);
 digitalWrite(LATCH, LOW);
}

void set_digits (byte k, long n)  // функция, выполненная на основе case: k равен 0-3, что соответствует каждому из 4-х разрядов индикатора. РЕЖИМ РАБОТЫ СЕКУНДОМЕРА: в течение первой минуты выводятся на индикатор секунды + сотые и десятые. Затем: минуты и секунды.
{
  switch(k)
  {
    case 0:                       // первый разряд 
    shift(all_off);               // такой процесс записи числа в разряд индикатора позволяет избавиться от паразитной засветки 
    digitalWrite(FIRST, LOW);
    digitalWrite(SECOND, LOW);
    digitalWrite(THIRD, LOW);
    digitalWrite(ZERO, HIGH);
    if (minute<1)                 //выбираем, что записывать. Либо минуты, если их больше одной на данный момент, либо секунды, если идут первые 60 секунд.
    {
      zero_digit = n/1000;        // n - счетчик секунд до 5999, достаем старший разряд числа секунд
    }
    else
    {
      zero_digit = minute/10;     // минуты, достаем старший разряд числа минут 
    }
    shift(figures[zero_digit]);   // записываем полученное число с помощью функции shift
   
    break;
  

    case 1:                       // второй разряд; все данные кейсы аналогичны друг другу по способу записи.
    shift(all_off);
    digitalWrite(ZERO, LOW);
    digitalWrite(SECOND, LOW);
    digitalWrite(THIRD, LOW);
    digitalWrite(FIRST, HIGH);
    if (minute<1)
    {
      first_digit = (n-(long)(n/1000)*1000)/100;
      shift(figures_DP[first_digit]); 
    }
    else
    {
      first_digit = minute - ((minute/10)*10);
      shift(figures_DP[first_digit]); 
    }
    
    break;
  
   
    case 2:                      // третий разряд
    shift(all_off); 
    digitalWrite(ZERO, LOW);
    digitalWrite(FIRST, LOW);
    digitalWrite(THIRD, LOW);  
    digitalWrite(SECOND, HIGH);
    if (minute<1)
    {
      second_digit = ((n-(long)(n/1000)*1000)-(long)((n-(long)(n/1000)*1000)/100)*100)/10;
    }
    else
    {
      second_digit = n/1000;
    }
    shift(figures[second_digit]);
    
    break; 
  
   
    case 3:                        // четвертый разряд
    shift(all_off);
    digitalWrite(ZERO, LOW);
    digitalWrite(FIRST, LOW);
    digitalWrite(SECOND, LOW);
    digitalWrite(THIRD, HIGH);
    if (minute<1)
    {
      third_digit = ((n-(long)(n/1000)*1000)-(long)((n-(long)(n/1000)*1000)/100)*100) - (long)(((n-(long)(n/1000)*1000)-(long)((n-(long)(n/1000)*1000)/100)*100)/10)*10;
    }
    else
    {
     third_digit = (n-(long)(n/1000)*1000)/100;
    }  
    shift(figures[third_digit]);

    break; 
  }
}

void loop()
{
  val_1 = digitalRead(SENSOR_1);     // читаем датчики
  val_0 = digitalRead(SENSOR_0);
  button = !digitalRead(BUTTON);     // читаем кнопку
  CURRENT = micros();



  if (val_0 == 1 && state == 0)      // примитивное меню управления секундомером: можно сбросить по кнопке. Конечный автомат.
  {
    state = 1;
  }

  if (val_1 == 1 && state == 1)
  {
    state = 2;
  }

  if (button == 1 && state == 1)         // возможность обнулить время с помощью нажатия кнопки и вернуться в состояние 0 
  {
    state = 0;
  }

  if (button == 1 && state == 2)
  {
    state = 0;
  }

  
  if (CURRENT - PREVIOUS_1 >= TIME_1)   // функция для динамической индикации, записываем числа в разряды индикатора поочередно
  {
    PREVIOUS_1 = CURRENT;
    set_digits(k,n);
    k++;
    if (k==4)
    {
      k=0;
    }
  }

  switch (state)  // Свитч, переменной которого является текущее состояние Конечного автомата
  {
    case 0:   // ожидание работы, секундомер выводит 00:00
    n=0;
    minute=0;

     counter++;
     if (counter >= beforeSleep)  // если ничего не происходит, то уходим в сон
     {
      digitalWrite(THIRD, LOW);
      digitalWrite(ZERO, LOW);
      digitalWrite(FIRST, LOW);
      digitalWrite(SECOND, LOW);
      digitalWrite(SYNHRO, LOW);
      digitalWrite(LATCH, LOW);
      digitalWrite(DATA, LOW);
      sleepMode();
     }
  
    break;

  

    case 1:                             // активная работа секундомера
  if (CURRENT - PREVIOUS_2 >= TIME_2)   // пытаемся отсчитывать секунды и минуты
  {
    PREVIOUS_2 = CURRENT;
    n++;
    if (n>5999)
    {
      n=0;
      minute++;
    }
  }

  if (minute == 100)   // обнуление счетчика минут 
  {
    minute = 0;
  }
    break;

    
    case 2:             // остановка секундомера при срабатывании датчика. Выводит время, которое было замерено. 

     counter++;   
     if (counter >= beforeSleep) // Через некоторое время уходит в сон
     {
      digitalWrite(THIRD, LOW);
      digitalWrite(ZERO, LOW);
      digitalWrite(FIRST, LOW);
      digitalWrite(SECOND, LOW);
      digitalWrite(SYNHRO, LOW);
      digitalWrite(LATCH, LOW);
      digitalWrite(DATA, LOW);
      sleepMode();
     }
     
    break; 
  }
}

 

Green
Offline
Зарегистрирован: 01.10.2015
Westwood, согласно негласных правил, наименования переменных пишутся прописными(!), константы заглавными. И что это ~(1<<7) или (3<<5)? Или Вы предлагаете нам открыть даташит? Тогда уж писали бы типа 0x80 или ещё как то более шифрованно.
 
Westwood
Offline
Зарегистрирован: 17.03.2020

Green, спасибо за информацию! Приму к сведению. По поводу вот этого вкл/выкл битов в регистрах, не расшифровал, так как полагаю, что не они являются причиной проблемы, которую я описал. Добавлю туда комментарии.

Green
Offline
Зарегистрирован: 01.10.2015

Westwood пишет:

По поводу вот этого вкл/выкл битов в регистрах, не расшифровал, так как полагаю, что не они являются причиной проблемы, которую я описал.

Сами тогда и разбирайтесь. Мне то это зачем.

Westwood
Offline
Зарегистрирован: 17.03.2020

Добавил комментарии. Я ведь писал об этом. 

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

При внутреннем RC генераторе и тем более 1мгц тактовой даже не пытайтесь выловить правильное время. Выше же писали - МК со спящим режимом и rtc - оптимально для вашей задачи.

Westwood
Offline
Зарегистрирован: 17.03.2020

Andycat, спасибо, не сразу обратил внимание. Пойду копать в этом направлении.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Динамическую индикацию лучше всего вешать на прерывания таймера. И работает стабильнее и код гораздо компактнее получается.

Green
Offline
Зарегистрирован: 01.10.2015

Зато без прерывания меньше проблем.)
ТС, я бы посоветовал вставить вывод n в case1 и включить "показать отметки времени" в мониторе порта. Таким образом вы проконтролируете время и кол-во приращений секундного счётчика. Потому что +/- 5 сек в минуту не должно быть ни от какого генератора.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Green пишет:

Зато без прерывания меньше проблем.)

 

Проблемы с прерываниями от таймера? Ну это надо очень кривые руки иметь. 

Green
Offline
Зарегистрирован: 01.10.2015

Именно такие они у начинающих. Да и volatile забывают многие.

Green
Offline
Зарегистрирован: 01.10.2015

Кстати, ТС, впишите volatile в 44 строку.)

VladimirTsibrov
Offline
Зарегистрирован: 05.03.2019

По-хорошему бы вообще использовать ATOMIC_BLOCK при работе с counter

Westwood
Offline
Зарегистрирован: 17.03.2020

Green, спасибо за указание на ошибки! Попробую промониторить изменение счётчика. Но вот сейчас в то же время крепко уцепился за идею использовать rtc. 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Westwood пишет:

крепко уцепился за идею использовать rtc. 

Это должна быть не идея, а заученное однажды, как отче наш, решение.  Там, где нужно мерить какое-нибудь время - хоть 1307 да поставь, оно много не съест.  (Но лучше 3231, не намного дороже, а точность - мммм, на годы забудешь, что такое часы подводить)

Westwood
Offline
Зарегистрирован: 17.03.2020

DetSimen, да, это я уже усвоил. По поводу микросхемы - на руках 1302 есть. Привлекает очень низкое заявленное энергопотребление в 300 нА. А про точность - то максимального высокого класса точности ставить нет необходимости, так как замеряются относительно короткие промежутки времени, и класса точности у 1302 с заявленным отклонением 5 секунд в сутки по сути более чем достаточно 

Green
Offline
Зарегистрирован: 01.10.2015

Только не понятно зачем тут RTC, если нужен таймер - просто счётчик времени.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Green пишет:

Только не понятно зачем тут RTC

У ей прерывания есть, с достаточной точностью, чтоб интервалы щитать. :) 

Green
Offline
Зарегистрирован: 01.10.2015

Ну если так, тогда да.) Но всё равно миллис проще считать.) И на 100 минутах погрешности быть не должно. 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Green пишет:

Ну если так, тогда да.) Но всё равно миллис проще считать.) И на 100 минутах погрешности быть не должно. 

В режиме PowerDown, с.ка, всё по другому происходит. :)  Поэтому, я - за RTC с прерываньями. 

Чечако
Offline
Зарегистрирован: 15.06.2018

Я тоже за 3231, главное 3231SN, ибо 3231M как раз точностью не отличается. Опять же, у нее есть встроенная возможность батарейного питания, и можно разнести задачи. :)

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Чечако пишет:

Я тоже за 3231, главное 3231SN, ибо 3231M как раз точностью не отличается. Опять же, у нее есть встроенная возможность батарейного питания, и можно разнести задачи. :)

 

Знать бы где эти SN брать... А то кетайцы фотки выставляют с 3231SN, а присылают с 3231M 

Westwood
Offline
Зарегистрирован: 17.03.2020

А никто не имел опыта работы с MCP7940N? RTC если что

 

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Westwood пишет:

А никто не имел опыта работы с MCP7940N? RTC если что

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

Green
Offline
Зарегистрирован: 01.10.2015

DetSimen пишет:

В режиме PowerDown, с.ка, всё по другому происходит. :)  Поэтому, я - за RTC с прерываньями. 


Не катит.) У ТС подсчёт времени идёт только в активном режиме, с индикацией.

Чечако
Offline
Зарегистрирован: 15.06.2018

asam пишет:

Знать бы где эти SN брать... А то кетайцы фотки выставляют с 3231SN, а присылают с 3231M 

В Дипе есть, в Электронщике есть, в Платане пишут срок 5 дней. Не Китаем единым. :)