Проблемы с драйвером двигателя L298N

(отредактировано)

Так жаль, что я виноват. Чтобы было ясно:

Судя по картинке, которую я опубликовал, мне нужно нажать PBA (as Button1), чтобы оба двигателя могли работать вперед (CW-по часовой стрелке) и назад (CCW-против часовой стрелки) и остановиться.

В то время как с другой стороны, PBB (как button2) предназначен для другого условия, оба двигателя могут работать влево, вправо и останавливаться.

Проблемы:

  1. Когда я запускаю свой код, он появляется на ЖК-дисплее.

  2. Я смог добиться этого для стороны PBB, но для стороны PBA оба двигателя вообще не двигаются.

  3. Я использовал потенциометр, чтобы регулировать скорость. Потенциометр работает нормально.

  4. Я использую debounce для обеих моих кнопок, и я не уверен, влияет ли debounce на мой void setmode(int Mode, int MotorMode1){}

////////////////////////////////////////////////////////////////////////////////[![введите описание изображения здесь][1]][1]



boolean lastButton=LOW;
boolean currentButton = LOW;

boolean last1Button = LOW;
boolean current1Button = LOW;

boolean debounce(boolean last){
    boolean current = digitalRead(PBA);
    if (last != current) {
      delay(5);
      current = digitalRead(PBA);
      return current;
    }
  }

  boolean debounce1(boolean last1) {
    boolean current1 = digitalRead(PBB);
    if (last1 != current1) {
      delay(5);
      current1 = digitalRead(PBB);
      return current1;
    }
  }

  int Mode = 0;
  int motorMode1 = 0;

  
   


  void loop() {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("SPEED:");
    lcd.setCursor(0, 1);

    // потенциометр LCD
    float inputValue = analogRead (pot);
    inputValue = map(inputValue, 0, 1023, 0, 100);
    lcd.setCursor(7, 0);
    lcd.print (inputValue);
    lcd.setCursor(12, 0);
    lcd.print ("%");

    //считывание значений с потенциометра
    MotorSpeed = analogRead(SpeedControl);
    MotorSpeed = map(MotorSpeed, 0 , 1023 , 0 , 255);
    // отрегулируйте для предотвращения на низкой скорости
    if (MotorSpeed < 8)MotorSpeed = 0;
    //установка частоты вращения двигателя
    //analogWrite (enA, MotorSpeed);
    //analogWrite (enB, MotorSpeed);
    // MotorLCD
    lcd.setCursor(0, 1);
    lcd.print("MOVE:");
 
    currentButton = debounce(lastButton);
    if (currentButton == HIGH && lastButton == LOW) {
      Mode++;
    }
    lastButton = currentButton;
    if (Mode == 3){
      Mode = 0;
    }


    current1Button = debounce1(last1Button);
    if (last1Button == HIGH && current1Button == LOW) {
      motorMode1++;
  
    }
    last1Button = current1Button;
    if (motorMode1 == 3){
      motorMode1 = 0;
    }
  
  setMode( Mode, motorMode1);  
  
 }
  


  void setMode(int Mode, int motorMode1) {
    analogWrite (enA, MotorSpeed);
    analogWrite (enB, MotorSpeed);

    
    if (Mode == 1 ) {
      lcd.setCursor(5, 8);
      lcd.print("Forward");

      //MOTOR_A МАКСИМАЛЬНАЯ СКОРОСТЬ ПО ЧАСОВОЙ СТРЕЛКЕ
      digitalWrite(in1, HIGH);
      digitalWrite(in2, LOW);

      //MOTOR_B МАКСИМАЛЬНАЯ СКОРОСТЬ ПО ЧАСОВОЙ СТРЕЛКЕ
      digitalWrite(in3, HIGH);
      digitalWrite(in4, LOW);
    }
    if (Mode == 2) {
      lcd.setCursor(5, 8);
      lcd.print("Reverse");

      //MOTOR_A МАКСИМАЛЬНАЯ СКОРОСТЬ ПРОТИВ ЧАСОВОЙ СТРЕЛКИ
      digitalWrite(in1, LOW);
      digitalWrite(in2, HIGH);

      //MOTOR_B МАКСИМАЛЬНАЯ СКОРОСТЬ ПРОТИВ ЧАСОВОЙ СТРЕЛКИ
      digitalWrite(in3, LOW);
      digitalWrite(in4, HIGH);

    }
     

   if (motorMode1 == 1) {

      lcd.setCursor(5, 8);
      lcd.print("Right");
      //MOTOR_A МАКСИМАЛЬНАЯ СКОРОСТЬ ПО ЧАСОВОЙ СТРЕЛКЕ
      digitalWrite(in1, LOW);
      digitalWrite(in2, HIGH);
      //MOTOR_B МАКСИМАЛЬНАЯ СКОРОСТЬ ПРОТИВ ЧАСОВОЙ СТРЕЛКИ
      digitalWrite(in3, HIGH);
      digitalWrite(in4, LOW);

    }
    if (motorMode1 == 2) {
      lcd.setCursor(5, 8);
      lcd.print("Left");
      //MOTOR_A МАКСИМАЛЬНАЯ СКОРОСТЬ ПРОТИВ ЧАСОВОЙ СТРЕЛКИ
      digitalWrite(in1, HIGH);
      digitalWrite(in2, LOW);
      //MOTOR_B МАКСИМАЛЬНАЯ СКОРОСТЬ ПО ЧАСОВОЙ СТРЕЛКЕ
      digitalWrite(in3, LOW);
      digitalWrite(in4, HIGH);

    }
     if (Mode == 0 || motorMode1 == 0) {
      lcd.setCursor(5, 8);
      lcd.print("Stop");
      digitalWrite(in1, LOW);
      digitalWrite(in2, LOW);
      digitalWrite(in3, LOW);
      digitalWrite(in4, LOW);
    }           
  }

