Switch and Case question

To whom this may concern,

On line 178 of the code below, I am having trouble getting a live reading from my analogRead(0) “val0” port. I am not sure if I can get live readings in a switch/case statement, however I can’t stop my robot if I can’t read these potentiometers. I am using the Adafruit Motor Shield and the Tigal EasyVR Shield to control all of these actions. If someone could look at my code and tell me if I can read live readings or not it would much appreciated.

Background: I am building a voice activated robot for my senior capstone. This robot will be commanded to pour a drink in a different cup. I have a robot that has DC motors that are being controlled by potentiometers. Therefore, I need them to stop when they get to a certain point on the pot.

if you have any question or concerns please let me know.

regards,

James

#include <EasyVR.h>
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *Motor1 = AFMS.getMotor(1);
int val0 = analogRead(0);
int val1 = analogRead(1);
int val2 = analogRead(2);
int val3 = analogRead(3);
int val4 = analogRead(4);

#if defined(ARDUINO) && ARDUINO >= 100
  #include "Arduino.h"
  #include "SoftwareSerial.h"
SoftwareSerial port(12,13);
#else // Arduino 0022 - use modified NewSoftSerial
#include "WProgram.h"
#include "NewSoftSerial.h"
NewSoftSerial port(12,13);
#endif

EasyVR easyvr(port);



//Groups and Commands
enum Groups
{
  GROUP_0  = 0,
  GROUP_1  = 1,
};

enum Group0 
{
  G0_ROBOT = 0,
};

enum Group1 
{
  G1_COKE = 0,
  G1_PEPSI = 1,
  G1_SPRITE = 2,
};


EasyVRBridge bridge;

int8_t group, idx;

void setup()
{
  // bridge mode?
  if (bridge.check())
  {
    cli();
    bridge.loop(0, 1, 12, 13);
  }
  // run normally
  Serial.begin(9600);
  port.begin(9600);

  if (!easyvr.detect())
  {
    Serial.println("EasyVR not detected!");
    for (;;);
  }

  easyvr.setPinOutput(EasyVR::IO1, LOW);
  Serial.println("EasyVR detected!");
  easyvr.setTimeout(5);
  easyvr.setLanguage(0);

  group = EasyVR::TRIGGER; //<-- start group (customize)
  
  Serial.println("Adafruit Motorshield v2 - DC Motor test!");
  Serial.println("Starting up controller!");
  AFMS.begin();  // create with the default frequency 1.6KHz
  //AFMS.begin(1000);  // OR with a different frequency, say 1KHz
  Serial.println("Controller has succsessfully !");
  // Set the speed to start, from 0 (off) to 255 (max speed)
  Motor1->setSpeed(150);
  
}

void action();

void loop()
{
  int val0 = analogRead(0);
  int val1 = analogRead(1);
  int val2 = analogRead(2);
  int val3 = analogRead(3);
  int val4 = analogRead(4);

  easyvr.setPinOutput(EasyVR::IO1, HIGH); // LED on (listening)

  Serial.print("Say a command in Group ");
  Serial.println(group);
  Serial.println(val0);
  Serial.println(val1);
  Serial.println(val2);
  Serial.println(val3);
  Serial.println(val4);
  easyvr.recognizeCommand(group);

  do
  {
    // can do some processing while waiting for a spoken command
  }
  while (!easyvr.hasFinished());
  
  easyvr.setPinOutput(EasyVR::IO1, LOW); // LED off

  idx = easyvr.getWord();
  if (idx >= 0)
  {
    // built-in trigger (ROBOT)
    // group = GROUP_X; <-- jump to another group X
    return;
  }
  idx = easyvr.getCommand();
  if (idx >= 0)
  {
    // print debug message
    uint8_t train = 0;
    char name[32];
    Serial.print("Command: ");
    Serial.print(idx);
    if (easyvr.dumpCommand(group, idx, name, train))
    {
      Serial.print(" = ");
      Serial.println(name);
    }
    else
      Serial.println();
    easyvr.playSound(0, EasyVR::VOL_FULL);
    // perform some action
    action();
  }
  else // errors or timeout
  {
    if (easyvr.isTimeout())
      Serial.println("Timed out, try again...");
    int16_t err = easyvr.getError();
    if (err >= 0)
    {
      Serial.print("Error ");
      Serial.println(err, HEX);
    }
  }
}

