Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как распознать кратковременное выключение на Tiny13
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Страницы: 1, 2, 3, 4, 5, 6, 7
VladislavS
Цитата
3.значения РОН сравниваем с сохраненными любимыми значениями из EEPROM. если совпали, то длинное отключение, если хоть 1 бит не совпал - то короткое. меняем или не меняем режим


Ууууу.... 300-е сообщение темы, а вы еще верите, что все биты могут совпасть???
galjoen
Цитата(stells @ Jan 18 2010, 22:34) *
...если хоть 1 бит не совпал - то короткое...

Работать не будет.
Прочтите мой пост N138. Там написано почему, и дан алгоритм как это обойти.
Коротко: У некоторых бит нет любимого значения, или оно не очень любимое. Тут нужно по байту EEPROM на бит ОЗУ (ну или хоть по 4 бита). В этом байте знаковое число, соответствующее любимому состоянию бита за 127 экспериментальных включений (бит=0 -> прибавляем 1). В зависимости от реального состояния (бит=0 считаем положительным числом =1, бит=1 считаем отрицательным числом =-1) это число или прибавляется или вычитается (- на - даёт +) из накопителя. Если этот накопител8е было короткое.
А писать в биты инверсный знаu044C получился <0 - выключенк числа из EEPROM при включении нужно...
Но это всё сложно, хотя и теоретически правильно. Моя программа в предыдущем моём посте делает всё тоже самое, но проще...

Кстати, никто не попробовал?

Ну Мегафон! Ну TCP/IP! Ну как они такого добиваются?!? Уже 2 из 3 пакетов в ошибкой CRC пошли... Это мы на своём сервере в пакеты, именно для таких случаев, дополнительно свою CRC добавляем... А родное TCP/IP CRC видимо замечательно совпадает... Называется контроль целостности данных... Простите за оффтоп. Не могу нормально свой пост из-за этого отправить. Вот так д.б. (если ещё получится):
Работать не будет.
Прочтите мой пост N138. Там написано почему, и дан алгоритм как это обойти.
Коротко: У некоторых бит нет любимого значения, или оно не очень любимое. Тут нужно по байту EEPROM на бит ОЗУ (ну или хоть по 4 бита). В этом байте знаковое число, соответствующее любимому состоянию бита за 127 экспериментальных включений (бит=0 -> прибавляем 1). В зависимости от реального состояния (бит=0 считаем положительным числом =1, бит=1 считаем отрицательным числом =-1) это число или прибавляется или вычитается (- на - даёт +) из накопителя. Если этот накопитель получился <0 - выключение было короткое.
А писать в биты инверсный знак числа из EEPROM при включении нужно...
Но это всё сложно, хотя и теоретически правильно. Моя программа в предыдущем моём посте делает всё тоже самое, но проще...
stells
Цитата(galjoen @ Jan 18 2010, 23:42) *
Работать не будет.
Прочтите мой пост N138. Там написано почему, и дан алгоритм как это обойти.

в посте 138 речь идет о регистрах ОЗУ, а РОН ведут себя по-другому. по крайней мере такое впечатление сложилось
Цитата(VladislavS @ Jan 18 2010, 23:09) *
Ууууу.... 300-е сообщение темы, а вы еще верите, что все биты могут совпасть???

пока верю, а где написано опровержение? smile.gif

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

это у меня по питанию кондер большой, надо шунтировать

вот это да! большой кондер у меня у меня по входу 7805. я его зашунтировал, а РОН все-равно помнит записанное значение. на выходе 7805 стоит 0,1мкФ, зашунтировал и ее 10кОм - РОН помнит значение примерно 1с - то, что надо biggrin.gif

