Можно ли настроить код Arduino для однократного запуска для отображения модели?

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

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

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

Я надеюсь, что кто-нибудь здесь подскажет, куда вводить команды, чтобы после ввода кодов всё остановилось. Пока я снова не нажму кнопку запуска.

, 👍-1

Обсуждение

Если дисплеи работают от батареек, вам может понадобиться схема с защёлкой, активируемая нажатием кнопки. Это позволит запустить цикл отображения, после чего Arduino автоматически отключится. Цикл повторяется после каждого последующего нажатия кнопки., @6v6gt

сложно посоветовать, где вносить изменения в неизвестный код, @jsotola

по сути, не используйте состояние кнопки для выполнения действий... вместо этого используйте состояние переменной флага... измените переменную флага, нажав кнопку... представьте себе пешеходный переход: нажатие кнопки не останавливает транспортные средства... нажатие кнопки изменяет состояние светофора... затем сымитируйте размышления водителя транспортного средства о том, какие действия выполнить., @jsotola

В вашем случае я предлагаю использовать внешние прерывания Gpio и поместить всю логическую обработку в функцию loop(). При нажатии кнопки будет сгенерировано внешнее прерывание, в котором вы можете изменить значение переменной, например, buttonPressed = 1; затем в функции loop() проверьте состояние этой переменной и, если оно равно 1, выполните необходимые действия. Кроме того, при повторном нажатии кнопки измените состояние buttonPressed на 0, и в функции loop() ваша логика не будет выполняться. Считывать состояние выводов в функции loop() не рекомендуется., @Vaibhav

Голосование за открытие: Этот вопрос достаточно ясен, и несколько участников дали рекомендации; если бы вопрос не был закрыт, их можно было бы предоставить больше. Заявление автора вопроса о том, что «теперь я хочу улучшить свои дисплеи, автоматизировав их нажатием одной кнопки для управления различными частями модели в заданном порядке», довольно ясно демонстрирует его намерения. Я и многие другие постоянные участники могли бы легко предложить один или несколько способов сделать это, лишь немного увеличив объём этого одного, ясно выраженного запроса., @JRobert


3 ответа


1

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

setup(){
// Инициализируем кнопку здесь
}

loop(){
   if (digitalRead(button)){
   // Делайте что-нибудь здесь
   }
}

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

  • Статическая переменная bool используется для отслеживания последнего состояния кнопки между каждым запуском цикла loop().
  • Условия if проверяют, является ли последнее состояние ложным (т.е. кнопка отпущена), а также текущее состояние нажатой. При выполнении обоих условий выполняются требуемые операции.
  • Наконец, предыдущее состояние кнопки необходимо обновить до текущего состояния, чтобы выполнять операции только один раз при нажатии кнопки, а также обнаруживать изменения состояния.
setup(){
// Инициализируем кнопку здесь
}
    
loop(){
   static bool previousButtonState{false};         
   const bool buttonState = digitalRead(button);

   if (!previousButtonState && buttonState){
   // Делайте что-нибудь здесь
   }

   previousButtonState = buttonState;
}
,

0

Есть несколько ключевых элементов для достижения цели «одна кнопка, чтобы управлять различными частями модели в определенном порядке».

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

  • В связи с вышеизложенным: как только вы определили, что состояние кнопки изменилось, сохраните это в логической переменной: 1 — «включено», 0 — «выключено». Напишите код отображения, реагирующий на эту переменную, а не на саму кнопку.

  • Чтобы циклически перебирать n дисплеев по порядку, сохраните переменную display-state — целое число, которое вы инициализировали нулем, прежде чем начать следить за состоянием кнопки. Каждый раз, когда переменная button-state меняется на «включено», выполняйте код для display-0, а затем увеличивайте display-state. После выполнения последнего отображения снова обнулите display-state. Не начинайте следующий вывод, пока кнопка не вернется в состояние «выключено».

  • Возможный способ реализации этого — использование конструкции switch / case из C/C++. Вот примерный план на псевдокоде:

loop(){
   while button_state is off,
     do nothing;               // ждать, пока кнопка не станет «нажатой»

   switch( display_state ){
   case(0):
     display_0();             // запустить display 0
     break;

   case(1):
     display_1();             // запустить дисплей 1
     break;
   }
   ++display_state;           // подсчитываем, какой дисплей должен запуститься следующим
   if display_state == number_of_displays,
     display_state = 0;

   while button_state != 0
     do nothing;              // ждать, пока кнопка не станет «отпущена»
}

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

Я также добавил в код «задержки». Это называется «блокировкой», и я не рекомендую такую практику, но для такой простой задачи это не повлияет на производительность.

,

0

Попробуйте аппаратное прерывание:

  • Ссылка: https://www.arduino.cc/reference/cs/language/functions/external-interrupts/attachinterrupt/

попробуйте:

const byte interruptPin = 2;  // *** ВНИМАНИЕ ***
unsigned char flagISR = 0;

void setup() {
    pinMode(interruptPin, INPUT_PULLUP);
    attachInterrupt( digitalPinToInterrupt(interruptPin ), My_ISR, FALLING); // запустить прерывание
}

void My_ISR()
{
    flagISR = 1;
}

void loop {
    if (flagISR) {
        flagISR = 0;
        // Сделайте то, что вы хотите сделать
    }
}

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

,