I am making a program to use a rotary encoder instead of a button in the buttoncycler example in the Adafruit NeoPixel library.
I am using the US Digital S1-256-250-IE-B-D. Datasheet can be found here:
https://cdn.usdigital.com/assets/datasheets/S1_datasheet.pdf?k=636466553771569761
#include < RotaryEncoder.h >
void setup() {
}
void loop() {
static int change = 0;
static int pos = 0;
static int oldPos = 0;
//Read the Encoder's state
encoder.tick();
int enc = encoder.getPosition();
pos = abs(enc) % 2;
change = oldPos-pos;
if (change != 0) {
switch (pos) {
case 0:
//do a program that lasts 5 seconds
break;
case 1:
//do a program that lasts 5 seconds
break;
}
oldPos = pos;
change = 0;
}
}
I was wondering if there is a way to change the program immediately after turning the rotary encoder, instead of having to wait for the program to complete.
2 Answers 2
I was wondering if there is a way to change the program immediately after turning the rotary encoder, instead of having to wait for the program to complete.
There is, but it's not completely trivial. The reason it is not trivial is each animation is implemented as a function that takes a while to execute. For doing what you ask, each of these animations should be modified, with a way to exit early if needed.
One approach would be to manage the rotary encoder using an interrupt. I let you investigate how to do that: you probably can find examples on the Web. Once the encoder reading is interrupt-based, you would need to do the following changes in your program:
At global scope, add
volatile bool stop_now = false;
This will be a sort of "flag" intended to inform the currently running animation that it should return ASAP.
Then, inside the interrupt handler, add
stop_now = true;
In loop(), just after if (change != 0) {
, add
stop_now = false;
In each animation, replace delay(wait)
with:
uint32_t start_time = millis();
while (millis() - start_time < wait) {
if (stop_now)
return;
}
Your code (if it worked) is right. All you need to do is turn the comments into function calls:
#include <RotaryEncoder.h>
// Define global variables
int pos = 0;
int oldPos = 0;
void setup() {
// Do stuff
}
void loop() {
//Read the Encoder's state
encoder.tick();
pos = encoder.getPosition();
const int change = (oldPos - abs(pos)) % 2;
switch (change)
{
case 0:
programOne();
break;
case 1:
programTwo()
break;
}
oldPos = pos;
}
}
void programOne()
{
//Do Stuff
}
void programTwo()
{
// Do stuff
}
Setup()
is missing.i
is not defined.