Robot con EasyVr + sensores

Buenas,

El proposito de este proyecto es crear un robot capaz de obeder ordenes mediante Easy Vr.
Primero le doy la orden Robot para que acceda al Wordset1, una vez que hice esto le doy la orden accion ,mi problemas es cuando le doy la orden Action, esperaba que al darle esta orden comenzara a "explorar" el entorno, es decir que use el sensor Ultrasonido hc-sr04 para reconocer obstaculos y poder evitarlos, que lo haga hasta que yo le de otra orden, por ejemplo Parar, sin embargo, al intentar plasmar esto, me di cuenta que no funciona, en los primeros intentos no hacia nada de lo que queria, solo iba hacia adelante, nada mas.

Probe a usar un programa mas simple, un servomotor, easy vr , el sensor hc-sr04 y una Arduino mega, el programa resultate de unos cuantos intentos es que adjunto, consegui que al darle la orden accion el sensor comienza a medir las distancias, a detectar obstaculos y el servo se mueve haciendo lo que queria.

El problema es que ahora ¡no se pararlo! , no escucha la orden Parar, ni ninguna otra solo ejecuta la orden Accion.

Espero que me explicara correctamente en cuanto al fallo y en lo que quiero hacer, tambien espero que alguien tenga un momento y me puede ayudar y tengo que decir que soy nuevo en esto, de hecho es el primer tema que creo, ante todo gracias por adelantado.


#include <NewPing.h>
#include <Servo.h>
Servo servoRight; 

//Sensores
const int TRIGGER_PIN = 22;
const int ECHO_PIN = 23; 

const int DISTANCIA_MAXIMA = 200;
const int MIN_DISTANCIA = 30;


const int SONAR_NUM = 1; 
unsigned int sensor_obstaculo[SONAR_NUM]; 

NewPing sonar(TRIGGER_PIN, ECHO_PIN, DISTANCIA_MAXIMA); // NewPing setup of pins and maximum distance.

#include "Arduino.h"
#if !defined(SERIAL_PORT_MONITOR)
  #error "Arduino version not supported. Please update your IDE to the latest version."
#endif

#if defined(__SAMD21G18A__)
  // Shield Jumper on HW (for Zero, use Programming Port)
  #define port SERIAL_PORT_HARDWARE
  #define pcSerial SERIAL_PORT_MONITOR
#elif defined(SERIAL_PORT_USBVIRTUAL)
  // Shield Jumper on HW (for Leonardo and Due, use Native Port)
  #define port SERIAL_PORT_HARDWARE
  #define pcSerial SERIAL_PORT_USBVIRTUAL
#else
  // Shield Jumper on SW (using pins 12/13 or 8/9 as RX/TX)
  #include "SoftwareSerial.h"
  SoftwareSerial port(12, 13);
  #define pcSerial SERIAL_PORT_MONITOR
#endif

#include "EasyVR.h"

EasyVR easyvr(port);

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

enum Group0 
{
  G0_HOLA = 0,
};

enum Group1 
{
  G1_GO = 0,
  G1_BACK = 1,
  G1_STOP = 2,
  G1_RIGH = 3,
  G1_LEFT = 4,
  G1_MOVE = 5,
};

//Grammars and Words
enum Wordsets
{
  SET_1  = -1,
  SET_2  = -2,
  SET_3  = -3,
};

enum Wordset1 
{
  S1_ACTION = 0,
  S1_MOVE = 1,
  S1_TURN = 2,
  S1_RUN = 3,
  S1_LOOK = 4,
  S1_ATTACK = 5,
  S1_STOP = 6,
  S1_HELLO = 7,
};

enum Wordset2 
{
  S2_LEFT = 0,
  S2_RIGHT = 1,
  S2_UP = 2,
  S2_DOWN = 3,
  S2_FORWARD = 4,
  S2_BACKWARD = 5,
};

