Перейти к содержанию
    

slanted

Участник
  • Постов

    159
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные slanted


  1. Компилятор на 99.9% не при чём. Вы скорее всего забыли объявить ваши bool-функции в том модуле, откуда вы их вызываете. В этом случае вступает в силу неявное объявление (implicit declaration), в котором у вызываемой функции подразумевается тип int.

     

    Код покажите.

  2. On 7/14/2021 at 8:15 PM, Сергей Борщ said:

    wdt_count у вас 16-битная, если между чтением младшего и старшего байта возникнет прерывание, в котором младший байт изменится с 0xFF на 0 (а старший увеличится) - ваша программа может дать сбой. Поэтому читать wdt_count надо либо с запрещенными прерываниями, либо дважды и проверять старший байт считанного значения (если он равен - использовать последнее значение, если не равен - считать еще раз и снова сравнить).

    Сергей, там изначальная версия (от 28 июня, см выше по треду) на которую я отмашку дал, так и написана. Просто это потом куда-то потерялось. Но даже и в таком виде, маловерятно что это причина глюков — после выхода из sleep процессор СНАЧАЛА выполнит прерывание, потом всё остальное, и учитывая что прерывание редкое, крайне вероятно что wdt_count считается одним куском. Да это грязно и по уму надо обкладывать это место cli/sei (как и было сделано), но то что гонка в данных обстоятельствах именно здесь я слабо верю.

  3. Откомментировал прямо в коде (SL). В любом случае это первое что я буду смотреть как соберу свою железку, т.к. то что есть мне как-то в целом не нравится.

    void setup() {
    
        noInterrupts();
        info.service = MCUSR; // причина перезагрузки
        MCUSR = 0;            // без этого не работает после перезагрузки по watchdog
                              // SL: да, это требуется для выключения WDT (см 8.5.2/bit 3 wde в даташите)
        wdt_disable();        // а нужно ли тут, если у меня код быстро дойдёт до инициализации watchdog?
                              // SL: по хорошему да, потому что мы не знаем сколько займёт инициализация.
      			  //     Если там еще и бутлоадер будет, к примеру, то это надо прямо там выключать.
      	 		  //     Надо это еще раз продумать.
        interrupts();
    
        set_sleep_mode( SLEEP_MODE_PWR_DOWN ); // достаточно же 1 раз сделать?
      					   // SL: В теории да, но мне встречалась рекомендация перезаписывать
      					   //     эти биты при каждом входе в sleep mode
    
        wakeup_period = WAKEUP_PERIOD_DEFAULT;
        
        .....
    }
    
    
    
    void loop() {
        power_all_disable(); 
        
        //NoInterrupts не нужно? т.к. в wdt_enable есть ассемблерная команда cli
        // SL: и interrupts() тоже не нужно, в wdt_enable есть сладкая парочка
        //     in tmp, SREG / out SREG, tmp, т.е. флаг прерывания оно восстановит
        //     как было
        wdt_enable(WDTO_250MS); 
        interrupts(); 
    
        wdt_count = 0;
        while ((wdt_count < wakeup_period) && !button.pressed())
        {        
            counting();
            WDTCR |= _BV(WDIE);  //пока не понял, обязательно ли здесь или можно после wdt_enable раз в WDT_vect есть. без этого не работает.
          			     //SL: WDIE нужно обновлять при каждом срабатывании таймера, потому что аппаратура его сбрасывает.
          			     //    Возможно, она его сбрасывает _при_выходе_ из прерывания, поэтому установка флага там не имеет эффекта.
            sleep_mode();
         }
    
         power_all_enable();
         // Далее: я не отключаю watchdog, для надежности. wdt_reset() вызывается в button.wait_release() где я могу долго ждать пока пользователь отпустит кнопку.
    
        ... //взаимоотношения с ESP
    }
  4. 16 minutes ago, dontsov said:

    питание теперь шире.

    Там другая беда (если я правильную версию посмотрел): земля к тиньке подключена ОЧЕНЬ длинным проводом, и блокировочный конденсатор в такой  ситуации бесполезен. И радиочастотная схема рядом.

     

    18 minutes ago, dontsov said:

    счетчики надо асинхронно с опросом по i2c.

    Ну, э.... примитивный параллелизм несложно делается. Таймер же есть и не один.

  5. Отловить ВСЕ глюки не удастся никогда, это аксиома. Я предлагаю зайти с другой стороны: с обеспечения возможности перешивки по воздуху.

     

    А стенд... ну чо стенд. Вторая ардуина рядом и пара транзисторов для имитации сухого контакта.

  6. А, и да, чтоб два раза не вставать. Не очень критично, но всё же.

     

    По поводу этого каунтера: переполнение signed int — это undefined behavior, поэтому очередной чрезмерно оптимизирующий компилятор может что-нибудь такое решить и, к примеру, вообще выкинуть этот счётчик. Поэтому я обычно делаю все подобные счётчики unsigned, считающими вверх, и не сбрасываю их никогда, только сравниваю при ожидании. Заодно это даёт глобальный счётчик тиков, который можно переиспользовать где-нибудь еще. Примерно так:

    volatile uint16_t wdt_count;
    
    ISR(WDT_vect)
    {
      ++wdt_count;
    }
    
    {
      // цикл ожидания
      uint16_t const now = wdt_count;
      while ( (wdt_count - now) < wakeup_period )
      {
        // работаем
        // спим
      }
    }

     

  7. Я просто забыл что они в avr-libc тоже есть :)

    Счас посмотрел — вполне адекватно написано, можно и их.

     

    PS. Одно последнее замечание — если у нас схема которая должна работать годами, то вочдог все же будет не лишним. Поэтому я бы оставил в WDT_vect остаётся только wdt_count--, а прерывание взводить только перед засыпанием:

    while ( wdt_count > 0 )
    {
      ...
        wdt_reset();
        WDTCR |= (1<<WDIE);
        interrupts();
        sleep_mode();
    }

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

  8. Я бы делал немного не так.

    setup()
    {
      cli();
      info.service = MCUSR;
      // отключаем WDT
      MCUSR = 0;
      WDTCR = (1<<WDCE) | (1<<WDE);
      WDTCR = 0;
      sei();
      
      // вся остальная инициализация
      ...
    }
    
    loop()
    {
      cli();
      wdt_reset();
      WDTCR = (1<<WDCE) | (1<<WDE);
      WDTCR = (1<<WDCE) | (1<<WDE) | (1<<WDIF) | (1<<WDIE)
        	  | (1<<WDP2) | (0<<WDP1) | (0<<WDP0);
      sei();
    }

    Вообще при любых действиях с флагом IE (это относится не только к WDT, а к любой периферии вообще) рекомендуется этим же оператором ставить соответствующий IF. Это гарантирует то что соответствующее прервыание будет подавлено на момент смены конфигурации.

  9. Да, работа с вочдогом выглядит странно. Если хочется его именно выключить, то надо не просто WDTCR=(1<<WDCE), а как в даташите написано:

    WDTCR = (1<<WDCE)|(1<<WDE);
    WDTCR = 0;

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

     

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

  10. 19 minutes ago, iiv said:

    в 4-ом кикаде еще нет

    Им еще кто-то пользуется?

     

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

  11. 2 hours ago, iiv said:

    спасибо! Но тут на каждую компоненту так делать же надо, я именно это и хотел избежать, или я Вас не понял как именно это делается.

    В том-то и дело что не на каждую! Опция называется "change footprint with identifier" и меняет все футпринты с данным наименованием.

  12. В пятерке все очень просто: выделяете компонент, далее Properties (E), Change footprint и там, собственно, есть фильтр по имени, значению, типу футпринта...

  13. 14 minutes ago, Егоров said:

    Излучает в общем-то конденсатор из двух обкладок.

    Излучает, но один случай когда у нас земля (вторая обкладка) распределена неравномерно в окружающем пространстве и E-поле, соответственно, везде; и совсем другое дело когда мы подсовываем вторую обкладку искуственно, на очень малом расстоянии, концентрируя тем самым поле там.

     

    О чём говорит rkit я, честно говоря, не очень понял. Токи — это h-мода, с ними отдельное разбирательство и в сети на самом деле масса руководств как сделать правильно в этом отношении.

     

    Ну и чтобы не быть голословным: на щуп осциллографа (x1, 1MΩ 20pF) просто лежащий в десятке сантиметров рядом наводится замечательный меандр порядка 10mVp-p. Если туда зажать даже небольшую пластинку текстолита, то... зависит от положения конечно, но до вольта может быть.

     

    45 minutes ago, Егоров said:

     Светильник - не тот объект где нужно сильно озаботиться помехами.

    А если их несколько?

    1 minute ago, rkit said:

    Может стоить изучить физику помех, прежде чем заниматься борьбой с ними?

    @rkit, перестаньте пожалуйста говорить загадками. Токи в данном случае отдельная проблема, не имеющая отношения к обсуждаемому. Как с ней бороться известно всем.

  14. 21 minutes ago, Егоров said:

    Так у нормальных людей к теплоотводу именно так и подключается, а не к земле.. Все транзисторы в SMD корпусах не доказательство?
     Да вроде не так мрачно все с помехами.  разве что узел используется в какой-то особо чувствительной к помехам аппаратуре.

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

  15. Доброго всем.

     

    Я тут потихоньку ваяю светодиодный DC-DC boost на XL6006 (даташит), и у него обнаружилась одна неприятная особенность — фланец корпуса, через который и осуществляется весь теплосброс, у него подключен не к GND (как у всех нормальных людей), а к стоку внутреннего MOSFET. Соответственно, на плате появляется нехилых размеров остров (порядка 1.5-2 кв дюйма) с прямоугольным напряжением амплитудой вольт так 50 и частотой под 200КГц.

     

    Возникают два вопроса: 1) не загадит ли он помехами всю округу; 2) как вообще с подобным жить? По второму вопросу пока думается, что нужно прикрутить его через тонкую термопрокладку к металлоконструкциям корпуса или радиатору, и далее тщательно соединить их с нулём схемы прямо по периметру полигона. При этом сколько-то тока будет, конечно, бесполезно утекать в землю, но прикидочно там не больше 10мА.

     

    Короче говоря, я не сильно перестраховываюсь?

     

    PS. Демоплата, если вдруг кому любопытно.

  16. У меня вот дошли руки сегодня поизучать что к чему... я не впечатлен мягко говоря. Там дичайший оверинжиниринг, всё тоже самое можно было решить в разы проще, а уж дешевле.... И да, вылечить это никак, только делать полностью новую версию железа с потерей совместимости; автор это вероятно тоже понимал, поэтому и забил скорее всего.

     

    Два канала там очень смешные, могут только попеременно работать.

     

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

     

    Короче, если делать, то делать с нуля. По уму, модульно, etc, etc.

     

    Остается только вопрос как организоваться :) Прямо так брать и тащить я лично не готов.

  17. 6 выводов у мотора — объедините просто середины обмоток.

     

    Насчет транзисторов: надо еще за бетой следить, в вашей схеме она должна быть не меньше 70 (исходя из максимального тока атмеги в 20мА), так что либо искать соответствующий транзистор, либо умощнять имеющиеся. Возьмите лучше какой-нибудь распространенный logic level mosfet, например IRLZ44n. Он здесь избыточен, зато вы его точно не спалите.

×
×
  • Создать...