latching buttons on 3 cascade 74HC4067

Hello,
I'm trying to use momentary buttons as ON/OFF on 3 cascaded 74HC4067 that I've copied from the Mux shield on a prototipe breadboard.
(I have also buy the shield from mayhewlabs but I'm still waiting it from the US so I cloned it for playing a bit)
I've used this code:

//Mux_Shield_DigitalIn_Example
//http://mayhewlabs.com/arduino-mux-shield

/*
This example shows how to read and store all pins as digital inputs into arrays and print the results over serial.
 Switches should be connected from ground to the pin input.
 Internal pull-up resistors are used on the inputs, so when a switch is depressed, the reading
 changes from 1 to 0, but to correct this logic, the digitalRead function is corrected with '!' 
 to actually store a 1 when a switch is depressed.
 
 To simplify this code further, one might use nested for loops or function calls.
 */

//Give convenient names to the control pins
#define CONTROL0 5    
#define CONTROL1 4
#define CONTROL2 3
#define CONTROL3 2

//Create arrays for data from the the MUXs
//See the Arduino Array Reference: http://www.arduino.cc/en/Reference/Array
int mux0array[16];
int mux1array[16];
int mux2array[16];

void setup()
{
  //Set MUX control pins to output
  pinMode(CONTROL0, OUTPUT);
  pinMode(CONTROL1, OUTPUT);
  pinMode(CONTROL2, OUTPUT);
  pinMode(CONTROL3, OUTPUT);

  //Open the serial port at 28800 bps
  Serial.begin(9600);

  //Set analog pins to digital input  
  pinMode(14, INPUT);         
  pinMode(15, INPUT);
  pinMode(16, INPUT);

  //Turn on pullup resistors
  digitalWrite(14, HIGH);       
  digitalWrite(15, HIGH);
  digitalWrite(16, HIGH);
}


void loop()
{
  //This for loop is used to scroll through and store the 16 inputs on the FIRST multiplexer
  for (int i=0; i<16; i++)
  {
    //The following 4 commands set the correct logic for the control pins to select the desired input
    //See the Arduino Bitwise AND Reference: http://www.arduino.cc/en/Reference/BitwiseAnd
    //See the Aruino Bitshift Reference: http://www.arduino.cc/en/Reference/Bitshift
    digitalWrite(CONTROL0, (i&15)>>3); 
    digitalWrite(CONTROL1, (i&7)>>2);  
    digitalWrite(CONTROL2, (i&3)>>1);  
    digitalWrite(CONTROL3, (i&1));     

    //Read and store the input
    //Since internal pullup is on, the pin goes low on changing, so the value needs to be flipped from 0 to 1 (!)
    mux0array[i] = !digitalRead(14);
  }

  //This for loop is used to scroll through the SECOND multiplexer
  for (int i=0; i<16; i++)
  {
    digitalWrite(CONTROL0, (i&15)>>3); 
    digitalWrite(CONTROL1, (i&7)>>2);  
    digitalWrite(CONTROL2, (i&3)>>1);  
    digitalWrite(CONTROL3, (i&1));     
    mux1array[i] = !digitalRead(15);
  }

  //This for loop is used to scroll through the THIRD multiplexer
  for (int i=0; i<16; i++)
  {
    digitalWrite(CONTROL0, (i&15)>>3); 
    digitalWrite(CONTROL1, (i&7)>>2);  
    digitalWrite(CONTROL2, (i&3)>>1);  
    digitalWrite(CONTROL3, (i&1));     
    mux2array[i] = !digitalRead(16);
  }    

  //The following lines are for printing out results of array0
  Serial.print("mux0array: ");
  for (int i=0; i<16; i++)
  {
    Serial.print(mux0array[i]);
    Serial.print("-");
  }
  Serial.println();  //line feed

  //The following lines are for printing out results of array1
  Serial.print("mux1array: ");
  for (int i=0; i<16; i++)
  {
    //Serial.print(mux1array[i]);
    //Serial.print("-");
  }
  //Serial.println();

  //The following lines are for printing out results of array2
  Serial.print("mux2array: ");
  for (int i=0; i<16; i++)
  {
    //Serial.print(mux2array[i]);
    //Serial.print("-");
  }
  //Serial.println();
}

Running the program everithing works fine and serial show me the button pressed with a 1. The problem is that when I release the button the status go back to 0. What I really need is that I press button and status of that button goes 1, pressing again bring it to 0 and viceversa.
I havbe try to create an array to store the old values and compare with the new ones, but if I leave the button pressed it change status continuosly.
Any help?

but if I leave the button pressed it change status continuosly.

So you only change the state of the variable corresponding to your button when the last state you read is different from the state you are reading this time round the loop.

thanks.
I have try to follow the way of the value in array and check if it changed. I've also simplified code for don't waste too much space in the thread. This the reult:

/*
simplified code that read only one 74HC4067 for learning purpose
 do not use!
 */

//Give convenient names to the control pins
#define CONTROL0 5    
#define CONTROL1 4
#define CONTROL2 3
#define CONTROL3 2

int oldMuxData[48];
int newMuxData[48];


void setup()
{
  //Set MUX control pins to output
  pinMode(CONTROL0, OUTPUT);
  pinMode(CONTROL1, OUTPUT);
  pinMode(CONTROL2, OUTPUT);
  pinMode(CONTROL3, OUTPUT);
  //Open the serial port at 9600 bps
  Serial.begin(9600);
  //Set analog pins to digital input  
  pinMode(14, INPUT);         
  pinMode(15, INPUT);
  pinMode(16, INPUT);
  //Turn on pullup resistors
  digitalWrite(14, HIGH);       
  digitalWrite(15, HIGH);
  digitalWrite(16, HIGH);
}

void muxPing (int port) {
  //The following 4 commands set the correct logic for the control pins to select the desired input
  digitalWrite(CONTROL0, (port&15)>>3); 
  digitalWrite(CONTROL1, (port&7)>>2);  
  digitalWrite(CONTROL2, (port&3)>>1);  
  digitalWrite(CONTROL3, (port&1));     
}

void loop()
{
  // read mux
  for (int i=0; i<16; i++)
  {
    muxPing(i);
    //Read and store the input (pullup so use!)
    newMuxData[i] = !digitalRead(14);//15/16
    if (newMuxData[i] != oldMuxData[i]) { //value changed
      oldMuxData[i] = newMuxData[i];
    }
  }
  showMuxData(16);
}

void showMuxData(int lenght){
  // printing out results of mux array x
  Serial.print("data: ");
  for (int i=0; i<16; i++)
  {
    Serial.print(newMuxData[i]);
    Serial.print("-");
  }
  Serial.println();  //line feed
}

At the end I got same result! Infact as soon I release button the value change and this reflects the old and new value.
I really need a little help here!

hello,
the page you suggest does the same I have now. Pressing button -> led on, releasing -> led off.
I'm looking for:
pressing button-> led ON, releasing -> nothing. Pressing again->led OFF, releasing-> nothing

I speak spainish, italian, japanese, some greek but my english is terrible, sorry.
Ok, I try follow what you say. thanks aniway!

I really need a little help here!

I'm looking for:
pressing button-> led ON, releasing -> nothing. Pressing again->led OFF, releasing-> nothing

Aleandrogreete,

before starting to bang out a program, it's a really, really good idea to sit down to understand the problem and find a solution. For people without experience in programming this works best with pen, a paper napkin and a glass of wine. Just randomly copying program fragments one found on the internet is voodoo-programming - it may work if the moon is right and you sacrificed enough chicken.

Once you have that, the result will become pretty obvious quickly. If you're at loss where to start, let me give you a few hint:

Start out with just one button to get the logic for the button right. Your multiplexing logic seems ok, you can add that later.

You will need to remember the current state of the led to know whether to turn it on or off. You will need to know when a off-on transition happens with your button. This should be enough for phase one.

Once you figured that out, you can start to tackle some other things you'll need for your project. Mainly debouncing your keys and how to address your buttons and leds.

Have fun.

Korman

Well, I'm here to learn so thanks you guys for your suggestions.
I'm pretty fast learn foreigner languages so it's better for all if we continue with english, I promise to do my best for being as much clear I can.
I don't have the habit to copy and paste code but always try to learn what is doing, this is why I've asked a suggestion.
The page that really helped me is this:

I have learned the time out mechanism that check how much time port was on and reset it, so I've used succesfully this method in the following code that working almost 80%.

/*
Very simple code for use 74HC4067 MUX for multiple switches. It uses just momentary buttons
 connected to each mux port and add latching capabilities.
 The result it's an array called muxState where it's stored the data of switches.
 NOTE: do not use this version since it's still in developing
 */

//Give convenient names to the control pins
#define MUXCONTROL0 5    
#define MUXCONTROL1 4
#define MUXCONTROL2 3
#define MUXCONTROL3 2
//IC's mounted has 16 out each, multiply for 3
#define MUXPORTS 48
//Create arrays for data from the the MUXs
int muxState[MUXPORTS];
int muxReading[MUXPORTS];
int muxPrevius[MUXPORTS];
// debounce timings
int outTime = 0;// last time we toggle out
int debounce = 200;// time for prevent mechanical glitches. Increase if there's errors

void setup()
{
  //Set MUX control pins to output
  pinMode(MUXCONTROL0, OUTPUT);
  pinMode(MUXCONTROL1, OUTPUT);
  pinMode(MUXCONTROL2, OUTPUT);
  pinMode(MUXCONTROL3, OUTPUT);
  // Set analog pins to digital input on MUX
  pinMode(14, INPUT);         
  pinMode(15, INPUT);
  pinMode(16, INPUT);
  // Turn on pullup resistors on MUX
  digitalWrite(14, HIGH);       
  digitalWrite(15, HIGH);
  digitalWrite(16, HIGH);
  // Open the serial port for debug
  Serial.begin(9600);
}

// set the correct logic for the control pins to select the desired input
void muxPing(int pin){
  digitalWrite(MUXCONTROL0, (pin&15)>>3); 
  digitalWrite(MUXCONTROL1, (pin&7)>>2);  
  digitalWrite(MUXCONTROL2, (pin&3)>>1);  
  digitalWrite(MUXCONTROL3, (pin&1));   
}

// debounce function, check state and fill the muxState array conseguently
void muxWrite(int pin, int muxVal) {
  if (muxVal == 1 && muxPrevius[pin] == 0 && millis() - outTime > debounce) {
    // toggle mux array
    if (muxState[pin] == 1) {
      muxState[pin] = 0;
    } 
    else {
      muxState[pin] = 1;
    }
    //reset the toggle out time
    outTime = millis();
  }
}
// Just for debug. Prints out the muxState content
void muxPrint(){
  Serial.print("->: ");
  for (int i=0; i<MUXPORTS; i++)
  {
    Serial.print(muxState[i]);
    Serial.print("-");
  }
  Serial.println();
}

void loop()
{
  // read data from first MUX
  for (int i=0; i<16; i++){
    //Read and store the input (use ! since we are using pullup)
    muxReading[i] = !digitalRead(14);
    // write data
    muxWrite(i, muxReading[i]);
  }
  // read data from second MUX
  for (int i=0; i<16; i++){
    // array size it's 48, this is second mux so we have offset by 16
    int pinOffset = 16;
    //Read and store the input (use ! since we are using pullup)
    muxReading[pinOffset] = !digitalRead(15);
    // write data
    muxWrite(pinOffset, muxReading[pinOffset]);
  }
  // read data from second MUX
  for (int i=0; i<16; i++){
    // array size it's 48, this is third mux so we have offset by 32
    int pinOffset = 32;
    //Read and store the input (use ! since we are using pullup)
    muxReading[pinOffset] = !digitalRead(16);
    // write data
    muxWrite(pinOffset, muxReading[pinOffset]);
  }
  // We finished to fill the array. Now we can read results
  muxPrint();
}

For semplicity I have isolated the function that handle the toggle.

// debounce function, check state and fill the muxState array conseguently
void muxWrite(int pin, int muxVal) {
  if (muxVal == 1 && muxPrevius[pin] == 0 && millis() - outTime > debounce) {
    // toggle mux array
    if (muxState[pin] == 1) {
      muxState[pin] = 0;
    } 
    else {
      muxState[pin] = 1;
    }
    //reset the toggle out time
    outTime = millis();
  }
}

Code it's working at 80% so press button, toggle the value in the mux array on and off as expected.
The only problem is that I press button for long time the array status will change On/Off continuosly because the outTime value is surpassed and reset continuosly.
I feel that I still need a part of code that identify if the button has holded.
I hope to be in the right way!

Solved!
I forget to set the oldReading variable!

// debounce function, check state and fill the muxState array conseguently
void muxWrite(int pin, int muxVal) {
  if (muxVal == 1 && muxPrevius[pin] == 0 && millis() - outTime > debounce) {
    // toggle mux array
    if (muxState[pin] == 1) {
      muxState[pin] = 0;
    } 
    else {
      muxState[pin] = 1;
    }
    //reset the toggle out time
    outTime = millis();
  }
  muxPrevius[pin] = muxReading[pin];
}