L298N Driver Motor Programming Issue

Hello, so I'm currently working on my project. For my project, is to make an automatic water - oil separator system using laser sensor and water level sensor. I have got the wiring for the components done and correct now I'm stuck at the code for using the L298N Driver Motor. I'm using these components as follows:

  • Arduino UNO R3
  • KY-008 Laser Module
  • Laser Receiver Module
  • 5 V Relay
  • Solu SLO67 Water Level Sensor
  • Driver Motor L298N
  • 12 V Pump with 4.2W (2)
  • 12 V Diaphragm Pump

An overview for my project is to automatically separate water from oil. Firstly the diaphragm pump will pump out mixed water and oil to a tank, the pump will automatically stop if it reach the Solu SLO67 Water Level Sensor. Second, the system stops (delays) for 40 seconds so the water and oil can naturally be separated in the tank, and then the KY-008 Laser Module which is aligned to the Laser Receiver Module will activate and with this trigger will activate the 12V, 4.2 W pump connected to the OUT1 and OUT2 L298N Driver Module to pump out the bottom layer of water first. Third if the layer of water is fully pumped then the Laser Receiver Module will deactivate because the KY-008 Laser Module can't penetrate through the oil, so the other 12V, 4.2 W pump connected to the OUT3 and OUT4 L298N Driver Module will activate and pump out the remaining left oil in the tank. Lastly, the system will reset and go back to step one.

I'm having problems with the code for the L298N with OUT 3 and OUT 4 seems to be activated when the systems starts, but when the Solu SLO67 Water Level Sensor is detected, the diaphragm pump deactivate but the L298N with OUT1 and OUT2 activated, is there any way to solve this problem? and how to make the system automatically resets to the top of the program? thank you in advance.

int motor1pin1 = 2; //OUT 1 PIN
int motor1pin2 = 3; //OUT 2 PIN
int motor2pin1 = 4; //OUT 3 PIN
int motor2pin2 = 5; //OUT 4 PIN
int Laser = 6; //KY-008 laser module
int LaserSensor = 7; //laser receiver
int RelayPump = 8; //5V relay
int WaterSensor = 9; //Solu SLOO87 water level sensor

void setup() {
  Serial.begin(9600);
  pinMode(Laser, OUTPUT);
  pinMode(LaserSensor, INPUT);
  pinMode(WaterSensor, INPUT);
  pinMode(RelayPump, OUTPUT);
  pinMode(motor1pin1, OUTPUT);
  pinMode(motor1pin2, OUTPUT);
  pinMode(motor2pin1, OUTPUT);
  pinMode(motor2pin2, OUTPUT);
  digitalWrite(Laser, LOW);
  digitalWrite(RelayPump, LOW);
  digitalWrite(motor1pin1, LOW);
  digitalWrite(motor1pin2, LOW);
  digitalWrite(motor2pin1, LOW);
  digitalWrite(motor2pin2, LOW);
}

void loop() {
  int SensorValue = digitalRead(WaterSensor);
  if (SensorValue >= 1)
  {
    digitalWrite(RelayPump, HIGH);
    digitalWrite(Laser, HIGH);
    digitalWrite(motor1pin1, LOW);
    digitalWrite(motor1pin2, LOW);
    digitalWrite(motor2pin1, LOW);
    digitalWrite(motor2pin2, LOW);
  }
  int LaserDetected = digitalRead(LaserSensor);
  if (LaserDetected == HIGH)
  {
    digitalWrite(motor1pin1, HIGH);
    digitalWrite(motor1pin2, LOW);
    digitalWrite(motor2pin1, LOW);
    digitalWrite(motor2pin2, LOW);
    delay(45000);
  } else {
    digitalWrite(motor1pin1, LOW);
    digitalWrite(motor1pin2, LOW);
    digitalWrite(motor2pin1, LOW);
    digitalWrite(motor2pin2, HIGH);
  }
}

A better way to do this is to use a state machine. Depending on which state the system is in, you check certain sensors and if necessary, turn pumps on/off and then advance to the next state. This lets loop() run over and over again as fast as possible. Here is the basic outline of how to do this, but you will have to adjust what gets checked and which pumps get turned on/off. I probably have them wrong.

const int motor1pin1 = 2; //OUT 1 PIN
const int motor1pin2 = 3; //OUT 2 PIN
const int motor2pin1 = 4; //OUT 3 PIN
const int motor2pin2 = 5; //OUT 4 PIN
const int Laser = 6; //KY-008 laser module
const int LaserSensor = 7; //laser receiver
cont int RelayPump = 8; //5V relay
const int WaterSensor = 9; //Solu SLOO87 water level sensor

void setup() {
  Serial.begin(9600);
  pinMode(Laser, OUTPUT);
  pinMode(LaserSensor, INPUT);
  pinMode(WaterSensor, INPUT);
  pinMode(RelayPump, OUTPUT);
  pinMode(motor1pin1, OUTPUT);
  pinMode(motor1pin2, OUTPUT);
  pinMode(motor2pin1, OUTPUT);
  pinMode(motor2pin2, OUTPUT);
  digitalWrite(Laser, LOW);
  digitalWrite(RelayPump, LOW);
  digitalWrite(motor1pin1, LOW);
  digitalWrite(motor1pin2, LOW);
  digitalWrite(motor2pin1, LOW);
  digitalWrite(motor2pin2, LOW);
}

