binary input from analog potentiometer?

Hi all,

I would like to use an analog joystick (2 potentiometers and a digital push switch) as a substitute for separate up/down/left/right/switch buttons on a project. Is there a straightforward way of converting the analog input from the potentiometers to a simple binary form input (on/off)?

My apologies if my questions are very basic - I am programmatically challenged.

My x axis in on A2, and y axis is on A1. The switch is on D2.

Thanks in advance for your help,

Lee

const int threshold = 127;
const int center = 1023/2;

const uint8_t xPin = A2;
const uint8_t yPin = A1;

void loop() {
  int xVal = analogRead (xPin);
  int yVal = analogRead (yPin);

  bool left = xVal < (center - threshold);
  bool right = xVal > (center + threshold);

  bool down = yVal < (center - threshold);
  bool up = yVal > (center + threshold);
}

Pieter

Pieter,

Thanks for taking the time to respond. I believe I understand your code, but I’m afraid I don’t know how to use the boolean parameters. For example, here is a snippet of the code I’m trying to modify:

      {
        case UP_KEY:
          mode_select++;
          if (mode_select > numModes)  // wrap around menu
            mode_select = 1;
          break;
        case DOWN_KEY:
          mode_select--;
          if (mode_select < 1)         // wrap around menu
            mode_select = numModes;
          break;
        case LEFT_KEY:           // left and right keys do nothing in main menu
          break;
        case RIGHT_KEY:
          break;
        case SELECT_KEY:         // user has picked a menu item
          cur_mode = mode_select;
          break;
      }

Currently, the parameters UP_KEY, DOWN_KEY etc are defined in the global area at the start of the code as follows:

// define LCD/Keypad buttons
#define NO_KEY 0
#define SELECT_KEY 1
#define LEFT_KEY 2
#define UP_KEY 3
#define DOWN_KEY 4
#define RIGHT_KEY 5

I’d like to use the output from the joystick potentiometers to replace UP_KEY, DOWN_KEY, LEFT_KEY and RIGHT_KEY if possible. I’m not sure what to do with the bool values, though - I tried renaming “bool left” to “bool LEFT_KEY”, but it threw the following errors:

StepIndexLA___11_21_17_c.ino: In function ‘void loop()’:
StepIndexLA___11_21_17_c.ino:88:18: error: expected unqualified-id before numeric constant
StepIndexLA___11_21_17_c.ino:167:8: note: in expansion of macro ‘LEFT_KEY’

Thanks again for your help!

Lee

const int threshold = 127;
const int center = 1023/2;

const uint8_t xPin = A2;
const uint8_t yPin = A1;

void loop() {
  int xVal = analogRead (xPin);
  int yVal = analogRead (yPin);

  if (xVal < (center - threshold)) { // Left
    ; // left key does nothing in main menu
  }
  if (xVal > (center + threshold)) { // Right
    ; // right key does nothing in main menu
  }

  if (yVal < (center - threshold)) { // Down
    mode_select--;
    if (mode_select < 1)         // wrap around menu
      mode_select = numModes;
  }
  if (yVal > (center + threshold)) { // Up
    mode_select++;
    if (mode_select > numModes)  // wrap around menu
      mode_select = 1;
  }
}

Pieter

Hi Pieter,

Thanks again!

I was able to use your code, and have this mostly working :). I made a couple of small modifications, as I realized after posting that the original code I’m modifying actually has a routine for defining the variables “LEFT_KEY”, “UP_KEY” etc - it’s found at the end of the code.

The last thing I haven’t been able to get working is the switch on the joystick. It works fine if I run a simple joystick sketch, so I think the wiring is ok, but not within the main program.

The code is a modification of a program created by Gary Liming used to drive a stepper motor for a step indexer application. The majority of the coding is beyond my level of understanding, so I’m sure there’s a straightforward reason why the switch doesn’t work! I tried to post the complete code, but it’s larger than the limit allowed by the forum software. I’ve instead posted the section of code where the variables are defined - hopefully this is where the issue lies.

Thanks once more for your help!

Lee

