Please help me with this code

Please help me with this code. I am working on a project using the following components:

  • L298N motor driver
  • Water pump (with only positive and negative terminals)
  • Arduino IR sensor modules (3 units) for obstacle detection
  • TTP223B capacitive touch sensor
  • Arduino Uno
  • Breadboard
  • Arduino ULN2003 motor driver with 28BYJ-48 5V stepper motors

I'm trying to create the following functionality using these sensors:

  1. Stepper motors 1 and 2 should rotate in clockwise and counterclockwise directions, respectively.
  2. If infrared sensor 1 detects an object, the stepper motors should stop and water pump 1 should operate for 21 seconds.
  3. After the water pump stops, the stepper motors should resume operation.
  4. If infrared sensor 2 detects an object, water pump 2 should operate for 9 seconds.
  5. After the water pump stops, the stepper motors should resume operation.
  6. If infrared sensor 3 detects an object, the code should end (reset).

Currently, I have composed the code based on these requirements, but no matter how much I modify it, either the stepper motors rotate, only water pump 1 operates, or only water pump 2 operates. Only one of these three functions seems to work continuously. I'm not sure what part of the code is causing the issue. Could you please let me know what might be wrong with this code?

#define MOTOR_DRIVER_PIN1 7
#define MOTOR_DRIVER_PIN2 6
#define MOTOR_DRIVER_PIN3 5
#define MOTOR_DRIVER_PIN4 4

#define INFRARED_SENSOR1_PIN A2
#define INFRARED_SENSOR2_PIN A1
#define INFRARED_SENSOR3_PIN A3

#define STEPPER_MOTOR1_PIN1 10
#define STEPPER_MOTOR1_PIN2 11
#define STEPPER_MOTOR1_PIN3 12
#define STEPPER_MOTOR1_PIN4 13
#define STEPPER_MOTOR2_PIN1 2
#define STEPPER_MOTOR2_PIN2 8
#define STEPPER_MOTOR2_PIN3 3
#define STEPPER_MOTOR2_PIN4 9

#define WATER_PUMP_PIN 14

#define PUMP_ON_TIME_SENSOR1 21000
#define PUMP_ON_TIME_SENSOR2 9000

int motorPattern[8][4] = {
  {1, 0, 0, 1},
  {1, 0, 0, 0},
  {1, 1, 0, 0},
  {0, 1, 0, 0},
  {0, 1, 1, 0},
  {0, 0, 1, 0},
  {0, 0, 1, 1},
  {0, 0, 0, 1}
};
int motorIndex = 0;

unsigned long previousMillisMotor = 0;  
unsigned long previousMillisPump1 = 0;  
unsigned long previousMillisPump2 = 0;  
bool pump1State = false;
bool pump2State = false;

void setup() {
  pinMode(MOTOR_DRIVER_PIN1, OUTPUT);
  pinMode(MOTOR_DRIVER_PIN2, OUTPUT);
  pinMode(MOTOR_DRIVER_PIN3, OUTPUT);
  pinMode(MOTOR_DRIVER_PIN4, OUTPUT);
  
  pinMode(STEPPER_MOTOR1_PIN1, OUTPUT);
  pinMode(STEPPER_MOTOR1_PIN2, OUTPUT);
  pinMode(STEPPER_MOTOR1_PIN3, OUTPUT);
  pinMode(STEPPER_MOTOR1_PIN4, OUTPUT);
  pinMode(STEPPER_MOTOR2_PIN1, OUTPUT);
  pinMode(STEPPER_MOTOR2_PIN2, OUTPUT);
  pinMode(STEPPER_MOTOR2_PIN3, OUTPUT);
  pinMode(STEPPER_MOTOR2_PIN4, OUTPUT);
  
  pinMode(INFRARED_SENSOR1_PIN, INPUT);
  pinMode(INFRARED_SENSOR2_PIN, INPUT);
  pinMode(INFRARED_SENSOR3_PIN, INPUT);

  pinMode(WATER_PUMP_PIN, OUTPUT);
}