enum Wordset3 
{
  S3_ZERO = 0,
  S3_ONE = 1,
  S3_TWO = 2,
  S3_THREE = 3,
  S3_FOUR = 4,
  S3_FIVE = 5,
  S3_SIX = 6,
  S3_SEVEN = 7,
  S3_EIGHT = 8,
  S3_NINE = 9,
  S3_TEN = 10,
};


// use negative group for wordsets
int8_t group, idx;

void setup()

{
   servoRight.attach(9);
  
  
  // setup PC serial port
  pcSerial.begin(9600);
bridge:
  // bridge mode?
  int mode = easyvr.bridgeRequested(pcSerial);
  switch (mode)
  {
  case EasyVR::BRIDGE_NONE:
    // setup EasyVR serial port
    port.begin(9600);
    // run normally
    pcSerial.println(F("Bridge not requested, run normally"));
    pcSerial.println(F("---"));
    break;
    
  case EasyVR::BRIDGE_NORMAL:
    // setup EasyVR serial port (low speed)
    port.begin(9600);
    // soft-connect the two serial ports (PC and EasyVR)
    easyvr.bridgeLoop(pcSerial);
    // resume normally if aborted
    pcSerial.println(F("Bridge connection aborted"));
    pcSerial.println(F("---"));
    break;
    
  case EasyVR::BRIDGE_BOOT:
    // setup EasyVR serial port (high speed)
    port.begin(115200);
    pcSerial.end();
    pcSerial.begin(115200);
    // soft-connect the two serial ports (PC and EasyVR)
    easyvr.bridgeLoop(pcSerial);
    // resume normally if aborted
    pcSerial.println(F("Bridge connection aborted"));
    pcSerial.println(F("---"));
    break;
  }

  // initialize EasyVR  
  while (!easyvr.detect())
  {
    pcSerial.println(F("EasyVR not detected!"));
    for (int i = 0; i < 10; ++i)
    {
      if (pcSerial.read() == '?')
        goto bridge;
      delay(100);
    }
  }

  pcSerial.print(F("EasyVR detected, version "));
  pcSerial.print(easyvr.getID());

  if (easyvr.getID() < EasyVR::EASYVR3)
    easyvr.setPinOutput(EasyVR::IO1, LOW); // Shield 2.0 LED off

  if (easyvr.getID() < EasyVR::EASYVR)
    pcSerial.print(F(" = VRbot module"));
  else if (easyvr.getID() < EasyVR::EASYVR2)
    pcSerial.print(F(" = EasyVR module"));
  else if (easyvr.getID() < EasyVR::EASYVR3)
    pcSerial.print(F(" = EasyVR 2 module"));
  else
    pcSerial.print(F(" = EasyVR 3 module"));
  pcSerial.print(F(", FW Rev."));
  pcSerial.println(easyvr.getID() & 7);

  easyvr.setDelay(0); // speed-up replies

  easyvr.setTimeout(5);
  easyvr.setLanguage(4); //<-- same language set on EasyVR Commander when code was generated

  group = EasyVR::TRIGGER; //<-- start group (customize)




  
}





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

  if (group < 0) // SI wordset/grammar
  {
    pcSerial.print("Say a word in Wordset ");
    pcSerial.println(-group);
    easyvr.recognizeWord(-group);
  }
  else // SD group
  {
    pcSerial.print("Say a command in Group ");
    pcSerial.println(group);
    easyvr.recognizeCommand(group);
  }

  do
  {
    
    
    // allows Commander to request bridge on Zero (may interfere with user protocol)
    if (pcSerial.read() == '?')
    {
      setup();
      return;
    }
    // <<-- can do some processing here, while the module is busy
  }
  while (!easyvr.hasFinished());
  
  if (easyvr.getID() < EasyVR::EASYVR3)
    easyvr.setPinOutput(EasyVR::IO1, LOW); // LED off

  idx = easyvr.getWord();
  if (idx == 0 && group == EasyVR::TRIGGER)
  {
    // beep
    easyvr.playSound(0, EasyVR::VOL_FULL);
    // print debug message
    pcSerial.println("Word: ROBOT");
    // write your action code here
     group = SET_1; //<-- jump to another group or wordset
    return;
  }
  else if (idx >= 0)
  {
    // beep
    easyvr.playSound(0, EasyVR::VOL_FULL);
    // print debug message
    uint8_t flags = 0, num = 0;
    char name[32];
    pcSerial.print("Word: ");
    pcSerial.print(idx);
    if (easyvr.dumpGrammar(-group, flags, num))
    {
      for (uint8_t pos = 0; pos < num; ++pos)
      {
        if (!easyvr.getNextWordLabel(name))
          break;
        if (pos != idx)
          continue;
        pcSerial.print(F(" = "));
        pcSerial.println(name);
        break;
      }
    }
    // perform some action
    action();
    return;
  }
  idx = easyvr.getCommand();
  if (idx >= 0)
  {
    // beep
    easyvr.playSound(0, EasyVR::VOL_FULL);
    // print debug message
    uint8_t train = 0;
    char name[32];
    pcSerial.print("Command: ");
    pcSerial.print(idx);
    if (easyvr.dumpCommand(group, idx, name, train))
    {
      pcSerial.print(" = ");
      pcSerial.println(name);
    }
    else
      pcSerial.println();
    // perform some action
  
    action();
    

    
  }
  else // errors or timeout
  {
    if (easyvr.isTimeout())
      pcSerial.println("Timed out, try again...");
    int16_t err = easyvr.getError();
    if (err >= 0)
    {
      pcSerial.print("Error ");
      pcSerial.println(err, HEX);
    }
  }
}

