DC motor code help

Can someone help me configure this code to properly run a dc motor via a L298N?

Basically, the way the DC motor is connected seems unnecessary and I could not get it to work properly. I now have the DC motor connected directly to OUT1 and OUT2, then EnA to D10, In1 to D9, and In2 to D8.

My question is, how do I change the code to reflect this? It looks like I need to change motorPWM to 10. What about voltPin A0? Since I scrapped the schematic way, what changes do I need to make? Any help would be appreciated. Thank you.

//##################  Adjust these values accordingly #######################################

#define chB 2                           //***pin B of the rotary encoder (channel B)
#define chA 3                           //***pin A of the rotary encoder (channel A)
#define motorDir1 9                     //***motor direction forward pin to driver
#define motorDir2 10                    //***motor direction reverse pin to driver            
#define motorPWM 6                      //***PWM pin to motor controller 
#define pushButton 7                    //***Button pin
#define voltPin A0                      //***Analog pin for motor voltage measurement
#define arduinoVoltage 4.98             //***Actual measured 5 volt pin from the arduino
#define R1 25                           //***Actual resistance of 100k resistor
#define R2 8.95                         //***Actual resistance of 10k resistor
float rpmPerVolt = (4825 / 12);         //***DC motor max RPM (4825) divided by max voltage (12VDC. Measure both paraments and adjust
LiquidCrystal_I2C lcd(0x27, 20, 4);     //***Adjust screen address if needed. Use File > Examples > Wire > i2c_scanner to acquire address and change 0x3F as needed.

//##################  End of adjustable parameters #######################################

int eeAddress = 0;
int pwmMax;
int pwmVal = 0;
bool setFlag = false;

int fanSpeed = 0;                   //speed of the turbofan in RPM
int mtrSpeed = 0;                   //speed of the motor in RPM
int deadBand = 20;                  //minimum PWM signal for the motor to move
float vout = 0.0;                   //Voltage out of the motor
float roughVoltage = 0.0;
int avgInst = 350;                  //this should equal the sizeof(tempArray)
int voltCount = 0;
float tempArray[350];               //temp array for averaging voltage readings: array size = number of averaging points
float finalVolt = 0.0;              //averaged result
float oldVolt = 0.0;                //check to see if voltage changes after each loop

long timeNew = 0;                   //time stamp at beginning of loop
long timeOld = 0;                   //time stamp at end of end
long tempTimer = 0;
long oldPos = 0;                    //old position of the encoder
long newPos = 0;                    //new position of the encoder

Encoder myEncoder(chA, chB);

void setup() {
  //Serial.begin(115200);
  pinMode(voltPin, INPUT);
  pinMode(motorDir1, OUTPUT);
  pinMode(motorDir2, OUTPUT);
  pinMode(motorPWM, OUTPUT);
  pinMode(pushButton, INPUT_PULLUP);
  pinMode(chA, INPUT_PULLUP);
  pinMode(chB, INPUT_PULLUP);

  myEncoder.write(oldPos);
  digitalWrite(motorDir1, HIGH);  //motor direction (FWD = HIGH). DON'T CHANGE. SWITCH THE WIRES IF DIRECTION IS WRONG
  digitalWrite(motorDir2, LOW);   //motor direction (REV = LOW). DON'T CHANGE. SWITCH THE WIRES IF DIRECTION IS WRONG
  analogWrite(motorPWM, 0);

  lcd.init();
  lcd.setCursor ( 3, 0 );
  lcd.print("Turbofan Driver");
  lcd.setCursor ( 0, 2 );
  lcd.print("Adam B. Johnson");
  lcd.setCursor( 0, 3);
  lcd.print("BC, Canada");
  lcd.setCursor ( 16, 3 );
  lcd.print("2021");

  delay(4500);
  lcd.clear();
  screenSetup();
  zeroNums();
  printSpeeds();
  printVoltage();
  myEncoder.write(0);
  analogWrite(motorPWM, 0);
}