void loop() {
  unsigned long currentMillis = millis();

  if(currentMillis - previousMillisMotor >= 1) {
    previousMillisMotor = currentMillis;
    runStepperMotor(STEPPER_MOTOR1_PIN1, STEPPER_MOTOR1_PIN2, STEPPER_MOTOR1_PIN3, STEPPER_MOTOR1_PIN4);
    runStepperMotor(STEPPER_MOTOR2_PIN1, STEPPER_MOTOR2_PIN2, STEPPER_MOTOR2_PIN3, STEPPER_MOTOR2_PIN4);
  }
  
  if (digitalRead(INFRARED_SENSOR1_PIN) == HIGH && !pump1State) {
    pump1State = true;
    previousMillisPump1 = currentMillis;
    digitalWrite(WATER_PUMP_PIN, HIGH);
  }
  
  if (digitalRead(INFRARED_SENSOR2_PIN) == HIGH && !pump2State) {
    pump2State = true;
    previousMillisPump2 = currentMillis;
    digitalWrite(WATER_PUMP_PIN, HIGH);
  }
  
  if (pump1State && currentMillis - previousMillisPump1 >= PUMP_ON_TIME_SENSOR1) {
    pump1State = false;
    digitalWrite(WATER_PUMP_PIN, LOW);
  }
  
  if (pump2State && currentMillis - previousMillisPump2 >= PUMP_ON_TIME_SENSOR2) {
    pump2State = false;
    digitalWrite(WATER_PUMP_PIN, LOW);
  }

  if (digitalRead(INFRARED_SENSOR3_PIN) == HIGH) {
    resetAll();
  }
}

void runStepperMotor(int pin1, int pin2, int pin3, int pin4) {
  digitalWrite(pin1, motorPattern[motorIndex][0]);
  digitalWrite(pin2, motorPattern[motorIndex][1]);
  digitalWrite(pin3, motorPattern[motorIndex][2]);
  digitalWrite(pin4, motorPattern[motorIndex][3]);

  motorIndex = (motorIndex + 1) % 8;
}

void resetAll() {
  digitalWrite(MOTOR_DRIVER_PIN1, LOW);
  digitalWrite(MOTOR_DRIVER_PIN2, LOW);
  digitalWrite(MOTOR_DRIVER_PIN3, LOW);
  digitalWrite(MOTOR_DRIVER_PIN4, LOW);

  digitalWrite(STEPPER_MOTOR1_PIN1, LOW);
  digitalWrite(STEPPER_MOTOR1_PIN2, LOW);
  digitalWrite(STEPPER_MOTOR1_PIN3, LOW);
  digitalWrite(STEPPER_MOTOR1_PIN4, LOW);
  digitalWrite(STEPPER_MOTOR2_PIN1, LOW);
  digitalWrite(STEPPER_MOTOR2_PIN2, LOW);
  digitalWrite(STEPPER_MOTOR2_PIN3, LOW);
  digitalWrite(STEPPER_MOTOR2_PIN4, LOW);

  digitalWrite(WATER_PUMP_PIN, LOW);
  
  motorIndex = 0;
}

If you could help me, I would truly appreciate it. I've spent countless nights trying to solve this but haven't been successful. Thank you in advance.:sob:

Probably the best thing you can do to solve your problem is to post an annotated schematic with links to all of the hardware devices that give technical information. Be sure to show all connections, power sources, ground etc. Consider using a bridge with MOSFET outputs in place of the L298N . That obsolete parts drops about 2.4 volts to your battery that is simply burnt up as heat.

