tttapa / Control-Surface

Arduino library for creating MIDI controllers and other MIDI devices.
GNU General Public License v3.0
1.27k stars 140 forks source link

Rotary encoder returns the same result when rotate left or right - SOLVED!!!! #1076

Open Basiliadis opened 2 months ago

Basiliadis commented 2 months ago

Hello all,

i have a problem with a rotary encoder. I have try all the codes that is for encoders and always i receive the same result. I receive the same result when rotate left or right. I have try different pins on the Pro Micro controller. I have try 3 types of rotary encoders. The problem remains. All the other parts of code works perfect.

I appreciate your help!

here is a screenshot of the problem

Enc-Error

My Code is :

// DAW Controller MMLB Project

include

include // Include the Control Surface library

include <AH/Hardware/Button.hpp>

include // Include the Arduino Helpers library

include <AH/Hardware/ExtendedInputOutput/AnalogMultiplex.hpp>

include <AH/Hardware/ExtendedInputOutput/SPIShiftRegisterOut.hpp>

// Instantiate a MIDI over USB interface. USBMIDI_Interface midi;

using namespace ExtIO;

const int speedMultiplier = 1;

// Instantiate an analog multiplexer CD74HC4067 mux{ A0, // Analog input pin { 3, 4, 5, 6 } // Address pins S0, S1, S2, S3 };

// Create an array of CCPotentiometer objects that send out MIDI Control Change // messages when you turn the potentiometers connected to the 8 inputs of the mux.

CCPotentiometer volumePotentiometers[] { { mux.pin(0), { MIDI_CC::General_Purpose_Controller_1, Channel_1 } }, { mux.pin(1), { MIDI_CC::General_Purpose_Controller_1, Channel_2 } }, { mux.pin(2), { MIDI_CC::General_Purpose_Controller_1, Channel_3 } }, { mux.pin(3), { MIDI_CC::General_Purpose_Controller_1, Channel_4 } }, { mux.pin(4), { MIDI_CC::General_Purpose_Controller_1, Channel_5 } }, { mux.pin(5), { MIDI_CC::General_Purpose_Controller_1, Channel_6 } }, };

// CCBUTTONS ON MULTIPLEXER

CCButton Buttons[] { { mux.pin(6), { MIDI_CC::General_Purpose_Controller_2, Channel_1 } }, { mux.pin(7), { MIDI_CC::General_Purpose_Controller_2, Channel_2 } }, { mux.pin(8), { MIDI_CC::General_Purpose_Controller_2, Channel_3 } }, { mux.pin(9), { MIDI_CC::General_Purpose_Controller_2, Channel_4 } }, { mux.pin(10), { MIDI_CC::General_Purpose_Controller_2, Channel_5 } }, { mux.pin(11), { MIDI_CC::General_Purpose_Controller_2, Channel_6 } }, { mux.pin(12), { MIDI_CC::General_Purpose_Controller_2, Channel_7 } }, { mux.pin(13), { MIDI_CC::General_Purpose_Controller_2, Channel_8 } }, { mux.pin(14), { MIDI_CC::General_Purpose_Controller_2, Channel_9 } },
{ mux.pin(15), { MIDI_CC::General_Purpose_Controller_2, Channel_10 } },
};

// BUTTONS READS BUTTONS STATE Button pushbutton1 { mux.pin(6)}; //RECORD BUTTON Button pushbutton2 { mux.pin(7)}; //PLAY BUTTON Button pushbutton3 { mux.pin(8)}; //STOP BUTTON Button pushbutton13 { mux.pin(13)}; //TRACK 2 ARM ENABLE Button pushbutton14 { mux.pin(14)}; //TRACK 2 ARM ENABLE

// Instantiate a shift register with the SPI slave select pin as latch pin, most // significant bit first, and a total of 8 outputs. SPIShiftRegisterOut<8> sreg { SPI, // SPI interface to use 10, // Latch pin (ST_CP) MSBFIRST, // Byte order };

const pin_t ledPin0 = sreg.pin(0); // RECORD LEDS (REC & PLAY) const pin_t ledPin1 = sreg.pin(1); // PLAY LED const pin_t ledPin2 = sreg.pin(2); // TRACK 2 ARM ENABLE const pin_t ledPin3 = sreg.pin(3); // TRACK 2 ARM ENABLE

