Как многозадачность с прерываниями на Arduino?

Я пытаюсь создать безналичную систему раздачи воды на основе RFID. Я использую Arduino mega 2560, PN532, реле, датчик потока. Вот поток программы в режиме I2C; У меня есть две функции, одна для сканирования карты, а другая для датчика потока. Как только RFID-карта помещается в модуль NFC, данные, хранящиеся на карте (т. е. дата истечения срока действия и сумма остатка), получаются и проверяются на достоверность. Если карта действительна, то включается реле. Датчик расхода измеряет количество подаваемой воды. Как только достигается предел в 1000 мл, реле отключается. Весь процесс происходит последовательно, когда сканирование карты завершено, он ждет, пока будет выдано все 1000 мл воды. Чего я хочу добиться, так это того, что после сканирования одной карты должно быть включено 1-е реле с датчиком потока и одновременно должно начаться сканирование второй карты. Если первое реле занято, второе реле должно быть назначено ему. Могу ли я добиться этого с помощью Arduino Mega? Как мне заставить атмегу выполнять все эти задачи одновременно?

, 👍1

Обсуждение

[BlinkWithoutDelay](https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay) из примеров Arduino IDE — ваш друг., @Kwasmich

Вот действительно тщательная запись, которую я сделал о том, как делать совместную многозадачность с голым металлом (как обычно Arduino): https://stackoverflow.com/a/50032992/4561887, @Gabriel Staples


2 ответа


Лучший ответ:

1

Не обязательно собирать "многозадачность с прерываниями на Arduino". Вместо этого рассмотрите возможность использования машины состояний. Сначала определите проблему, нарисовав диаграмму состояний:

Рассмотрите все состояния, в которых вы хотите находиться. Включая ваш пример "...после сканирования одной карты должно быть включено 1-е реле с датчиком потока и одновременно должно начаться сканирование второй карты... ". После того, как вы определили все состояния и правила, которые необходимо проверить перед переходом к новому состоянию, вы можете приступить к программированию конечного автомата.

В Интернете есть множество руководств, в том числе это специально для люди, которые хотят реализовать конечный автомат на Arduino. Но, вкратце, вы захотите создать цикл, который будет выполняться без остановок снова и снова как можно быстрее. Этот цикл будет (1) знать, каково текущее состояние, и (2) будет неоднократно проверять, может ли программа перейти в любое из возможных следующих состояний. Когда вы меняете состояния, это когда, если вам нужно, вы выполняете такие задачи, как включение или выключение воды.

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

,

Я попытался реализовать конечный автомат для своей программы. Это помогло мне найти решение. Большое спасибо. Ваше здоровье!, @Riya

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

Как вы упомянули, я разработал диаграмму состояний. Следовательно, мне было ясно, в каком состоянии каждый компонент должен находиться в определенное время. Я гарантировал, что программе не нужно ждать продолжения. Я нашел решение, просто манипулируя прерываниями, используемыми датчиками потока, чтобы заставить их работать почти одновременно. Однако я не полностью реализовал программу конечного автомата на своей ардуино. Разработка диаграммы состояний помогла мне найти решение., @Riya

Рад, что ответ помог. Теперь у меня есть к вам вопрос: похоже, что вы реализовали свое решение, используя только прерывания, насколько легко было его протестировать? А вы уверены, что проверяли каждую ситуацию? Готовы ли вы прокатиться на ракетном корабле или водить машину с вашим кодом? Я ловлю тебя. Ответ? Очень сложно протестировать все ситуации, когда задействованы прерывания. Вот почему я предложил государственную машину. Вы все еще можете обнаруживать ситуации, используя прерывания. Но использование конечного автомата означает, что вы контролируете, что и когда происходит. Вместо того, чтобы оставить это на удачу., @st2000

Спасибо @st2000. У вас есть верная точка зрения. Я попытаюсь реализовать это с помощью конечных автоматов, чтобы иметь контроль над программой., @Riya


1

На ардуино нет настоящей многозадачности. Arduino может делать только одну вещь за раз.

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

  • Все задержки в вашем коде (по крайней мере, длинные) должны быть устранены. если вы хотите выполнять временные действия, вам следует использовать принцип кодирования из примера BlinkWithoutDelay, поставляемого с Arduino IDE.

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

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

,

Спасибо за помощь! Я удалил все задержки в своей программе, и код заработал как надо., @Riya

@Riya Пожалуйста, отметьте один ответ, который вам больше всего подходит. Это поможет другим, ищущим помощи по аналогичным проблемам., @the busybee