, 👍1

Обсуждение

Если вы хотите, чтобы кто-то помог вам, правильно отформатируйте код и сократите его только для того, чтобы сосредоточиться на той области, которая, по вашему мнению, потенциально вызвала проблему., @hcheung

Для этого в IDE есть пункт меню Инструменты / автоформат., @timemage

Кстати: В чем вопрос? И что вы подразумеваете под асинхронностью и синхронностью? И почему вы используете два имени для вывода A0 (pot, SpeedControl)? Почему вы называете выходные контакты "inX"? Почему вы сначала устанавливаете inX в функции mode в зависимости от переменной Mode, а затем перезаписываете ее в зависимости от переменной motorMode1? Но самый важный вопрос: чего вы хотите достичь? Попробуйте объяснить это, и, возможно, вы сами увидите, что происходит не так. Мы могли бы помочь, если бы знали, каковы ваши цели. Только глядя на код, я не могу сказать, что вы пытаетесь сделать. ;-), @Peter Paul Kiefer

Привет, Питер, я уже загрузил фотографию, чтобы вы могли правильно понять. 1. почему вы используете два имени для вывода A0 (pot, SpeedControl)? Я объявил дважды с другой функцией, и это вызвало путаницу, и я удалил ее. 2. Почему вы называете выходные контакты "inX"? Почему вы сначала устанавливаете inX в функции mode в зависимости от переменной Mode, а затем перезаписываете ее в зависимости от переменной motorMode1? inX - для выхода двигателя Ln298 имеется 4 выхода inX. и 2 выхода enX под ШИМ. Спасибо за комментарии. :D, @Chow Wye En


1 ответ


Лучший ответ:

1

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

Я решил отредактировать вашу программу. У меня нет оборудования, чтобы попробовать это. Так что это просто пример, чтобы показать вам эту идею. Возможно, это работает так, как есть.

Пожалуйста, проверьте комментарии. Если вы действительно заинтересованы в понимании проблемы и решения, а вещи неясны, вы (или другие) можете спросить с комментариями ниже. И конечно, если вы найдете ошибку, я буду рад узнать об этом и исправить ее. ;-)

#include <Wire.h>
#include <LiquidCrystal_I2C.h>


// Это разные состояния движения
#define STATE_STOP 0
#define STATE_LEFT 1
#define STATE_RIGHT 2
#define STATE_FORWARD 3
#define STATE_BACKWARD 4

// всегда используйте выразительные имена

// Назначение выводов
//////////////////////////////////////////////

// Analog
int pinPotiSpeed = A0;

// Двигатель A
int pinEnA = 9;
int pinInA1 = 8;
int pinInA2 = 7;

// Двигатель B
int pinEnB = 3;
int pinInB1 = 5;
int pinInB2 = 4;

// Кнопки
const int pinBtnDir = 10;
const int pinBtnTurn = 11 ;

int stateMotors = STATE_STOP;
boolean flagBtnDirPressed = LOW;
boolean flagBtnTurnPressed = LOW;

int stateMotorsSpeed = 0;
int speedPercent = map( stateMotorsSpeed, 0, 255, 0, 100 );

LiquidCrystal_I2C lcd(0x27, 16, 2);

// У меня нет времени много думать об этом разоблачении, но
// У меня плохое предчувствие. Если Arduino не реагирует на нажатия кнопок 
// или смена режима на быстрый, пожалуйста, дайте мне знать. Я посмотрю на это, если
// необходимо. ;-)
boolean readButtonAndDebounce(int btnPin, boolean lastState)
{
    boolean actualState = digitalRead(btnPin);
    if (lastState != actualState) 
    {
      delay(15);
      actualState = digitalRead(btnPin);
      return actualState;
    }

    // этот возврат отсутствовал в исходной программе
    return actualState;
}

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

    pinMode(pinEnA, OUTPUT);
    pinMode(pinInA1, OUTPUT);
    pinMode(pinInA2, OUTPUT);

    pinMode(pinEnB, OUTPUT);
    pinMode(pinInB1, OUTPUT);
    pinMode(pinInB2, OUTPUT);

    pinMode(pinBtnDir, INPUT);
    pinMode(pinBtnTurn, INPUT);

    digitalWrite(pinInA1,LOW);
    digitalWrite(pinInA2,LOW);
    
    digitalWrite(pinInB1,LOW);
    digitalWrite(pinInB2,LOW);

    lcd.init();
    lcd.backlight();

    

    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("SPEED:");
    lcd.setCursor(0, 1);

    lcd.setCursor(7, 0);
    // преобразовать 0-255 в 0%-100%
    lcd.print ("0 %");

    lcd.setCursor(0, 1);
    lcd.print("MOVE: Stop");
}