Please, provide a drawing.
Where does the touch sensor fit?
Where is pin 14?
This is why your motors runs without letting other devices run...

  if (currentMillis - previousMillisMotor >= 1) { // the interval is only 1ms

Water pump 1 will operate when the sensor is HIGH... and stay on for 21 seconds... BUT is never set LOW again and turns back on for 21 seconds
Water pump 2 will operate when the sensor is HIGH... and stay on for 9 seconds.... BUT is never set LOW again and turns back on for 9 seconds

Did you get your beverage dispenser and heart rate monitor working?

It seems to be robot made sketch.

1 Like

Here is your code in a WoSim (a WOKWI-Simulation based on xfpd's WOSim) where I added debug-macros that make visible what is happening inside your code through printing to the serial monitor

I use a digitalRead of the waterpump-pin for an if-condition that the stepper-motors only run in case waterpump is off and stop as soon as waterpump is switched on

look this over
i don't know what you know/don't know, so ask questions about what you don't understand

const byte PinReset = A3;

char s [80];

// -----------------------------------------------------------------------------
enum { For = 1, Rev = -1 };

const int NstepPin = 4;

struct Thing {
    const byte    PinStep [NstepPin];
    int           dir;
    unsigned long usecStep;

    const byte    PinPump [2];
    unsigned long msecPeriod;

    const byte    PinSensor;
    const char   *label;
    
    bool          active;
    byte          idx;

    unsigned long usecLst;
    unsigned long msecLst;
};

// define parameters for each "thing"

Thing things [] = {
    {{ 10, 11, 12, 13}, For, 1000, { 7, 6 },  5000, A2, "Thing-A" },
    {{  2,  8,  3,  9}, Rev, 1000, { 5, 4 },  3000, A1, "Thing-B" },
};
const int Nthing = sizeof(things) / sizeof(Thing);

// -----------------------------------------------------------------------------
const int Npat = 8;
const byte StepPat [Npat][4] = {
    {1, 0, 0, 1},
    {1, 0, 0, 0},
    {1, 1, 0, 0},
    {0, 1, 0, 0},

    {0, 1, 1, 0},
    {0, 0, 1, 0},
    {0, 0, 1, 1},
    {0, 0, 0, 1}
};

// -------------------------------------
void
step (
    Thing *p )
{
#undef MyHW     // for testing on my hardware using LEDs
#ifdef MyHW
    unsigned long usec = millis ();
#else
    unsigned long usec = micros ();
#endif

    if (usec - p->usecLst >= p->usecStep)  {
        p->usecLst = usec;
        
        for (int i = 0; i < NstepPin; i++)
            digitalWrite (p->PinStep [i], StepPat [p->idx][i]);

        p->idx += p->dir;
        if (0 > p->idx)
            p->idx = Npat - 1;
        if (Npat <= p->idx)
            p->idx = 0;
    }
}

// -----------------------------------------------------------------------------
enum { Off = LOW, On = HIGH };
void
pump (
    Thing *p,
    int    state)
{
    sprintf (s, "  %s: state %s %s", __func__, state ? "On" : "Off", p->label);
    Serial.println (s);

    digitalWrite (p->PinPump [0], state);
}

// -----------------------------------------------------------------------------
void
reset (void)
{
    Thing *p = things;
    for (int n = 0; n < Nthing; n++, p++)  {
        Serial.print   (" reset: ");
        Serial.println (p->label);

        p->active = false;
        p->idx    = 0;

        for (int i = 0; i < NstepPin; i++)
            digitalWrite (p->PinStep [i], LOW);

        pump (p, Off);
    }
}

// -----------------------------------------------------------------------------
void
loop (void)
{
    unsigned long msec = millis ();

    if (LOW == digitalRead (PinReset))
        reset ();

    else {
        Thing *p = things;
        for (int n = 0; n < Nthing; n++, p++)  {
            if ( p->active)  {
                if (msec - p->msecLst >= p->msecPeriod)  {
                    p->active = false;
                    pump (p, Off);

                    sprintf (s, " %s: timeout %s", __func__, p->label);
                    Serial.println (s);
                }
            }
            else {
                if (LOW == digitalRead (p->PinSensor))  {
                    sprintf (s, "%s: sensor %s", __func__, p->label);
                    Serial.println (s);
                    p->active  = true;
                    p->msecLst = msec;
                    pump (p, On);
                }
                else
                    step (p);
            }
        }
    }
}

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

    pinMode (PinReset, INPUT_PULLUP);

    Thing *p = things;
    for (int n = 0; n < Nthing; n++, p++)  {
        pinMode (p->PinSensor, INPUT_PULLUP);

        for (int i = 0; i < NstepPin; i++)
            pinMode      (p->PinStep [i], OUTPUT);

        for (int i = 0; i < 2; i++)
            pinMode      (p->PinPump [i], OUTPUT);
    }

    reset ();
}

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