Кодирование задержки работает не так как ожидалось

Добавлена вторая попытка в нижней части кода, пожалуйста, проверьте это, работает без задержки, но никогда не выключает вакуум? Этот проект довольно хорошо объяснен в описании кода. Моя главная проблема заключается в том,что мне нужна задержка для ditialWrite(vacPin, LOW);. С включенной этой деталью шаговый двигатель реагирует не так быстро, как раньше, с задержкой в 2/3 секунды, а датчик тока ACS712 вообще не считывает показания на экране консоли. Я пробовал разные оперативники, операторы и перемещал код в разные места, но безуспешно!
Я думаю, что это простое решение, но оно намекнуло мне!. Надеюсь, это достаточно ясно, и любая помощь будет оценена по достоинству.

/*Эта версия работает как есть **ЗА ИСКЛЮЧЕНИЕМ того, что задержка vac 4 секунды должна быть выключена. См.########### область для проблемы.
/*Проект Auto Blast gate: для сбора пыли в деревообрабатывающем цехе.
  Arduino Nano
  Датчик тока ACS712
  Шаговый драйвер DRV8825
  Nema 17 шаговый
  Каждый инструмент будет контролироваться датчиком тока и когда этот аналоговый порт превысит заданный порог
  1. Поверните шагомер в заданное положение, чтобы выровнять порты для этого инструмента.
  2. После того, как ворота выровняются, цифровой вывод приведет реле в действие, чтобы включить вакуумную систему.
      Вакуум будет оставаться включенным до тех пор, пока датчик превысит порог во время работы инструмента. 
      **Когда инструмент остановится, вакуум будет продолжаться в течение 4 секунд, чтобы очистить оставшуюся пыль.**
  3. Если тот же инструмент используется далее, шаговый останется в его текущем положении.
      Но вакуумная система все равно должна работать.
  4. в настоящее время используются кнопки для имитации инструментов, а также один ACS712 для тестирования  */


// определяет номера контактов
const int stepPin = 3;
const int dirPin  = 2;
const int enPin  = 8;
const int vacPin = 4; //simulate Vacuum relay

int ca = 0;  //currentAngle
int na = 0;  //angle
int stepPerAngle = 5 / 9; // full step = 1.8 or could have used "*1.8"
int   numstep;
int analogValue = 0;

void setup() {
  Serial.begin(9600);

  // Sets the 3 pins as Outputs
  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
  pinMode(enPin, OUTPUT);
  pinMode(vacPin, OUTPUT); //Just added this for vac

  //set values for 2 outputs
  digitalWrite(enPin, LOW);
  digitalWrite(dirPin, HIGH);
  digitalWrite(vacPin, LOW); //just add this for vac

 
}

void loop() {
  int n;
 analogValue = 0;
 
  
  // Assign button degrees
  if      ( analogRead(A0) > 600) {
    analogValue = (analogRead(A0));
    Serial.print("AO = ");
    Serial.println(analogValue);
    na = 0; 
    
  }
  else if ( analogRead(A1) > 600) {
    analogValue = (analogRead(A1));
    Serial.print("A1 = ");
    Serial.println(analogValue);
    na = 45;    
  }
  
  else if ( analogRead(A2) > 600) {
    analogValue = (analogRead(A2));
    Serial.print("A2 = ");
    Serial.println(analogValue);
    na = 225;
  }
  
  else if ( analogRead(A3) > 600) {   //=tool on
  analogValue = (analogRead(A3));
    Serial.print("A3 = ");
    Serial.println(analogValue);
    na = 270;
   
  }

   
 /*###########################################################
 **this is where I need help.  The first if statement works as it should.
 when those 2 condition are met the vacPin goes high.** */  

  if(analogValue > 600 && ca==na) {
    digitalWrite(vacPin, HIGH);
  }

/* **this part is not working correctly.  If the delay is remove it works as the "else if" statment reads.
  I need the delay so when a tool is stopped, the vacuum continues for a few secounds to clear remaining saw dust** */

else if (analogValue < 600) {
   delay (4000); **/*  with this on:
             the stepper does not start as quickly as before,
             the analog will not read the ACS712 sensor at all,  only the buttons*/** 
    digitalWrite(vacPin, LOW);
  }

//################################################################################

  if ( ca != na ) {

  //2nd SCENARIO
  if (na - ca > 0 && na - ca <= 180)
    { digitalWrite(dirPin, HIGH);
      n = ((na - ca) * 5 / 9);
      numstep = n;
      ca = na;
     
    }

    //3rd SCENARIO
    else if (ca - na > 0 && ca - na > 180)
    { digitalWrite(dirPin, HIGH);
      n = ((na + 360 - ca) * 5 / 9);
      numstep = n;
      ca = na;
    }

    // 4th SCENARIO
    else if (na - ca < 0 && na - ca <= 180)
    { digitalWrite(dirPin, LOW);
      n = ((ca - na) * 5 / 9);
      numstep = n;
      ca = na;
    }

    //5th SCENARIO
    else if (na - ca > 0 && na - ca > 180)
    { digitalWrite(dirPin, LOW);
      n = ((ca + 360 - na) * 5 / 9);
      numstep = n;
      ca = na;   
  }
    

   

    for (int x = 0; x < numstep; x++) {

      digitalWrite(stepPin, HIGH);
      delayMicroseconds(1000);  //speed
      digitalWrite(stepPin, LOW);
      delayMicroseconds(1000);



    }
    
    
    
    delay(200);
  }
  
}

