Управление двигателем Arduino Uno с помощью 2 реле, 2 концевых выключателей и Bluetooth. Вперед Назад Стоп

Изменен существующий проект по этой ссылке: Проблема: срабатывание концевого выключателя для остановки двигателя постоянного тока

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

  • Последовательный вход «А» включает одно реле. При нажатии Limitswitch1 это реле выключается.
  • Он определяет текущее состояние системы и ожидает последовательного входа «B», который затем включает второе реле. При нажатии Limitswitch2 это реле выключается.

Вопросы:

  1. Пожалуйста, помогите с кодом - мне нужен вариант, когда два реле выключаются на последовательном входе буквы 'S' и добавляются соответствующие конечные автоматы. По сути, чтобы добавить функцию остановки.

  2. Концевые выключатели работают с перебоями, иногда реагируют безотказно, иногда вообще никак. Я купил переключатели трех разных марок для тестирования, но все они ведут себя одинаково. Я напрасно дергал переключатели вверх и вниз резисторами. Я выполнил проверку количества кнопок, используя код с этого форума, и подтверждаю, что переключатель также ведет себя хаотично. Могут ли изменения в коде улучшить обратную связь при переключении?

Предложения будут приняты с благодарностью.

const byte RELAY1 = 2;
const byte RELAY2 = 3;

const byte LimitSwitch1 = A1;
const byte LimitSwitch2 = A2;

const byte State_Idle = 0;
const byte State_Forward = 1;
const byte State_Reverse = 2;
byte currentState;

void setup(){
pinMode(RELAY1,OUTPUT);
pinMode(RELAY2,OUTPUT);

pinMode(LimitSwitch1, INPUT);
pinMode(LimitSwitch2, INPUT);

Serial.begin(9600);
currentState = 0xFF; // Принудительное изменение для перехода в состояние ожидания
 }

void loop(){
// Проверяем, нужно ли нам изменить состояние
byte nextState = currentState;
switch (currentState)
{
case State_Idle:
    { // Если мы получили верную команду, запускаем операцию
        if(Serial.available() > 0)
        {
            switch (Serial.read())
            {
            case 'A':
                nextState = State_Forward;
                break;
            case 'B':
                nextState = State_Reverse;
                break;
            default:
                break;
            }
        }
    }
    break;
case State_Forward:
    if(digitalRead(LimitSwitch2))
        nextState = State_Idle;
    break;
case State_Reverse:
    if(digitalRead(LimitSwitch1))
        nextState = State_Idle;
    break;
default:
    nextState = State_Idle;
    break;
}

// Если было изменение, переключаем состояние и запускаем условие ввода
if (nextState != currentState)
{
    currentState = nextState; // Переходим в новое состояние
    switch (currentState)
    { // Вход в новое состояние
    case State_Idle:
        // Выключить оба реле
        digitalWrite(RELAY1, HIGH);
        digitalWrite(RELAY2, HIGH);
        break;
    case State_Forward:
        // Двигаться вперед
        digitalWrite(RELAY1, LOW);
        digitalWrite(RELAY2, HIGH);
        break;
    case State_Reverse:
        // Двигаться в обратном направлении
        digitalWrite(RELAY1, HIGH);
        digitalWrite(RELAY2, LOW);
        break;
    }
}
}

, 👍0

Обсуждение

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

Я хотел бы добавить функцию отключения реле после ввода буквы «S» на последовательном мониторе. также Case_Stop для определения состояния после остановки., @S B

@SB, так как этот вопрос много раз попадал на главную страницу, пожалуйста, заполните его или закройте. Если вы считаете, что приведенный ниже ответ полностью отвечает на ваш вопрос, отметьте его как принятый (зеленая галочка слева). Если это не решает проблему, прокомментируйте, почему, чтобы получить дальнейшую поддержку., @frarugi87


1 ответ


1

А вот и еще один захватывающий эпизод "Веселье с StateMachines".. ;)

Хорошо, в основном вы хорошо модифицировали код, но неправильно подумали об модификации.

Прежде всего опишите простыми словами, что вы хотите сделать. Допустим, вы этого хотите

Когда я двигаюсь в одном направлении и получаю букву "S", я немедленно останавливаюсь, не дожидаясь конечной остановки

Следовательно, вы знаете, что

  1. вам придется что-то добавить, когда вы движетесь в одном направлении
  2. это "что-то" превзойдет вас, что и делает концевик

Итак, чтобы реализовать это, вы можете сделать что-то вроде этого:

switch (currentState)
{
case State_Idle:
    { // Если мы получили верную команду, запускаем операцию
        if(Serial.available() > 0)
        {
            switch (Serial.read())
            {
            case 'A':
                nextState = State_Forward;
                break;
            case 'B':
                nextState = State_Reverse;
                break;
            default:
                break;
            }
        }
    }
    break;
case State_Forward:
    if(digitalRead(LimitSwitch2))
        nextState = State_Idle;
    else  if((Serial.available() > 0) && (Serial.read() == 'S'))
        nextState = State_Idle;
    break;
case State_Reverse:
    if(digitalRead(LimitSwitch1))
        nextState = State_Idle;
    else  if((Serial.available() > 0) && (Serial.read() == 'S'))
        nextState = State_Idle;
    break;
default:
    nextState = State_Idle;
    break;
}

Вашу вторую проблему немного сложнее понять. Когда я прочитал это, я сразу подумал о том, что Крисл уже указал, а именно о скачках переключателя. Но когда я был на полпути к завершению этой части ответа, я обнаружил, что ... нет, отказы - это не то, что может создать здесь проблемы, если только вы постоянно не пишете «A» или «B» в сериале. Итак, что касается второй части вопроса, пожалуйста, опубликуйте свою схему и/или фотографии установки, чтобы мы могли увидеть, есть ли что-то ненормальное

,