Запуск фрагмента кода на основе функции

Я студент-инженер, совершенно новичок в использовании Arduino, поэтому мой следующий вопрос может показаться глупым, но все же. Я не думаю, что вам понадобится весь код, поэтому я собираюсь лишь раскрыть идею. По сути, я бы хотел, чтобы клиент выбрал одну из трех функций (назовем их 1, 2, 3). В зависимости от выбранной им функции должны быть запущены соответствующие setup() и соответствующий loop(). Например, если он выберет вторую функцию, в основном setup() должен быть запущен setup2() и в основном loop(), должен выполняться только loop2(). Остальные функции setup() и loop() не должны ничего делать. Сначала я думал, что смогу сделать это, используя переключатели, но я ищу другой способ реализовать это, поскольку учитель сказал мне, что этот метод займет слишком много времени.

void setup() {

      setup1(); //работает только в том случае, если выбрана первая функция
      setup2();
      setup3();
}




void loop() {

      loop1(); //работает только в том случае, если выбрана первая функция
      loop2();
      loop3();
}

А еще я написал три setup() и три loop() в разных файлах (конечно, setup1()) находится в том же файле, что и loop1() и т. д., ...). Можно ли их включить в основной файл (например, как <#include nameoffile.h)?

, 👍0

Обсуждение

Какой физический метод вы используете, чтобы определить, какой признак выбран?, @Majenko

@Majko Я буду использовать веб-конфигуратор, чтобы клиент мог выбрать. Его имя MQTT, @alexmerchant

То есть устройство подпишется на тему MQTT и получит сохраненное сообщение для получения конфигурации? Я бы сказал, что вы хотите реализовать конечный автомат, поскольку вся система «конфигурации» сама по себе является другой конфигурацией., @Majenko

Я не понимаю, о чем говорит ваш учитель. Мне кажется, что коммутатор будет работать нормально., @Gerben

@Маженко да, это идея! Я никогда не слышал о конечном автомате, но собираюсь провести о нем небольшое исследование., @alexmerchant

@Gerben Тогда я тоже попробую этот способ. Просто нужно выяснить, как я собираюсь получить функцию, выбранную клиентом., @alexmerchant

Switch-Case обычно является сердцем конечного автомата. Это самый простой способ реализации. https://majko.co.uk/blog/finite-state-machine, @Majenko

@majko спасибо, посмотрю эту ссылку! я действительно думал, что смогу избежать случаев Switch, но, думаю, мне придется с этим справиться, @alexmerchant

вам действительно нужно вызывать настройку после каждого изменения функции? или вы могли бы просто инициализировать все функции одновременно и просто переключить то, что используете?, @mystery

@mystery Я действительно мог бы переключить переменные, которые использую!, @alexmerchant


2 ответа


1

Возможно, вы захотите сделать что-то вроде этого:

typedef enum { FEATURE1, FEATURE2, FEATURE3 } Feature;

//реализуем эти
Feature getFeatureFromUser(){}
void setup1(){}
void setup2(){}
void setup3(){}
void loop1(){}
void loop2(){}
void loop3(){}

void setup() {
  Feature f = getFeatureFromUser();

  switch (f) {
    case FEATURE1:
      setup1();
      while (true) {
        loop1();
        if (serialEventRun) serialEventRun();
      }
    case FEATURE2:
      setup2();
      while (true) {
        loop2();
        if (serialEventRun) serialEventRun();
      }
    case FEATURE3:
      setup3();
      while (true) {
        loop3();
        if (serialEventRun) serialEventRun();
      }
  }
}

//никогда не достигал
void loop() {}

Приятно знать, что не существует жестких правил использования функций Arduino. Подобные примеры демонстрируют, что стандартные требования Arduino к void setup() и voidloop() не совсем соответствуют каждому варианту использования.

EDIT: Строки серийного события обычно вызываются за кулисами после каждого выполнения обычного loop() Arduino, поэтому добавление их сюда приведет к стандартному поведению последовательного порта. события

,

да, это идея! большое спасибо за помощь, это действительно полезно! но что вы имеете в виду, когда говорите, что цикл void() никогда не достигается, почему? Arduino кажется намного понятнее, @alexmerchant

После совпадения одного из параметров в операторе переключения и запуска соответствующей функции настройки функция цикла# будет вызываться навсегда внутри цикла while. Поэтому он останется в этом цикле навсегда и никогда не достигнет функции цикла() Arduino. Блоки в операторе переключения очень похожи на то, как Arduino работают за кулисами., @sealj553

ок, теперь ясно! спасибо, тогда попробую так, @alexmerchant

Недостатком этого метода является то, что он нарушает обработку последовательных событий. Если вы не используете последовательные события, это не проблема., @Majenko

@Маженко, я тоже об этом думал, так как у меня могут быть другие операции. Действительно, после первой настройки() должны запуститься еще три опции setup11(), setup12() и setup13() со своими собственными циклами, опять же в зависимости от выбора клиента (выбор может быть 11, 12,13) не знаю если это еще ясно, @alexmerchant

@Majko Я также только что нашел интересную статью о разработке линейки программных продуктов. Если вы слышали об этом, как вы думаете, смогу ли я почерпнуть идеи из этой концепции?, @alexmerchant

@Majko Я только что обновил, чтобы добавить обработку последовательных событий., @sealj553

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

@MikaelPatel ОП хотел выбрать функцию во время выполнения. В противном случае это можно было бы легко сделать с помощью определений препроцессора. В ОП не упоминалось об ограничении памяти. Конечно, существует множество вариантов, если кто-то ограничен в памяти, например, динамическое выделение памяти (один раз) при выборе функции, сохранение данных в EEPROM или повторное использование переменных. Это выходит за рамки этого вопроса., @sealj553


0

Если выбор функции происходит не во время выполнения, а во время компиляции, вы можете сделать это следующим образом:

#define FEATURE1 true   // Функция 1 включена

void setup() {
    #if FEATURE1
    setup1(); //работает только в том случае, если выбрана первая функция
    #endif
    setup2();
    setup3();
}

void loop() {
    #if FEATURE1
    loop1(); //работает только в том случае, если выбрана первая функция
    #endif
    loop2();
    loop3();
}

void setup1(void) {}
void setup2(void) {}
void setup3(void) {}

void loop1(void) {}
void loop2(void) {}
void loop3(void) {}
,