Можно ли настроить код Arduino для однократного запуска для отображения модели?
Не могу задать этот вопрос, так как прочитал несколько комментариев, которые показались мне довольно снисходительными. Но в то же время некоторые из них были очень полезными.
Я уже несколько лет занимаюсь сборкой небольших моделей. Я добавлял им движения, добавляя к каждой детали кнопку для включения и выключения. Теперь я хочу усовершенствовать свои дисплеи, автоматизировав их нажатием одной кнопки для управления различными частями модели в определённом порядке.
Я разобрался, как использовать Arduino для реализации нужных мне движений. Но они постоянно повторяются в коде цикла. Я понимаю, что именно для этого и предназначен код цикла. Я пробовал добавлять их в настройках, но постоянно получаю сообщения об ошибках.
Я надеюсь, что кто-нибудь здесь подскажет, куда вводить команды, чтобы после ввода кодов всё остановилось. Пока я снова не нажму кнопку запуска.
@Phil Bagley, 👍-1
Обсуждение3 ответа
Если желаемые операции должны быть выполнены, пока кнопка удерживается, вы можете просто напрямую считать контакт кнопки, чтобы получить ее состояние:
setup(){
// Инициализируем кнопку здесь
}
loop(){
if (digitalRead(button)){
// Делайте что-нибудь здесь
}
}
Если желаемые операции должны быть выполнены один раз при нажатии кнопки и не повторяться до тех пор, пока кнопка не будет нажата снова, потребуется немного дополнительного кода для сравнения состояний кнопок:
- Статическая переменная bool используется для отслеживания последнего состояния кнопки между каждым запуском цикла loop().
- Условия if проверяют, является ли последнее состояние ложным (т.е. кнопка отпущена), а также текущее состояние нажатой. При выполнении обоих условий выполняются требуемые операции.
- Наконец, предыдущее состояние кнопки необходимо обновить до текущего состояния, чтобы выполнять операции только один раз при нажатии кнопки, а также обнаруживать изменения состояния.
setup(){
// Инициализируем кнопку здесь
}
loop(){
static bool previousButtonState{false};
const bool buttonState = digitalRead(button);
if (!previousButtonState && buttonState){
// Делайте что-нибудь здесь
}
previousButtonState = buttonState;
}
Есть несколько ключевых элементов для достижения цели «одна кнопка, чтобы управлять различными частями модели в определенном порядке».
Кнопки не срабатывают автоматически; их электрическое состояние многократно и быстро меняется при нажатии и отпускании. Некоторые действия настолько медленные по сравнению с работой самой кнопки, что дребезг кнопки можно игнорировать, особенно те, которые наблюдает человек. Поскольку вы уже пользуетесь кнопками, я пока оставлю это; вы всегда можете поискать на этом сайте способы устранения дребезга кнопки.
В связи с вышеизложенным: как только вы определили, что состояние кнопки изменилось, сохраните это в логической переменной: 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; // ждать, пока кнопка не станет «отпущена»
}
Я не показал, как считывать состояние кнопки и сохранять ее, поскольку вы уже знакомы с кнопками, но это необходимый шаг.
Я также добавил в код «задержки». Это называется «блокировкой», и я не рекомендую такую практику, но для такой простой задачи это не повлияет на производительность.
Попробуйте аппаратное прерывание:
- Ссылка: 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;
// Сделайте то, что вы хотите сделать
}
}
Обратите внимание, что в зависимости от модели существуют различные определения контактов аппаратного прерывания.
Ссылайтесь на таблицу на странице документа.
- Как объявить массив переменного размера (глобально)
- Программирование Arduino с использованием Python, а не C/C ++
- Загрузка Arduino Nano дает ошибку: avrdude: stk500_recv(): programmer is not responding
- Как справиться с rollover millis()?
- Является ли использование malloc() и free() действительно плохой идеей для Arduino?
- Можно ли сделать несколько функций loop() с помощью Arduino Uno?
- Печать string and integer LCD
- устаревшее преобразование из строковой константы в 'char*'
Если дисплеи работают от батареек, вам может понадобиться схема с защёлкой, активируемая нажатием кнопки. Это позволит запустить цикл отображения, после чего Arduino автоматически отключится. Цикл повторяется после каждого последующего нажатия кнопки., @6v6gt
сложно посоветовать, где вносить изменения в неизвестный код, @jsotola
по сути, не используйте состояние кнопки для выполнения действий... вместо этого используйте состояние переменной флага... измените переменную флага, нажав кнопку... представьте себе пешеходный переход: нажатие кнопки не останавливает транспортные средства... нажатие кнопки изменяет состояние светофора... затем сымитируйте размышления водителя транспортного средства о том, какие действия выполнить., @jsotola
В вашем случае я предлагаю использовать внешние прерывания Gpio и поместить всю логическую обработку в функцию loop(). При нажатии кнопки будет сгенерировано внешнее прерывание, в котором вы можете изменить значение переменной, например, buttonPressed = 1; затем в функции loop() проверьте состояние этой переменной и, если оно равно 1, выполните необходимые действия. Кроме того, при повторном нажатии кнопки измените состояние buttonPressed на 0, и в функции loop() ваша логика не будет выполняться. Считывать состояние выводов в функции loop() не рекомендуется., @Vaibhav
Голосование за открытие: Этот вопрос достаточно ясен, и несколько участников дали рекомендации; если бы вопрос не был закрыт, их можно было бы предоставить больше. Заявление автора вопроса о том, что «теперь я хочу улучшить свои дисплеи, автоматизировав их нажатием одной кнопки для управления различными частями модели в заданном порядке», довольно ясно демонстрирует его намерения. Я и многие другие постоянные участники могли бы легко предложить один или несколько способов сделать это, лишь немного увеличив объём этого одного, ясно выраженного запроса., @JRobert