CCRotaryEncoder enc { {1, 0}, // pins MIDI_CC::General_Purpose_Controller_5, // address speedMultiplier, // multiplier 4, // pulses per click };

// SETUP void setup() { Control_Surface.begin(); // Initialize Control Surface
sreg.begin();
pushbutton1.begin(); // RECORD BUTTON pushbutton2.begin(); // PLAY BUTTON pushbutton3.begin(); // STOP BUTTON pushbutton13.begin(); // TRACK 2 ARM pushbutton14.begin(); // TRACK 3 ARM // You can invert the input, for use with normally closed (NC) switches: // pushbutton.invert(); }

// LOOP void loop() { Control_Surface.loop(); // Update the Control Surface

static bool ledState0 = LOW; //RECORD LED
static bool ledState1 = LOW; //PLAY LED
static bool ledState2 = LOW; //TRACK 2 ENABLE LED
static bool ledState3 = LOW; //TRACK 3 ENABLE LED

// Read the digital input, debounce the signal, and check the state of // the button: if (pushbutton1.update() == Button::Falling) { ledState0 = !ledState0; // Invert the state of the LED ledState1 = !ledState1; // Invert the state of the LED // Update the LED with the new state digitalWrite(ledPin0, ledState0 ? HIGH : LOW); digitalWrite(ledPin1, ledState1 ? HIGH : LOW); } if (pushbutton2.update() == Button::Falling) { ledState1 = !ledState1; // Invert the state of the LED ledState0 = !ledState0; // Update the LED with the new state digitalWrite(ledPin0, LOW); digitalWrite(ledPin1, ledState1 ? HIGH : LOW); } if (pushbutton3.update() == Button::Falling) { ledState0 = !ledState0; // Invert the state of the LED ledState1 = !ledState1; // Invert the state of the LED // Update the LED with the new state digitalWrite(ledPin0, LOW); digitalWrite(ledPin1, LOW); } if (pushbutton13.update() == Button::Falling){ ledState2 = !ledState2; // Invert the state of the LED // Update the LED with the new state digitalWrite(ledPin2, ledState2 ? HIGH : LOW); } if (pushbutton14.update() == Button::Falling){ ledState3 = !ledState3; // Invert the state of the LED // Update the LED with the new state digitalWrite(ledPin3, ledState3 ? HIGH : LOW); } }

tttapa commented 2 months ago

This is usually caused by incorrect connections. Double-check whether you've got the pins the right way around (you may have swapped ground and one of the signal pins, for example).

Basiliadis commented 2 months ago

Hello Pieter,

pin connections is ok mate... Left pin on the 7 pin , right pin and the 8 pin and center pin on the GND... I have check them many many times and i use a breadboard so it is clearly correct... Also rotary encoders are Bourns very good quality that is use them many years for other structures.. It is very weird indeed!

Basiliadis commented 2 months ago

After two days of tests and changes to the code and components by changing rotary encoders, I could not make the rotary encoder work properly with anything. I also tried another Arduino Pro Micro and again the same problem. Whether it rotates to the right or to the left the result is the same ...It exits with the same button number....Disappointment because I wanted to use it....

tttapa commented 2 months ago

First of all, which messages are you expecting to see? In the MIDI-OX output, data2=01means +1, and data2=7F means -1. Usually, you have four increments/decrements per physical "click" of the encoder. See relativeCCmode for details. These messages only include the relative position changes. If you're expecting to see absolute encoder positions, then CCRotaryEncoder is not the right tool for the job, try CCAbsoluteEncoder instead.

If that's all fine, check the signals coming from the encoders using a modified "digital read serial" sketch for the two encoder pins. Rotate the encoder slowly, and verify that you're getting the correct quadrature output by looking at the serial monitor.

Basiliadis commented 2 months ago

I want to use the rotary to change values on DAW Pieter...For example , to change BPM +10 or -10 .... As i know rotary encoders works like 2 rotary pulse buttons if we can say it like this , so i was expect to react like B0 and B1. Is it possible to do this?

Basiliadis commented 2 months ago

So...problem solved!!!

Here is the code that works with 2 rotary encoders connected on pins 10,16 and 14,15. Both rotaries works as "+" and "-" when you need to change values. I try it on Reaper to change the " Increase/Decrease BPM for 01" with the first rotary and " Increase/Decrease BPM for 10" with second encoder and they worked fine. Also both Encoders works with any pin that i try so no need to use only "INT" pins of Arduino.

Here is the screenshot of test...

As you can see B0,B1,B2,B3 are the push buttons that i use and B4,B5 are the rotary encoders.

Untitled-2

P.S...... i think that the trick done with this line....

RelativeCCSender::setMode(relativeCCmode::NEXT_ADDRESS);

Here is the code....

// Create an array of CCPotentiometer objects that send out MIDI Control Change // messages when you turn the potentiometers connected to the 8 inputs of the mux. CCPotentiometer volumePotentiometers[]{ { mux.pin(0), { MIDI_CC::Channel_Volume, Channel_1 } }, { mux.pin(1), { MIDI_CC::Channel_Volume, Channel_2 } }, { mux.pin(2), { MIDI_CC::Channel_Volume, Channel_3 } }, { mux.pin(3), { MIDI_CC::Channel_Volume, Channel_4 } },
};

CCButton buttons[]{ { mux.pin(4), { MIDI_CC::General_Purpose_Controller_1, Channel_1 } }, { mux.pin(5), { MIDI_CC::General_Purpose_Controller_1, Channel_2 } }, { mux.pin(6), { MIDI_CC::General_Purpose_Controller_1, Channel_3 } }, { mux.pin(7), { MIDI_CC::General_Purpose_Controller_1, Channel_4 } }, };

const int speedMultiplier = 1;

CCRotaryEncoder enc1 { {16, 10}, // pins { MIDI_CC::General_Purpose_Controller_1, Channel_5 },// address speedMultiplier, // multiplier 4, // pulses per click };

CCRotaryEncoder enc2 { {14, 15}, // pins { MIDI_CC::General_Purpose_Controller_1, Channel_6 }, // address speedMultiplier, // multiplier 4, // pulses per click };

void setup() { //pinMode(0, INPUT_PULLUP); //pinMode(1, INPUT_PULLUP); RelativeCCSender::setMode(relativeCCmode::NEXT_ADDRESS); Control_Surface.begin(); // Initialize Control Surface

}

void loop() { Control_Surface.loop(); // Update the Control Surface
}