Прерывания в Critical Statements
Я переделал предыдущий скетч Arduino, который я опубликовал, в котором у меня были проблемы с захватом количества кодировщиков в критических заявлениях, не удавалось правильно прикреплять и отсоединять прерывания. Я изучил различные скетчи ISR, но не смог создать ничего, что отвечало бы моим потребностям.
Теперь у меня есть корпус переключателя, в котором двигатель постоянного тока с кодером CPR правильно вращается взад и вперед между указанными границами, если он один находится в пустом контуре. Однако, будучи заключенным в критическое утверждение (я хочу, чтобы это действие происходило только при нажатии кнопки), двигатель постоянного тока продолжает вращаться только в одном направлении.
Мне нужна помощь в том, где правильно подключить и отсоединить эти прерывания и как правильно передать значение кодера следующему действию. Ниже приведено то, что я сделал до сих пор, и любая помощь будет очень признательна.
#define enA 9
#define in1 6
#define in2 7
const int button1Pin = 8;
int button1State = 0;
volatile long temp, counter = 0;
long local_counter=counter;
enum {IdleState, ForwardState, BackwardState} State;
void setup() {
Serial.begin(9600);
pinMode(enA, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
Serial.begin (9600);
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
attachInterrupt(0, ai0, RISING);
attachInterrupt(1, ai1, RISING);
pinMode(button1Pin, INPUT);
State = IdleState;
}
void loop() {
button1State = digitalRead(button1Pin);
if( counter != temp ){
Serial.print("counter = ");
Serial.print (counter);
Serial.print(" local counter = ");
Serial.println(local_counter);
temp = counter;
}
//if (button1State == HIGH) {
switch (State) {
case IdleState:
halt ();
if (counter<2000)
State = ForwardState;
break;
case ForwardState:
clockwise();
if (counter>=2000)
State = BackwardState;
break;
case BackwardState:
counterclockwise();
if (counter <=0)
State = ForwardState;
break;
} // end switch
// }
}
void ai0() {
if(digitalRead(3)==LOW) {
counter++;
}else{
counter--;
}
}
void ai1() {
if(digitalRead(2)==LOW) {
counter--;
}else{
counter++;
}
}
void clockwise (){
analogWrite(enA, 255);
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
}
void counterclockwise () {
analogWrite(enA, 255);
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
}
void halt () {
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
}
Объяснение моей настройки выглядит следующим образом:
Моя кнопка-это тактильная кнопка на макете (подключена к контакту 8 Arduino Uno) с питанием 5 В от Arduino. Контакты 6 Arduino подключены к входу 1 драйвера двигателя L298N, вывод 7 Arduino подключен к входу 2 драйвера двигателя, а вывод 9 Adruino подключен к разъему включения драйвера двигателя. Их драйвер двигателя питается от внешнего источника питания 12 В, который также питает мотор-редуктор постоянного тока 12 В с энкодером. Выходы кодера подключены к контактам 2 и 3 Arduino.
@wickedhurricane, 👍4
Обсуждение1 ответ
Насколько я понимаю, состояние должно вернуться в состояние ожидания, если кнопка не нажата. Просто поместите корпус переключателя внутрь оператора if, и двигатель продолжит вращаться так же, как он вращался, когда кнопка была отпущена.
if (button1State == LOW ) {
State = IdleState;
counter=2000;
}
else if(button1State==HIGH && State==IdleState ) {
counter = 0;
}
switch(State) {
...
В зависимости от того, что вы хотите сделать, вы можете добавить другое состояние (скажем,
StoppedState), в котором двигатели остановлены, как в режиме ожидания, но вы не получите изменения состояния, если счетчик<2000
. Тогда вам не нужно менять переменную счетчика
.
if (button1State == LOW ) {
State = StoppedState;
}
else if(button1State==HIGH && State==StoppedState ) {
State = IdleState;
}
switch(State) {
case StoppedState:
halt ();
break;
case IdleState:
...
PS пожалуйста, сделайте отступы в утверждениях if внутри вашего дела
s.
На самом деле я хочу, чтобы он непрерывно вращался вперед и назад, даже после нажатия кнопки. Позже я планирую добавить кнопки для остановки и поворота в одном указанном направлении. Итак, если я хочу, чтобы это непрерывное движение вперед и назад продолжалось после нажатия кнопки, следует ли изменить первое утверждение IF (кнопка == НИЗКИЙ)? Я пытался удалить его, но это не помогает., @wickedhurricane
Какая часть вашего кода заставит его остановиться и пойти другим путем? Это внутри оператора if, который выполняется только при нажатии кнопки? Тогда это произойдет только в том случае, если кнопка не нажата. Позвольте кнопке нажать выбрать состояние. Пусть переключатель работает все время., @Delta_G
Я полагаю, что это должна быть первая часть инструкции IF для того, когда кнопка находится на низком уровне, поскольку "счетчик=2000" - условие для движения против часовой стрелки. Я пытался изменить или удалить это условие без какого-либо успеха. Должен ли я больше сосредоточиться на втором предложении Гербена? Похоже, он ведет себя так же, как и первый в моих попытках., @wickedhurricane
Я в замешательстве. Вы хотите, чтобы двигатель ничего не делал, пока не будет нажата кнопка? А затем переходить туда и обратно, независимо от того, нажата кнопка или нет? Если это так, перейдите ко второму решению, но опустите "State = StoppedState;" в операторе if и поместите это в настройку (вместо State = IdleState
)., @Gerben
Ты выйдешь за меня замуж, Гербен???!!! Это именно то, чего я хотел, и это сработало!!! Но медовый месяц длится недолго, я добавил вторую кнопку, чтобы остановиться, но все, что она делает, это поворачивается против часовой стрелки при нажатии: если(button2State==ВЫСОКИЙ){ Состояние = остановленное состояние; } Будет ли корпус коммутатора не работать с этой настройкой?, @wickedhurricane
Код, который вы предоставили, выглядит нормально, поэтому я не уверен, в чем проблема. Пожалуйста, опубликуйте свой код, так как я все еще немного в замешательстве. А твое предложение руки и сердца еще больше сбивает меня с толку. Я думаю, что было бы лучше создать новый вопрос., @Gerben
Извините, я по натуре человек сбивающий с толку, но была также проблема с моим кодом для остановки (), который я исправил, и теперь моя вторая кнопка правильно останавливает двигатель. Но я добавил третью кнопку, при нажатии я хочу, чтобы двигатель непрерывно двигался по часовой стрелке, поэтому я добавил следующее: если(button3State==ВЫСОКИЙ){по часовой стрелке ();}, но это ничего не делает. Должен ли я создать другое состояние или функцию void? <-- но мне это кажется необходимым. Я действительно могу опубликовать это как еще один вопрос, если вы чувствуете, что это лучше всего., @wickedhurricane
Похоже, ты решил нашу проблему с медовым месяцем. Для третьей задачи используйте вместо этого " while(button3State==HIGH){по часовой стрелке ();}". Таким образом, оператор switch не вызывается сразу после него и отрицает вращение по часовой стрелке. Добавление отдельного состояния также будет работать и, вероятно, приведет к более приятному и легкому для чтения коду., @Gerben
Это сработало; однако оно не прерывается действием кнопки 3 при нажатии кнопки 1 или 2. Я также попробовал это: в то время как(button3State==ВЫСОКИЙ&&button1State==НИЗКИЙ&&button2State==НИЗКИЙ){ по часовой стрелке();} но это действительно ничего не меняет. Мы так близки!!!, @wickedhurricane
Я добавил другое состояние, и кнопка 3 работает, но затем кнопка 1 больше не работает ПОСЛЕ нажатия кнопки 3 (кнопка 2 работает в любое время)., @wickedhurricane
Неважно, я понял это....и под "я" я имею в виду 99% StackExchange и 1% меня. У меня возникла проблема со значением счетчика, его нужно было сбросить до 0, прежде чем кнопка 1 сможет нормально работать. Я не могу отблагодарить вас всех как следует, потому что теперь мы можем разойтись в разные стороны...Я думаю, мы разводимся :(, @wickedhurricane
Это было на 100% то, что искал SE. Так что "Ты" решил это на 100% самостоятельно. Я думаю, этому не суждено было случиться ;-p, @Gerben
- Управление скоростью вентилятора с помощью библиотеки Arduino PID
- Как устранить шум от вентилятора 12 В с ШИМ-управлением на низкой скорости
- Arduino uno + cnc Shield v3 + драйвер шагового двигателя A4988 + AccelStepper?
- Как заставить сервопривод вращаться на угол больше 180°
- Почему Adafruit motor shield не крутит моторы?
- Как управлять 6 шаговыми двигателями с помощью Arduino?
- Пропорциональный контроль расхода воды
- L298N Dual Motor Controller Enable Pin имеет питание, но двигатели не работают
что такое критическое утверждение?, @jsotola
Для остановки не следует ли вам отключить этот контакт включения?, @Delta_G
Установка НИЗКОГО значения in1 и ВЫСОКОГО значения on2 в "halt ()" кажется неправильной, @Sim Son