Switch code format question - call function to gain readings?

Hello all

I am currently writing a code for my first robot.

I would like the robot to flip between straight obstacle avoidance and IR tracking and obstacle avoidance when battery drops low.

I am stuck as to whether or not I need to call the functions that provide the readings needed to decide which mode to run at the top of each case, then do a ‘if’.

Other switch’s i have looked at seem to go straight to comparing two or more values, but how does it know what the values are if they haven’t been measured?

I have included the start of my switch and case 0, if someone could let me know if the flow is right that would be great.

void SetMode()//enclosing program to determine robots movements
{
  switch (mode)
  {
    case 0 : //obstacle avoidance only
      {
        BatCheck(); //reads battery level sensor
        readMotionSensor(); //reads motion detector
      }
      if (BatLevel > minBatVolts && MotionDetected == HIGH) //if the battery level is over the miinimum set and the motion is detected
        Serial.println("Obstacle Only Mode");
      {
        readChargePadSensor();
        if (chargeVolts >= minVoltsSensed) // if voltage is detected from charge mat
        {
          Serial.println("stop and charge"); //Robot has been manually placed on chargePad and will now charge
          (stopMoving);
          (centreHead);
          delay(1000); // this is just incase i want to pick him up and put him on charge manually
          delay(2700000);//45 minute delay for charging cycle - 60k x 45
          (reverse); //reverse out of docking station
          (turn180); //turns 180
        }
        else readCentreDist(); //readds center distance and returns center distance value

        if (centreDistMeasurement < maxClearPathMeasurement) //if path is clear
        {
          (moveForward);
        }
        else //if path is blocked
        {
          (stopMoving);
          (readRightDist);// reads right left and center distances and returns readings
          (readLeftDist);
          (centreHead);
          if (leftDistMeasurement < rightDistMeasurement) //if left is less obstructed
          {
            (turnLeft);
          }
          else if (rightDistMeasurement < leftDistMeasurement) //if right is less obstructed
          {
            (turnRight);
          }
          if (rightDistMeasurement == leftDistMeasurement) //if they are equally obstructed
          {
            (turn180);
          }
          break;

If you want to switch on the mode variable you have to fill it with something useful.

But uhm

          (stopMoving);
          (readRightDist);// reads right left and center distances and returns readings
          (readLeftDist);
          (centreHead);

What's that supposed to do? Just random variables between brackets????

I am stuck as to whether or not I need to call the functions that provide the readings needed to decide which mode to run at the top of each case, then do a ‘if’.

How else are you going to operate in the correct mode, on each pass through loop()?

The function that you posted is called SetMode() but it does not set the mode. Of course, there are serious issues with that code, too.

You could make a choice in loop() as to whether to execute the wanderAround() mode or the huntForHome() mode, but the conditions that cause you to decide which mode you are going to execute can change each time loop() is called, so basing a decision on what you knew last time doesn’t feel right.

Whoops, they should be functions…

As you can see writing this has been a very steep learning curve.

Amended posted below;

void SetMode()//enclosing program to determine robots movements
{
  switch (mode)
  {
    case 0 : //obstacle avoidance only
      {
        BatCheck(); //reads battery level sensor
        readMotionSensor(); //reads motion detector
      }
      if (BatLevel > minBatVolts && MotionDetected == HIGH) //if the battery level is over the miinimum set and the motion is detected
        Serial.println("Obstacle Only Mode");
      {
        readChargePadSensor();
        if (chargeVolts >= minVoltsSensed) // if voltage is detected from charge mat
        {
          Serial.println("stop and charge"); //Robot has been manually placed on chargePad and will now charge
          stopMoving();
          centreHead();
          delay(1000); // this is just incase i want to pick him up and put him on charge manually
          delay(2700000);//45 minute delay for charging cycle - 60k x 45
          reverse(); //reverse out of docking station
          turn180(); //turns 180
        }
        else readCentreDist(); //readds centre distance and returns centre distance value

        if (centreDistMeasurement < maxClearPathMeasurement) //if path is clear
        {
          moveForward();
        }
        else //if path is blocked
        {
          stopMoving();
          readRightDist();// reads right left and centre distances and returns readings
          readLeftDist();
          (centreHead);
          if (leftDistMeasurement < rightDistMeasurement) //if left is less obstructed
          {
            turnLeft();
          }
          else if (rightDistMeasurement < leftDistMeasurement) //if right is less obstructed
          {
            turnRight();
          }
          if (rightDistMeasurement == leftDistMeasurement) //if they are equally obstructed
          {
            turn180();
          }
          break;

Measure the battery voltage at the top of loop() and execute the appropriate block of code based on the value.

void loop()
 {
  voltage = measureBatteryVoltage);
  if (voltage < threshold)
  {
    //execute this code
  }
  else
  {
    //execute this code
  }
}

[quote author=Valve Child link=msg=3178417 date=1489659861] Whoops, they should be functions...

As you can see writing this has been a very steep learning curve. [/quote] That's not what I see... That's you trying to do everything at once. Like building a JSF before you learned how to fold a paper glider... Baby steps! Baby steps!

Thanks All,

Bob, would I then just ditch the Switch all together, as the if and else would do the same?

I would just make a 'AvoidStuff()' function with all the code and a 'SeekIR()' function with all that code and call each one?

Might be an easier solution for this as Switch is hurting my brain.

I moved all the code for the Obstacle avoidance into a function called ‘avoidMode()’ and all the code for IRseek and obstacleavoidance into a function called ‘IRSeekMode()’ makes the main loop look like this now… much tidier and far less confusing. Thanks Bob.

void loop()
{
  BatCheck(); //reads battery level sensor
  readMotionSensor(); //reads motion detector

  if (BatLevel > minBatVolts && MotionDetected == HIGH) //if the battery level is over the miinimum set and the motion is detected
  { Serial.println("Obstacle Only Mode");
    avoidMode();
  }
  else if (BatLevel <= minBatVolts && MotionDetected == HIGH) //if the battery level detected falls below the set minimum and motion is detected
  {
    Serial.println("IR Tracking Mode");
    IRSeekMode();
  }
}

The whole code would be a lot cleaner if you minimized the number of global variables. There is no reason that BatCheck() and loop() should exchange information through a global variable when there is only one piece of information, and no other function cares what the battery voltage is.

I can’t imagine a relationship between a battery going low, and the need to recharge it, and motion being detected. Why should the robot squat in place, and let the battery go dead, just because all the humans left the room?

Hello Paul,

Thanks for the feedback, the idea was that the little guy would only run if there was someone there to see it running, saving on battery power.

I'm not sure how long he could sit there idle, just running through the program but I'm sure it would be longer than him buzzing around the house with no one home.

You have made me think though that if he even stops detecting motion for a moment he will stop, I will have to research how to make him keep motion as detected for a set period of time (say 5 mins).

Thanks for the feedback, the idea was that the little guy would only run if there was someone there to see it running, saving on battery power.

If there wasn't anyone there, wouldn't that be a good time to duck out for a recharge?