void action()
{
  switch (group)
  {
  case GROUP_0:
    switch (idx)
    {
    case G0_HOLA:
      // write your action code here
       group =SET_1; 
      break;
    }
    break;
  case GROUP_1:
    switch (idx)
    {
    case G1_GO:
      // write your action code here
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    case G1_BACK:
      // write your action code here
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    case G1_STOP:
      // write your action code here
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    case G1_RIGH:
      // write your action code here
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    case G1_LEFT:
      // write your action code here
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    case G1_MOVE:
      // write your action code here
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    }
    break;
  case SET_1:
    switch (idx)
    {
    case S1_ACTION:
      // write your action code here
           do
          {
              sensorUltra();
              if  (sensor_obstaculo[0] ==0) 
              {

                    forward();
              }
   
              else 
              {
                   stopRobot(); 
              }
          }
      
         while (!easyvr.hasFinished());
         idx = easyvr.getWord();
         if (idx == 6 && group == SET_1)
         {
   
            group = SET_1; //<-- jump to another group or wordset
            

         }
  
 
    
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    case S1_TURN:
      // write your action code here


      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    case S1_RUN:
      // write your action code here
         

      
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    case S1_LOOK:
      // write your action code here
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    case S1_ATTACK:
      // write your action code here
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    case S1_STOP:
      // write your action code here
       
      
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    case S1_HELLO:
      // write your action code here
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    }
    break;
  case SET_2:
    switch (idx)
    {
    case S2_LEFT:
      // write your action code here
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    case S2_RIGHT:
      // write your action code here
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    case S2_UP:
      // write your action code here
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    case S2_DOWN:
      // write your action code here
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    case S2_FORWARD:
      // write your action code here
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    case S2_BACKWARD:
      // write your action code here
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    }
    break;
  case SET_3:
    switch (idx)
    {
    case S3_ZERO:
      // write your action code here
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    case S3_ONE:
      // write your action code here
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    case S3_TWO:
      // write your action code here
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    case S3_THREE:
      // write your action code here
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    case S3_FOUR:
      // write your action code here
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    case S3_FIVE:
      // write your action code here
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    case S3_SIX:
      // write your action code here
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    case S3_SEVEN:
      // write your action code here
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    case S3_EIGHT:
      // write your action code here
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    case S3_NINE:
      // write your action code here
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    case S3_TEN:
      // write your action code here
      // group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
      break;
    }
    break;
  }
}