void action()
{
    switch (group)
    {
    case GROUP_0:
      switch (idx)
      {
      case G0_ROBOT:
        // write your action code here
        group = GROUP_1;// group = GROUP_X; <-- or jump to another group X for composite commands
        break;
      }
      break;
    case GROUP_1:
      switch (idx)
      {
      case G1_COKE:
        Serial.println ("before");
              val0 = analogRead(0);
              if (val0 >500)
              {
                while (val0 >500)
                {
              Serial.print ("value = ");
              Serial.println (val0);
              Motor1->setSpeed(100);
              Motor1->run(FORWARD);
              delay(100);
                }
               Motor1->setSpeed(0);
              }
         
        Serial.println ("after");
        group = GROUP_0;// group = GROUP_X; <-- or jump to another group X for composite commands
        break;
      case G1_PEPSI:
        // write your action code here
        group = GROUP_0;// group = GROUP_X; <-- or jump to another group X for composite commands
        break;
      case G1_SPRITE:
        // write your action code here
        group = GROUP_0;// group = GROUP_X; <-- or jump to another group X for composite commands
        break;
      }
      break;
    }
}

What values do you see over serial. Or is the switch case not even entering?

Could this be due to the fact that you have both a global variable and a local variable named val0? I think it is unlikely but still this seems like a bad way to code due to the possible conflict. Try getting rid of the local variable declaration in the loop() and see if that makes it work.

dagardner10:
I am not sure if I can get live readings in a switch/case statement, however I can't stop my robot if I can't read these potentiometers.

Why not? And why not just put your robot "up on blocks" while you test the code?

BTW... your code contains the following construct:

        while (val0 >500)
        {
          Serial.print ("value = ");
          Serial.println (val0);
          Motor1->setSpeed(100);
          Motor1->run(FORWARD);
          delay(100);
        }

Hint: Inside of a while loop it is normal to check the condition that is keeping you in the loop to see if anything has changed. As written, if you do get inside that while loop you'll never get back out.

Also can you really do the following? Outside of any function? Does each (poorly named) int just get zero'd?

int val0 = analogRead(0);
int val1 = analogRead(1);
int val2 = analogRead(2);
int val3 = analogRead(3);
int val4 = analogRead(4);

But overall it'd really help with debugging your code if you could include the serial debug information. That's the easiest way to see what's going on.

Regards,

Brad
KF7FER

PS rglazebr's suggestion is a good one... if nothing else it's bad style

You need to identify the line where you are having the problem . The line number doesn’t help. Post that line or put a comment there in CAPS so we can find it.

Could this be due to the fact that you have both a global variable and a local variable named val0? I think it is unlikely but still this seems like a bad way to code due to the possible conflict. Try getting rid of the local variable declaration in the loop() and see if that makes it work.

I know that I had a global and a local bit in there. I did that for testing to see if i could get the live reading inside of the case.

Furthermore…

Hint: Inside of a while loop it is normal to check the condition that is keeping you in the loop to see if anything has changed. As written, if you do get inside that while loop you’ll never get back out.

case G1_COKE:
        Serial.println ("before");
              if (val0 >500)
              {
                while (val0 >500)
                {
              Serial.print ("value = ");
              Serial.println (val0);
              Motor1->setSpeed(100);
              Motor1->run(FORWARD);
              delay(100);
                }
               Motor1->setSpeed(0);
              }
Serial.println ("after");
        group = GROUP_0;// group = GROUP_X; <-- or jump to another group X for composite commands
        break;

Correct me if I am wrong, however the way I read the above code is as follows: I switch to this case upon my voice saying coke. Then if val0 is greater than 500 move to the while statement. If val0 is greater than the 500 still (which it shouldn’t move) then do everything in the while. Next I print off the value the whole time it is running so I can see what the pot is reading every 10th of a second. Once the value is less then 500 making the while statement not true, it drops out of the while and goes to the end of the if statement where I have it turning off the motor? Finally print after so I know it came out of the while loop, and go back to group_0 which is my trigger group for my robot.

2.PNG

3.PNG

Next… to show you why I put those local and global bits in, look at the code below.

#include <EasyVR.h>
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *Motor1 = AFMS.getMotor(1);
int val0 = analogRead(0);
int val1 = analogRead(1);
int val2 = analogRead(2);
int val3 = analogRead(3);
int val4 = analogRead(4);

#if defined(ARDUINO) && ARDUINO >= 100
  #include "Arduino.h"
  #include "SoftwareSerial.h"
SoftwareSerial port(12,13);
#else // Arduino 0022 - use modified NewSoftSerial
#include "WProgram.h"
#include "NewSoftSerial.h"
NewSoftSerial port(12,13);
#endif

EasyVR easyvr(port);



//Groups and Commands
enum Groups
{
  GROUP_0  = 0,
  GROUP_1  = 1,
};

enum Group0 
{
  G0_ROBOT = 0,
};

enum Group1 
{
  G1_COKE = 0,
  G1_PEPSI = 1,
  G1_SPRITE = 2,
};


EasyVRBridge bridge;

int8_t group, idx;

