Codes are making a conflict

Hello !

First of all, thank you so much for "giving me" a bit of your time to help me fix this issue.

I'm doing a project with some friends for school and we're actually using arduino, xbee bluetooth shield and motor shield r3.
Our gold is to get a the model, wich is a gate, opened by an Android app.
We have 4 limit switches, 2 for each gate, when it opens, and when it closes.

The code is working and we can open and close the gate through the app but we can't put the code all together because it generates a conflict and so nothing works.

 int dirA = 12; // Direction motor A
int dirB = 13; // Direction motor B
int pwmA = 3; // Motor A speed // 0 - 255
int pwmB = 11; // Motor B speed // 0 - 255
int brkA = 9; // Motor A brake
int brkB = 8; // Motor B brake
int fc1 = 4; // Limit switch 1
int fc2 = 5; // Limit switch 2
int fc3 = 6; // Limit switch 3
int fc4 = 7; // Limit switch 4
int led = 2;
int pos_a = 0; 
int pos_aa = 0;
int pos_b = 0; 
int pos_bb = 0;

void setup(){

  pinMode(fc1, INPUT);
  pinMode(fc2, INPUT);
  pinMode(fc3, INPUT);
  pinMode(fc4, INPUT);
  pinMode(led, OUTPUT);
  pinMode(dirA, OUTPUT);
  pinMode(dirB, OUTPUT);
  digitalWrite(brkA, HIGH);
  digitalWrite(brkB, HIGH);
  Serial.begin(9600);
}

void loop(){

pos_a = digitalRead(fc1);
pos_aa = digitalRead(fc2);
pos_b = digitalRead(fc3);
pos_bb = digitalRead(fc4);
  
char caracter = Serial.read(); // Variable responsable for saving the value of the serial port

// Opening the gate through the app
 if ((caracter == 'a')&&(pos_a == HIGH)&&(pos_aa == HIGH)) {
    digitalWrite(brkA, LOW);
    digitalWrite(brkB, LOW);
    digitalWrite(dirA, LOW);
    digitalWrite(dirB, HIGH);
    analogWrite(pwmA, 95);
    analogWrite(pwmB, 100); 
  }
  else {
    digitalWrite(brkA, HIGH);
    digitalWrite(brkB, HIGH);
  }
  
  if (pos_b == HIGH) {
   digitalWrite(brkA, HIGH);
   analogWrite(pwmA, 0);
}

 if (pos_bb == HIGH) {
  digitalWrite(brkB, HIGH);
  analogWrite(pwmB, 0);
}

// Closing the gate through the app

 if ((caracter == 'b')&&(pos_b == HIGH)&&(pos_bb == HIGH)) {
    digitalWrite(brkA, LOW);
    digitalWrite(brkB, LOW);
    digitalWrite(dirA, HIGH);
    digitalWrite(dirB, LOW);
    analogWrite(pwmA, 95);
    analogWrite(pwmB, 100);
 }
 else {
   digitalWrite(brkA, HIGH);
  digitalWrite(brkB, HIGH);
 }
 
 if (pos_a == HIGH) {
   digitalWrite(brkA, HIGH);
   analogWrite(pwmA, 0);
 }
 
 if (pos_aa == HIGH) {
   digitalWrite(brkB, HIGH);
   analogWrite(pwmB, 0);
  }
}

What I mean is, that when we have just the code for opening or closing the gate on arduino, it works, but when we mix it all together, it doesn't work, it just doesn't move! I know they are making a conflict, I just can't solve it and I tried a lot with my friends.

How can I avoid that conflict and get everything working ?

Once more, thank you for helping me and thanks for your patiente :slight_smile:

This is a problem:

  char caracter = Serial.read(); // Variable responsable for saving the value of the serial port

You're reading whether or not there is anything to read. Most of the time you're getting -1 (255). Since that's neither 'a' or 'b' the brakes are applied. When you send 'a' or 'b', the motors won't be on for long enough to notice.

Take a look at serial.available.

char caracter = Serial.read(); // Variable responsable for saving the value of the serial port

Doesn't it matter that there usually won't be anything to read?

The code is working

but when we mix it all together, it doesn't work