void sensorUltra() {

    unsigned int distancia_medida = 0;

    // Mirar la distancia detectada en los 3 sensores
    for (uint8_t i = 0; i < SONAR_NUM; i++)                    
    { 
      sensor_obstaculo[i] = 0;  
             
      // "distancia_medida" devolverá el valor 0 (NO_ECHO) si no hay retorno del ping enviado (ej: fuera del rango de distancia que puede medir) 
      distancia_medida = sonar.ping_cm();   

       Serial.print(distancia_medida);
       Serial.println("cm");


             
      if ((distancia_medida != NO_ECHO) && (distancia_medida < MIN_DISTANCIA))   
        sensor_obstaculo[i] = 1;
    
      // Hay que dejar un poco de tiempo entre pings (29 ms seria el límite más bajo)
      delay(50);    
      
      }


     
      
    }



void forward() {
  servoRight.write(0);
  
}

void stopRobot() {
  servoRight.write(1530);   //Para 1530 no se observa movimiento
}
  

Lo primero que debiste hacer es practicar con Easy VR logrando que reconozca comandos y que los presente en el monitor Serie.
Luego agregar el control a un robot es una tarea muy simple.
Supongo que de los ejemplos de Easy Vr has hecho gran parte de esto.
Vuelve a lo básico, como te digo, comando y reconocimiento correcto y visualización por Monitor Serie.
Luego regresa a la interfaz con los motores, sensores, etc.
No olvides prescindir de delay()

Agrego a lo que te señala @Surbyte que usar SoftwareSerial en un Mega es completamente innecesario porque tiene 4 puertos serie hardware.

Comenta o elimina el siguiente bloque de código que no lo necesitas a menos que cambies de micro

#if !defined(SERIAL_PORT_MONITOR)
  #error "Arduino version not supported. Please update your IDE to the latest version."
#endif

#if defined(__SAMD21G18A__)
  // Shield Jumper on HW (for Zero, use Programming Port)
  #define port SERIAL_PORT_HARDWARE
  #define pcSerial SERIAL_PORT_MONITOR
#elif defined(SERIAL_PORT_USBVIRTUAL)
  // Shield Jumper on HW (for Leonardo and Due, use Native Port)
  #define port SERIAL_PORT_HARDWARE
  #define pcSerial SERIAL_PORT_USBVIRTUAL
#else
  // Shield Jumper on SW (using pins 12/13 or 8/9 as RX/TX)
  #include "SoftwareSerial.h"
  SoftwareSerial port(12, 13);
  #define pcSerial SERIAL_PORT_MONITOR
#endif

y agrega

#define port SERIAL_PORT_HARDWARE1
#define pcSerial SERIAL_PORT_MONITOR

o directamente

#define port Serial1
#define pcSerial Serial

El Serial1 utiliza los pines 19 (RX) y 18 (TX).

Saludos

Consegui solucionar el problema, muchas gracias a los dos por responder, mirare lo que me comentasteis.

Una ultima cosa aprovechando este tema, https://www.amazon.es/diámetro-redondo-interna-altavoz-Arduino/dp/B073TSC7RW/ref=asc_df_B073TSC7RW/?tag=googshopes-21&linkCode=df0&hvadid=469782154207&hvpos=&hvnetw=g&hvrand=827795873019646651&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=9047040&hvtargid=pla-386019813494&psc=1, seria un buen altavoz para easy vr?

Saludos

Si, considero que va perfectamente.

Saludos

La hoja de datos del Easy VR dice en su página 8

Entonces un parlante de 8 ohms como el que indicas deberia ir bien.

y además en la página 14 dice

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