void setup()
{
  // bridge mode?
  if (bridge.check())
  {
    cli();
    bridge.loop(0, 1, 12, 13);
  }
  // run normally
  Serial.begin(9600);
  port.begin(9600);

  if (!easyvr.detect())
  {
    Serial.println("EasyVR not detected!");
    for (;;);
  }

  easyvr.setPinOutput(EasyVR::IO1, LOW);
  Serial.println("EasyVR detected!");
  easyvr.setTimeout(5);
  easyvr.setLanguage(0);

  group = EasyVR::TRIGGER; //<-- start group (customize)
  
  Serial.println("Adafruit Motorshield v2 - DC Motor test!");
  Serial.println("Starting up controller!");
  AFMS.begin();  // create with the default frequency 1.6KHz
  //AFMS.begin(1000);  // OR with a different frequency, say 1KHz
  Serial.println("Controller has succsessfully !");
  // Set the speed to start, from 0 (off) to 255 (max speed)
  Motor1->setSpeed(150);
  
}

void action();

void loop()
{
  easyvr.setPinOutput(EasyVR::IO1, HIGH); // LED on (listening)

  Serial.print("Say a command in Group ");
  Serial.println(group);
  Serial.println(val0);
  Serial.println(val1);
  Serial.println(val2);
  Serial.println(val3);
  Serial.println(val4);
  easyvr.recognizeCommand(group);

  do
  {
    // can do some processing while waiting for a spoken command
  }
  while (!easyvr.hasFinished());
  
  easyvr.setPinOutput(EasyVR::IO1, LOW); // LED off

  idx = easyvr.getWord();
  if (idx >= 0)
  {
    // built-in trigger (ROBOT)
    // group = GROUP_X; <-- jump to another group X
    return;
  }
  idx = easyvr.getCommand();
  if (idx >= 0)
  {
    // print debug message
    uint8_t train = 0;
    char name[32];
    Serial.print("Command: ");
    Serial.print(idx);
    if (easyvr.dumpCommand(group, idx, name, train))
    {
      Serial.print(" = ");
      Serial.println(name);
    }
    else
      Serial.println();
    easyvr.playSound(0, EasyVR::VOL_FULL);
    // perform some action
    action();
  }
  else // errors or timeout
  {
    if (easyvr.isTimeout())
      Serial.println("Timed out, try again...");
    int16_t err = easyvr.getError();
    if (err >= 0)
    {
      Serial.print("Error ");
      Serial.println(err, HEX);
    }
  }
}

void action()
{
    switch (group)
    {
    case GROUP_0:
      switch (idx)
      {
      case G0_ROBOT:
        // write your action code here
        group = GROUP_1;// group = GROUP_X; <-- or jump to another group X for composite commands
        break;
      }
      break;
    case GROUP_1:
      switch (idx)
      {
      case G1_COKE:
        Serial.println ("before");
              if (val0 <500)
              {
                while (val0 <500)
                {
              Serial.print ("value = ");
              Serial.println (val0);
              Motor1->setSpeed(100);
              Motor1->run(FORWARD);
              delay(100);
                }
               Motor1->setSpeed(0);
              }
         
        Serial.println ("after");
        group = GROUP_0;// group = GROUP_X; <-- or jump to another group X for composite commands
        break;
      case G1_PEPSI:
        // write your action code here
        group = GROUP_0;// group = GROUP_X; <-- or jump to another group X for composite commands
        break;
      case G1_SPRITE:
        // write your action code here
        group = GROUP_0;// group = GROUP_X; <-- or jump to another group X for composite commands
        break;
      }
      break;
    }
}

Now look at Image #3. Everything is zero.

Now look at this code with a global and local bit, but not “int” in the case.

#include <EasyVR.h>
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *Motor1 = AFMS.getMotor(1);
int val0 = analogRead(0);
int val1 = analogRead(1);
int val2 = analogRead(2);
int val3 = analogRead(3);
int val4 = analogRead(4);

#if defined(ARDUINO) && ARDUINO >= 100
  #include "Arduino.h"
  #include "SoftwareSerial.h"
SoftwareSerial port(12,13);
#else // Arduino 0022 - use modified NewSoftSerial
#include "WProgram.h"
#include "NewSoftSerial.h"
NewSoftSerial port(12,13);
#endif

EasyVR easyvr(port);



//Groups and Commands
enum Groups
{
  GROUP_0  = 0,
  GROUP_1  = 1,
};

enum Group0 
{
  G0_ROBOT = 0,
};

enum Group1 
{
  G1_COKE = 0,
  G1_PEPSI = 1,
  G1_SPRITE = 2,
};


EasyVRBridge bridge;

int8_t group, idx;

