Почему показания датчика Холла меняются, когда я записываю их в последовательный порт?

У меня есть небольшой проект, в котором я подключил датчик Холла (см. Рисунок) к Arduino Mega. Синий провод подключается к контакту 45, красный - к +5 В, а черный - к GND.

Hall-Sensor AZDelivery KY-003

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

#define HALL_PIN 45

void setup()
{
  pinMode(HALL_PIN, INPUT);
}

Я написал функцию для считывания показаний датчика. Пока поблизости нет магнита, датчик возвращается ВЫСОКО. Если магнит приближается в правильной ориентации, датчик возвращается на НИЗКИЙ уровень. Функция должна возвращать true, если рядом находится магнит, то есть если значение считывания НИЗКОЕ.

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

Реализация 1:

В первой реализации я сначала считывал значение датчика Холла. Затем я отправляю значение в последовательный порт. Последовательный монитор в Arduino IDE выводит число 1 (HIGH). Это ожидаемое поведение, так как во время тестирования поблизости нет магнита. Основываясь на последующем поведении программы, я могу подтвердить, что функция возвращает false. Я могу позволить Arduino работать в течение нескольких минут, и поведение остается стабильным.

bool readHallSensor()
{
  int s = digitalRead(HALL_PIN);

  Serial.println(s); // Последовательный монитор выводит 1 (ВЫСОКИЙ) 
    
  return s == LOW; // Возвращает false
}

Реализация 2:

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

bool readHallSensor()
{
  int s = digitalRead(HALL_PIN);

  // Serial.println(s); // Нет вывода на последовательный монитор
    
  return s == LOW; // Возвращает true
}

Мое первое подозрение состояло в том, что разница заключается в задержке, вызванной записью в последовательный порт. Я спросил инженера-электрика, могут ли датчики Холла нуждаться в коротких перерывах между последовательными показаниями. Он опроверг мое предположение, и действительно, если я просто вставлю задержку (300); после считывания значения (без записи в последовательный порт) поведение не изменится и будет идентично реализации 2.

Я могу переключаться между этими двумя реализациями и прошивать их на Arduino столько раз, сколько захочу. Поведение всегда таково, как описано выше для обоих случаев. Я не могу понять этого, так как в поведении, по-видимому, отсутствует какая-либо (программная) логика. Кто-нибудь когда-нибудь делал подобные наблюдения и может дать мне подсказку, что может вызвать это? Заранее благодарю вас.


Я еще не нашел проблему, но подошел на шаг ближе. Проблема снова возникла в аналогичном проекте на том же Arduino. Я использую новый датчик Холла с подтягиванием, который при определенных обстоятельствах снова считывается неправильно (всегда считывается как НИЗКИЙ, независимо от того, находится ли поблизости магнит). Проблема возникает только тогда, когда я использую определенный выход. На этот раз пин на Arduino Mega - это пин 37. Если я подключу датчик Холла к другому контакту (я протестировал 34 и 36), он будет работать нормально. Если я подключу ранее работавший датчик Холла к контакту 37, он больше не будет работать (всегда оценивается как НИЗКИЙ). Единственные объяснения, которые имеют смысл для меня на данный момент, заключаются в том, что либо Arduino Mega поврежден, либо есть побочные эффекты, возможно, вызванные внешними библиотеками, использующими определенные контакты без моего ведома и неправильно инициализирующими их.

, 👍1

Обсуждение

что произойдет, если вы используете Serial.println('x');?, @jsotola

Есть ли у вас подтягивающее устройство, подключенное между напряжением 5 В и выводом цифрового выхода? Пожалуйста, проверьте. то же самое и с другими цифровыми контактами?, @ArduinoFan

@goodarduinocode.com Хорошее наблюдение, но, похоже, оно может присутствовать на сенсорной плате., @StarCat

Проблема может быть в другой части кода. Когда вы сталкиваетесь с ситуациями, когда, казалось бы, несвязанное изменение полностью меняет поведение программы, вы часто сталкиваетесь с какой-то проблемой, вызывающей неопределенное поведение, такое как переполнение буфера, проблема с памятью, неверный указатель или что-то в этом роде. Это может быть совершенно не связанная часть программы. Но если где-то нарушается память, то невозможно предсказать, каковы будут последствия. Опубликуйте полный и компилируемый пример, иллюстрирующий проблему., @Delta_G

Запись строковой константы в последовательный порт (вместо считанного значения) приводит к тому же поведению, что и в реализации 2 (запись в последовательный порт вообще не выполняется). Я добавил подтягивание, так как выходное напряжение было немного низким. Однако это не изменило поведение. Похоже, что раньше датчик работал нормально и что проблема связана с программным обеспечением. К сожалению, я все еще не мог найти причину проблемы. Я обязательно обновлю эту тему, если узнаю, что это такое. Спасибо всем вам за ваши предложения!, @xoric


1 ответ


3

3144 требует подтягивающего резистора. Он тонет только тогда, когда присутствует магнит. Он не имеет источника, поэтому штифт плавает, если магнита нет.

Вы можете использовать внутренний подтягивающий резистор с помощью pinMode (HALL_PIN, INPUT_PULLUP);

,

Датчик Холла был уже предварительно смонтирован на печатной плате с резистором (см. Рисунок в моем первом посте). Мое предположение состояло в том, что подтягивание уже было там. Но когда мы измерили напряжение выходного сигнала, то обнаружили, что оно составляет всего 3,8 В (при входном напряжении 4,8 В). Добавление подтягивания увеличило выходное напряжение до полных 4,8 В. Однако это не изменило поведение Arduino, так что, похоже, это не аппаратная проблема. Тем не менее, ваш совет абсолютно оправдан, и, безусловно, лучше добавить подтягивание. Так что спасибо вам за это., @xoric

Я думаю, что этот резистор предназначен для светодиода, а не для подтягивания. Хотя конечный эффект заключается в том, что он подтянет выходной вывод до 5 В минус прямое напряжение светодиода. Прямое напряжение красного светодиода составляет около 1 В, так что это даст вам измеренные вами напряжения., @Gerben

Спасибо вам за разъяснение. Мое понимание электротехники все еще довольно ограничено, и я действительно ценю вашу помощь., @xoric