void loop() 
{
    stateMotorsSpeed = map( analogRead( pinPotiSpeed ), 0, 1023, 0, 255 );
    if ( stateMotorsSpeed < 8 ) stateMotorsSpeed = 0;
    speedPercent = map( stateMotorsSpeed, 0, 255, 0, 100 );

    boolean flagBtnDirPressedOld = flagBtnDirPressed;
    flagBtnDirPressed = readButtonAndDebounce( pinBtnDir, flagBtnDirPressed );

    boolean flagBtnTurnPressedOld = flagBtnTurnPressed;
    flagBtnTurnPressed = readButtonAndDebounce( pinBtnTurn, flagBtnTurnPressed );


    // this is a bit tricky, because I don't know if i understood the problem correctly.
    // Моя проблема в том, что произойдет, если обе кнопки будут нажаты, я решил дать 
    // кнопка направления приоритет
    if ( flagBtnDirPressed && ! flagBtnDirPressedOld )
    {
      switch( stateMotors )
      {
        case STATE_STOP:
          stateMotors = STATE_FORWARD;
          break;
        
        case STATE_FORWARD:
          stateMotors = STATE_BACKWARD;
          break;
      
        case STATE_BACKWARD:
          stateMotors = STATE_STOP;
          break;

        default:
          // это происходит, если состояние из другой кнопки активно
          // В таблице нет правила, что делать в этом случае.
          // Возможно, вы могли бы посчитать нажатие кнопки по модулю 3 для каждой кнопки
          // и тогда вы можете переключиться в правильное состояние
          stateMotors = STATE_STOP;
      }

    }
    else if ( flagBtnTurnPressed && ! flagBtnTurnPressedOld )
    {
      // вводится только в том случае, если состояние нажатия кнопки направления не изменилось
      switch( stateMotors )
      {
        case STATE_STOP:
          stateMotors = STATE_RIGHT;
          break;
        
        case STATE_RIGHT:
          stateMotors = STATE_LEFT;
          break;

        case STATE_LEFT:
          stateMotors = STATE_STOP;
          break;

        default:
          // это происходит, если состояние из другой кнопки активно
          stateMotors = STATE_STOP;
      }
    }

    controlMotorAndUpdateLcd();
}

void setMotorSignals( boolean sigA1 , boolean sigA2, boolean sigB1, boolean sigB2 )
{
      //MOTOR_A
      digitalWrite(pinInA1, sigA1);
      digitalWrite(pinInA2, sigA2);

      //MOTOR_B
      digitalWrite(pinInB1, sigB1);
      digitalWrite(pinInB2, sigB2);
}
  
void controlMotorAndUpdateLcd() 
{
    lcd.clear();
    lcd.setCursor( 0, 0 );
    lcd.print( "SPEED:" );
    lcd.setCursor( 0, 1 );

    // потенциометр LCD
    lcd.setCursor( 7, 0 );
    lcd.print ( speedPercent );
    lcd.setCursor( 12, 0 );
    lcd.print ("%");

    analogWrite ( pinEnA, stateMotorsSpeed );
    analogWrite ( pinEnB, stateMotorsSpeed );

    // MotorLCD
    lcd.setCursor(0, 1);
    lcd.print("MOVE:");

    lcd.setCursor(5, 8);
    switch( stateMotors )
    {
      case STATE_STOP:
        lcd.print("Stop");
        setMotorSignals( LOW, LOW, LOW, LOW);
        break;
        
      case STATE_FORWARD:
        lcd.print("Forward");
        setMotorSignals( HIGH, LOW, HIGH, LOW);
        break;
      
      case STATE_BACKWARD:
        lcd.print("Reverse");
        setMotorSignals( LOW, HIGH, LOW, HIGH);
        break;

       case STATE_LEFT:
        lcd.print("Left");
        setMotorSignals( HIGH, LOW, LOW, HIGH);
        break;
      
      case STATE_RIGHT:
        lcd.print("Right");
        setMotorSignals( LOW, HIGH, HIGH, LOW);
        break;
    }
}
,

Спасибо за помощь.. На Жидкокристаллическом дисплее все еще есть некоторые сбои. Ты хоть представляешь, почему? Когда я запускаю void setup в части "добро пожаловать", она все еще работает нормально, пока не достигнет конечного состояния части, где "Скорость" и "Движение". Формулировка неясна, и у некоторых есть некоторые сбои., @Chow Wye En

1. Извините, я не понимаю, что вы подразумеваете под "глюками". Вы имеете в виду, например, что значение скорости быстро меняется? Я могу помочь только в том случае, если точно знаю причину ошибки. 2. Я не могу вам помочь с формулировкой, но вы можете использовать тексты, которые вам больше подходят., @Peter Paul Kiefer

Все в порядке, Питер. Я постараюсь решить ее сам. Большое спасибо, Питер. , @Chow Wye En