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,
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!
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.
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?
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.
#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
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.
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().
why is that declared “static”?
the first if will always be true when dataNumber is <= 50.
the second if will always be true when dataNumber is >= 30 and <= 50, and always false if <30 or >50.
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.
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
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!
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.
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);
}
}
}
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:
As I turn on the Arduino, the motor rotates once.
When it reads number >=51, nothing happens
When it reads number <=50, it rotates, clockwise, once.
When i try to make the input higher, nothing happens
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!