Возможно ли, чтобы цифровой контактный режим Arduino переключился с ВЫХОДА на ВХОД?
У меня есть проект Arduino (регистратор данных, предназначенный для выборки 100 выборок в секунду в течение нескольких месяцев) с прошивкой, которая слишком длинна для публикации. В основном он работает так, как и предполагалось, но у меня есть одна запутанная проблема, которую я не могу понять: редко индикаторные светодиоды (управляемые цифровыми контактами) перестают работать. Под редкостью я подразумеваю, что если я запускаю 20 устройств в течение двух недель, то, возможно, у одного из них возникнет проблема, так что это очень трудно проверить эмпирически, но это достаточно часто, чтобы это имело значение. Я знаю, что это не аппаратная проблема, потому что они снова запускаются после сброса. Устройство, по-видимому, продолжает нормально работать, если не считать проблемы со светодиодом, когда это происходит.
У меня есть три гипотезы:
- В моем программном коде есть логическая проблема. Я настроен скептически, потому что соответствующий блок кода довольно прост.
- Переполнение памяти или какая-то подобная проблема приводит к тому, что программа терпит неудачу в этой конкретной задаче, но не в других. Я немного скептически отношусь к этому, потому что устройство сообщает о свободном стеке метаданных каждую секунду, и он всегда превышает 40 байт; однако я, возможно, неправильно понимаю использование памяти.
- Каким-то образом цифровой вывод (4), управляющий светодиодом, переключается с ВЫХОДА на ВХОД. Однако
в моем коде определенно нет команды pinMode(4, INPUT)
, так что если это и происходит, то делает это не мой код.
Давайте предположим, что это не № 1. Рассматривая вопрос № 2: вполне вероятно, что странная проблема с памятью вызывает очень специфический сбой, не затрагивая при этом основные функции устройства?
Учитывая #3, существует ли в любом случае регистр, устанавливающий вывод на ВХОД или ВЫХОД, который может быть неожиданно перевернут? Для меня это звучит безумно, но я хочу исключить это.
Платформа похожа на Arduino Pro (3,3 В, 8 МГц, ATmega328P), и я использую текущую версию IDE (1.8.13). Спасибо за любую помощь.
@Vulcan, 👍0
Обсуждение1 ответ
Лучший ответ:
Тот факт, что их можно установить неправильно, является причиной того, что в некоторых проектах, где меня это беспокоит, я добавлю небольшое сопротивление серии входящему сигналу. Если контакт становится выходным
и приводится в движение в противоположном направлении к сигналу, сопротивление служит для предотвращения короткого замыкания через оба устройства. Возможность всегда есть, есть ли у вас прямая ошибка, или нестабильность, или флэш-повреждение.
С pinMode
возможность случайно установить порт в неправильном направлении, возможно, немного хуже, чем для кода, который непосредственно манипулирует регистром направления данных. Вызовы pinMode обычно не вставляются, потому
что pinMode
на Arduino-это довольно сложная функция во время выполнения для того, что она на самом деле делает. Итак, есть общий код, к которому можно перейти, который установит различные порты в любом направлении, в отличие от более мелких фрагментов кода, которые содержат инструкции, устанавливающие определенные порты на определенные настройки.
ВХОД
примерно выводит ваш цифровой вывод из схемы. И INPUT_PULLUP
вроде бы делает это, за исключением того, что внутри AVR будет 20k - 50k сопротивления, идущего к "5V". Зная это, вы можете проверить свою третью гипотезу. Когда вы найдете свой проект в состоянии, когда светодиод не горит, возьмите некоторое сопротивление (скажем, 1K) и используйте его, чтобы потянуть контакт к "5V". Затем потяните его к GND. Следите за напряжением на контакте с помощью измерителя. На основе того, что вы подключили и что вы видите для напряжения, вы можете определить, вошел ли он в состояние INPUT
или INPUT_PULLUP
. Вы также сможете увидеть, если его просто загоняют в то состояние, которое вы называете "не работает" ("выключено", я предполагаю).
Вы можете взять всю догадку о том , какие напряжения видеть в каждом сценарии , если вы загружаете скетч , который устанавливает соответствующий контакт во ВХОДНОЕ
, INPUT_PULLUP
, ВЫХОДНОЕ
/ВЫСОКОЕ
и ВЫХОДНОЕ
/НИЗКОЕ
состояния и измеряете напряжение на контакте, когда вы тянете его к каждой рейке с помощью резистора. Позже вы можете посмотреть таблицу, которую вы построили, чтобы увидеть, что произошло.
Есть только так много, чтобы сказать об этом, особенно ваши первые две идеи, не видя кода и других деталей. Просто иногда в простом коде есть ошибки. В проекте ATmega328P 40 байт-это совсем не много свободного места. Чтобы дать вам представление о том, какую проблему это может вызвать: Реализация Arduino new
, находящаяся в ядре 1.8.3, с радостью сдует ваш регистровый файл и все остальное, что он может получить после этого, если лежащий в основе malloc
сообщит о нехватке памяти. В основном new
продолжает инициализировать объект, который, по его мнению, был выделен, даже если возвращаемое значение равно nullptr. Маржа __malloc_
в версии 1.8.3 равна 128 байтам, поэтому, если вы попытаетесь использовать malloc
с расстоянием 40 байт между стеком и кучей, вы уничтожите состояние своей программы, возможно, даже установив в процессе регистр направления данных.
- Получить доступ к EEPROM ATtiny с помощью кода Arduino?
- Выделение строковой памяти Arduino
- Spiffs против Eeprom на esp8266
- Как очистить кучу памяти в esp32
- Есть ли способ подключить оперативную память компьютера к Arduino?
- Как исправить код утечки памяти в ESP8266/NodeMCU, вызванный концентрацией строк?
- Arduino sketch использует слишком много места в памяти?
- Файловая система внешней флэш-памяти
конечно, вывода могут неожиданно перевернуться ... вы просто должны убедиться, что ваша программа выполняет только ожидаемые действия, @jsotola
Светодиод гаснет или собирается войти? Обычно вы видите это, потому что если светодиод прикреплен к входному контакту, он мерцает, а не включается или выключается (потому что из входного контакта выходит какой-то ток)., @PMF
Светодиод перестает мигать, хотя мне кажется очень маловероятным, что соответствующий код перестанет работать. Вывод, установленный на вход, может объяснить, как светодиод может перестать заметно мигать, пока код все еще работает в обычном режиме. Последовательный резистор светодиода составляет всего 470 Ом, что намного меньше, чем высокоимпедансное состояние контакта, так что даже если бы он подавал некоторый ток, его, вероятно, было бы недостаточно для кратковременной видимости при дневном свете., @Vulcan
Что касается 2.: нетривиально получить информацию о свободной оперативной памяти в не многозадачной системе, потому что она даст вам только свободную оперативную память в тот момент, когда вы вызовете соответствующую функцию "get_free_ram ()". Если вы вызовете эту функцию в высокой области (например, в
loop ()
), она будет возвращать что-то совершенно другое, чем при вызове в более глубокой области, где локальные переменные, обратные адреса и т. Д. Также Хранятся в оперативной памяти. Если вы не используете динамическое выделение памяти, оно всегда будет давать один и тот же результат, но это, вероятно, не является "высокой отметкой" использования оперативной памяти., @Sim Son