I found this older post and I am trying to do the same thing. I downloaded the NewEncoder library. It does what I want for counting but what I would like to do is a button press if the encoder moves a set number of pulses CW it pulls pin high. Then a set number of pulses CCW pulls a different pin high. (button push)
Post your code.
In the IDE click on Edit then Copy for Forum. Then come back here and just do a paste.
#include "Arduino.h"
#include "NewEncoder.h"
// Pins 2 and 3 should work for many processors, including Uno. See README for meaning of constructor arguments.
// Use FULL_PULSE for encoders that produce one complete quadrature pulse per detnet, such as: https://www.adafruit.com/product/377
// Use HALF_PULSE for endoders that produce one complete quadrature pulse for every two detents, such as: https://www.mouser.com/ProductDetail/alps/ec11e15244g1/?qs=YMSFtX0bdJDiV4LBO61anw==&countrycode=US¤cycode=USD
NewEncoder encoder(2, 3, -20, 20, 0, FULL_PULSE);
int16_t prevEncoderValue;
void setup() {
NewEncoder::EncoderState state;
Serial.begin(115200);
delay(2000);
Serial.println("Starting");
if (!encoder.begin()) {
Serial.println("Encoder Failed to Start. Check pin assignments and available interrupts. Aborting.");
while (1) {
yield();
}
} else {
encoder.getState(state);
Serial.print("Encoder Successfully Started at value = ");
prevEncoderValue = state.currentValue;
Serial.println(prevEncoderValue);
}
}
void loop() {
int16_t currentValue;
NewEncoder::EncoderState currentEncoderState;
if (encoder.getState(currentEncoderState)) {
Serial.print("Encoder: ");
currentValue = currentEncoderState.currentValue;
if (currentValue != prevEncoderValue) {
Serial.println(currentValue);
prevEncoderValue = currentValue;
} else
switch (currentEncoderState.currentClick) {
case NewEncoder::UpClick:
Serial.println("at upper limit.");
break;
case NewEncoder::DownClick:
Serial.println("at lower limit.");
break;
default:
break;
}
}
}
if (up || down) { //**************************************** Encoder left/right
currentValue = encoder1;
if (currentValue != prevEncoderValue) {
prevEncoderValue = currentValue;
if (up) {
Joystick.setButton(enc1CWNum, ON);
delay(50);
Joystick.setButton(enc1CWNum, OFF);
} else {
Joystick.setButton(enc1CCWNum, ON);
delay(50);
Joystick.setButton(enc1CCWNum, OFF);
}
}
}//********************************************************** Encoder left/right
I am trying to figure out how to put these two together to get what I need. I am new at Arduino code and trying to learn as I go.
When do either of these pins get "pulled" low?
a7
Hard to understand what you mean. A "button push" is an input to Arduino code ... a person pushes a button and the Arduino detects it. A pin going high / low is an output from Arduino code. It controls some external hardware like an LED, Relay, or Chip Select on an IC.
From these snippets, maybe put these sorts of bits:
Inside of the appropriate cases:
gfvalvo
I am trying to use your NewEncode sample but I want to be able to count if the encoder has moved 3 pulses cw. If so the I want it to act as a button on a joystick and pull pin 2 high then low. If I rotate the encoder ccw 3 pulses then it pulls pin 3 high / low
So count up/dn clicks. See the github example for ideas.
You need to define your requirements better. What happens if someone clicks CW two times and then reverses direction? Would they be required to click CCW 5 times (2 + 3) to trigger a Pin 3 action, or only 3 times? The former case means you have a 6-click wide dead zone in the middle. Which do you want?
Can you have a counter that you check to see if the new value is +3 or more higher than previous counter...pull pin 2 high. If counter is -3 or more then pull pin 3 high.
I am looking to use an encoder as a gaming device. I want to be able to turn the encoder a quarter of a rotation and trigger the event. If I turn it back a quarter of a turn it triggers another event. The event would be the same as a keyboard push. If you turn it one half turn it would equal to two keyboard push.
That might run into problems with these encoder limits:
For instance, if you wanted 7 right button events, or 7 more buttons one way than the other, the encoder would top out at 20, and not make it to 21. You might be able to make it work by reconfiguring the encoder at each button event.
I'd try a sort of change-detection on whether the currentEncoderState.currentValue is >=3 different than the value at the previous event.
Completely untested snippet (I couldn't get the code above to work within Wokwi per IDE/Wokwi naming conflict with https://github.com/alexitoo00/NewEncoder · Issue #33 · gfvalvo/NewEncoder · GitHub) :
static int lastEventValue = 0;
...
if(currentValue - lastEventValue >= 3)
{ // up
lastEventValue += 3; // advance CW
Joystick.setButton(enc1CWNum, ON);
delay(50);
Joystick.setButton(enc1CWNum, OFF);
}
else if (currentValue - lastEventValue <= -3) { // down
lastEventValue -= 3; // advance CCW
Joystick.setButton(enc1CCWNum, ON);
delay(50);
Joystick.setButton(enc1CCWNum, OFF);
}
I don't think you really answered my questions. Remember, good engineering starts with good, well-written requirements. I'll assume you don't want the dead zone behavior. So, something like this:
void loop() {
static uint8_t upClickCount {0};
static uint8_t downClickCount {0};
NewEncoder::EncoderState currentEncoderState;
if (encoder.getState(currentEncoderState)) {
switch (currentEncoderState.currentClick) {
case NewEncoder::UpClick:
upClickCount++;
downClickCount = 0;
if (upClickCount >= 3) {
upClickCount = 0;
//
// Three up clicks counted. Do something here
//
}
break;
case NewEncoder::DownClick:
downClickCount++;
upClickCount = 0;
if (downClickCount >= 3) {
downClickCount = 0;
//
// Three down clicks counted. Do something here
//
}
break;
default:
break;
}
}
}
#include "Arduino.h"
#include "NewEncoder.h"
#include <Joystick.h>
#define ENABLE_PULLUPS
// Pins 2 and 3 should work for many processors, including Uno. See README for meaning of constructor arguments.
// Use FULL_PULSE for encoders that produce one complete quadrature pulse per detnet, such as: https://www.adafruit.com/product/377
// Use HALF_PULSE for endoders that produce one complete quadrature pulse for every two detents, such as: https://www.mouser.com/ProductDetail/alps/ec11e15244g1/?qs=YMSFtX0bdJDiV4LBO61anw==&countrycode=US¤cycode=USD
NewEncoder encoder(2, 3, -20, 20, 0, FULL_PULSE);
int16_t prevEncoderValue;
Joystick_ Joystick;
void setup() {
NewEncoder::EncoderState state;
Serial.begin(115200);
delay(2000);
Serial.println("Starting");
if (!encoder.begin()) {
Serial.println("Encoder Failed to Start. Check pin assignments and available interrupts. Aborting.");
while (1) {
yield();
}
} else {
encoder.getState(state);
Serial.print("Encoder Successfully Started at value = ");
prevEncoderValue = state.currentValue;
Serial.println(prevEncoderValue);
}
// Initialize Button Pins
pinMode(9, INPUT_PULLUP);
pinMode(10, INPUT_PULLUP);
Joystick.begin();
}
// Constant that maps the phyical pin to the joystick button.
const int pinToButtonMap = 2;
// Last state of the button
int lastButtonState[4] = {0,0,0,0};
void loop() {
static uint8_t upClickCount {0};
static uint8_t downClickCount {0};
NewEncoder::EncoderState currentEncoderState;
if (encoder.getState(currentEncoderState)) {
switch (currentEncoderState.currentClick) {
case NewEncoder::UpClick:
upClickCount++;
downClickCount = 0;
if (upClickCount >= 5) {
upClickCount = 0;
//
Serial.println("It Worked UpClick");
// Read pin values
for (int index = 0; index < 4; index++)
{
int currentButtonState = !digitalRead(index + pinToButtonMap);
if (currentButtonState != lastButtonState[index])
{
Joystick.setButton(index, currentButtonState);
lastButtonState[index] = currentButtonState;
}
}
delay(50);
}
break;
case NewEncoder::DownClick:
downClickCount++;
upClickCount = 0;
if (downClickCount >= 5) {
downClickCount = 0;
//
Serial.println("It Worked DownClick");
// Read pin values
for (int index = 0; index < 4; index++)
{
int currentButtonState = !digitalRead(index + pinToButtonMap);
if (currentButtonState != lastButtonState[index])
{
Joystick.setButton(index, currentButtonState);
lastButtonState[index] = currentButtonState;
}
}
delay(50);
}
break;
}
}
}
This is what I am looking to do. I can get it to serial print the "it works" but the button function does not work. Windows computer see it as a joystick but does not do the button push.
#include "Arduino.h"
#include "NewEncoder.h"
#include <Keyboard.h>
// Pins 2 and 3 should work for many processors, including Uno. See README for meaning of constructor arguments.
// Use FULL_PULSE for encoders that produce one complete quadrature pulse per detnet, such as: https://www.adafruit.com/product/377
// Use HALF_PULSE for endoders that produce one complete quadrature pulse for every two detents, such as: https://www.mouser.com/ProductDetail/alps/ec11e15244g1/?qs=YMSFtX0bdJDiV4LBO61anw==&countrycode=US¤cycode=USD
NewEncoder encoder(2, 3, -2000, 2000, 0, FULL_PULSE);
int16_t prevEncoderValue;
void setup() {
NewEncoder::EncoderState state;
Serial.begin(115200);
delay(2000);
Serial.println("Starting");
if (!encoder.begin()) {
Serial.println("Encoder Failed to Start. Check pin assignments and available interrupts. Aborting.");
while (1) {
yield();
}
} else {
encoder.getState(state);
Serial.print("Encoder Successfully Started at value = ");
prevEncoderValue = state.currentValue;
Serial.println(prevEncoderValue);
}
}
void loop() {
static uint8_t upClickCount {0};
static uint8_t downClickCount {0};
NewEncoder::EncoderState currentEncoderState;
if (encoder.getState(currentEncoderState)) {
switch (currentEncoderState.currentClick) {
case NewEncoder::UpClick:
upClickCount++;
downClickCount = 0;
if (upClickCount >= 5) {
upClickCount = 0;
Keyboard.press('f');
delay(10);
Keyboard.releaseAll();
Serial.println("Front Click");
//
}
break;
case NewEncoder::DownClick:
downClickCount++;
upClickCount = 0;
if (downClickCount >= 5) {
downClickCount = 0;
Keyboard.press('r');
delay(10);
Keyboard.releaseAll();
Serial.println("Rear Click");
//
}
break;
default:
break;
}
}
}
Got this to work using keyboard instead of joystick. Question I have is there a way to tell when the rotary encoder changes direction? I am losing 1 step when I change directions. I can count 0 to 5 but when I change directions I go 5 to 1. After that I count 5 clicks.
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.