Only one of these statements can be true. You need to define what you add/remove/move/change that causes the code to go from working to not working.

I thought the Serial.read was the way to go since it worked!

How can I use Serial.available ?

Dytrox:
How can I use Serial.available ?

Use it to see if there's anything to read (>0 means there is at least one character waiting).

JimboZA:

Dytrox:
How can I use Serial.available ?

Serial.available() - Arduino Reference

Use it to see if there's anything to read (>0 means there is at least one character waiting).

I've changed it

 if(Serial.available() > 0) {
  char caracter = Serial.read();
  
  if((caracter == 'a')&&(pos_a == HIGH)&&(pos_aa == HIGH)) {
    digitalWrite(brkA, LOW);
    digitalWrite(brkB, LOW);
    digitalWrite(dirA, LOW);
    digitalWrite(dirB, HIGH);
    analogWrite(pwmA, 95);
    analogWrite(pwmB, 100);
  }
  else if((caracter == 'b')&&(pos_b == HIGH)&&(pos_bb == HIGH)) {
    digitalWrite(brkA, LOW);
    digitalWrite(brkB, LOW);
    digitalWrite(dirA, HIGH);
    digitalWrite(dirB, LOW);
    analogWrite(pwmA, 95);
    analogWrite(pwmB, 100);
  }
  
  if(pos_a == HIGH) { 
    digitalWrite(brkA, HIGH);
    analogWrite(pwmA, 0);
  }
  if(pos_aa == HIGH) {
    digitalWrite(brkB, HIGH);
    analogWrite(pwmB, 0);
  }
  if(pos_b == HIGH) {
    digitalWrite(brkA, HIGH);
    analogWrite(pwmA, 0); 
  }
  if(pos_bb == HIGH) {
    digitalWrite(brkB, HIGH);
    analogWrite(pwmB, 0);
    }
  }
}

Is it right ?

Why does checking the limit switches depend on having received serial data?

PaulS:
Why does checking the limit switches depend on having received serial data?

Because I only want the gate to move when arduino receives the serial data, in this case, through the bluetooth app.

Because I only want the gate to move when arduino receives the serial data, in this case, through the bluetooth app.

Starting to move is one thing. Stopping when it hits a limit switch switch is something else. The code does not block until the gate has completed its travel.

PaulS:

Because I only want the gate to move when arduino receives the serial data, in this case, through the bluetooth app.

Starting to move is one thing. Stopping when it hits a limit switch switch is something else. The code does not block until the gate has completed its travel.

So, what do you suggest me ?

So, what do you suggest me ?

Pay attention to when things need to be done. If the ONLY trigger to move the gate is serial input, then the code to start the gate moving goes in the if(Serial.available() > 0) block. If there is ALSO a switch, then the code to start moving the gate can NOT be inside the if(Serial.available() > 0) block, or it must be duplicated outside the block.

Checking whether or not the limit switches are pressed, and stopping the gate if they are, does not happen in the if(Serial.available() > 0) block.

Pay attention to when things need to be done. If the ONLY trigger to move the gate is serial input, then the code to start the gate moving goes in the if(Serial.available() > 0) block. If there is ALSO a switch, then the code to start moving the gate can NOT be inside the if(Serial.available() > 0) block, or it must be duplicated outside the block.

Checking whether or not the limit switches are pressed, and stopping the gate if they are, does not happen in the if(Serial.available() > 0) block.

I understand what you’re saying and it makes perfect sense, I’m sorry for my lack of attention.
Anyway, if I put the the code to start moving the gate outside the if(Serial.available() > 0) block, I’ll get an error trying to compile, it’ll say that the variable wasn’t declared. So, what do I gotta do ? Create a global variable for caracter ?

So, what do I gotta do ? Create a global variable for caracter ?

Maybe. It helps to answer the questions. Is the gate opened and closed only by the arrival of serial data? Or, are there switches to open and close the gate, too?

PaulS:

So, what do I gotta do ? Create a global variable for caracter ?

Maybe. It helps to answer the questions. Is the gate opened and closed only by the arrival of serial data? Or, are there switches to open and close the gate, too?

He is opened and closed only by the arrival of serial data.