дааа... и стоило из-за этого 300 постов писать? lol.gif
stells
напряжение на контроллере падает так же, как приводил VladislavS еще в самом начале темы:
Нажмите для просмотра прикрепленного файла
цена деления 100мс/1В. видно, где срабатывает BOD (1,8В) и затем идет плавный спад. но видимо РОН хватает где-то 100-200мВ, чтобы удержать значение
ARV
мне кажется, алгоритм готов... протестировал на 2 разных мега32 и на одной мега8 - естественно, все "любимые" значения РОН разные, но алгоритм настраивается на них сам и работает. если есть возможность - протестируйте на возможно большем числе камней...
Код
// переменные в неинициализируемой области ОЗУ, чтобы start-up не обнулил
volatile __attribute__((section(".noinit"))) uint8_t mem;
volatile __attribute__((section(".noinit"))) uint8_t mcucsr;

// функция выполняется сразу после сброса еще до start-up кода Си
__attribute__((section(".init0"), naked)) void get_r10(void){
    register uint8_t r2 asm("r2");
    register uint8_t r3 asm("r3");
    register uint8_t r4 asm("r4");
    register uint8_t r5 asm("r5");
    register uint8_t r6 asm("r6");
    register uint8_t r7 asm("r7");
    mcucsr = MCUCSR;
    MCUCSR = 0;
    mem = r2 + r3 + r4 + r5 + r6 + r7;
}

int main(void){
    uint8_t mode = eeprom_read_byte((void*)12);
    // отладочный вывод
    printf_P(PSTR("\nSUM=%u EEPROM=%u"),mem, mode);
    if(mode == 0xFF){
        // первый старт после прошивки
        if(mcucsr & _BV(PORF)){
            // если холодный сброс - запоминание суммы в качестве критерия короткого отключения
            printf_P(PSTR("\nFirst run - INIT."));
            eeprom_write_byte((void*)12, mem);
        } else {
            // при теплом сбросе ничего не надо делать
            printf_P(PSTR("\nWarm reset - nothing to do"));
        }
    } else {
        // при любом последующем включении питания
        if(mem > mode){
            // с течением времени регистры заполняются единицами, поэтому сумма растет
            printf_P(PSTR("\nOld mode - long power off"));
        } else {
            // если сумма меньше, чем была - запомним ее в качестве критерия
            eeprom_write_byte((void*)12, mem);
            printf_P(PSTR("\nNew mode - short power off"));
        }
    }
    // очищаем регистры
    asm volatile(
            "clr r0 \n"
            "clr r1 \n"
            "clr r2 \n"
            "clr r3 \n"
            "clr r4 \n"
            "clr r5 \n"
            "clr r6 \n"
            "clr r7 \n"
            );
    // ждем отключения
    while(1);
}

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

алгоритм с потенциально слабым местом - суммирую в байт, т.е. если регистры будут содержать слишком много единиц, то результат будет случайным - но это лечится, сами понимаете, элементрано smile.gif да и фонарик - не атомная бомба, если иной раз сработает не так - не страшно, никто и не заметит (юзер и забудет давно, в каком режиме выключал его, чтобы возмутиться тем, что он включился в новом режиме).
akken
Цитата(stells @ Jan 19 2010, 09:39) *
напряжение на контроллере падает так же, как приводил VladislavS еще в самом начале темы:
Нажмите для просмотра прикрепленного файла
цена деления 100мс/1В. видно, где срабатывает BOD (1,8В) и затем идет плавный спад. но видимо РОН хватает где-то 100-200мВ, чтобы удержать значение


Когда-то давно для процессора К1820 потребовалось ОЗУ на 4 бита. Была применена м\с
К561ие4 с подпиткой от элемента СЦ-21 через 1 Мом при рабочем питании 5 Вольт.
Так вот, эта конфигурация позволяла сохранять состояние выходов счетчика при отключении питания, хотя напряжение на ножке питания опускалось до 500 мВ.
Причем, при отключении питания 5 вольт выходы становились в одинаковое состояние
( 1 или 0 - не помню), но при подаче питания восстанавливалось ранее записанное состояние со 100% гарантией. Ток потребления в этом случае еле -еле заставлял сдвинуться стрелку тестера на пределе 50 мкА.
stells
я корректнее провел эксперимент - отключил кондер на входе 7805, т.е. в отсутствие питания контроллер питался только от кондера 4,7мкФ на выходе 7805. нифига РОН не сохраняет долго значение... сотни миллисекунд от силы sad.gif
МП41
Очевидно, сохранность данных в РОН зависит от остаточного напряжения на конденсаторе. 7805 не шунтирует выходом конденсатор?
stells
Цитата(МП41 @ Jan 19 2010, 14:18) *
Очевидно, сохранность данных в РОН зависит от остаточного напряжения на конденсаторе. 7805 не шунтирует выходом конденсатор?

