Нужна помощь с функцией 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);
  }
}

, 👍-1

Обсуждение

Вы не должны полагаться на код Arduino вообще, "millis()" или иначе, для ваших функций безопасности. В более широком смысле вы вообще не должны полагаться на программное обеспечение, когда речь идет о том, чтобы не раздавить ваших детей или домашних животных., @timemage

Определенно открыт для других предложений.... Приводы рассчитаны только на 20 фунтов. Я позволил дверям закрыться от меня, и это совсем не плохо... но все же предпочел бы, чтобы двери не закрывались от вещей., @Chris Groat

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

Каждый привод имеет регулируемую защиту от перегрузки по току. Это нормально-отключать питание приводов, если двери на что-то натыкаются, но я надеюсь, что на самом деле двери перевернутся задом наперед, прежде чем наткнуться на что-нибудь. В конце концов, разве наши гаражные ворота не полагаются на программное обеспечение для выполнения той же функции безопасности?, @Chris Groat

Также обратите внимание - Мой запасной план, если я не смогу заставить это работать с Arduino, состоит в том, чтобы подключить электрический глаз к паре реле, которые будут менять полярность приводов в случае блокировки луча, заставляя двери менять направление. Это был бы один из методов, который позволяет избежать использования программного обеспечения. Может также привести к тому, что двери закроются на что-то, если луч заблокирован во время открытия дверей... так не идеально!, @Chris Groat


1 ответ


0

Вы подошли к требованию, называемому неблокирующим программированием. Суть в том, что ваша функция 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