Нужна помощь с функцией millis () для двух линейных приводов
На прошлой неделе я был благодарен за помощь в программировании Arduino для управления двумя линейными приводами.
Мне нужна помощь в переписывании кода с помощью функции millis (). Я более чем счастлив возместить вам время, потраченное на этот проект. Это мой первый опыт работы с Arduino, и millis () слишком сложен для меня.
Приводы управляют набором амбарных дверей в моем доме. Приводы запрограммированы на открытие и закрытие нажатием кнопки (z-волновое реле запрограммировано как 6-секундный мгновенный переключатель). Приводы не дают обратной связи, поэтому программа используется для управления скоростью от 0 до 255 с помощью ШИМ-портов, чтобы приводы выглядели несколько синхронизированными. Они двигаются с тремя разными скоростями, чтобы не хлопать при открывании и закрывании. Вот тут-то и вступает в игру функция millis (). Прямо сейчас я использую задержку для управления скоростью в течение различных промежутков времени, но использование задержки создает проблему безопасности, так как Arduino ничего не может сделать в течение этого времени.
Причина, по которой мне нужно использовать функцию millis (), заключается в том, что мне нужно уметь останавливать двери и поворачивать назад в случае, если что-то блокирует их путь. Для этого я буду использовать электрический глазок гаражной двери, подключенный через самодельную печатную плату. Выходная мощность будет снижаться каждый раз, когда луч будет сломан, а в противном случае она останется высокой. Я бы хотел, чтобы программа Arduino использовала этот сигнал в любое время, когда двери закрываются, и если луч сломан - заставьте приводы повернуть вспять. Я понимаю, что без обратной связи я не могу заставить двери открываться полностью в зависимости от того, когда луч сломан. На самом деле меня это не слишком беспокоит. Пока они хоть немного останавливаются и разворачиваются, я буду счастлив. Я не хочу раздавить своих детей или домашних животных.
Опять же, я более чем счастлив возместить ущерб любому, кто захочет помочь написать код для этого. Вот код, который я сейчас использую, который использует функцию задержки. Я хотел бы, чтобы этот код был изменен, чтобы использовать функцию millis, а также добавить в программирование для датчика, как описано выше.
/* Program enables momentary direction control of actuator using push button
*/
int RPWM = 10; //connect Arduino pin 10 to IBT-2 pin RPWM
int LPWM = 11; //connect Arduino pin 11 to IBT-2 pin LPWM
int RPWM2 = 5; //connect Arduino pin 5 to IBT-2 pin RPWM
int LPWM2 = 6; //connect Arduino pin 6 to IBT-2 pin LPWM
int downPin = 12;
int upPin = 13;
int speed1 = 0; // Top speed you can change it between [0-255]
int speed2 = 0; // Low speed you can change it between [0-255]
int speed3 = 0; // Low speed you can change it between [0-255]
void setup() {
pinMode(RPWM, OUTPUT);
pinMode(LPWM, OUTPUT);
pinMode(RPWM2, OUTPUT);
pinMode(LPWM2, OUTPUT);
pinMode(downPin, INPUT_PULLUP);
pinMode(upPin, INPUT_PULLUP);
}
void loop() {
if(digitalRead(upPin)==LOW){ //check if extension button is pressed
analogWrite(RPWM, 0);
analogWrite(RPWM2, 0);
analogWrite(LPWM, 255); // rotate motor with top speed
analogWrite(LPWM2, 245); // rotate motor with top speed
delay(3000); // wait for x sec
analogWrite(LPWM, 180); // rotate motor with low speed
analogWrite(LPWM2, 176); // rotate motor with low speed
delay(1500); // wait for x sec
analogWrite(LPWM, 80); // rotate motor with low speed
analogWrite(LPWM2, 80); // rotate motor with low speed
delay(1500); // wait for x sec
analogWrite(LPWM, 0); // uncomment if you want to stop motor now
analogWrite(LPWM2, 0); // uncomment if you want to stop motor now
}
else if(digitalRead(downPin)==LOW){ //check if retraction button is pressed
analogWrite(LPWM, 0);
analogWrite(LPWM2, 0);
analogWrite(RPWM, 250); // rotate motor with top speed
analogWrite(RPWM2, 255); // rotate motor with top speed
delay(3000); // wait for x sec
analogWrite(RPWM, 165); // rotate motor with low speed
analogWrite(RPWM2, 165); // rotate motor with low speed
delay(1500); // wait for x sec
analogWrite(RPWM, 80); // rotate motor with low speed
analogWrite(RPWM2, 80); // rotate motor with low speed
delay(1500); // wait for x sec
analogWrite(RPWM, 0); // uncomment if you want to stop motor now
analogWrite(RPWM2, 0); // uncomment if you want to stop motor now
}
else{ //if no button is pushed, remain stationary
analogWrite(RPWM, 0);
analogWrite(LPWM, 0);
analogWrite(RPWM2, 0);
analogWrite(LPWM2, 0);
}
}
@Chris Groat, 👍-1
Обсуждение1 ответ
Вы подошли к требованию, называемому неблокирующим программированием. Суть в том, что ваша функция loop() делает мало что, кроме вызова ряда функций "может быть"-мое название для функций, которые оценивают необходимость действовать, действовать или нет, и возвращают как можно быстрее. Таким образом, в псевдокоде ваш цикл может выглядеть примерно так:
void loop(){
maybeStartMotor1();
maybeSlowMotor1();
maybeStartMotor2();
maybeSlowMotor2();
maybeStopMotor1();
maybeStopMotor2();
// Call maybe-do()s for ... whatever else might need to happen
}
Ваши функции "возможно", вероятно, будут выглядеть следующим образом, например:
maybeSlowMotor1(){ if( millis() - millis_at_motor1_start > ЗАМЕДЛЕНИЕ2 ) установите motor1 на медленную скорость;
в противном случае, если( millis() - millis_at_motor1_start > ЗАМЕДЛЕНИЕ1 ) установите motor1 на среднюю скорость;
возвращение; }
Обратите внимание, что мое понимание вашей механической системы ограничено, и вышеизложенное предназначено для описания программного обеспечения, а не решения.
Также обратите внимание, что я полностью согласен с предостережением @timemage не зависеть от программного обеспечения для блокировки вашей безопасности. Ваш 3 - й комментарий под вашим вопросом - для прямого реверса дверей с помощью фотоэлементов и реле - в дополнение к обнаружению и управлению программным обеспечением-обеспечивает необходимую избыточность.
Я также хотел бы сослаться на это несколько более полное описание, которое я написал, чтобы ответить на другой, аналогичный, вопрос.
Спасибо вам за ваш ответ. Я просто полный новичок в Arduino, и это находится за пределами моей рулевой рубки. Возможно, самым простым решением для меня было бы использовать электрический глаз, чтобы просто отключить питание приводов в случае блокировки луча. Направление вспять было бы неплохо, но для того, чтобы оно функционировало должным образом, потребуется программное обеспечение/программирование., @Chris Groat
Сначала используйте электрические приводы для глаз / стопора. Затем вы можете работать над программным обеспечением, понемногу за раз, и вам не придется делать "было бы неплохо" его части спереди. В случае наихудшего случая вы можете поэкспериментировать с программным обеспечением по чуть-чуть за раз, не оставляя никаких вопиющих проблем с безопасностью., @JRobert
Вот что я сделаю. Я все равно был бы более чем счастлив заплатить кому-нибудь за программирование для меня, если найдутся желающие! Если бы у меня просто было с чем работать, держу пари, я мог бы заставить его функционировать должным образом., @Chris Groat
@ChrisGroat, свяжитесь со мной через мой профиль., @JRobert
- Печать string and integer LCD
- Почему мои часы реального времени показывают неверное время с моего ПК?
- Arduino uno + cnc Shield v3 + драйвер шагового двигателя A4988 + AccelStepper?
- Отправьте несколько значений int из Python в Arduino, используя pySerial
- Глобальные переменные занимают много места в динамической памяти.
- (Код ультразвукового датчика: такого файла или каталога нет)
- rfid_default_keys проверить с помощью RC522
- Команда strtok() с Serial связью
Вы не должны полагаться на код Arduino вообще, "millis()" или иначе, для ваших функций безопасности. В более широком смысле вы вообще не должны полагаться на программное обеспечение, когда речь идет о том, чтобы не раздавить ваших детей или домашних животных., @timemage
Определенно открыт для других предложений.... Приводы рассчитаны только на 20 фунтов. Я позволил дверям закрыться от меня, и это совсем не плохо... но все же предпочел бы, чтобы двери не закрывались от вещей., @Chris Groat
Я не уверен, что мне удобно давать вам советы по этому поводу. Но, если ваши приводы отвечают за разные направления, кажется, что *как минимум* закрытие двери на чем-то должно механически прервать питание, идущее к приводу, который закрывает дверь, и он, вероятно, должен защелкнуться в этом прерванном положении, так что требуется ручное вмешательство, чтобы заставить его работать снова., @timemage
Каждый привод имеет регулируемую защиту от перегрузки по току. Это нормально-отключать питание приводов, если двери на что-то натыкаются, но я надеюсь, что на самом деле двери перевернутся задом наперед, прежде чем наткнуться на что-нибудь. В конце концов, разве наши гаражные ворота не полагаются на программное обеспечение для выполнения той же функции безопасности?, @Chris Groat
Также обратите внимание - Мой запасной план, если я не смогу заставить это работать с Arduino, состоит в том, чтобы подключить электрический глаз к паре реле, которые будут менять полярность приводов в случае блокировки луча, заставляя двери менять направление. Это был бы один из методов, который позволяет избежать использования программного обеспечения. Может также привести к тому, что двери закроются на что-то, если луч заблокирован во время открытия дверей... так не идеально!, @Chris Groat