Nested while statements to hijack motor control?

Hely guys, in need of a little code guidance. New to coding so still trying to figure out a few things. I have a robot that basically runs autonomously with ultrasonic sensors as inputs to control the motors. I need to interrupt this main program when the robots camera finds something. once interrupted, all the motor control code on the main arduino will be controlled through outputs of a second arduino... i know.... please be kind.

so my question, is this line of nested while statements enough to stop the robots main function on arduino 1 while arduino 2 starts sending it inputs to control the motors?`

Thanks in advance!

while(ObjectDetected, HIGH){
    while(TurnLeftCommand, HIGH){
      turnLeft();
    }
    while(TurnRightCommand, HIGH){
      turnRight();
    }
    while(MoveForwardCommand, HIGH){
      moveForward();
    }
    while(MoveBackwardComand, HIGH){
      moveBackward();
    }    
  }

why so many while loops? (and have never seen that syntax with a comma).

the arduino loop() is invoked repeatedly from a while with main() common to all sketches. why not have different modes invoked using an if or switch statement. change modes depending on what the camera sees

within loop() there should probably be a function that is always reading commands, independent of mode, regardless if they are used or not, as well as something that is processing camera images, again independent of mode

This will always evaluate to true. You probably want to do something like:

while (ObjectDetected == HIGH) {
  // ...

The same holds for the other while statements.

gotta wonder why there is a comma operator used in that way

LOL. NP.

First, I will assume that you know that what you posted is not code at all yet.

It is, however, valid pseudo code, a way programmers write informally, using syntax that might resemble code, but is meant to rapidly convey the idea of an algorithm or process rather than to get every syntax pesky detail exactly right.

pseudo code is almost always valid! That's what makes it so easy to use. We can hope to live long enough where we will program computers that way.

After all, if Bill Gates sketched out something with lotsa hand waving and vagueness, his engineers woukd have no problem writing Windows 1.1.

So there's the downside to pseudo code. :expressionless:

As such, your pseudo-sketch is a fine start. I would only replace every while idea inside the big while with an if.

If you thought that was code, we can continue to kindly point out all the ways it isn't.

Oh, and welcome to the forum. When you have some code we can look at that and help with getting it to do what you want.

a7

Wow. Thanks for the rapid responses. thank you or clearing up some of my confusion (theres alot more where that came from) so here is my... code?... for arduino 1 after youre guys' recomendations.

#include <NewPing.h>        //Ultrasonic sensor function library. You must install this library

//control pins
const int LeftMotorForward = 6;
const int LeftMotorBackward = 7;
const int RightMotorForward = 4;
const int RightMotorBackward = 5;
const int ObjectDetected = 10;
const int TurnLeftCommand = 11;
const int TurnRightCommand = 12;
const int MoveForwardCommand = 13;
const int MoveBackwardComand = 14;

//Define Constants
#define trigger_pin_1 8
#define echo_pin_1 8
#define trigger_pin_2 9
#define echo_pin_2 9
#define maximum_distance 250
boolean goesForward = false;


NewPing sonar1(trigger_pin_1, echo_pin_1, maximum_distance); 
NewPing sonar2(trigger_pin_2, echo_pin_2, maximum_distance);

// Define Variables
int distance1;
int distance2; 
int LED_RED = 10;
int LED_BLUE = 11;

void setup(){
  Serial.begin(9600);
  pinMode(RightMotorForward, OUTPUT);
  pinMode(LeftMotorForward, OUTPUT);
  pinMode(LeftMotorBackward, OUTPUT);
  pinMode(RightMotorBackward, OUTPUT);
  pinMode(LED_RED, OUTPUT);
  pinMode(LED_BLUE, OUTPUT);
  pinMode(ObjectDetected, INPUT);
  pinMode(TurnLeftCommand, INPUT);
  pinMode(TurnRightCommand, INPUT);
  pinMode(MoveForwardCommand, INPUT);
  pinMode(MoveBackwardComand, INPUT);
}

void loop(){

  distance1 = sonar1.ping_cm(250); //measure duration of sesnor 1 ping
  delay(250);
  distance2 = sonar2.ping_cm(250); //measure duration of sensor 2 ping
  delay(50);
  
  if (distance1 <= 35 || distance2 <= 35){
    moveStop();
    Serial.println('STOP');
    delay(1000);
    moveBackward();
    Serial.println('BACKWARDS');
    delay(3000);
    moveStop();
    Serial.println('STOP');
    delay(1000);
    if (distance1 > distance2){
      turnRight();
      Serial.println('RIGHT');
      delay(2000);
      moveForward();
    }       
    else if(distance1 < distance2){
      turnLeft();
      Serial.println('LEFT');
      delay(2000);
      moveForward();
    } 
  else if(distance1 > 35 && distance2 > 35){
    moveForward();
    Serial.println('FORWARD');
  }
  }

  while(ObjectDetected == HIGH){
    if(TurnLeftCommand == HIGH){
      turnLeft();
    }
    if(TurnRightCommand == HIGH){
      turnRight();
    }
    if(MoveForwardCommand == HIGH){
      moveForward();
    }
    if(MoveBackwardComand == HIGH){
      moveBackward();
    }    
  }
}

void moveStop(){

  analogWrite(RightMotorForward, 0);
  analogWrite(LeftMotorForward, 0);
  analogWrite(RightMotorBackward, 0);
  analogWrite(LeftMotorBackward, 0);
  digitalWrite(LED_RED, LOW);
  digitalWrite(LED_BLUE, LOW); 
}

void moveForward(){

  if(!goesForward){

    goesForward=true;

    analogWrite(LeftMotorForward, 50);
    analogWrite(RightMotorForward, 50);
    analogWrite(LeftMotorBackward, 0);
    analogWrite(RightMotorBackward, 0);
    digitalWrite(LED_RED, HIGH);
    digitalWrite(LED_BLUE, HIGH);

  
  }
}

void moveBackward(){

  goesForward=false;

  analogWrite(LeftMotorBackward, 50);
  analogWrite(RightMotorBackward, 50);
  analogWrite(LeftMotorForward, 0);
  analogWrite(RightMotorForward, 0);
  digitalWrite(LED_RED, LOW);
  digitalWrite(LED_BLUE, LOW);

}

void turnRight(){

  analogWrite(LeftMotorForward, 50);
  analogWrite(RightMotorBackward, 50);
  analogWrite(LeftMotorBackward, 0);
  analogWrite(RightMotorForward, 0);
  digitalWrite(LED_RED, HIGH);
  digitalWrite(LED_BLUE, LOW);
  
}

void turnLeft(){

  analogWrite(LeftMotorBackward, 50);
  analogWrite(RightMotorForward, 50);
  analogWrite(LeftMotorForward, 0);
  analogWrite(RightMotorBackward, 0);
  digitalWrite(LED_RED, LOW);
  digitalWrite(LED_BLUE, HIGH);

}

heres the code running on arduino 2. hopefully this isn't too amusing lol.

//(150, 130): (x, y): center/ grab location
#include <Pixy2.h>

Pixy2 pixy;

void setup(){
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  
  Serial.begin(115200);
  Serial.print("Starting...\n");
  
  pixy.init();
}

void loop(){ 
  int i; 

  //get blocks
  pixy.ccc.getBlocks();
  
  //If there are detect blocks
  if(pixy.ccc.numBlocks){//If object is detected
    Serial.print("Detected ");//Print
    Serial.println(pixy.ccc.numBlocks);
    for (i=0; i<pixy.ccc.numBlocks; i++){
      Serial.print("  block ");
      Serial.print(i);
      Serial.print(": ");
      pixy.ccc.blocks[i].print();
    }
  }
  if(pixy.ccc.numBlocks){//if object is detected 
    digitalWrite(2, HIGH);//pauses autonomous roaming while object is detected
    if(!(pixy.ccc.blocks[0].m_x >=130) && (pixy.ccc.blocks[0].m_x <=170)){//if object is not centered on x axis
      if(pixy.ccc.blocks[0].m_x <150){//if detected object is left of center x
        digitalWrite(3, HIGH);//turn left until centered x
      }
      else if(pixy.ccc.blocks[0].m_x >150){//if detected object is right of center x
        digitalWrite(4, HIGH);//turn right until centered x
      }
    }
    if((pixy.ccc.blocks[0].m_x >=130) && (pixy.ccc.blocks[0].m_x <=170)){//if object is centered on x axis
      if(!(pixy.ccc.blocks[0].m_y >=110) && (pixy.ccc.blocks[0].m_y <=150)){//if object is not centered on y axis
        if(pixy.ccc.blocks[0].m_y >150){//if object is further away from center y
          digitalWrite(5, HIGH);//move forward until centered y
        }
        else if(pixy.ccc.blocks[0].m_y <150){//if object is closer than center y
          digitalWrite(6, HIGH);//move backward until centered y
        }
      }
      if((pixy.ccc.blocks[0].m_x >=130) && (pixy.ccc.blocks[0].m_x <=170) && (pixy.ccc.blocks[0].m_y >=110) && (pixy.ccc.blocks[0].m_y <=150)){//if object is centered
        digitalWrite(7, HIGH);//pick up object
        delay(30000);
      }
      else{
        digitalWrite(7, LOW);
      }
    }
  }
  else{
    digitalWrite(2, LOW);//resume autonomous roaming
  }
}     

Here's the code that operates the robotic arm. This code is tested and works. Except for the arm trying to murder itself upon startup..

#include <VarSpeedServo.h>

VarSpeedServo servo01;
VarSpeedServo servo02;
VarSpeedServo servo03;
VarSpeedServo servo04;
VarSpeedServo servo05;
VarSpeedServo servo06;
VarSpeedServo servo07;

int detectionPin = 4;
int detectionState;

void setup() {
  // put your setup code here, to run once:
servo01.attach(5);
servo02.attach(6);
servo03.attach(7);
servo04.attach(8);
servo05.attach(9);
servo06.attach(10);
servo07.attach(11);

servo01.write(90, 30, false);
servo02.write(180, 30, false); 
servo03.write(180, 30, false);
servo04.write(135, 30, false);
servo05.write(90, 30, false);
servo06.write(75, 30, false);
servo07.write(75, 30, false);

pinMode(detectionPin, INPUT);
}

void loop() {
  // Neutral position, POS A
servo01.write(90, 30, false); // 0-180, increase angle to turn right  
servo02.write(180, 30, true); // increase angle to raise arm
servo03.write(180, 30, false); // increase angle to lower arm
servo04.write(135, 30, true); // increase angle to lower arm
servo05.write(90, 30, true); // claw rotation servo
servo06.write(75, 30, false); // 37-75 claw servo 1, increase angle to upen
servo07.write(75, 30, false); // 37-75 claw servo 2, increase angle to open
delay(5000);

detectionState = digitalRead(detectionPin);
if (detectionState == HIGH)
{
  // Lower arm and close claw, POS
  delay(2000);
  servo01.write(90, 30, false); // 0-180, increase angle to turn right
  servo02.write(52, 30, false); // increase angle to raise arm
  servo03.write(130, 30, true); // increase angle to lower arm
  delay(500);
  servo04.write(90, 30, true); // increase angle to lower arm
  servo05.write(150, 30, false); // claw rotation servo
  delay(250);
  servo06.write(37, 30, false); // 37-75 claw servo 1, increase angle to open
  servo07.write(37, 30, false); // 37-75 claw servo 2, increase angle to open}
  delay(5000);

// Return to neutral position
  servo01.write(90, 30, false); // 0-180, increase angle to turn right  
  servo02.write(180, 30, true); // increase angle to raise arm
  servo03.write(180, 30, false); // increase angle to lower arm
  servo04.write(135, 30, true); // increase angle to lower arm
  servo05.write(90, 30, true); // claw rotation servo
  servo06.write(75, 30, false); // 37-75 claw servo 1, increase angle to upen
  servo07.write(75, 30, false); // 37-75 claw servo 2, increase angle to open
  delay(5000);
}
}

I'm a borderline Lenny with this Arduino stuff. I wasn't sure what to do here and what I had come up with didn't feel right. thanks for the confirmation lol. I think I ended up here because I started with trying to use digitalRead and walked myself into a hole.

I cannot look closely from where I sit just now, but a general Good Idea, which you may already have done, is to start with simple sketches that make no pretense of solving the problem.

The smallest of example programs meant for the parts you are using, so you can read code that shows how they are interfaced and controlled, what they report and so forth.

And so you can get the experience of hooking one up all by itself and confirming your state of knowledge, or having preconceived notions tested in the fire of reality.

Not to mention confirming that the $0.99 module that finally got here off the slow boat from wherever actually comes anywhere meeting specs.

a7

I have done this to varying degrees to get to here, incredibly helpful advice. using LEDs to verify the ultrasonic control function was super convenient (not having to test that on a 150lb rover was nice). i just wasn't sure how to isolate and test the parts of code that i'm working on at this point.

Thank You!

It's def a skill. Ironically, by the time you are really good at it, you may no longer need to do it so much, or maybe it will just become natural.

The key is to think way ahead, and strive to keep separate things that can be. So don't put a buncha LCD printing in the same logic that does a buncha ultra-pinging what also does the handling of the keypad. For example.

This is where the structure of your code can help - functions can be used to isolate pesky particulars and manage/handle low level details. They can really simplify the top level code, and as a benefit make it easy to write tests, or even to leave tests of some parts in the code that can be placed in or out of program flow, or invoked as a sort of secret.

Functions can also mean that others will be better able read your code. Even you will benefit from that in the future when you open ip a sketch for the first time in moths or years. Or days if you are like me wooosh! details fly out of my head, oh yes.

Functions also make it easier for others to find and fix flaws in your reasoning or code, and make it easier for others to come along and steal benefit from your work.

a7

4x gear motors. 10" pneumatic tires. 2 linear actuators. 5x ibt2 h bridge motor drivers. 3x arduinos. 24v @ 48AH. Who's got the best Tim Allen impression?

I know this is a programming forum, but i figured id see if you gurus had any constructive criticism/ helpful experience for me to profit off of regarding the hardware used.

There are a lot of digitaRead()s missing.

Gonna have to sit down with some LEDs when i get more time,,, guessing with the code is apparently not working well for me. Thank you!

Wow i feel stupid. I hope its not too presumptuous to thank you guys already. Thanks for really spelling it out for me too. This community is excellent.

while((digitalRead(ObjectDetected) == HIGH)){
    if((digitalRead(TurnLeftCommand) == HIGH)){
      turnLeft();
    }
    if((digitalRead(TurnRightCommand) == HIGH)){
      turnRight();
    }
    if((digitalRead(MoveForwardCommand) == HIGH)){
      moveForward();
    }
    if((digitalRead(MoveBackwardCommand) == HIGH)){
      moveBackward();

like a brick to the face! than you.

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