диод стоит sad.gif
МП41
А если попробовать хранить режим в каком-нибудь регистре, например, в OSCCAL или в другом, который не РОН?
stells
Цитата(МП41 @ Jan 19 2010, 14:44) *
А если попробовать хранить режим в каком-нибудь регистре, например, в OSCCAL или в другом, который не РОН?

так они все сбрасываются при включении
Александр Куличок
Прошелся по ссылкам, приведенным в 120-м сообщении, автором коего является топикстартер, и по одной из них нашел алгоритм переключения режимов работы даного драйвера.
Может я чего-то там не так понял, но время выключения в нем не фигурирует:
Цитата
16-mode consolidated into 3 groups:
Low (10%) - Mid (35%) - High (100%) - Strobe - SOS
Low (10%) - Mid (35%) - High (100%)
Low (10%) - Mid (35%) - High (100%) - Special Police Type Strobe - Slow Strobe (3Hz) - Super Slow Strobe (1Hz) - SOS

- To switch mode, stay in any mode for no more than 2 seconds then switch off. The next time the light is turned on it will enter the next mode.
- To change mode group, stay in the LOW mode for about 4 to 5 seconds, wait for a quick flash response then switch off. The next time the light is turned on it will enter the next group of modes. If you do not turn off after the initial quick flash response, the flashlight will quickly flash once more after 2 seconds meaning that mode group switch has been cancelled.

мой вольный перевод:
- если хотим запомнить режим, то нам надо на него переключиться и почти сразу (<2 c) выключить питания. Последующие включения будут стартовать с сохраненного режима.
- если хотим поменять группу режимов, то после переключения в режим LOW через 4-5 сек дождаться вспышки и выключить фонарик. В противном случае через время >2c будет еще одна короткая вспышка, которая сгнализирует о том, что смена группы режимов не состоялась.

P.S. Вот только режимов приведено не 16, а 15. А уникальных - и вовсе 7 или 8. Хотя выключенное состояние - тоже режим smile.gif (под номером 0, как в анектоде о том, как программист сумки считал).
Rst7
Мда. 300+ постов. Один(!) человек, который прочитал мануал.

Посыпаю голову пеплом.
SysRq
Этот алгоритм уже предлагали в #106.

Перевод
Цитата(Александр Куличок @ Jan 20 2010, 00:14) *
- если хотим запомнить режим, то нам надо на него переключиться и почти сразу (<2 c) выключить питания. Последующие включения будут стартовать с сохраненного режима.
не верен.

Цитата
- To switch mode, stay in any mode for no more than 2 seconds then switch off. The next time the light is turned on it will enter the next mode.
"Чтобы переключить режим, оставить в любом режиме не более 2 секунд, и затем выключить. При следующем включении оно переключит режим."

Цитата(Rst7 @ Jan 20 2010, 02:00) *
Мда. 300+ постов. Один(!) человек, который прочитал мануал.
За неимением чего умного сказать, я google мучал по поводу этих фонариков, и инструкции эти видел. Ничего писать не стал, ибо из темы выходит, что эти инструкции или не про этот фонарик, или автор темы чего-то недоговаривает (о времени включения никто ничего не спрашивал)...
(На форумах поддержки есть еще собственная разработка пользователей для подобного фонарика на PIC. Утверждается, что детектирование кратковременного отключения реализуется посредством BOD.)
alevnew
Цитата(SysRq @ Jan 20 2010, 05:03) *
Этот алгоритм уже предлагали в #106.

Перевод
не верен.

"Чтобы переключить режим, оставить в любом режиме не более 2 секунд, и затем выключить. При следующем включении оно переключит режим."


