multiplexer 4067 with 2 encoders

hello to all, am very new to arduino, actually i have no idea about programming c++

i try to built traktorino but with few modification, for traktos softwear, because i dont have a dj consol using it for a hobby now( i used to be pro dj many years ago)

to make long stories short i manage to make the trakrorino but i missing the jog weels, so i open my cdj100 pioneer and notice that it is use ENCODER for jog weel.

because i use arduino uno, there is no any more ports to conect 2 more encoders
pins 2,3 is for one encoder pins 4,5,6,7 are for HC4067 pin 8 (RCLK) is for HC595 (CONTROLING LEDS) PIN 9 control THE encoder switch PIN10 is for ledON pins 11,12 are for hc595 (
srclk and srclr, so no more pins..

There are many ways to reduce the number of Arduino pins required by a circuit so that some pins are freed up for additional uses. For example, perhaps a second 74hc595 could be chained to the existing one, and is outputs could be used to control the 4067.

Please post a schematic so we can see how your circuit works today and advise the best way to achieve adding more controls.

hello to all, am very new to Arduino, actually i have no idea about programming c++

i try to built traktorino but with few modification, for tractor software, because i don't have a dj console using it for a hobby now( i used to be pro dj many years ago)

to make long stories short i manage to make the trakrorino but i missing the jog wheels, and so i open my cdj100 pioneer and notice that it is use ENCODER for jog wheel.

because i use Arduino Uno, there is no any more ports to connect 2 more encoders
pins 2,3 is for one encoder pins 4,5,6,7 are for HC4067 pin 8 (RCLK) is for HC595 (CONTROLING LEDS) PIN 9 control THE encoder switch PIN10 is for ledON pins 11,12 are for hc595 (
srclk and srclr, so no more pins..

so i did a lot of read, and manage to add one more hc4067 and send midi note, (code is writen to have 2 hc4067)
and here is where i need you help. can some one add me a few lines to my code so the thirt HC4067 CAN handle 2 or 3 encoders?

THANK YOU SO MUTCH for you help and time

Traktorino.ino (21 KB)

this is my schematic and how is connected all, just is missing the third HC4067

Cross-posts merged

I am not sure if it will be possible to attach encoders to a 4067. Encoders require a fast response from the Arduino, otherwise signal edges will be lost, and the encoder will appear to "slip" or even appear to be moving in the wrong direction. With the encoders attached to the 4067 it will only be possible to "poll" the encoders pins at a relatively slow rate. It is best to attach the encoders directly to Arduino pins.

You are not using pins A2 to A5? Could you use those for your encoders?

hmm sound good, i didnt know that i can use A0-A5 for encoder, i thought those pins was only for analoque inputs and not digital.

and how i can do that my friend Paulrb?? like i said i have no idea about programing, very few thinks i know.

Yes, A0 to A5 can be used as digital inputs or outputs as well as analog inputs.

Is your code short enough to include in your post, between code tags? I cannot open .ino attachments on my phone.

I can see that the encoder you have now is connected to D2 & D3. These pins have interrupt capability, and they are the only such pins on Uno. Using other pins as digital inputs for the encoders may still result in some problems and not work as well as the encoder on pins D2/3. You may need to use the "pin change interrupt" feature to enable interrupts on pins other than D2/3.

no sir the code is big more than 400line.. but no problem, when you can open my .ino file, take a look and tell me where and what lines to put.. i appreciate you fantastic help

I can see why your code is so long. There is much duplication! For example, I re-wrote one of your functions to be shorter:

void handleNoteOff(byte channel, byte number, byte value) {

  if (number >= 36 && number <= 40)
    ShiftPWM.SetOne(buttonsLedL[40 - number], LOW);
  else if (number >= 44 && number <= 48)
    ShiftPWM.SetOne(buttonsLedR[number - 44], LOW);

}

Please try that and let me know if it still works OK. Then try to shrink some of your other functions in similar ways.

like i said i don’t know to write code, the code i get it from Gustavo Silveira that i assume he disign the traktorino..

in the code i figure out how to add one more hc4067 on pin A2
by copy paste parameters, changing names, and finally i make it work with 3 hc4067. this code you write where i should place it, and what to delete.

void handleNoteOff(byte channel, byte number, byte value) {

if (number >= 36 && number <= 40)
ShiftPWM.SetOne(buttonsLedL[40 - number], LOW);
else if (number >= 44 && number <= 48)
ShiftPWM.SetOne(buttonsLedR[number - 44], LOW);

}

what i did was to copy paste and rename the parameters and add somewhere a line for reading one more hc4067, first part is the original, second (ex… const byte nbuttons1) is mine.

any way i need a code so i will have 2 rotary encoders on pin A2-A3 AND A4-A5 to send midi notes
and to replace pin 10 (ledOnOff) ...and in pin 10 to have one more hc4067

The encoder library you are using is this one from PJRC.

That page says that if you do not use interrupt pins, the performance will be low. A2 to A5 are not interrupt pins. The library does not offer the possibility to use "pin change interrupts".

Do you still want to connect these encoders, with low performance?

I FOUND THIS CODE, AND IT SEAMS WORKING VERY GOOD ON PINS A2-A3.. in the very end you will see that is working fine... but i dont know how to adopt this code in the main code, and how to make it to send midi notes. inst POS1 DIR 1 OR POS1 DIR-1

#include <Arduino.h>
#include <RotaryEncoder.h>

#if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_NANO_EVERY)
// Example for Arduino UNO with input signals on pin 2 and 3
#define PIN_IN1 A2
#define PIN_IN2 A3

#elif defined(ESP8266)
// Example for ESP8266 NodeMCU with input signals on pin D5 and D6
#define PIN_IN1 D5
#define PIN_IN2 D6

#endif

// Setup a RotaryEncoder with 4 steps per latch for the 2 signal input pins:
// RotaryEncoder encoder(PIN_IN1, PIN_IN2, RotaryEncoder::LatchMode::FOUR3);

// Setup a RotaryEncoder with 2 steps per latch for the 2 signal input pins:
RotaryEncoder encoder(PIN_IN1, PIN_IN2, RotaryEncoder::LatchMode::TWO03);

#if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_NANO_EVERY)
// This interrupt routine will be called on any change of one of the input signals
void checkPosition()
{
encoder.tick(); // just call tick() to check the state.
}

#elif defined(ESP8266)
/**

  • @brief The interrupt service routine will be called on any change of one of the input signals.
    */
    ICACHE_RAM_ATTR void checkPosition()
    {
    encoder.tick(); // just call tick() to check the state.
    }

#endif

void setup()
{
Serial.begin(115200);
while (! Serial);
Serial.println("InterruptRotator example for the RotaryEncoder library.");

attachInterrupt(PIN_IN1, checkPosition, CHANGE);
attachInterrupt(PIN_IN2, checkPosition, CHANGE);
} // setup()

// Read the current position of the encoder and print out when changed.
void loop()
{
static int pos = 0;
encoder.tick();

int newPos = encoder.getPosition();
if (pos != newPos) {
Serial.print("pos:");
Serial.print(newPos);
Serial.print(" dir:");
Serial.println((int)(encoder.getDirection()));
pos = newPos;
} // if
} // loop ()

InterruptRotator example for the RotaryEncoder library.
pos:1 dir:1
pos:2 dir:1
pos:3 dir:1
pos:4 dir:1
pos:5 dir:1
pos:6 dir:1
pos:7 dir:1
pos:8 dir:1
pos:7 dir:-1
pos:6 dir:-1
pos:5 dir:-1
pos:4 dir:-1
pos:3 dir:-1
pos:2 dir:-1

i will use pins A2 TO A5 they will send a midi note and if there is a small misreading, is not a big deal
they encoder on those pins will control the PITCH of a song,

This code does nothing else except monitor one encoder. That may be why it seems to work well. Once added to your big sketch, which performs many other operations, the performance may not be as good. There is only one way to find out...

How would 2 encoders be used to control pitch?

What MIDI commands would be needed to change the pitch? Can you find other example code which controls pitch?

encoder on pin A2 -A3 will control the (pitch (jog wheel turn) on deck A and encoder on pins A4-A5 will control pitch (jog wheel turn) for deck B.. pins A2-A3 will send o midi note ex. ch5.cc.005 on one direction and ch5.cc.004 on the other direction. A4-A5 will send ch5.cc003 AND ch5.cc.002. it doesn't matter what cc note will send it can be any, inside tractor dj software, i will map pitch at those cc note and address it for pitch.

am so happy but and so disappoint. i found this code and i modify it, for 2 encoder.
my big big problem is how i will adopt this to my main sketch, so it will send midi notes and not just.. count... my main sketch has the following i assume for readding the encoder and send the midi notes

//// read encoder
void readEncoder () {

int newPosition = myEnc.read();
int encoderVal = map(newPosition, -1024, 1024, -256, 256);
int encoderValue;

if (encoderVal != oldPosition) {

if ((encoderVal - oldPosition) > 0) {
  encoderValue = 127;
}
else {
  encoderValue = 1;
}

MIDI.sendControlChange(14, encoderValue, 1);

oldPosition = encoderVal;

}

}

THIS IS MY ENCODER AND IS WORKING SUPER FINE FOR WHAT I NEED IT FOR

Direction: CCW- ENCODER A | Counter: 0
Direction: CCW- ENCODER A | Counter: -1
Direction: CCW- ENCODER A | Counter: -2
Direction: CW- ENCODER A | Counter: -1
Direction: CW- ENCODER A | Counter: 0
Direction: CW- ENCODER A | Counter: 1

Direction: CCW -- ENCODER B | Counter: 0
Direction: CCW -- ENCODER B | Counter: -1
Direction: CCW -- ENCODER B | Counter: -2
Direction: CW -- ENCODER B | Counter: -1
Direction: CW -- ENCODER B | Counter: 0
Direction: CW -- ENCODER B | Counter: 1

I NEED TO ADOPT THIS SOME HOW TO MY MAIN SKETCH BUT NOT LIKE A COUNTER BUT LIKE MIDI NOTE SENDER..

// Rotary Encoder Inputs
#define CLK A2 // ENCODER PIN A
#define DT A3 // ENCODER PIN B
#define CLK1 A4 // ENCODER(B) PIN A
#define DT1 A5 // ENCODER (B) PIN B

#define SW 8 //ENCODER SWITCH
#define SW1 9 // ENCODER (B) SWITCH

int counter = 0;
int counter1 = 0;
int currentStateCLK;
int currentStateCLK1;
int lastStateCLK;
int lastStateCLK1;

String currentDir ="";

unsigned long lastButtonPress = 0;
unsigned long lastButtonPress1 = 0;

void setup() {

// Set encoder pins as inputs
pinMode(CLK,INPUT);
pinMode(DT,INPUT);
pinMode(SW, INPUT_PULLUP);
pinMode(CLK1,INPUT);
pinMode(DT1,INPUT);
pinMode(SW1, INPUT_PULLUP);

// Setup Serial Monitor
Serial.begin(9600);

// Read the initial state of CLK
lastStateCLK = digitalRead(CLK);
lastStateCLK1 = digitalRead(CLK1);
}

// ------------------------------------------------------------------------------------
void loop() {

// Read the current state of CLK
currentStateCLK = digitalRead(CLK);

// If last and current state of CLK are different, then pulse occurred
// React to only 1 state change to avoid double count
if (currentStateCLK != lastStateCLK && currentStateCLK == 1){

// If the DT state is different than the CLK state then
// the encoder is rotating CCW so decrement
if (digitalRead(DT) != currentStateCLK) {
  counter --;
  currentDir ="CCW- ENCODER A";
} else {
  // Encoder is rotating CW so increment
  counter ++;
  currentDir ="CW- ENCODER A";
}

Serial.print("Direction: ");
Serial.print(currentDir);
Serial.print(" | Counter: ");
Serial.println(counter);

}

// Remember last CLK state
lastStateCLK = currentStateCLK;

// ------------------------------------------------------------------------------

// Read the current state of CLK
currentStateCLK1 = digitalRead(CLK1);

// If last and current state of CLK are different, then pulse occurred
// React to only 1 state change to avoid double count
if (currentStateCLK1 != lastStateCLK1 && currentStateCLK1 == 1){

// If the DT1 state is different than the CLK state then
// the encoder is rotating CCW so decrement
if (digitalRead(DT) != currentStateCLK1) {
  counter --;
  currentDir ="CCW-ENCODER B";
} else {
  // Encoder is rotating CW so increment
  counter ++;
  currentDir ="CW-ENCODER B";
}

Serial.print("Direction: ");
Serial.print(currentDir);
Serial.print(" | Counter: ");
Serial.println(counter);

}

// Remember last CLK state
lastStateCLK1 = currentStateCLK1;

// ------------------------------------------------------------------------------------

// Read the button state
int btnState = digitalRead(SW);
int btnState1 = digitalRead(SW1);

//If we detect LOW signal, button is pressed
if (btnState == LOW) {
//if 50ms have passed since last LOW pulse, it means that the
//button has been pressed, released and pressed again
if (millis() - lastButtonPress > 50) {
Serial.println("Button pressed!");
}

// Remember last button press event
lastButtonPress = millis();

}

//If we detect LOW signal, button is pressed
if (btnState1 == LOW) {
//if 50ms have passed since last LOW pulse, it means that the
//button has been pressed, released and pressed again
if (millis() - lastButtonPress > 50) {
Serial.println("Button pressed!");
}

// Remember last button press event
lastButtonPress = millis();

}

// Put in a slight delay to help debounce the reading
delay(1);
}

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.