HC595s and 4051s for MIDI Controller

Hello,

I hope you all doing good! I got my Arduino UNO R3 and started to work on MIDI Controller. Since, I'm DJ and producer I really like to have my own MIDI Controller. Recently, I've found that Arduino has not so many Analog inputs to read value of Pots. Also, It doesn't have enough digital input or output for leds and buttons. So, I searched for an answer and found that I can get HC595 for multiplexing the digital outputs and 4051 for multiplexing the analog inputs.

I designed a circuit for about 32 pots and 32 buttons. However, when I measure the 1 loop time it shows me about 50 ms even if I don't have my buttons connected.

So what have I done so far ? I daisy chained 2 HC595s and first HC959s first 3 bits sending messages to first 4051's S0 S1 and S2 and second HC595's first 3 bits sending messages to second 4051. My first 4051 is my main MUX. I've connected my second MUX the first 4051. I multiplexed Arduino's analog inputs with a 4051. I wanted to use only A0 of arduino and I controlled first mux with HC595s first 3 bits because I want to connect more pots or buttons to my Arduino. Also, I have 4067s so I can directly connect them to my Arduino this way i can eliminate 1 mux but this time I will only have 6 * 16 input for pots or buttons for analog read.

Here is my question: I said I measured 1 loop cycle takes about 50 ms. Is it normal? On code side, I'm shifting out bits to my first HC595 so it can control first MUX, and I'm shifting out second 8-bit value to my HC595.Then I'm reading the value of selected pot and if the value is not the same with ex value of this pot Arduino sends midi data. However, It takes about 50ms and it looks too much to me. I tested it with for loop for only 32 inputs. Is there a problem with my algorithm or is it the circuit issue? Also, When I read the value of pot it is not accurate. When I fully turned my pot it shows 1012-1013 etc. but the pot's max value is 1023. I'm using 10K pots. Also, even if I don't touch the pot it's changing its value like 1012-1013-1011-1012. Maybe it is breadboard issue ?

I done this circuit to reach excessive amount of pots and buttons. Searched manys sites but they only use 16 or fewer inputs. It's not done yet. I'm just checking and controlling the system if Arduino can handle it or not. That's why I connected 4051 to 4051. I attached the circuit's picture. I didn't created a schema. Currently, I'm working with just 2 pots but I have array which length is 32 so can code check 32 values from this array and write to it if it is necessary.

Thanks for your upcoming replys and have a nice day !

(Picture was too large for attachment so I uploaded it to dropbox.Here is the link: https://dl.dropboxusercontent.com/u/10760869/595s4051s.png . Also, I attached jpg version of it.

)

I said I measured 1 loop cycle takes about 50 ms. Is it normal?

Well it is what you get. However because you haven't posted any code it is impossible to tell you about things to speed that loop up.

Things to consider:-

  1. Use direct port access for digital I/O
  2. Use reduced resolution on the A/D, ( you only need 7 bits )

When I fully turned my pot it shows 1012-1013 etc. but the pot's max value is 1023. I'm using 10K pots. Also, even if I don't touch the pot it's changing its value like 1012-1013-1011-1012.

Never have unwired inputs on the 4051s
Yes bread boarding is often rubbish.
Use star wiring to keep your digital and analogue grounds from interfering with each other. That is only common the grounds at one point do not chain them.
4) Replace the shift registers with something like a MCP23S17, with that you can see if any of 16 buttons are pressed by just monitoring a single pin. Then when you know something is being pressed you cha check each input to see which one it is.

Quick question, why is it that you are controlling the 4051 select pins w/ shift registers and not directly from UNO pins? It seems like you have an extra layer of complexity in there that you do not need to control the muxes.

5 select pin outputs would give you enough to mux 32 inputs

Grumpy_Mike:
2) Use reduced resolution on the A/D, ( you only need 7 bits )

Sorry for hijacking. But how can you lower the A/D resolution?
thanks

From the attached application note:-

The ADC can prescale the system clock to provide an ADC clock that is between 50kHz and 200kHz to get maximum resolution. If ADC resolution of less than 10 bits required, then the ADC clock frequency can be higher than 200kHz. At 1MHz it is possible to achieve eight bits of resolution maximum.
The pre-scalar value is selected with ADPS bits (ADPS2:0) in ADCSRA. When initiating a single ended conversion by setting the ADSC bit in ADCSRA, the conversion starts at the following rising edge of the ADC clock cycle.

doc8444.pdf (232 KB)

Thanks for your precious answers. I changed the circuit a bit. First, I removed the first HC595 and used 1 HC595 for controlling BUS Mux and child muxes. I don't want to use every digital pins on arduino so that's why I'm using HC595. Here I paste my code down. Also, here is the link for new circuit:
https://dl.dropboxusercontent.com/u/10760869/Photo%2020-11-14%2021%2019%2003.jpg

Leds are for me to see if HC595 is getting correct binary number to select the mux.

Now I connected 8 pots and will add 4067s for 16 channel mux. This way I managed to drop loop time to 8ms for 32 pots. However, I still get wrong numbers from pots. For example, I'm getting 20-30 while pot is all the way down and not getting 1023 while pot is completely open. Hope I can make myself clear.

Some variables and comments was added before so please forgive me if they confuse you. I removed few of them but not completely revised.

/* 595 */
#define STCP_PIN 8//Latch pin
#define SHCP_PIN  7//Clock
#define DS_PIN 10//data
#define SMOOTHING 3
byte HC595a = B00000000;// chain's final element
byte HC595b = B00000000;// chain's final element