lol.gif
Ну отпад. 300 постов. lol.gif
Предположение, что считается время ВКЛЮЧЕНИЯ я также предлагал в 141 посту, и простейший алгоритм, но он был отвергнут smile.gif :
http://electronix.ru/forum/index.php?s=&am...st&p=702833

Цитата
Мда. 300+ постов. Один(!) человек, который прочитал мануал.

Мануалы настоящие любители трудностей читают только в состоянии крайнего отчаяния. Это не наш метод smile.gif
ARV
Цитата(alevnew @ Jan 20 2010, 07:23) *
Мануалы настоящие любители трудностей читают только в состоянии крайнего отчаяния. Это не наш метод smile.gif
настоящее отчаяние возникает после 600? biggrin.gif видимо, здесь не читатели мануалов собрались, а писатели...
VladislavS
Цитата(Rst7 @ Jan 20 2010, 02:00) *
Мда. 300+ постов. Один(!) человек, который прочитал мануал.

Я счастлив, что он прочитал мануал от чего-то, что в руках не держал. А как быть с фонарями, которые есть у меня?

Вот вам программа для алгоритма по коротким включениям:
Код
#include <ioavr.h>
#include <intrinsics.h>

volatile __regvar __no_init unsigned char mode @ 15;
volatile __regvar __no_init unsigned char power_low_counter @ 14;
volatile __regvar __no_init unsigned int adc_c @ 12;

__no_init __eeprom unsigned char ee_mode;