#################################################

if(analogValue > 600 && ca==na) {
    digitalWrite(vacPin, HIGH);
  }

/* this part is not working correctly.  If the delay is remove it works as the "else if" statment reads.
  I need the delay so when a tool is stopped, the vacuum continues for a few secounds to clear remaining saw dust */

// another variation to the section in question
else if (analogValue < 600 && vacPin==HIGH) {
   delay (4000);
/*  written this way it works but never turn Vacuum off?*/ 
    digitalWrite(vacPin, LOW);
  }

, 👍1

Обсуждение

Спасибо за ваш ответ, я переписал по-другому, если(аналоговое значение > 600 && ca==na) { Цифровая запись(vacPin, ВЫСОКАЯ); } /* эта часть работает неправильно. Если задержка удалена, она работает как говорится в заявлении "в противном случае, если". Мне нужна задержка, поэтому, когда инструмент остановлен, вакуум продолжается в течение нескольких секунд, чтобы очистить оставшуюся пыль от пилы */ в противном случае, если (аналоговое значение < 600 && vacPin==ВЫСОКИЙ) { задержка (4000); /* написано таким образом, что он работает, но никогда не выключает вакуум?*/ Цифровая запись(vacPin, НИЗКАЯ); } Этот способ работает, но никогда не выключает вакуум после его включения?, @Greg

// другой вариант рассматриваемого раздела , если (аналоговое значение < 600 && vacPin==ВЫСОКИЙ) { задержка (4000); /* написано таким образом, что он работает, но никогда не выключает вакуум?*/ цифровая запись(vacPin, НИЗКАЯ); }, @Greg

Еще раз извините! Я прочитал ваши комментарии и понятия не имею, почему часть моего ответа не появилась, а остальная часть не выглядит так, как она выглядела при вводе. Меня интересует ваш вклад, но я боюсь повторить попытку в ответе. Что я узнал, так это то, что мне нужно перейти на неблокирующую задержку., @Greg

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

Я думаю, что я медленно учусь, я наконец-то понял, что вы говорите мне о коде (не в комментариях) Я думал, вы говорили мне не вставлять комментарии в код! На данный момент я не могу найти ваш первоначальный вопрос. Изучение этой системы примерно так же сложно, как и само кодирование "для меня". Спасибо за ваше терпение., @Greg


2 ответа


3

Не совсем ясно, что вы пытаетесь сделать, но я думаю, что вы хотите запустить vac и запустить шаговый двигатель, а затем через 4 секунды остановить vac. Задержка в 4 секунды заставляет остальной код ждать (ничего не делая) в течение этих 4 секунд.

Посмотрите на пример программы Arduino IDE, BlinkWithoutDelay. Используемая там техника-это то, что вам нужно использовать вместо задержек, чтобы ваша программа могла управлять несколькими вещами одновременно. Этот метод называется неблокирующим; каждый раз, когда часть вашей программы ожидает, что что-то произойдет, блокирует код от выполнения чего-либо еще, пока это "что-то" не завершится.

Найдите неблокирующее программирование, чтобы узнать больше. В Интернете есть множество статей, в том числе и в Arduino Stack Exchange, которые обсуждают этот вопрос.

Обновление (после вашего обновления 2021-05-05, 20:48Z):

Вот ответ, который я написал на аналогичный вопрос, в котором я более подробно писал о неблокирующем программировании. Короткий ответ заключается в том, что вы не можете использовать delay (), когда вам нужно контролировать или контролировать несколько вещей одновременно. Задержки удерживают все остальное от того, чтобы произойти до тех пор, пока они не истечут, и именно это мешает вашему степперу продвигаться так, как вы намеревались. Вам нужно сделать что-то вроде:

if the tool is running,
  ; // ничего не делать
else,
  save the time;    // this is the tool-stopped time
  move the stepper; // I assume the stepper completes in < 4s
end

if the tool is stopped and the vac is running,
  if (current_time - saved_time) >= 4000,
    stop the vac;
  end;
end;
// и пусть функция loop() продолжает работать

Обратите внимание, что он никогда не ждет ни инструмента, ни вентилятора. Он просто быстро и часто проверяет, нужно ли что-то делать; если да, то он это делает; и в любом случае он продолжает.