void setup()
{
  // bridge mode?
  if (bridge.check())
  {
    cli();
    bridge.loop(0, 1, 12, 13);
  }
  // run normally
  Serial.begin(9600);
  port.begin(9600);

  if (!easyvr.detect())
  {
    Serial.println("EasyVR not detected!");
    for (;;);
  }

  easyvr.setPinOutput(EasyVR::IO1, LOW);
  Serial.println("EasyVR detected!");
  easyvr.setTimeout(5);
  easyvr.setLanguage(0);

  group = EasyVR::TRIGGER; //<-- start group (customize)
  
  Serial.println("Adafruit Motorshield v2 - DC Motor test!");
  Serial.println("Starting up controller!");
  AFMS.begin();  // create with the default frequency 1.6KHz
  //AFMS.begin(1000);  // OR with a different frequency, say 1KHz
  Serial.println("Controller has succsessfully !");
  // Set the speed to start, from 0 (off) to 255 (max speed)
  Motor1->setSpeed(150);
  
}

void action();

void loop()
{
  int val0 = analogRead(0);
  int val1 = analogRead(1);
  int val2 = analogRead(2);
  int val3 = analogRead(3);
  int val4 = analogRead(4);
  
  easyvr.setPinOutput(EasyVR::IO1, HIGH); // LED on (listening)

  Serial.print("Say a command in Group ");
  Serial.println(group);
  Serial.println(val0);
  Serial.println(val1);
  Serial.println(val2);
  Serial.println(val3);
  Serial.println(val4);
  easyvr.recognizeCommand(group);

  do
  {
    // can do some processing while waiting for a spoken command
  }
  while (!easyvr.hasFinished());
  
  easyvr.setPinOutput(EasyVR::IO1, LOW); // LED off

  idx = easyvr.getWord();
  if (idx >= 0)
  {
    // built-in trigger (ROBOT)
    // group = GROUP_X; <-- jump to another group X
    return;
  }
  idx = easyvr.getCommand();
  if (idx >= 0)
  {
    // print debug message
    uint8_t train = 0;
    char name[32];
    Serial.print("Command: ");
    Serial.print(idx);
    if (easyvr.dumpCommand(group, idx, name, train))
    {
      Serial.print(" = ");
      Serial.println(name);
    }
    else
      Serial.println();
    easyvr.playSound(0, EasyVR::VOL_FULL);
    // perform some action
    action();
  }
  else // errors or timeout
  {
    if (easyvr.isTimeout())
      Serial.println("Timed out, try again...");
    int16_t err = easyvr.getError();
    if (err >= 0)
    {
      Serial.print("Error ");
      Serial.println(err, HEX);
    }
  }
}

void action()
{
    switch (group)
    {
    case GROUP_0:
      switch (idx)
      {
      case G0_ROBOT:
        // write your action code here
        group = GROUP_1;// group = GROUP_X; <-- or jump to another group X for composite commands
        break;
      }
      break;
    case GROUP_1:
      switch (idx)
      {
      case G1_COKE:
        Serial.println ("before");
              if (val0 <500)
              {
                while (val0 <500)
                {
              Serial.print ("value = ");
              Serial.println (val0);
              Motor1->setSpeed(100);
              Motor1->run(FORWARD);
              delay(100);
                }
               Motor1->setSpeed(0);
              }
         
        Serial.println ("after");
        group = GROUP_0;// group = GROUP_X; <-- or jump to another group X for composite commands
        break;
      case G1_PEPSI:
        // write your action code here
        group = GROUP_0;// group = GROUP_X; <-- or jump to another group X for composite commands
        break;
      case G1_SPRITE:
        // write your action code here
        group = GROUP_0;// group = GROUP_X; <-- or jump to another group X for composite commands
        break;
      }
      break;
    }
}

Now look at image #2. This is what I am talking about.

Please provide insight if I am just doing something completely wrong.

2.PNG

3.PNG

Youre wrong about the while loop. Youre right that it will exit if val0 ever goes below 500 but val0 will never do that since you never read the pin again. If val0 was over 500 and you never set it to anything else then how will it magically ever get below 500? Youll be stuck in that while loop forever.

If val0 was over 500 and you never set it to anything else then how will it magically ever get below 500? Youll be stuck in that while loop forever.

It will exit while loop because the potentiometer is moving. Once it is reading less than 500 it will say the while loop is invalid backing it out of the while loop. This is where the problem is existing, I am not getting a live reading inside the while loop and I don't know why. I am going to try to give it a local bit to read and see if that is problem.

Now look at this code and picture. I added a “val = analogRead(0);” into the while look and I get a live reading.

case G1_COKE:
        Serial.println ("before");
              if (val0 <500)
              {
                while (val0 <500)
                {
                 val0 = analogRead(0);
                 Serial.print ("value = ");
                 Serial.println (val0);
                 Motor1->setSpeed(100);
                 Motor1->run(FORWARD);
                 delay(1000);
                }
               Motor1->setSpeed(0);
              }

4.PNG

Right. The value in the variable doesnt automagically track the pot. It only changes when your code explicitly changes it.