int read_LCD_button()     // routine to read the LCD's buttons
{
  // int key_in;
     int buttonstate;
  //Added by LA
  int xVal = analogRead (xPin);
  int yVal = analogRead (yPin);
  //End LA Edits
  
  delay(ADSettleTime);         // wait to settle
  // key_in = analogRead(0);      // read ADC once
  buttonstate = digitalRead(SW_pin);
  delay(ADSettleTime);         // wait to settle 
  if (xVal > (center + threshold))   return RIGHT_KEY;  
  if (yVal > (center + threshold))  return UP_KEY; 
  if (yVal < (center - threshold))  return DOWN_KEY; 
  if (xVal < (center - threshold))  return LEFT_KEY; 
  if (buttonstate == HIGH)  {return SELECT_KEY;
  } else {return NO_KEY;
  }

Here is the complete code as an attachment - hope this is ok

Thanks

LA_Step_Index_11_23_17_for_upload.ino (19.3 KB)

I'm wondering if the problem is having more than one input as variables inside the last "nested if" statement? But I'm not sure the correct syntax for how to separate those.

I see in your code you have:

if (analogRead(AnalogKeyPin) < 850 )  // if a keypress is present

which begs the question: Why use an analog input for a digital button press??

Also, you need to take some time to learn how to properly format and indent your code. Your code is rather difficult to follow (for me, at least).

As for your question, try this instead:

  if (xVal > (center + threshold))
    return RIGHT_KEY;
  else if (xVal < (center - threshold))  
    return LEFT_KEY;
  if (yVal > (center + threshold))
    return UP_KEY;
  else if (yVal < (center - threshold))
    return DOWN_KEY;
  if (buttonstate == HIGH)
    return SELECT_KEY;
    
  return NO_KEY;

Hi Power_Broker,

Thanks for your help. Unfortunately, the result is the same - left and right work fine. I’m unable to test up/down, because they don’t function in the main menu. The switch doesn’t work, same as before.

Thanks also for looking at the code. To answer your question, the code was originally written (by Mr Liming) to work with the LCD keypad shield, which uses up/down/left/right/select microswitches. These microswitches are all tied to analog pin 0 (A0), to save the digital input pins. Each has a different resistor value allowing the different keypresses to be differentiated, and the code was originally written to reflect that.

I’d prefer to use a single joystick rather than the tiny buttons on the LCD shield. The analog game controller style joysticks are cheap and fit my project box - I didn’t come across a digital equivalent at a similar price point.

But, now you highlight it, I’m wondering if this line:

if (analogRead(AnalogKeyPin) < 850 )  // if a keypress is present

is why my “buttonstate == HIGH” isn’t functioning as expected? i.e. the switch is wired to digital input 2, so analogkeypin doesn’t drop its value and so get_real_key never happens

I tried this instead:

if ((analogRead(AnalogKeyPin) < 850) || (digitalRead(SW_pin) == HIGH))  // if a keypress is present

It compiles fine, but doesn’t seem to make a difference.

Lastly, thanks for your suggestions re: code formatting and indenting. 99% of the code isn’t mine, but that said it’s a lot better formatted than I’d be able to do! I’m by no means a programmer, but I’m trying :slight_smile:

Lee

In my opinion, the logic of the code I gave you is fine. If your program isn’t working, I suggest trying these things:

1.) Create a new program that implements only the features you think aren’t working properly so you can focus only on what you need to. This helps boil the problem down to a specific bug or set of bugs.

2.) Ensure all hardware connections are properly made. You might even want to run a test to see if the joystick is running properly with a simple analogRead() to the serial plotter just to make sure (and test the output limits of the stick).

3.) Use Serial prints to the serial monitor (or plotter) to see if certain sections of code have been executed (and when) or to see how the variable values change.

4.) Post a photograph of your hardware/connections.

Do some testing and come back with any specific problems you run up against. Until then, we can’t help much.

Hi Power_Broker

Thanks for sticking with me on this

I've previously run a simple joystick sketch, which prints the A1,A2 and D2 inputs to the serial monitor, and everything works fine there - A1 and A2 give values between 0 and 1023, and D2 moves between 0 and 1 when pressed. I went ahead and soldered the connections at that point.

I've posted some photos of my hardware, but there's not too much to see. The LCD shield sits on top of the arduino, and the joystick is wired to 5v, GND, A1 (Y axis), A2 (X axis) and D2 (Switch).

I will do my best to try (1) and/or (3). I am learning the syntax as I go, though, so it may take a little while!

Lee

For some reason, jpgs wouldn’t attach. Trying again here