void loop() {
  newPos = myEncoder.read() ;
  timeNew = millis();
  EEPROM.get(eeAddress, pwmMax);

  if (voltCount < avgInst) {
    vout = (analogRead(voltPin) * arduinoVoltage) / 1024.0;             //Measure your 5VDC rail to ground with your DMM. Change 4.98 to whatever yours is
    roughVoltage = vout / (R2 / (R1 + R2));
    tempArray[voltCount] = roughVoltage;
  } else {
    voltCount = 0;
  }

  if (newPos > 0) {
    //Serial.println(newPos);
    if (timeNew - timeOld > 300) {
      finalVolt = 0.0;
      for (int i = 0; i < avgInst; i++) {
        finalVolt += tempArray[i];
      }
      timeOld = timeNew;
      finalVolt = finalVolt / avgInst;
      if (abs(finalVolt - oldVolt) > 0.03) {
        mtrSpeed = rpmPerVolt * finalVolt;
        fanSpeed = mtrSpeed / gearRatio;
        oldVolt = finalVolt;
        clearNums();
        printVoltage();
        printSpeeds();
      }
    }
  }
  voltCount++;

  if ((newPos != oldPos) && (newPos > 0) && (newPos < pwmMax - deadBand)) {
    pwmVal = newPos + deadBand;
    analogWrite(motorPWM, pwmVal);
    oldPos = newPos;
  }
  if ((newPos != oldPos) && (newPos <= 0) && (newPos < pwmMax - deadBand)) {
    delay(250);
    myEncoder.write(0);
    analogWrite(motorPWM, 0);
    clearNums();
    zeroNums();
    delay(50);
    myEncoder.write(0);
    analogWrite(motorPWM, 0);
  }
  if ((newPos != oldPos) && (newPos > 0) && (newPos >= pwmMax - deadBand)) {
    myEncoder.write(4 * (pwmMax - deadBand));
    analogWrite(motorPWM, pwmVal);
    pwmVal = pwmMax;
    oldPos = pwmMax - deadBand;
    mtrSpeed = mtrSpeed = rpmPerVolt * finalVolt;
    fanSpeed = mtrSpeed / gearRatio;
  }


  if (digitalRead(pushButton) == LOW) {
    //Serial.print("buttonPressed");
    delay(25);
    if (digitalRead(pushButton) == LOW) {
      //Serial.print("buttonStillPressed");
      setFlag = false;
      delay(500);
      if (digitalRead(pushButton) == LOW) {
        EEPROM.put(eeAddress, pwmVal);
        for (int i = 0; i < 20; i++) {
          lcd.setCursor(i, 0);
          lcd.print(" ");
        }
        lcd.setCursor(1, 0);
        lcd.print("Max Speed Set: ");
        lcd.setCursor(16, 0);
        lcd.print(fanSpeed);
        delay(3000);
        if (digitalRead(pushButton) == LOW) {
          EEPROM.put(eeAddress, 255);
          for (int i = 0; i < 20; i++) {
            lcd.setCursor(i, 0);
            lcd.print(" ");
          }
          lcd.setCursor(2, 0);
          lcd.print("Max Speed Reset");
          delay(3000);
        }
        for (int i = 0; i < 20; i++) {
          lcd.setCursor(i, 0);
          lcd.print(" ");
        }
        lcd.setCursor(3, 0);
        lcd.print("Turbofan Stats");
        setFlag = true;
      }
      if (setFlag == false) {
        myEncoder.write(0);
        analogWrite(motorPWM, 0);
        clearNums();
        zeroNums();
        setFlag = true;
      }
    }
  }

}



void printVoltage() {
  if ((finalVolt > 0) && (finalVolt < 10.0)) {
    lcd.setCursor (12, 3 );
  } else if ((finalVolt < 15.0) && (finalVolt >= 10.0)) {
    lcd.setCursor (11, 3 );
  } else {
    lcd.setCursor (12, 3 );
    finalVolt = 0;
  }
  lcd.print(finalVolt, 2);
}


void printSpeeds() {
  if (fanSpeed < 100 && fanSpeed >= 10) {
    lcd.setCursor(14, 1);
  } else if (fanSpeed < 1000 && fanSpeed >= 100) {
    lcd.setCursor (13, 1 );
  } else if (fanSpeed < 10000 && fanSpeed >= 1000) {
    lcd.setCursor (12, 1 );
  } else if (fanSpeed == 0) {
    lcd.setCursor (15, 1 );
  } else {
    lcd.setCursor (15, 1 );
    fanSpeed = 0;
  }
  lcd.print(fanSpeed);
  if (mtrSpeed < 100 && mtrSpeed >= 10) {
    lcd.setCursor(14, 2);
  } else if (mtrSpeed < 1000 && mtrSpeed >= 100) {
    lcd.setCursor (13, 2 );
  } else if (mtrSpeed < 10000 && mtrSpeed >= 1000) {
    lcd.setCursor (12, 2 );
  } else if (mtrSpeed == 0) {
    lcd.setCursor (15, 2 );
  } else {
    lcd.setCursor (15, 2 );
    mtrSpeed = 0;
  }
  lcd.print(mtrSpeed);
}


void clearNums() {
  for (int i = 11; i < 17; i++) {
    for (int j = 1; j < 4; j++) {
      lcd.setCursor (i, j);
      lcd.print(" ");
    }
  }
}


void zeroNums() {
  oldPos = 0;
  mtrSpeed = 0;
  fanSpeed = 0;
  finalVolt = 0;
  delay(100);
  printSpeeds();
  printVoltage();
}


void screenSetup() {
  lcd.setCursor ( 3, 0 );
  lcd.print("Turbofan Stats");
  lcd.setCursor ( 0, 1 );
  lcd.print("Fan Speed:");
  lcd.setCursor (17, 1 );
  lcd.print("RPM");
  lcd.setCursor ( 0, 2 );
  lcd.print("Mtr Speed:");
  lcd.setCursor (17, 2 );
  lcd.print("RPM");
  lcd.setCursor ( 0, 3 );
  lcd.print("Voltage:");
  lcd.setCursor (17, 3 );
  lcd.print("VDC");
}

Hi,
What is the motor voltage supply?

What is t he purpose of A0 analog input?

Can I suggest you for the moment, dump that code, and write some code that JUST tries to run the motor, nothing else, this will make sure you have control before adding encoders etc.

Can you please post a link to data/specs of your motor?

Your circuit appears to be part of a bigger assembly, can I also suggest you JUST make a circuit that only concerns the motor and the 289, there are more efficient motor drivers around but it will work.

Tom… :smiley: :+1: :coffee: :australia:

The motor is a 12v DC motor, rated current 2A.

I did run a test where it was just the dc motor, l298n and arduino and it worked great.

I’m not really sure the point of the A0 pin and I don’t really know enough about code to do it myself. I was hoping I could just change the pins and delete the A0 and be good to go but it’s not responding to the encoder. I have tested everything Independently and it works, but I just can’t get the encoder to control the dc motor for the life of me.

You cannot read motor voltage like that, motor voltage is pulsating 0V to 12V at the PWM frequency, (980Hz in your case). Use the pulse count from the encoder to compute speed.

Connecting one of the outputs of the L298 to ground is a sure way of killing it.
Leo…

Hi,
I think this is what you are trying to achieve with the potential divider and A0;

Tom… :smiley: :coffee: :australia:

I believe the L298 outputs can be paralleled as long as correct polarity is maintained, but the motor speed cannot be obtained by reading the pulsating voltage with analogRead. Also, the L298N does not have kickback diodes, is yours on a module or a bare IC?

What encoder?
Can you please post a link to spec/data for the motor and the “encoder”?

Thanks… Tom… :grinning: :+1: :coffee: :australia:

Sorry for the delayed response.

Here is a picture of the entire schematic:

Rotary encoder spec:
https://tech.alpsalpine.com/prod/e/html/encoder/incremental/ec11/ec11e1834403.html

DC motor:

Also, I've taken pictures of the board itself. Maybe you can spot an issue with my connections??


This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.