Поскольку это происходит в вашей циклической функции, этот код выполняется снова и снова, так что в конце концов, когда пройдет 4 секунды (в случае vac), vac будет остановлен, но тем временем шаговый двигатель сможет работать, и любые другие небольшие задачи, требующие выполнения, получат такую возможность. Важно то, что ваш код никогда не зависает в ожидании чего-либо; он просто очень быстро проверяет все, что может понадобиться {начать, остановить, ускорить ...}, если/когда что-то готово быть сделано, он делает это, но в любом случае он немедленно движется дальше.

,

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

https://www.instructables.com/Simple-Multi-tasking-in-Arduino-on-Any-Board/, @Greg

Эти таблицы инструкций представляют те же ide, теперь структурированные более приятным образом. Обратите внимание на важный момент: каждая задача получает множество частых возможностей для выполнения. Они решают, нужно ли им использовать какую-либо из этих возможностей, но они никогда не ждут. "Делай или не делай, ждать неоткуда", - перефразируя Йоду., @JRobert


1

Я не знаю, с чего начать, но это сработало ИДЕАЛЬНО! Мне нужно поработать над скоростью шагового шага и длиной рампы, чтобы сгладить их, или перемычками на расширителе DRV8825 bd. Кроме того, я хочу понять библиотеку! Я пошел в readme, и он объяснил, что он может сделать, но я не знаю, как использовать его самостоятельно. Я заметил, что ваше имя и написанное вами-одно и то же! Я говорю с человеком или компанией? Еще раз спасибо Спасибо всем остальным, кто тоже помогает, и мне тоже нужно изучить некоторые из этих решений!

MicroBahner 8 мая Это было бы мое предложение с MobaTools:

/*Эта версия работает как есть, ЗА исключением того, что задержка vac 4 сек должна быть выключена. См.########### область для проблемы. Проект автоматических взрывных ворот: для сбора пыли в деревообрабатывающем цехе. Arduino Nano Датчик тока ACS712 Шаговый драйвер DRV8825 Nema 17 шаговый Каждый инструмент будет контролироваться датчиком тока и когда этот аналоговый порт превысит заданный порог

  1. Поверните шаговый механизм в заданное положение, чтобы выровнять порты для этого инструмента.
  2. После выравнивания затвора цифровой штифт приведет в действие реле для включения вакуумной системы. Вакуум будет оставаться включенным до тех пор, пока датчик превысит порог во время работы инструмента. Когда инструмент остановится, вакуум будет продолжаться в течение 4 секунд, чтобы очистить оставшуюся пыль.
  3. Если тот же инструмент будет использован в следующий раз, шаговый механизм останется в своем текущем положении. Но вакуумная система все равно должна работать.
  4. в настоящее время используются кнопки для имитации инструментов, а также один ACS712 для тестирования */ // предложение с MobaTools для управления функцией шагового двигателя и таймера #include <MobaTools.h>

// определяет номера контактов const int stepPin = 3; const int dirPin = 2; const int enPin = 8; const int vacPin = 4; //имитирует вакуумное реле

const int stepPer360Degree = 200; // Количество шагов за один оборот ( подстраивается под ваши потребности ) MoToStepper stepper ( stepPer360Degree, STEPDIR ); MoToTimer vacTimer; // для отложенного отключения const long runOnTime = 4000;

int na = 0; //угол

int analogValue = 0;

настройка void() { Serial.begin(9600);

// Setup the stepper stepper.attach( stepPin, dirPin ); stepper.setSpeedSteps( 1000, 20 ); // устанавливает скорость и длину рампы stepper.attachEnable( enPin, 100, LOW ); // Отключает через 100 мс. включено низко

pinMode(vacPin, OUTPUT); //Просто добавил это для vac

//установите значения для 2 выходов digitalWrite(vacPin, LOW); //просто добавьте это для vac

}

void loop() { analogValue = 0;

// Назначить градусы кнопок if ( analogRead(A0) > 600) { analogValue = (analogRead(A0)); Serial.print("AO = "); Serial.println(analogValue); na = 0;

} else if ( analogRead(A1) > 600) { analogValue = (analogRead(A1)); Serial.print("A1 = "); Serial.println(analogValue); na = 45; }

else if ( analogRead(A2) > 600) { analogValue = (analogRead(A2)); Serial.print("A2 = "); Serial.println(analogValue); na = 225; }

else if ( analogRead(A3) > 600) { //=tool on analogValue = (analogRead(A3)); Serial.print("A3 = "); Serial.println(analogValue); na = 270;

}

// при необходимости расположите stepper if ( stepper.read() != na ) stepper.write( na );

// start vac if tool is on and stepper is in position if (analogValue > 600 && !stepper.moving()) { digitalWrite(vacPin, HIGH); }

если ( vacTimer.expired() ) { // выключите ВПТ, если таймер истекает Serial.println( "Vac = off"); digitalWrite(vacPin, LOW); }

if (analogValue()) { // пусковой таймер для отключения переменного тока через некоторое время Serial.println( " start vac run-on-time" ); vacTimer.setTime( runOnTime ); }

} Если вы хотите попробовать, то библиотеку можно установить с помощью менеджера библиотек ( введите mobatools в поле поиска).

,