Switch case problem

I am Northeat from Switzerland and new in this forum, a friendly hello to all.

Since two weeks I am working with programming and robotics. Now I come across a problem which I cannot solve alone.

I have a Hexapot which can be controlled very well with a PS2 controller. Now I want to have some of the functions of PS2 on my mobile phone and control the robot over the internet. With Blynk, it’s relatively easy. I made everything work even if I didn’t understand everything. The robot has different MoveModes, which are controlled by a left and right joystick. The arguments are passed like this - SendData(CMD_REG_WALK, WALK_F, WALK_S, ROTATE2, 0); - the left joystick passes WALK_F and WALK_S and the right joystick passes ROTATE2 - if I move a joystick I always have to pass all arguments to it and I think that somehow works but I think there is a smarter way to solve it. Now I tried with switch case to be able to choose between the different MoveModes and this also works. But if I move the robot forwards (joystick left) it won’t stop running.

Can someone help me to understand what I have to do differently?

  • nodeMCU
  • newest Blynk liblary
  • Hexapot with custom board
- The sample show the basic movements w/o the hexapod library
- Send data from the User-Board to Locomotion-Controller

******************************************************************************/
// Arduino or NodeMCU (select one)
//#define ARDUINO
#define NODEMCU


// UART
#define SERIAL_CMD_BAUD         38400       // Locomotion-Controller to User-Board

#define CMD_SYNC0               33          // Sync byte 1
#define CMD_SYNC1               42          // Sync byte 2
#define CMD_TERM_BYTE           255         // Termination byte

// CMD REGISTER [WRITE-VALUES]
#define CMD_REG_TRANSLATE       35
#define CMD_REG_WALK            40
#define CMD_REG_ROTATE          45


int MOVEMODE = 1;

int BODY_HIGHT;
int SPEED = 100;
int ROTATE;
int ROTATE2;
int WALK_F;
int WALK_S;
int x;
int y;
int z;
int f;

// Software Serial (Locomotion-Controler <--> User-Board)
SoftwareSerial SERIAL_CMD(RXD_U, TXD_U); // RX, TX Arduino UNO

/******************************************************************************
UART SEND- and READ-COMMANDS
******************************************************************************/
void SendData(byte _cmd, byte _data1, byte _data2, byte _data3, byte _data4)
{
    // calc CRC
    byte _crc = CMD_SYNC0 ^ CMD_SYNC1 ^ _cmd ^ _data1 ^ _data2 ^ _data3 ^ _data4;
   
    // send bytes
    SERIAL_CMD.write(CMD_SYNC0);
    SERIAL_CMD.write(CMD_SYNC1);
    SERIAL_CMD.write(_crc);
   
    SERIAL_CMD.write(_cmd);
    SERIAL_CMD.write(_data1);
    SERIAL_CMD.write(_data2);
    SERIAL_CMD.write(_data3);
    SERIAL_CMD.write(_data4);
    SERIAL_CMD.write(CMD_TERM_BYTE);
}

     //V1 and V2 work, but i think this is not a good solution //WALK Joystick forward sideward
    /*BLYNK_WRITE(V1)
    {       
      int x = param[0].asInt();
      int y = param[1].asInt();
      WALK_F = x;
      WALK_S = y;
      if (MOVEMODE == 1){
      SendData(CMD_REG_WALK, WALK_F, WALK_S, ROTATE2, 0);}
      else
      {
      SendData(CMD_REG_ROTATE, WALK_F, WALK_S, ROTATE2, ROTATE);}
    }
     //WALK rotate parameter
    BLYNK_WRITE(V4)
    {       
      int z = param[0].asInt();
      int f = param[1].asInt();
      ROTATE = f;
      ROTATE2 = z;
      if (ROTATE_SWITCH_STATE == 0){
      SendData(CMD_REG_WALK, WALK_F, WALK_S, ROTATE2, 0);}
      else {
      SendData(CMD_REG_ROTATE, WALK_F, WALK_S, ROTATE2, ROTATE);}
     
    }*/

    //MOVE SELECTOR
    BLYNK_WRITE(V7) {
      switch (param.asInt()) {
        case 1: { //WALKMODE
          MOVEMODE = 1;
          break;
        }
        case 2: { //TRANSLATEMODE
          MOVEMODE = 2;
          break;
        }
        case 3: { //ROTATEMODE
          MOVEMODE = 3;
          break;
        }
        case 4: { //SINGLEMODE
          MOVEMODE = 4;
          break;
        }}
      }
