If on boolean wont work

This sketch will be used to steer a dish using servo's either manual(by keyboard) or by a program. To enable manual opperation I am looking for a 'special charracter' in this code section:

    if (saByte == CTRL1 || saByte == CTRL2 ) {
      // is special character sequence(1B5B41 - 1B5B44)
      Serial.println("Manual enabled");
      num_keypad = true;
    }
    if (num_keypad == true) {
      switch (saByte) {

but this if (num_keypad == true) doesnt work

Total code:

/*-----( Import needed libraries )-----*/
#include <LiquidCrystal.h>
#include <HCPCA9685.h>
#define  I2CAdd 0x40    // default HCPCA9685 address
/*-----( Declare objects )-----*/
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
HCPCA9685 servo(I2CAdd);

void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
  servo.Init(SERVO_MODE);
  servo.Sleep(false);
  lcd.clear();
  delay(150);
  //         12345678901243456
  lcd.print("Start Callibrate");
  refresh_output();
}
#define strMAX_LEN 12 //max. nbr characters from Xtrack
int SERVONBR  = 0;    // servo accessed in manual opperation
int MAXSERVO  = 15;   // Nbr outputs hcpca9685
int SERVOMINPOS = 110;
int SERVOMAXPOS = 590;
float SERVOPOS  = (SERVOMAXPOS - SERVOMINPOS) / 2;
char saByte;              // save inByte
char MESSAGE[17];
char MESGLCD[17];
char MESGTMP[6];
char STRVALUE[strMAX_LEN];
bool  num_keypad = false;   // becomes true after a CTRL1 or CTRL2 character
// define characters used in manual opperation
#define CTRL1 0x1B
#define CTRL2 0x5B
#define UP    0x41  // Pos+1
#define DOWN  0x42  // Pos-1
#define RIGHT 0x43  // Servo+1
#define LEFT  0x44  // Servo-1
#define PGUP  0x39  // pos+10
#define PDWN  0x33  // pos-10

void loop() {

  while (Serial.available() > 0) {
    char inByte = Serial.read();
    saByte = inByte;
    Serial.print("Received 0x");
    Serial.println(saByte, HEX);
    if (saByte == CTRL1 || saByte == CTRL2 ) {
      // is special character sequence(1B5B41 - 1B5B44)
      Serial.println("Manual enabled");
      num_keypad = true;
    }
    if (num_keypad == true) {
      switch (saByte) {

        case  UP:
          SERVOPOS++;
          if (SERVOPOS > SERVOMAXPOS) {
            SERVOPOS = SERVOMINPOS;
          }
          refresh_output();
          refresh_servo(SERVONBR, SERVOPOS);
          num_keypad = false;
          break;

        case  PGUP:
          SERVOPOS += 10;
          if (SERVOPOS > SERVOMAXPOS) {
            SERVOPOS = SERVOMINPOS;
          }
          refresh_output();
          refresh_servo(SERVONBR, SERVOPOS);
          num_keypad = false;
          break;

        case  DOWN:
          SERVOPOS--;
          if (SERVOPOS < SERVOMINPOS) {
            SERVOPOS = SERVOMAXPOS;
          }
          refresh_output();
          refresh_servo(SERVONBR, SERVOPOS);
          num_keypad = false;
          break;

        case  PDWN:
          SERVOPOS -= 10;
          if (SERVOPOS < SERVOMINPOS) {
            SERVOPOS = SERVOMAXPOS;
          }
          refresh_output();
          refresh_servo(SERVONBR, SERVOPOS);
          num_keypad = false;
          break;

        case  RIGHT:
          SERVONBR++;
          if (SERVONBR > MAXSERVO) {
            SERVONBR = 0;
          }
          refresh_output();
          refresh_servo(SERVONBR, SERVOPOS);
          num_keypad = false;
          break;

        case  LEFT:
          SERVONBR--;
          if (SERVONBR < 0) {
            SERVONBR = MAXSERVO;
          }
          refresh_output();
          refresh_servo(SERVONBR, SERVOPOS);
          num_keypad = false;
          break;

        default:
          //        Serial.print("Not decoded: 0x");
          //        Serial.println(saByte, HEX);
          num_keypad = false;
          break;

      }// end switch
    }
    // Run this in 'normal' opperation mode
    // receiving a command sequence eg. 123.4,123.5\n
    if (!num_keypad == false && saByte == ',' || saByte == '.' || saByte >= '0' && saByte <= '9') {
      Serial.println("proccess command sequence");
      Serial.print("Received 0x");
      Serial.println(saByte, HEX);
    }
  }// end while
}// end loop

void refresh_output() {
  dtostrf(SERVOPOS, 3, 1, MESGTMP);
  sprintf(MESSAGE, "S: %-2d  P: %s \0", SERVONBR, MESGTMP);
  Serial.println(MESSAGE);
  lcd.setCursor(0, 1);
  lcd.println(MESSAGE);
}

void refresh_servo(int srv, int pos) {
  //  servo.Servo(srv, pos);
}

void makePosition() {
  Serial.print("Nbr decoded: 0x");
  Serial.println(saByte, HEX);
}

How do you know?
Why is it even there?

did this line print on serial monitor when you press CTRL ?

CTRL1 & CTRL2 doesnt mean CTRL key but a CTRLsequence received and yes it did

This is printed: Serial.println("Manual enabled");
But this isnt executed: if (num_keypad == true) {
switch (saByte) {

did you check Serial.print(num_keypad) before

and
after switch (saByte)

if not then see if its print true

Again - how do you know?

It looks like the only place you turn on 'num_keypad' is when saByte is CTRL1 or CTRL2. You then drop into "switch (saByte)" because num_keypad is true. There is no case in that switch for CTRL1 or CTRL2 so the 'default' case is used. The default is "num_keypad = false;".

One fix would be to have do-nothing cases for CTRL1 and CTRL2:

    case CTRL1:
    case CTRL2:
        break;

It works great. It is your logic that doesn't work so great.

Then please enlight me

It actually goes better if you prove it to yourself.
Grab a pencil and paper, and pretend to be a dumb processor.

You test the following condition saByte == CTRL1 || saByte == CTRL2 and if true you set num_keypad to true. Then in the following conditional you test num_keypad == true and if so you have a switch (saByte) in which you could not possibly match any of the cases except default since that conditional would only be entered if saByte is equal to CTRL1 or CTRL2.

The other thing to consider is Occam's Razor - is it more likely that

  1. "if on boolean won't work" * ?
  2. you've done something wrong, or misinterpreted a result ?

* imagine how busy the forum would be, if this were true.

1 Like

I started allover by creating the paper framework first

void loop() {
  while (Serial.available() > 0) {
    char inByte = Serial.read();
    saByte = inByte;
    Serial.print("0x");
    Serial.println(saByte, HEX);
    if (saByte == 0x1B || saByte == 0x5B) {
      num_keypad = true;
      Serial.println("Do Manual");
    }
    if (num_keypad == true) {
//      Serial.println("Do switch manual");
      switch (saByte) {
        case 0x41: // UP
          Serial.println("UP+1");
          break;
        case 0x42: // DOWN
          Serial.println("DOWN-1");
          break;
        case 0x43: // RIGHT
          Serial.println("RIGHT+1");
          break;
        case 0x44: // LEFT
          Serial.println("LEFT-1");
          break;
      }
    } else if (num_keypad == false && saByte == ',' || saByte == '.' || saByte >= '0' && saByte <= '9') {
      Serial.println("Create XY data");
    }
  }
}

It wil need some finetuning

Indeed. You still have the same issue:

    if (saByte == 0x1B || saByte == 0x5B) {
      num_keypad = true;
      Serial.println("Do Manual");
    }
    if (num_keypad == true) {
      //      Serial.println("Do switch manual");
      switch (saByte) {
        case 0x41: // UP
          Serial.println("UP+1");
          break;
        case 0x42: // DOWN
          Serial.println("DOWN-1");
          break;
        case 0x43: // RIGHT
          Serial.println("RIGHT+1");
          break;
        case 0x44: // LEFT
          Serial.println("LEFT-1");
          break;
      }
    } else if (num_keypad == false && saByte == ',' || saByte == '.' || saByte >= '0' && saByte <= '9') {
      Serial.println("Create XY data");
    }

All you need to do is add a case to the switch statement to capture CTRL1 and CTRL2, and do nothing in response.

However, the switch statement has cases that are completely useless since that conditional will only be entered if saByte is equal to CTRL1 or CTRL2.

Hi @gharryh, I was thinking about your code structure last night and your original loop() function would work quite well with the following simple mods:

  1. Replace while with if and let loop() do the looping
  2. Use else if instead of sequential if statements. This will solve the problem of unnecessarily executing the switch right after setting the num_keypad flag.
  3. inByte is not needed
  4. In the num_keypad == true block in all cases you set num_keypad = false. I removed it from all cases and set it one time in the code block.

Untested but it should work.

void loop() {

  if (Serial.available() > 0) {
    saByte = Serial.read();
    Serial.print("Received 0x");
    Serial.println(saByte, HEX);
    if (saByte == CTRL1 || saByte == CTRL2 ) {
      // is special character sequence(1B5B41 - 1B5B44)
      Serial.println("Manual enabled");
      num_keypad = true;
    }
    else if (num_keypad) {
      switch (saByte) {

        case  UP:
          SERVOPOS++;
          if (SERVOPOS > SERVOMAXPOS) {
            SERVOPOS = SERVOMINPOS;
          }
          refresh_output();
          refresh_servo(SERVONBR, SERVOPOS);
          break;

        case  PGUP:
          SERVOPOS += 10;
          if (SERVOPOS > SERVOMAXPOS) {
            SERVOPOS = SERVOMINPOS;
          }
          refresh_output();
          refresh_servo(SERVONBR, SERVOPOS);
          break;

        case  DOWN:
          SERVOPOS--;
          if (SERVOPOS < SERVOMINPOS) {
            SERVOPOS = SERVOMAXPOS;
          }
          refresh_output();
          refresh_servo(SERVONBR, SERVOPOS);
          break;

        case  PDWN:
          SERVOPOS -= 10;
          if (SERVOPOS < SERVOMINPOS) {
            SERVOPOS = SERVOMAXPOS;
          }
          refresh_output();
          refresh_servo(SERVONBR, SERVOPOS);
          break;

        case  RIGHT:
          SERVONBR++;
          if (SERVONBR > MAXSERVO) {
            SERVONBR = 0;
          }
          refresh_output();
          refresh_servo(SERVONBR, SERVOPOS);
          break;

        case  LEFT:
          SERVONBR--;
          if (SERVONBR < 0) {
            SERVONBR = MAXSERVO;
          }
          refresh_output();
          refresh_servo(SERVONBR, SERVOPOS);
          break;

        default:
          //        Serial.print("Not decoded: 0x");
          //        Serial.println(saByte, HEX);
          break;

      }// end switch
      num_keypad = false;
    }
    // Run this in 'normal' opperation mode
    // receiving a command sequence eg. 123.4,123.5\n
    else if (saByte == ',' || saByte == '.' || saByte >= '0' && saByte <= '9') {
      Serial.println("proccess command sequence");
      Serial.print("Received 0x");
      Serial.println(saByte, HEX);
    }
  }// end if
}// end loop

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