enum { STATE_IDLE, STATE_PUMPING, STATE_WAITING, STATE_WATER_PUMPING, STATE_OIL_PUMPING };
int state;

unsigned long startWaitTime;
const unsigned long waitDuration = 1000UL * 40; // wait 40 seconds

void loop() {

case swtich(state) {
  case STATE_IDLE:
    // waiting to begin
    // don't know if a button press or ???
    // just starting filling seperator tank
    // TODO: turn on whatever pumps are needed
    state++;  // advance to next state
    break;

  case STATE_PUMPING:
    // filling tank with fluid, wait until sensor says we are full
    // TODO: read sensor and if full, turn off pump advance to next state
    if (digitalRead(WaterSensor)) {
      digitalWrite(RelayPump, HIGH);
      digitalWrite(Laser, HIGH);
      digitalWrite(motor1pin1, LOW);
      digitalWrite(motor1pin2, LOW);
      digitalWrite(motor2pin1, LOW);
      digitalWrite(motor2pin2, LOW);
      startWaitTime = millis();
      state++;
    }
    break;

  case STATE_WAITING:
    // waiting for oil/water to separate
    if ( millis() - startWaitTime >= waitDuration ) {
      // TODO: begin next state, turn on pumps, etc.
      state++;
    }
    break;

  case STATE_WATER_PUMPING:
    // check laser to see if we are done pumping water
    if (LaserDetected == digitalRead(LaserSensor)) {
      // all done, turn off water pump
      digitalWrite(motor1pin1, HIGH);
      digitalWrite(motor1pin2, LOW);
      digitalWrite(motor2pin1, LOW);
      digitalWrite(motor2pin2, LOW);

      // turn on oil pump
      digitalWrite(motor1pin1, HIGH);
      digitalWrite(motor1pin2, LOW);
      digitalWrite(motor2pin1, LOW);
      digitalWrite(motor2pin2, LOW);
      state++;
    }
    break;

  case STATE_OIL_PUMPING:
    // check laser to see if we are done pumping oil or
    // how to we know to stop pummping
    if (LaserDetected == digitalRead(LaserSensor)) {
      // turn off oil pump
      state = STATE_IDLE;
    }
    break;

  }
}

Thank you very much, I will try this code and I will tell you if it works :slight_smile:

girteny:
Thank you very much, I will try this code and I will tell you if it works :slight_smile:

I seriously doubt if it will work without some effort on your part. I don't have your hardware and it wasn't entirely clear to me what conditions are needed to transition to different state. This is more of an outline that will require refinement and adjustment on your part to get it to work.

I have made some adjustment to the code for my hardware, right now the problem with the L298N Driver motor is solved, at the start of the code it doesn't activate at pin OUT 3 and OUT 4, but right now the problem is the code won't proceed to the next case, so it's always stops at case STATE_PUMPING even though it already reached the if conditions, is there is something wrong with the code?

const int motor1pin1 = 2; //OUT 1 PIN
const int motor1pin2 = 3; //OUT 2 PIN
const int motor2pin1 = 4; //OUT 3 PIN
const int motor2pin2 = 5; //OUT 4 PIN
const int Laser = 6; //KY-008 laser module
const int LaserSensor = 7; //laser receiver
const int RelayPump = 8; //5V relay
const int WaterSensor = 9; //Solu SLOO87 water level sensor

void setup() {
  Serial.begin(9600);
  pinMode(Laser, OUTPUT);
  pinMode(LaserSensor, INPUT);
  pinMode(WaterSensor, INPUT);
  pinMode(RelayPump, OUTPUT);
  pinMode(motor1pin1, OUTPUT);
  pinMode(motor1pin2, OUTPUT);
  pinMode(motor2pin1, OUTPUT);
  pinMode(motor2pin2, OUTPUT);
  digitalWrite(Laser, LOW);
  digitalWrite(RelayPump, LOW);
  digitalWrite(motor1pin1, LOW);
  digitalWrite(motor1pin2, LOW);
  digitalWrite(motor2pin1, LOW);
  digitalWrite(motor2pin2, LOW);
}

enum {STATE_PUMPING, STATE_WAITING, STATE_WATER_PUMPING, STATE_OIL_PUMPING };
unsigned long startWaitTime;
long previousMillis = 0;
const unsigned long waitDuration = 1000UL * 40;
int state;

void loop() {
switch (state)  {
  case STATE_PUMPING:
  int SensorValue = digitalRead(WaterSensor); //Read the Water Level Sensor if it detects liquid
  if (SensorValue >= 1){
    digitalWrite(RelayPump, HIGH);
    digitalWrite(Laser, HIGH);
    digitalWrite(motor1pin1, LOW);
    digitalWrite(motor1pin2, LOW);
    digitalWrite(motor2pin1, LOW);
    digitalWrite(motor2pin2, LOW);
    startWaitTime = millis();
    state++;
  }
  break;

  case STATE_WAITING:
  if(startWaitTime - previousMillis > waitDuration)//Wait for 40 seconds
  {
    state++;
  }
  break;

  case STATE_WATER_PUMPING:
  int LaserDetected = digitalRead(LaserSensor);//Read the Laser Receiver if it reads incoming laser
  if(LaserDetected == HIGH){
    digitalWrite(motor1pin1, HIGH);
    digitalWrite(motor1pin2, LOW);
    digitalWrite(motor2pin1, LOW);
    digitalWrite(motor2pin2, LOW);
    } else {
    digitalWrite(motor1pin1, LOW);
    digitalWrite(motor1pin2, LOW);
    digitalWrite(motor2pin1, LOW);
    digitalWrite(motor2pin2, HIGH);
    state++;
  }
  break;

  case STATE_OIL_PUMPING:
  if (LaserDetected == digitalRead(LaserSensor)){
    state = STATE_PUMPING;//Back to the start of the loop
  }
  break;
 }
}

You can't declare variables inside of case statements and then use them in other case statements. They need to be outside the switch statement. If you turn on warnings in your preferences file, it will tell you this. Also, you never turn your relay back on to start the pumping. I've added a few debug statements as well

const int motor1pin1 = 2; //OUT 1 PIN
const int motor1pin2 = 3; //OUT 2 PIN
const int motor2pin1 = 4; //OUT 3 PIN
const int motor2pin2 = 5; //OUT 4 PIN
const int Laser = 6; //KY-008 laser module
const int LaserSensor = 7; //laser receiver
const int RelayPump = 8; //5V relay
const int WaterSensor = 9; //Solu SLOO87 water level sensor

void setup() {
  Serial.begin(9600);
  pinMode(Laser, OUTPUT);
  pinMode(LaserSensor, INPUT);
  pinMode(WaterSensor, INPUT);
  pinMode(RelayPump, OUTPUT);
  pinMode(motor1pin1, OUTPUT);
  pinMode(motor1pin2, OUTPUT);
  pinMode(motor2pin1, OUTPUT);
  pinMode(motor2pin2, OUTPUT);
}

enum {STATE_BEGIN, STATE_PUMPING, STATE_WAITING, STATE_WATER_PUMPING, STATE_OIL_PUMPING, STATE_DONE };
unsigned long startWaitTime;
const unsigned long waitDuration = 1000UL * 40;
int state;

void loop() {
  int SensorValue = digitalRead(WaterSensor); //Read the Water Level Sensor if it detects liquid
  int LaserDetected = digitalRead(LaserSensor);//Read the Laser Receiver if it reads incoming laser

  switch (state) {
    case STATE_BEGIN:
      // begin the cycle by turning on the pump
      // motors off
      digitalWrite(Laser, LOW);
      digitalWrite(RelayPump, LOW);
      digitalWrite(motor1pin1, LOW);
      digitalWrite(motor1pin2, LOW);
      digitalWrite(motor2pin1, LOW);
      digitalWrite(motor2pin2, LOW);
      state++;
      Serial.println("Pumping");
      break;

    case STATE_PUMPING:
      if (SensorValue == HIGH) {
        digitalWrite(RelayPump, HIGH);
        digitalWrite(Laser, HIGH);
        digitalWrite(motor1pin1, LOW);
        digitalWrite(motor1pin2, LOW);
        digitalWrite(motor2pin1, LOW);
        digitalWrite(motor2pin2, LOW);
        startWaitTime = millis();
        state++;
        Serial.println("Waiting");
      }
      break;

    case STATE_WAITING:
      if (millis() - startWaitTime >= waitDuration) {
        state++;
        Serial.println("Removing water");
      }
      break;

    case STATE_WATER_PUMPING:
      if (LaserDetected == HIGH) {
        digitalWrite(motor1pin1, HIGH);
        digitalWrite(motor1pin2, LOW);
        digitalWrite(motor2pin1, LOW);
        digitalWrite(motor2pin2, LOW);
      } else {
        digitalWrite(motor1pin1, LOW);
        digitalWrite(motor1pin2, LOW);
        digitalWrite(motor2pin1, LOW);
        digitalWrite(motor2pin2, HIGH);
        state++;
        Serial.println("Removing oil");
      }
      break;

    case STATE_OIL_PUMPING:
      if (LaserDetected == HIGH) {
        digitalWrite(motor1pin1, LOW);
        digitalWrite(motor1pin2, LOW);
        digitalWrite(motor2pin1, LOW);
        digitalWrite(motor2pin2, LOW);
        state++;
        Serial.println("All Done");
      }
      break;

    case STATE_DONE:
      state = STATE_PUMPING;//Back to the start of the loop
      Serial.println("Cycle begins");
      break;
  }
}

the code works perfectly! thank you so much :slight_smile:

Hi,
Is there a reason for using the motor driver?
Do you need to reverse any of the motors?

If not then just a MOSFET to turn your motor ON and OFF will do the job.
All you need is one output for each motor.

Tom... :slight_smile:

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