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 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:
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’
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;
}
}
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;
}
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.
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
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.
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!