//*4051 * analog multiplexer / demultiplexer
byte r0 = 0;      //value of select pin at the 4051 (s0)
byte r1 = 0;      //value of select pin at the 4051 (s1)
byte r2 = 0;
byte r3 = 0;//value of select pin at the 4051 (s2)
byte s0 = 0;      //value of select pin at the 4051 (s0)
byte s1 = 0;      //value of select pin at the 4051 (s1)
byte s2 = 0;
byte s3 = 0;//value of select pin at the 4051 (s2)
byte toBusMUX = 0;   //which y pin we are selecting
byte toChildMUX = 0;   //which y pin we are selecting
int index = 0;
int potValue;
int pots[32]= {
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
byte busValues[3] = {
  B00000000,B00000001,B00000010};
byte childValues[16] = {
  B00000000,B00010000,B00100000,B00110000,B01000000,B01010000,B01100000,B01110000,
  B10000000,B10010000,B10100000,B10110000,B11000000,B11010000,B11100000,B11110000};
long time=0;

//First MUX multiply the A0 this way the system only uses the A0 analog input.
//With shift registers system controls MUXes and gets the values from every pot. 

//HC165s will be added. They will be used for buttons. 
void setup() {
  //Serial.begin(9600);
 Serial.begin(57600);
  pinMode(STCP_PIN, OUTPUT);
  pinMode(SHCP_PIN, OUTPUT);
  pinMode(DS_PIN, OUTPUT);
}
void loop()
{
  time = millis();
  index = 0;
  for(toBusMUX = 0; toBusMUX<=0; toBusMUX++)
  {
    HC595a = busValues[toBusMUX]; 
    for(toChildMUX = 0; toChildMUX<=7; toChildMUX++)
    {
      HC595b = childValues[toChildMUX];
      HC595b = HC595b | HC595a;
      writeToReg();
      potValue = analogRead(A0);
      if(abs(pots[index]-potValue) > SMOOTHING)
      {
        pots[index] = potValue;
        potValue = map(potValue,5,1020,0,127);
        noteOn(0xB0,index,potValue);
/*
           Serial.print("Pot Value of ");
         Serial.print(index);
         Serial.print(" : ");
         Serial.println(potValue);   
    */
      } 
      index++;
    } 
  }
  //Serial.println(millis() - time);

  delay(10);

}
void writeToReg()
{
  //time = millis();
  //A is the last daisy chained
  //B is first one
  //if A is 11111110 means A's left hand sided first bit is 0.
  digitalWrite(STCP_PIN,LOW);
  shiftOut(DS_PIN, SHCP_PIN, MSBFIRST, HC595b);
  //Serial.println(HC595b);
  //shiftOut(DS_PIN, SHCP_PIN, LSBFIRST, B00000000);
  digitalWrite(STCP_PIN,HIGH);
  //Serial.println(millis() - time);
  //delay(1);
  delayMicroseconds(10);   

}

void noteOn(int cmd, int pitch, int velocity) {
  Serial.write(cmd);
  Serial.write(pitch);
  Serial.write(velocity);
}

It helps if you provide a schematic it is almost impossible to tell anything from that photograph.
However I do notice a total lack of decoupling capacitors. And your wiring to the pots is chained not star. That causes ground lift and can mess up the readings.

Actually, I'm new to electronics and Arduino. However, I know coding in many languages but don't know so many things in Arduino :slight_smile: I have Arduino for 2 weeks. If you don't mind, what is star-chaining and decoupling capacitors and where should I put them? I couldn't find remarkable information about them still searching btw.

I tried to create schematic on 123D circuits but there is no 4051 etc. Also, there are so many erros in that application.

Thank you so much for your quick answer !

Decoupling is not an arduino specific thing it is needed in all electronics.

http://www.thebox.myzen.co.uk/Tutorial/De-coupling.html

Likewise star wiring is universal, this link looks at the difference between star and daisy chain wiring.

http://www.sw-em.com/1800Ignition_Wiring_Swedisch_vs_British.htm

I tried to create schematic on 123D circuits

Just draw it with a pen.

https://dl.dropboxusercontent.com/u/10760869/Photo%2020-11-14%2023%2027%2025.jpg Here is the schematic. I didn't show every cable i just write which input goes to which output or vice versa. Also only showed 2 pots since other 6 are connected as like the first one. D10,D8 and D7 are cables connected to Arduino. A0 is the Arduino's analog input. BUS Mux's all legs connected to the gorund except the Y0 leg so I Connected there the cable coming from child Mux's Z output.Please let me know if I done something wrong or if there is something that unclear.

Thanks for your help again I'm reading the text now.

Maybe it is breadboard issue

It is looking like it, if the decoupling and star wiring does not fix it.

I have little knowlidge in electronics. I read your links. When I try this circuit with only 1 4051 and no hc595 it worked well but now it shows wrong values. I will try to change the circuit. My loop takes 6 -8 ms for now it is a good timing for me. I didnt get how star wiring works. I mean i may change few pots on same time plus i will add few buttons to my circuit. Currently, i dont have any capacitor in my tools. I think i should buy for the circuit. I found few midi controller circuits but couldnt see any capacitor actually. If there were few of them i should have saw them. Sorry my questions can be very frustrating.

Frustrating or not you need decoupling capacitors. That is the end to it.
You can find all sorts of crap circuits on the Internet it dosn't mean it is right.

You have daisy chained wiring to the pots. It needs to be star. With star wiring all the wires meet at one point only so there is a wire from each pot to one point not one to an other to another and so on like you have.

When I say "midi circuit" it was Korg brand not some ordinary circuit :slight_smile: maybe they didn't need that. So,I never worried about capacitors but now I'm gonna order as you say.

Thanks for your reply Mr. ! Really helped me a lot. Also, thank you for your patience. I will do as you say and check the result.

Have a nice day and weekend!

When I say "midi circuit" it was Korg brand not some ordinary circuit

Often schematics miss out decoupling capacitors because everybody knows you need them.

See :-