Need help with programming. Thanks!

So hello everyone! i am doing my project well and i have encountered a problem with programming. I am using if/else statement to satisfy some condition but there are things i want to do more. so i’ll show you my code first,

void loop() {

  recvWithEndMarker();
  showNewNumber();

  if (dataNumber <= 50)
  { runMotor1();
  }
    else {
    }

  if (dataNumber >= 30)
  { runMotor2();
  }
    
    else {
    }
  
}

so here in the part of my code, i need to only run the runMotor1 once if the statement is satisfied. But as i have observed, as long as it is satisfied, the runMotor1 is continuously running too. but what i need in my project is for it to run once then wait for the second condition to runMotor2.

This is because i only need to open and close the gate using the motor and my sensor. If anyone can give me some points and advices with my code, it’s really appreciated. Thank you and God Bless!

you need remember when runMotor1() has been called and take appropriate action, e.g.

void loop() {
  static bool runningMotor1=false;
  recvWithEndMarker();
  showNewNumber();
  if (!runningMotor1 && dataNumber <= 50)
    { runMotor1();
     ruunningMotor1=true;
    }

  if (runningMotor1 && dataNumber >= 30)
  { runMotor2();
    ....

Post all your code, nobody can tell you what is wrong if they cannot see what you are doing.
Put print statements in your code so that you can see what your code is doing.

At the moment I assume runMotor1() switches on motor1 it will keep running until you turn it off which you never seem to do.

horace:
you need remember when runMotor1() has been called and take appropriate action, e.g.

void loop() {

static bool runningMotor1=false;
  recvWithEndMarker();
  showNewNumber();
  if (!runningMotor1 && dataNumber <= 50)
    { runMotor1();
    ruunningMotor1=true;
    }

if (runningMotor1 && dataNumber >= 30)
  { runMotor2();
    …

Thank you for this! i got it to stop working after a loop! But will i get it running again after i satisfy my second condition? or i will need to reset the whole program for it to run again?

Thanks!!

at some point after the second condition (after a time?) you will need to set runningMotor1=false; so runMotor1() can be called again

Posting code fragments makes it impossible for others to help you. Without seeing the entire program, or at least the entire section in question, there is zero chance that the smartest programmer in the world could answer your question(s). So, we ask for the entire program since newbies don't know what's important and what isn't.

So here is my program hehe

#include <SoftwareSerial.h>
SoftwareSerial XBee(10, 11); // RX, TX

#define relayPin 4
int stepPin = 5;
int dirPin = 6;
int enblPin = 7;
long Distance = 0;

const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;

int dataNumber = 0;             // new for this version

void setup() {
  XBee.begin(9600); //SERIALS
  Serial.begin(9600);
  Serial.println("<Arduino is ready>");
  pinMode(relayPin, OUTPUT); //RELAY SERIAL
  digitalWrite(relayPin, HIGH);
  pinMode (stepPin, OUTPUT); //MOTOR SERIAL
  pinMode (dirPin, OUTPUT);
  pinMode (enblPin, OUTPUT);
  digitalWrite(stepPin, LOW);
  digitalWrite(dirPin, LOW);
  digitalWrite(enblPin, HIGH);
}

void loop() {

  static bool runningMotor1 = false;

  recvWithEndMarker();
  showNewNumber();

  if (!runningMotor1 && dataNumber <= 50)
  { runMotor1();
    runningMotor1 = true;
  }

  else {
  }
  if (runningMotor1 && dataNumber >= 30)
  { runMotor2();
  }
  else {
  }

}
//runMotor();


void recvWithEndMarker() {
  static byte ndx = 0;
  char endMarker = '\n';
  char rc;

  if (XBee.available() > 0) {
    rc = XBee.read();

    if (rc != endMarker) {
      receivedChars[ndx] = rc;
      ndx++;
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }
    }
    else {
      receivedChars[ndx] = '\0'; // terminate the string
      ndx = 0;
      newData = true;
    }
  }
}

void showNewNumber() {
  if (newData == true) {
    dataNumber = 0;             // new for this version
    dataNumber = atoi(receivedChars);   // new for this version
    Serial.print("his just in ... ");
    Serial.println(receivedChars);
    Serial.print("Data as Number ... ");    // new for this version
    Serial.println(dataNumber);     // new for this version
    newData = false;
  }
}

void runMotor1() {

  //CLOCKWISE

  {
    digitalWrite(relayPin, LOW);  // Turn Relay ON
    Serial.println("Relay is ON");
    delay(2000);
  }
  {
    for (long x = 0; x < 38400; x++)
    {
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(100);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(100);
      //Distance = Distance + 1;
    }
  }
}

void runMotor2() {

  //COUNTER CLOCKWISE
  {
    digitalWrite(relayPin, LOW);  // Turn Relay ON
    Serial.println("Relay is ON");
    delay(2000);
  }
  {
    for (long x = 0; x < 38400; x++)
    {
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(100);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(100);
      //Distance = Distance + 1;
    }
  }
}
}

As you can see, there are some mistakes in my code. the runMotor2 (which is for my counter clockwise rotation) is still wrong and i am somehow working on it. if you can advice me, it’s better and thank you so much in advance. my next step is to satisfy my next condition and run the function runMotor2, and after a certain level in my sensor, satisfy the first condition again and run the runMotor1.

Thank you everyone for your interest in helping. I really appreciate it :smiley:

Both runMotor1() and runMotor(2) set

digitalWrite(relayPin, LOW);

Nowwhere do you seem to change the direction dirPin

Many issues.

  1. one pin is defined using a #define macro, the others as int. That’s inconsistent. Choose a style.
    If you want to use variables, make it a const byte instead.

  2. at the start of loop() (which runs over and over again) you set runningMotor1 to false. So every time you run loop (and that should be hundreds of times a second or more) you set that variable to false. You better declare it as a global variable (so on top of the sketch) so it won’t be set every time you run loop().

  3. why is that declared “static”?

  4. the first if will always be true when dataNumber is <= 50.

  5. the second if will always be true when dataNumber is >= 30 and <= 50, and always false if <30 or >50.

  6. your layout is a mess. Do ctrl-T in the IDE to fix your indentation. Then never put { on the same line as a statement, unless the { is at the end of the line. That also makes your code much more readable. Many people even prefer to put every { and } on their own lines. I place the { at the end of the line that opens the block, the } on a separate line. A matter of style but your code looks a lot better if you are consistent.

ardly:
Both runMotor1() and runMotor(2) set

digitalWrite(relayPin, LOW);

Nowwhere do you seem to change the direction dirPin

hello sir! thanks for replying, here is my original code for the runMotor2

 //COUNTER CLOCKWISE

  if (Distance == 38400);

  { if
    (digitalRead(dirPin) == LOW)
    {
      digitalWrite(dirPin, HIGH);
    }

    else
    {
      digitalWrite(dirPin, LOW);
    }

  }

  {
    digitalWrite(relayPin, HIGH);  // Turn Relay OFF
    Serial.println("Relay is OFF");
    delay(2000);
  }

}

i was trying to figure things out here first thats why i thought i might change it to something the same with runMotor1 and then just add the directions. Maybe you can give me some advice. Thanks for replying :smiley:

If you read a digital pin that's set to output, you get back the latest state (so if you set an output to high, and you read that pin, the result is high). If you write to it, you set its output state to HIGH or LOW as per the state given in the digitalWrite call.

If you read a digital pin that's set to input, you read the signal that's provided to it. If you do digitalWrite(pin, HIGH) to an input, it enables the internal pullup. A LOW disables it.

One of them is what you're trying to do to dirPin.

wvmarle:
If you read a digital pin that’s set to output, you get back the latest state (so if you set an output to high, and you read that pin, the result is high). If you write to it, you set its output state to HIGH or LOW as per the state given in the digitalWrite call.

If you read a digital pin that’s set to input, you read the signal that’s provided to it. If you do digitalWrite(pin, HIGH) to an input, it enables the internal pullup. A LOW disables it.

One of them is what you’re trying to do to dirPin.

this code is working clockwise and counter clockwise in a separate program. but i dont know how can i make it to work with the condition im trying to satisfy. thanks!

I cant seem to make my counter clockwise rotation work :frowning: any help and advices are very much welcome! here’s my code :smiley:

#include <SoftwareSerial.h>
SoftwareSerial XBee(10, 11); // RX, TX

int relayPin = 4;
int stepPin = 5;
int dirPin = 6;
int enblPin = 7;
long Distance = 0;

const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;

int dataNumber = 0;             // new for this version

void setup()
{
  XBee.begin(9600); //SERIALS
  Serial.begin(9600);
  Serial.println("<Arduino is ready>");
  pinMode(relayPin, OUTPUT); //RELAY SERIAL
  digitalWrite(relayPin, HIGH);
  pinMode (stepPin, OUTPUT); //MOTOR SERIAL
  pinMode (dirPin, OUTPUT);
  pinMode (enblPin, OUTPUT);
  digitalWrite(stepPin, LOW);
  digitalWrite(dirPin, LOW);
  digitalWrite(enblPin, HIGH);
}

void loop()
{

  static bool runningMotor1 = false;

  recvWithEndMarker();
  showNewNumber();

  if (!runningMotor1 && dataNumber <= 50)
  { runMotor1();
    runningMotor1 = true;
  }

  else {
  }

  if (dataNumber >= 51)
  { runMotor2();
  }

  else {
  }

}
//runMotor();


void recvWithEndMarker() {
  static byte ndx = 0;
  char endMarker = '\n';
  char rc;

  if (XBee.available() > 0) {
    rc = XBee.read();

    if (rc != endMarker) {
      receivedChars[ndx] = rc;
      ndx++;
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }
    }
    else {
      receivedChars[ndx] = '\0'; // terminate the string
      ndx = 0;
      newData = true;
    }
  }
}

void showNewNumber() {
  if (newData == true) {
    dataNumber = 0;             // new for this version
    dataNumber = atoi(receivedChars);   // new for this version
    Serial.print("his just in ... ");
    Serial.println(receivedChars);
    Serial.print("Data as Number ... ");    // new for this version
    Serial.println(dataNumber);     // new for this version
    newData = false;
  }
}

void runMotor1() {

  //CLOCKWISE

  {
    digitalWrite(relayPin, LOW);  // Turn Relay ON
    Serial.println("Relay is ON");
  }
  {
    for (long x = 0; x < 38400; x++)
    {
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(100);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(100);
      //Distance = Distance + 1;
    }
  }
}

void runMotor2()
{

// first rotation COUNTER CLOCKWISE
if (Distance == 38400);

{ if 
  (digitalRead(dirPin) == LOW)
      { 
         digitalWrite(dirPin, HIGH);
      }

   else
     {
        digitalWrite(dirPin, LOW);
     }
       

    }
  


}

Do you have one motor or two motors?

If I was you I would start with a very simple program that just ran the motor continuously in one direction.
Then I would change it to make the motor run in the other direction.

Once I understood how to do that I would gradually build up my program. Don't try and write it all at once and then wonder why it does not work. Start with something very simple that does work then move forward step by step.

I wonder if the OP would benefit by looking at some Stepper motor sketches?

So the problem i am encountering now is the satisfaction of the second condition, which is the runMotor2, which seems doesnt work provided my code here:

#include <SoftwareSerial.h>
SoftwareSerial XBee(10, 11); // RX, TX

int relayPin = 4;
int stepPin = 5;
int dirPin = 6;
int enblPin = 7;
long Distance = 0;

const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;

int dataNumber = 0;             // new for this version

void setup()
{
  XBee.begin(9600); //SERIALS
  Serial.begin(9600);
  Serial.println("<Arduino is ready>");
  pinMode(relayPin, OUTPUT); //RELAY SERIAL
  digitalWrite(relayPin, HIGH);
  pinMode (stepPin, OUTPUT); //MOTOR SERIAL
  pinMode (dirPin, OUTPUT);
  pinMode (enblPin, OUTPUT);
  digitalWrite(stepPin, LOW);
  digitalWrite(dirPin, LOW);
  digitalWrite(enblPin, HIGH);
}

void loop()
{

  static bool runningMotor1 = false;

  recvWithEndMarker();
  showNewNumber();

  if (!runningMotor1 && dataNumber <= 50)
  { runMotor1();
    runningMotor1 = true;
  }

  //else {
    //runningMotor1 = false;
  //}

  if (dataNumber >= 51)
  { runMotor2();
  }

  else {
  }

}
//runMotor();


void recvWithEndMarker() {
  static byte ndx = 0;
  char endMarker = '\n';
  char rc;

  if (XBee.available() > 0) {
    rc = XBee.read();

    if (rc != endMarker) {
      receivedChars[ndx] = rc;
      ndx++;
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }
    }
    else {
      receivedChars[ndx] = '\0'; // terminate the string
      ndx = 0;
      newData = true;
    }
  }
}

void showNewNumber() {
  if (newData == true) {
    dataNumber = 0;             // new for this version
    dataNumber = atoi(receivedChars);   // new for this version
    Serial.print("This just in ... ");
    Serial.println(receivedChars);
    Serial.print("Data as Number ... ");    // new for this version
    Serial.println(dataNumber);     // new for this version
    newData = false;
  }
}

void runMotor1() {

  //CLOCKWISE

  {
    digitalWrite(relayPin, LOW);  // Turn Relay ON
    Serial.println("Relay is ON");
  }
  {
    for (long x = 0; x < 38400; x++)
    {
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(100);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(100);
      //Distance = Distance + 1;
    }
  }
}

void runMotor2()
{

// first rotation COUNTER CLOCKWISE
if (Distance == 38400);

{ if 
  (digitalRead(dirPin) == LOW)
      { 
         digitalWrite(dirPin, HIGH);
      }

   else
     {
        digitalWrite(dirPin, LOW);
     }
       

    }
  


}

please help? thanks!

-andrea

you are not testing runningMotor1 for true when checks runMotor2()

oid loop()
{

  static bool runningMotor1 = false;

  recvWithEndMarker();
  showNewNumber();

  if (!runningMotor1 && dataNumber <= 50)
  { runMotor1();
    runningMotor1 = true;
  }
  if (runningMotor1 && dataNumber >= 51)
  { runMotor2();
  runningMotor1 = false;
  }
}

do you have two motors or does runMotor2() just set direction?

horace:
you are not testing runningMotor1 for true when checks runMotor2()

oid loop()

{

static bool runningMotor1 = false;

recvWithEndMarker();
  showNewNumber();

if (!runningMotor1 && dataNumber <= 50)
  { runMotor1();
    runningMotor1 = true;
  }
  if (runningMotor1 && dataNumber >= 51)
  { runMotor2();
  runningMotor1 = false;
  }
}



do you have two motors or does runMotor2() just set direction?

Hello! I only have one motor. the runMotor1 is for clockwise direction and runMotor2 is for counter clockwise.

So far, I have been satisfying my first condition, and it only run once. Im trying to satisfy the second condition now and im having some troubles. im not really familiar with deep coding so please bear with me.

With your codes, i am having a good idea how this things works, i just cant figure out yet the coding for it because im really a newbie here. Anyway, thanks for helping me!

So Horace, i modified my code and change the part that you shared to me.

Here’s what happens:

  1. As I turn on the Arduino, the motor rotates once.
  2. When it reads number >=51, nothing happens
  3. When it reads number <=50, it rotates, clockwise, once.
  4. When i try to make the input higher, nothing happens
  5. When I try to make in <=50 again, it rotates, counter clockwise.

So as i have observed, the first condition is satisfied. It waits for the second condition to be satisfied. then, the first condition can be satisfied again, but with different rotation.

I get it right? haha! im feeling kinda happy right now.

So what i need is to satisfy my first condition (it will rotate clockwise for example) then run ONCE ONLY, and it waits to satisfy my second condition (it will rotate counter clockwise for example) then run ONCE ONLY too.

It’s like closing and opening gates? somehow like that but with certain level of input. I hope you get my point here. Thank you sir! Big help, really! :smiley:

-andrea