#ifdef __cplusplus
extern "C" {
#endif
char __low_level_init()
{
  CLKPR|=(1<<CLKPCE);
  CLKPR=3; //Снизим тактовую частоту до 9.6/8 МГц
  
  DDRB=(0<<DDB5)|(0<<DDB4)|(0<<DDB3)|(0<<DDB2)|(1<<DDB1)|(1<<DDB0);
  PORTB=(0<<PORTB5)|(0<<PORTB4)|(0<<PORTB3)|(0<<PORTB1)|(0<<PORTB0);
  
  ACSR=(1<<ACD); //Analog Comparator Disable
  DIDR0=(1<<ADC0D)|(0<<ADC1D)|(1<<ADC2D)|(1<<ADC3D)|(1<<AIN1D)|(1<<AIN0D);
  PRR=(1<<PRTIM0)|(0<<PRADC);
  
  ADMUX=(1<<REFS0)| 1; // Vref=1.1V , ADC1
  ADCSRA=(1<<ADEN)|(0<<ADSC)|(1<<ADATE)|(0<<ADIF)|(1<<ADIE)|(0<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
  ADCSRB=0;      
  
  return 1;
}
#ifdef __cplusplus
}
#endif

#pragma vector=ADC_vect
__interrupt void ADC_Interrupt(void)
{  
  switch(mode)
  {
    case 0: // Яркость 100%
      if(ADC<600) power_low_counter++; else power_low_counter=0;
      if(power_low_counter>100) { ee_mode=0; mode=2; power_low_counter=0; }
      PORTB|=(1<<PORTB1);
      PORTB|=(1<<PORTB0);      
      break;
    case 1: // Яркость 40%
      if(ADC<600) power_low_counter++; else power_low_counter=0;
      if(power_low_counter>100) { ee_mode=1; mode=2; power_low_counter=0; }
      PORTB|=(1<<PORTB0);
      PORTB&=~(1<<PORTB1);
      break;
    case 2: // Яркость 4%
      if(ADC<558) power_low_counter++; else power_low_counter=0;
      if(power_low_counter>100) { ee_mode=2; mode++; }
      PORTB&=~(1<<PORTB1);
      PORTB|=(1<<PORTB0);
      __delay_cycles(10);      
      PORTB&=~(1<<PORTB0);
      break;
    default: // Защитное выключение
      PORTB&=~(1<<PORTB1);
      PORTB&=~(1<<PORTB0);
      MCUCR=(1<<SE)|(2<<SM0); //Power Down
      __sleep();
      break;
  }
};

int main( void )
{  
  __delay_cycles(100000);
  adc_c=0;  
  mode=ee_mode;
  switch(mode)
  {
    case 0:
    case 1:
      ee_mode++;
      break;
    default:
      mode=2;      
      ee_mode=0;
      break;
  }  
  power_low_counter=0;

  ADCSRA|=(1<<ADSC);  
  __enable_interrupt();
  for(;;)  
  {  
    MCUCR=(1<<SE)|(1<<SM0); //Sleep
    __sleep();
    if(adc_c<16000) adc_c++;
    else
    {
      if(adc_c==16000)
      {
        __disable_interrupt();
        PORTB&=~(1<<PORTB1);
        PORTB&=~(1<<PORTB0);
        adc_c++;        
        ee_mode=mode;
        __delay_cycles(75000);
        __enable_interrupt();
      }
    }  
  }
}
stells
VladislavS, Вы драйвера так и не зашунтировали? хотелось бы уже отбросить и забыть про этот вариант. правда в какую сторону дальше думать - непонятно.
а алгоритм ARV, как я понял, так никто и не попробовал?
Rst7
Цитата
А как быть с фонарями, которые есть у меня?


И тем не менее. Несмотря на некоторую избитость этих слов, проверьте внимательно, может все-таки время включения (а не выключения) пляшет?
Petka
Цитата(Rst7 @ Jan 20 2010, 09:44) *
И тем не менее. Несмотря на некоторую избитость этих слов, проверьте внимательно, может все-таки время включения (а не выключения) пляшет?

а ещё лучше выложите видео на какой-нибудь youtube.
ARV
Цитата(stells @ Jan 20 2010, 09:19) *
а алгоритм ARV, как я понял, так никто и не попробовал?
попробовал... unsure.gif я сам... боюсь, что мои эксперименты с STK500 давали эффект все же за счет остаточного напряжения на емкостях по питанию - там их куча... когда я стал передергивать питание перемычкой V.TARGET - эффект исчез sad.gif это был выстрел в молоко sad.gif
@Ark
Не совсем понятно, что, в конечном итоге, желает автор данной темы.
Переключение режимов по времени включения питания - сложности никакой не представляет. Алгоритмы переключения по времени выключения - также были предложены. Причем, вполне работоспособные, в том числе - в рамках приведенной схемы фонарика. Хотите непременно узнать, как работает данное конкретное "китайское чудо"? А оно Вам нужно?
Пока только видно настойчивое желание реализовать переключение по "любимому состоянию" регистров. IMHO, это метод изначально "кривой" и ненадежный, и не заслуживает того, чтобы на него опираться. По крайней мере, я бы никогда так делать не стал. Тем более в серийных изделиях. Ну, если автор темы хочет, то как говорится - флаг в руки. smile.gif
stells
Цитата(ARV @ Jan 20 2010, 11:40) *
мои эксперименты с STK500 давали эффект все же за счет остаточного напряжения на емкостях по питанию - там их куча...

да, экспериментировать проще на конкретной платке, я из-за питания тоже накололся, пришел к выводу, что за сотню-другую миллисекунд и РОН, и ячейки ОЗУ теряют значение и принимают любимое - единицы секунд на этом эффекте не поймать

Цитата(@Ark @ Jan 20 2010, 11:42) *
Не совсем понятно, что, в конечном итоге, желает автор данной темы.
Переключение режимов по времени включения питания - сложности никакой не представляет. Алгоритмы переключения по времени выключения - также были предложены. Причем, вполне работоспособные, в том числе - в рамках приведенной схемы фонарика. Хотите непременно узнать, как работает данное конкретное "китайское чудо"? А оно Вам нужно?

так-то оно так, но очень любопытно все-таки узнать, как реализовано переключение по времени отключения в оригинальной прошивке
ARV
Цитата(stells @ Jan 20 2010, 11:58) *
так-то оно так, но очень любопытно все-таки узнать, как реализовано переключение по времени отключения в оригинальной прошивке
а вот мне чисто из академического интереса хотелось бы получить надежный алгоритм решения задачи, даже не алгоритм, а конкретный код, применимый всегда или почти всегда smile.gif главное, одинаковый результат, а процесс его достижения не обязательно должен совпадать...
@Ark
Цитата
но очень любопытно все-таки узнать, как реализовано переключение по времени отключения в оригинальной прошивке

Точно это можно узнать, только считав прошивку. Либо спросить непосредственно у автора. smile.gif
В любом случае, imho, метод будет основан на RC-цепочке с постоянной времени порядка 1с, в том или ином виде.
Других методов (если не считать "просадку" батареи и саморазогрев) я что-то не вижу. Может кто предложит?
stells
Цитата(ARV @ Jan 20 2010, 12:11) *
а вот мне чисто из академического интереса хотелось бы получить надежный алгоритм решения задачи

ну для АВР с делителем на питании и внутренним АЦП алгоритм понятен и опробован. он сбоил, но видимо потому, что контроллер отключался спонтанно. если ловить момент отключения питания и оставлять кондер УВХ в одинаковом состоянии, то сбои исчезнут
МП41
Может заняться вопросом поиска сколупывающего прошивку устройства? wink.gif
Александр Куличок
Цитата(SysRq @ Jan 20 2010, 02:03) *
Этот алгоритм уже предлагали в #106.
...
Перевод не верен.

106-пост начинается со слов "Я бы сделал так...". Я же привел алгоритм с сайта, на котором продается данный драйвер, а не привел свою собственную реализацию алгоритма.
А дословно я и не переводил. Просто пересказал принцип. Хотя соглашусь, что между "переключить" и "оставить" в данном случае есть небольшая разница.

Цитата(SysRq @ Jan 20 2010, 02:03) *
... эти инструкции или не про этот фонарик, или автор темы чего-то недоговаривает (о времени включения никто ничего не спрашивал)...

Цитата(VladislavS @ Jan 20 2010, 07:35) *
Я счастлив, что он прочитал мануал от чего-то, что в руках не держал. А как быть с фонарями, которые есть у меня?

2 VladislavS:
Я и не утверждал, что это алгоритм именно вашего драйвера. Я привел алгоритм драйвера по указанной ссылке (которых схемотехнически полностью повторяет Ваш)
Но, честно говоря, я сомневаюсь, что для данного девайса китайцы наштамповали кучу разных прошивок. Хотя кто их знает. Китайцев много smile.gif
Еще есть вероятность того, что писатели мануала ошиблись.

И все-таки, попробуйте по приведенному алгоритму попереключать. В частности, сменить группу режимов. Если группа менятся не будет, то прошивка точно не та.
VladislavS
Нет там никаких групп режимов...
А что-то попробовать смогу только посоле того как вот эту штуку починю.
A-50
Александр Куличок
Цитата
Нет там никаких групп режимов...
А что-то попробовать смогу только посоле того как....

Поражает Ваша категоричность. Еще не пробывали, а уже заявляете, что групп нету.
VladislavS
Ну да, это мой первый фонарь, первый драйвер и осциллограф я уже один раз видел на выставке... Пойду "Hello, World!" писать.
Александр Куличок
Цитата
Ну да, это мой первый фонарь, первый драйвер и осциллограф я уже один раз видел на выставке... Пойду "Hello, World!" писать.

bb-offtopic.gif
Излишняя самоуверенность здесь ни к чему. Тем более, что уже был прецедент, когда Вы на словах описали схему, которая "на 200% соответствует моему словеcному описанию". Тем не менее, большинство учасников форума представляла ее немного по-иному.
То же касается и вашего предположения о том, что я недооценил Вас как специалиста. Хотя я с Вами лично и не знаю и в форуме Вы активно себя не проявляли.
Тем не менее, для меня, по-большому счету, все равно, сколько Вы имеете фонариков, тестеров, осциллографов и кандидатом каких наук Вы являетесь. Я исхожу из того, что право на ошибку/недосмотр/неправильную версию имеет каждый. И не стОит это рассматривать как недооценку Ваших знаний и умений с моей стороны.
VladislavS
Обидны ваши слова. Ближайшие две недели минимум у меня не получится заняться темой топика.
Дабы не перессориться всем за это время - прикрою я его... Извините.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.