//LEFT JOYSTICK
      BLYNK_WRITE(V1){
        switch(MOVEMODE) {   
          case 1: { //WALKMODE
            int x = param[0].asInt();
            int y = param[1].asInt();
            WALK_F = x;
            WALK_S = y;
            SendData(CMD_REG_WALK, WALK_F, WALK_S, ROTATE2, 0);
            break;
            }
           case 2: { //TRANSLATEMODE
            SendData(CMD_REG_TRANSLATE, WALK_F, WALK_S, ROTATE2, ROTATE);
            break;
            }
           case 3: { //ROTATEMODE
            SendData(CMD_REG_ROTATE, WALK_F, WALK_S, ROTATE2, ROTATE);
            break;
            }
           case 4: { //SINGLELEGMODE
            SendData(SINGLELEGMODE, WALK_F, WALK_S, ROTATE2, ROTATE);
            break;
            }
          }
        }

//RIGHT JOYSTICK
        BLYNK_WRITE(V4){
        switch(MOVEMODE) {   
          case 1: { //WALKMODE
            int z = param[0].asInt();
            int f = param[1].asInt();
            ROTATE = f;
            ROTATE2 = z;
            SendData(CMD_REG_WALK, WALK_F, WALK_S, ROTATE2, 0);
            break;
            }
           case 2: { //TRANSLATEMODE
            SendData(CMD_REG_TRANSLATE, WALK_F, WALK_S, ROTATE2, ROTATE);
            break;
            }
           case 3: { //ROTATEMODE
            SendData(CMD_REG_ROTATE, WALK_F, WALK_S, ROTATE2, ROTATE);
            break;
            }
           case 4: { //SINGLELEGMODE
            SendData(SINGLELEGMODE, WALK_F, WALK_S, ROTATE2, ROTATE);
            break;
            }
          }
        }

I guess the Joystick sends the values x=512 and y=512 (scale 0-1023) if it’s at center position; and you have to minus 512 from the value x/y you received from the joystick widget.

You can put a debugging code inside to know exactly

//LEFT JOYSTICK
      BLYNK_WRITE(V1){
        switch(MOVEMODE) {   
          case 1: { //WALKMODE
            int x = param[0].asInt();
            int y = param[1].asInt();
            WALK_F = x;
            WALK_S = y;

            // Try
            //WALK_F = x - 512;
            //WALK_S = y - 512;

          
            Serial.print("X = " + String(x) + "; Y = " + String(y));

            SendData(CMD_REG_WALK, WALK_F, WALK_S, ROTATE2, 0);
            break;
            }
           case 2: { //TRANSLATEMODE
            SendData(CMD_REG_TRANSLATE, WALK_F, WALK_S, ROTATE2, ROTATE);
            break;
            }
           case 3: { //ROTATEMODE
            SendData(CMD_REG_ROTATE, WALK_F, WALK_S, ROTATE2, ROTATE);
            break;
            }
           case 4: { //SINGLELEGMODE
            SendData(SINGLELEGMODE, WALK_F, WALK_S, ROTATE2, ROTATE);
            break;
            }
          }
        }

Thank you so much for your help. I am confused. I entered MERGE for the joystick in Blynk, 0-256 for the x axis and 0-256 for the y axis. The joystick shows me 128 in the middle position, 128 in the middle position, but the serial monitor gives me completely different values for the middle position - x: 511 and y: 128. (128 is for the hexapot - no movement, 0 is forwards and 256 backwards). What am I missing here?

You have to double check to be sure:

  1. 0-256 set for x axis. You might delete the joystick widget and recreate it. It seems to have some kind of bug here if you modify the widget parameters while running without deleting it first.
  2. the serial monitor print code is correct while printing x
  3. no other place modifying the x value

If everything has been fixed (x=128 and y=128 in middle position), you can remap the x and y value to match the expectation of hexapot.
For example: 256-0 for x and y axis, not 0-256…

Currently, you move the joystick UP => y=256,RIGHT => x=256

Great, it’s working! I had to delete the widgets, that’s it. It took me hours now and I should have been asleep a long time ago. Thank you very much!

May I ask one more question.

Do I have to specify the “int x = param[0].asInt();” in every case or can I only specify it at the beginning, before the first case 1?

I’m going to sleep now and if you still have that in front of you - good night, sleep well.

That’s encouraging. You did it.
You can specify x and y as global variables and don’t have to put them locally and have them dynamically allocated inside the function.

int x, y;

BLYNK_WRITE(V1){
        switch(MOVEMODE) {   
          case 1: { //WALKMODE
            x = param[0].asInt();
            y = param[1].asInt();
            ...

There are pros and cons of each way. But it’s very negligible for these 2 small vars.
Good sleep :slight_smile: