Jump to content

    

dontsov

Участник
  • Content Count

    132
  • Joined

  • Last visited

Everything posted by dontsov


  1. @Сергей Борщ спасибо! Я вчера поучаствовал в долгой дискуссии в которой объяснили (и я понял и признал) насколько у меня «французский с Нижегородским» в коде.. ахах Буду рефакторить. Вообще, если начать понимать, что написал, можно убрать половину кода. Мда. Я до сих пор удивлен, насколько мало находится примеров с watchdog. И те без комментариев. Вот думаю насколько целесообразно переписать с нуля на регистрах всё.
  2. @Сергей Борщ @jcxz У меня прерывание после sleep... Других нет.
  3. А как это сделать?
  4. Хм… атомарного не уверен… а где это можно узнать? да, uint32_t здорово увеличивают память
  5. Да, в последней версии сделали uint32_t его! https://github.com/dontsovcmc/waterius/tree/dev
  6. @slanted wdt_enable в setup убрал. Посмотри, пожалуйста: https://github.com/dontsovcmc/waterius/tree/dev
  7. Все таки зависает прошивка. Не понятно отчего. Да, она не перезагружается по watchdog аварийно. Тему продолжил тут:
  8. Я попробовал имитировать задержку в коде, чтобы сработал watchdog на перезагрузку - он срабатывает, но плата уходит в зависание. Кажется потому что не выставлял MCUSR = 0. @slanted: Вот такой код корректно перезагружает если wdt_reset не наступит за 250мс: volatile uint32_t wdt_count; ISR( WDT_vect ) { ++wdt_count; WDTCR |= _BV(WDIE); } void setup() { noInterrupts(); info.service = MCUSR; // причина перезагрузки MCUSR = 0; // без этого не работает после перезагрузки по watchdog wdt_disable(); // а нужно ли тут, если у меня код быстро дойдёт до инициализации watchdog? interrupts(); set_sleep_mode( SLEEP_MODE_PWR_DOWN ); // достаточно же 1 раз сделать? wakeup_period = WAKEUP_PERIOD_DEFAULT; ..... } void loop() { power_all_disable(); //NoInterrupts не нужно? т.к. в wdt_enable есть ассемблерная команда cli wdt_enable(WDTO_250MS); interrupts(); wdt_count = 0; while ((wdt_count < wakeup_period) && !button.pressed()) { counting(); WDTCR |= _BV(WDIE); //пока не понял, обязательно ли здесь или можно после wdt_enable раз в WDT_vect есть. без этого не работает. sleep_mode(); } power_all_enable(); // Далее: я не отключаю watchdog, для надежности. wdt_reset() вызывается в button.wait_release() где я могу долго ждать пока пользователь отпустит кнопку. ... //взаимоотношения с ESP }
  9. @slanted последняя версия пока не зависала. но и предыдущая на столе 3 месяца назад не висла.. https://github.com/dontsovcmc/waterius/commit/612b8c626a5d018d566dfa210f00ac661e73affe#diff-9f275c81ac6d42b2d0a1caa9dee157db9fa36a1193217286fb083b66fb933914
  10. Мы там как то лихо потискали регистры прерываний , поэтому думаю дело в софте.
  11. @Vasily_ спасибо! я ищу специалиста, который найдёт зависания. @slanted :( , значит нужно перетрассировать схему ещё. а помехи могут привести к зависанию?
  12. @Vasily_ вы меня пугаете :) да, питание теперь шире. Фото не обновил на сайте(. @mcuprog хм разве? В разработке ПО всегда быстрее найти ошибку и исправить, чем переписывать с нуля и нанести новых ошибок. Разве с embedded не так же? @slanted ага. Только замыкать счетчики надо асинхронно с опросом по i2c. Для пущей реалистичности. Хотя если у меня на вторые сутки зависал код лёжа на столе…
  13. Мне нужна надежная прошивка, а моделированием или стендом это будет достигаться не важно :). Железо вышлю.
  14. Аудит или доработка (при необходимости) прошивки attiny Требуется проверить прошивку attiny. Требования: надежность работы, отсутствие зависаний, аварийная перезагрузка. Хочется понимать, сколько ресурсов она потребляет, стек, есть ли слабые места. Какой стоит собрать стенд для тестирования прошивки? framework: ATTinyCore watchdog для подсчёта импульсов i2c для общения с внешним миром. Оплачиваемо. Возможна работа по договору.
  15. Спасибо огромное за помощь! Сутки работают.. Кажется нужно сделать стенд, регулярно дрючащий attiny в кнопку и входы, чтобы проверять такие ситуации =(
  16. Огромное спасибо!! За wdt_count тоже - люблю когда behavior defined! Корректно, я понял вас? volatile uint16_t wdt_count; ISR( WDT_vect ) { ++wdt_count; } void setup() { noInterrupts(); info.service = MCUSR; wdt_disable(); interrupts(); .... } void loop() { power_all_disable(); // Отключаем все лишнее: ADC, Timer 0 and 1, serial interface set_sleep_mode( SLEEP_MODE_PWR_DOWN ); // Режим сна noInterrupts(); wdt_enable(WDTO_250MS); interrupts(); // Цикл опроса входов // Выход по прошествию wakeup_period_min минут или по нажатию кнопки // ONE_MINUTE = 240 для 250мс for (uint16_t i = 0; i < ONE_MINUTE && !button.pressed(); ++i) { wdt_count = 0; while (wdt_count < info.wakeup_period_min) { noInterrupts(); if (button.pressed()) { // Пользователь нажал кнопку interrupts(); break; } else { counting(); //Опрос входов. Тут т.к. https://github.com/dontsovcmc/waterius/issues/76 wdt_reset(); WDTCR |= _BV(WDIE); interrupts(); sleep_mode(); } } } wdt_disable(); power_all_enable(); ...пробуждаемся и общаемся по i2с... }
  17. А почему не использовать готовые функции? Я их сам редко в примерах вижу - обычно все напрямую с битами работают.. Поставил работать этот вариант, 8ч полет нормальный: ISR( WDT_vect ) { wdt_count--; WDTCR |= _BV( WDIE ); } void setup() { noInterrupts(); info.service = MCUSR; //причина перезагрузки wdt_disable(); interrupts(); ... работа с EEPROM } void loop() { power_all_disable(); set_sleep_mode( SLEEP_MODE_PWR_DOWN ); noInterrupts(); wdt_enable(WDTO_250MS); WDTCR |= _BV(WDIE); interrupts(); .... LOOP wdt_count wdt_disable(); power_all_enable(); .... }
  18. Его хочется просто инициализировать для пробуждения каждые 250мс. А если так делать? wdt_enable(WDTO_250MS); WDTCR |= _BV(WDIE); interrupts(); По выходу из цикла опроса раз в сутки я делаю wdt_disable();
  19. Гипотеза, что проблема в том что я не поднимаю WDE: WDTCR = bit( WDCE ) | bit( WDE );
  20. Кажется я делаю что-то не то при сбросе watchdog.. но вопрос, почему тогда эта ошибка возникла только сейчас? (кстати я апгрейднул attinycore с 1.2.0 до 1.5.2...) сейчас откатил и поставил на тест.
  21. Прошу помощи! Счетчик импульсов (watchdog в режиме генерации прерываний) на attiny85 считает импульсы просыпаясь раз в 250мс и раз в сутки выходит из цикла и общается по i2c. Возникла проблема — очень редко attiny85 уходит в бесконечный цикл. Как я это понял: 1. Устройство не выходит на связь через 15 мин. 2. Потребление вместо 12-17мкА стабильно 670мкА (без скачков и какой то работы). Нажатие на кнопку приводит к выходу из цикла. Т.е. цикл работает - состояние кнопки проверяется. Гипотеза: ISR(WDT_vect) не вызывается. Подозрения на некорректный ресет watchdog. Проблема проявляется крайне редко и не понятно как отловить. После зависания wdt_count = 15, т.е. значению иницилизации. Эту информацию вывел только что, поэтому поймал пока 1 зависание. Странно, что потребление линией 670мкА (измеряю EFM32 Energy monitor), потому что когда Ватериус считает импульсы - там четкие скачки потребления из-за пробуждения из deepsleep. volatile int16_t wdt_count; /* Вектор прерываний сторожевого таймера watchdog */ ISR( WDT_vect ) { wdt_count--; WDTCR |= bit( WDIE ); // так делать написано в datasheet } void resetWatchdog() { MCUSR = 0; WDTCR = bit( WDCE ); // Пробуждаемся (проверяем входы) каждые 250 мс WDTCR = bit( WDIE ) | bit( WDP2 ); // 250 ms #define ONE_MINUTE 240 // 1 минута примерно равна 240 пробуждениям wdt_reset(); } inline void counting() { power_adc_enable(); //т.к. мы обесточили всё а нам нужен компаратор adc_enable(); //после подачи питания на adc if (counter0.is_impuls()) { info.data.value0++; //нужен т.к. при пробуждении запрашиваем данные info.states.state0 = counter0.state; info.adc.adc0 = counter0.adc; storage.add(info.data); } #ifndef LOG_ON if (counter1.is_impuls()) { info.data.value1++; info.states.state1 = counter1.state; info.adc.adc1 = counter1.adc; storage.add(info.data); } #endif adc_disable(); power_adc_disable(); } //Запрос периода при инициализции. Также период может изменится после настройки. // Настройка. Вызывается однократно при запуске. void setup() { .... } void loop() { power_all_disable(); // Отключаем все лишнее: ADC, Timer 0 and 1, serial interface set_sleep_mode( SLEEP_MODE_PWR_DOWN ); // Режим сна resetWatchdog(); // Выход по прошествию WAKE_EVERY_MIN минут или по нажатию кнопки for (unsigned int i = 0; i < ONE_MINUTE && !button.pressed(); ++i) { wdt_count = info.wakeup_period_min; while ( wdt_count > 0 ) { noInterrupts(); if (button.pressed()) { interrupts(); break; } else { counting(); //Опрос входов. Тут т.к. https://github.com/dontsovcmc/waterius/issues/76 interrupts(); sleep_mode(); // Спим (WDTCR) } } } wdt_disable(); // disable watchdog power_all_enable(); // power everything back on storage.get(info.data); // Берем из хранилища текущие значения импульсов info.wdt = wdt_count; LOG_BEGIN(9600); LOG(F("Data:")); .... } Вот здесь была в другом проблема. Теперь не перезагружается... Но вот зависает: Если кто-то может потратить чуть больше времени, чтобы отладить проблему за вознаграждение - пишите. Спасибо!
  22. Столкнулся с очень редкими зависаниями (цикла? чипа?) attiny85 в Ватериусе. Проявляется через пару суток, когда период пробуждения ESP короткий (15 мин). Не могу понять причины. Требуются консультации + симулировать прошивку в AVR Studio. https://github.com/dontsovcmc/waterius/blob/master/Attiny85/src/main.cpp То, что Ватериус завис видно, потому что он перестает выходить на связь через 15 мин + потребление 400мкА, вместо 12-17мкА. Если нажать на кнопку, то Ватериус выйдет на связь. Взаимодействие, оплату предлагайте. Спасибо!
  23. Эта версия мне наиболее вероятной кажется. Я порылся в "бракованной" партии из 30шт, где думал причиной является флюс. И там было 2 экземпляра у кого причиной были "бракованные" конденсаторы. 1мкФ показывал сопротивление 1кОм.
  24. Да. Но того, что обрывается быть не должно. Это нормальное потребление 15мкА. А 600мкА быть не должно.
  25. Отличная версия, я ее проверю. нет, не шлифовали