-
Greetings @luni64 , I am working on a sketch where I am trying to set different min and max encoder values:
I am able to get the min and maximum encoder values to set correctly depending on the button state. However, when I switch from one button state to the other and then back, the encoder still holds the last MIDI CC (continuous controller) value and I would like it it to reset back to This should be done with Here's an example of what I am trying to do: #include <Arduino.h>
#include <MIDI.h>
using namespace midi; // midi::Start, midi::Stop, midi::Continue, etc
MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI);
#include "EncoderTool.h"
using namespace EncoderTool;
PolledEncoder encoder; // Polling encoder, please call corresponding tick() functions as often as possible, e.g. in loop
// Bourns PEL12D Rotary Encoder (2 LEDs, 1 button)
const int ENC_PIN_A = 12; // encoder pin A
const int ENC_PIN_B = 11; // encoder pin B
const int ENC_BUTTON = 2; // encoder button pin
const int LED_2_GREEN = 22; // encoder led green
const int LED_1_RED = 23; // encoder led red
// encoder limit variables for velocity modes
int32_t encoder_min = 0;
int32_t encoder_max = 127;
byte type, note, velocity, channel_received, data1, data2, cc_number, cc_value; // MIDI data
void onValueChanged(int value, int delta) {
if (encoder.valueChanged()) {
if (velocity_mode == 0) { // encoder range of 0-16
velocity_mode_1_intensity = encoder.getValue();
if (accent_pattern_cc == 102) {
cc_number = velocity_mode_0_cc;
cc_value = velocity_mode_0_intensity;
MIDI.sendControlChange(cc_number, cc_value, channel_received); // midi cc value = 0-16
}
}
if (velocity_mode == 1) { // encoder range of 0-127
velocity_mode_1_intensity = encoder.getValue();
if (velocity_randomizer_cc == 103) {
cc_number = velocity_mode_1_cc;
cc_value = velocity_mode_1_intensity;
MIDI.sendControlChange(cc_number, cc_value, channel_received); // midi cc value = 0-127
}
}
}
}
void onStateChanged(int32_t state) { // button state
// if the button fell and button state is low, change the mode
if (encoder.buttonChanged() && encoder.getButton() == LOW) { // LOW when pressed
velocity_mode++;
if (velocity_mode > 1) {
velocity_mode = 0;
}
} // button if over
}
void velocityMode() { // encoder.setLimits(min, max) instead of in the setup...
if (velocity_mode == 0) { // accent pattern
digitalWrite(LED_2_GREEN, LOW);
encoder_max = 16;
encoder.setLimits(encoder_min, encoder_max); // limits the count range
}
if (velocity_mode == 1) { // velocity randomizer
digitalWrite(LED_2_GREEN, HIGH);
encoder_max = 127;
encoder.setLimits(encoder_min, encoder_max); // limits the count range
}
}
void processMidi() {
if (MIDI.read()) {
/// ...
} // if MIDI read is over
}
void setup() {
pinMode(LED_2_GREEN, OUTPUT);
pinMode(LED_1_RED, OUTPUT);
pinMode(ENC_BUTTON, INPUT_PULLUP);
digitalWrite(LED_1_RED, HIGH); // init red LED on
encoder.begin(ENC_PIN_A, ENC_PIN_B, ENC_BUTTON);
encoder.setValue(0); // set the counter to a position
encoder.setLimits(encoder_min, encoder_max); // 0-127 for cc values
encoder.attachCallback(onValueChanged); // connect the encoder callback function
encoder.attachButtonCallback(onStateChanged); // connect the button callback function
MIDI.begin(MIDI_CHANNEL_OMNI); // turn on DIN MIDI
MIDI.turnThruOff(); // if you want the incoming MIDI notes to be copied and sent out comment out this line
}
void loop() {
current_time = millis();
encoder.tick();
velocityMode();
processMidi();
} // loop is over |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
Your code does not compile since a couple of variable definitions are missing... Anyway, from your description I assume that you want to change the counting range of the encoder when the encoder button is pressed. After such a change the encoder value shall be reset to 0. Here some code (without all the midi stuff) which shows how to achieve this: #include "Arduino.h"
#include "EncoderTool.h"
using namespace EncoderTool;
PolledEncoder encoder;
int mode = 0;
void onEncoderChanged(int value, int delta)
{
if (mode == 0)
{
// do something with the value....
Serial.print("Mode 0, value: ");
Serial.println(value);
}
else
{
// do something with the value....
Serial.print("Mode 1, value: ");
Serial.println(value);
}
}
void onButtonChanged(int32_t state)
{
if (state == LOW)
{
if (mode == 0)
{
Serial.println("Mode set to 1 (0-128)");
encoder.setLimits(0, 128);
encoder.setValue(0);
mode = 1;
}
else
{
Serial.println("Mode set to 0 (0-16)");
encoder.setLimits(0, 16);
encoder.setValue(0);
mode = 0;
}
}
}
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
encoder.begin(0, 1, 2);
encoder.setLimits(0, 16);
encoder.setValue(0);
encoder.attachCallback(onEncoderChanged);
encoder.attachButtonCallback(onButtonChanged);
}
void loop()
{
encoder.tick();
} And here a few remarks to your original code: //....
void onValueChanged(int value, int delta)
{
if (encoder.valueChanged()) { //<===== onValueChanged is only called if the encoder value changed, no need to check here
if (velocity_mode == 0) { // encoder range of 0-16
velocity_mode_1_intensity = encoder.getValue(); // <====== no need to call encoder.getValue, the current encoder value is already passed to the function in the value parameter (see my example)
//....
if (velocity_mode == 1) { // encoder range of 0-127
velocity_mode_1_intensity = encoder.getValue(); // <===== same as above
//.....
void onStateChanged(int32_t state) { // button state
// if the button fell and button state is low, change the mode
if (encoder.buttonChanged() && encoder.getButton() == LOW) { // LOW when pressed //<==== no need to check for changed see |
Beta Was this translation helpful? Give feedback.
Your code does not compile since a couple of variable definitions are missing... Anyway, from your description I assume that you want to change the counting range of the encoder when the encoder button is pressed. After such a change the encoder value shall be reset to 0. Here some code (without all the midi stuff) which shows how to achieve this: