1

I am currently working on an Arduino project that needs alot of on/off toggles. Because my Arduino Mega does not have enough pins I connected 5 multiplexers to it (the MuxShield 2's). The problem is that only one of them functions correctly at any given moment.
Each multiplexer has 3 rows and they each have their _shiftReg1, _shiftReg2 and _shiftReg3 array in the library. I think there's something up with this, when I loop over the rows of each multiplexers only the first first, second and third row of any given multiplexer work as expected. The outputs on each row light up one by one as they should. But when I loop over a row number which is already looped over all the outputs turn on at once. I have no idea why this is happening and really need some help figuring this out.

This is my main project file, I commented which loops work and which ones don't:

#include <Arduino.h>

#include <MuxShield.h>
#include <ToggleMux.h>

// Initialize the Mux Shields
MuxShield muxShield1 = MuxShield(31, 29, 27, 25, 23, 10, 11, 12, A0, A1, A2);
MuxShield muxShield2 = MuxShield(41, 39, 37, 35, 33, 10, 11, 12, A3, A4, A5);
MuxShield muxShield3 = MuxShield(2, 4, 6, 7, 8, 10, 11, 12, A6, A7, A8);
MuxShield muxShield4 = MuxShield(51, 49, 47, 45, 43, 10, 11, 12, A9, A10, A11);
MuxShield muxShield5 = MuxShield(22, 24, 26, 28, 30, 10, 11, 12, A12, A13, A14);
// ToggleMux
ToggleMux t1 = ToggleMux(muxShield1, 1, 0, muxShield3, 3, 0);
ToggleMux t2 = ToggleMux(muxShield1, 1, 1, muxShield3, 3, 1);
ToggleMux t3 = ToggleMux(muxShield1, 1, 2, muxShield3, 3, 2);
ToggleMux t4 = ToggleMux(muxShield1, 1, 3, muxShield3, 3, 3);
...

void setup()
{
    muxShield1.setMode(1, DIGITAL_IN);
    muxShield1.setMode(2, DIGITAL_IN);
    muxShield1.setMode(3, DIGITAL_IN);

    muxShield2.setMode(1, DIGITAL_IN);
    muxShield2.setMode(2, DIGITAL_IN);
    muxShield2.setMode(3, DIGITAL_IN);

    muxShield3.setMode(1, DIGITAL_IN);
    muxShield3.setMode(2, ANALOG_IN);
    muxShield3.setMode(3, DIGITAL_OUT);

    muxShield4.setMode(1, DIGITAL_OUT);
    muxShield4.setMode(2, DIGITAL_OUT);
    muxShield4.setMode(3, DIGITAL_OUT);

    muxShield5.setMode(1, DIGITAL_OUT);
    muxShield5.setMode(2, DIGITAL_OUT);
    muxShield5.setMode(3, DIGITAL_OUT);
}

boolean hilo = true;

void loop()
{
    for (int i = 0; i < 16; i++) {     // works as expected
      muxShield3.digitalWriteMS(3, i, hilo ? 1 : 0);
      delay(10);
    }

    for (int i = 0; i < 16; i++) {     // turns them all on at once because row 3 has already been looped over
      muxShield4.digitalWriteMS(3, i, hilo ? 1 : 0);
      delay(10);
    }

    for (int i = 0; i < 16; i++) {     // works as expected
      muxShield4.digitalWriteMS(1, i, hilo ? 1 : 0);
      delay(10);
    }

    for (int i = 0; i < 16; i++) {     // works as expected
      muxShield4.digitalWriteMS(2, i, hilo ? 1 : 0);
      delay(10);
    }

    // for (int i = 0; i < 16; i++) {
    //   muxShield4.digitalWriteMS(3, i, hilo ? 1 : 0);
    //   delay(10);
    // }

    for (int i = 0; i < 16; i++) {    // turns them all on at once because row 1 has already been looped over
       muxShield5.digitalWriteMS(1, i, hilo ? 1 : 0);
       delay(10);
     }

     for (int i = 0; i < 16; i++) {    // turns them all on at once because row 2 has already been looped over
       muxShield5.digitalWriteMS(2, i, hilo ? 1 : 0);
       delay(10);
     }

     for (int i = 0; i < 16; i++) {    // turns them all on at once because row 3 has already been looped over
       muxShield5.digitalWriteMS(3, i, hilo ? 1 : 0);
       delay(10);
     }
     hilo = !hilo;

  // t1.listen();
  // t2.listen();
  // t3.listen();
  // t4.listen();
    ...
}

This is my toggle library:

#include "Arduino.h"
#include "ToggleMux.h"
#include "MuxShield.h"

ToggleMux::ToggleMux(MuxShield muxShieldIn, int inRow, int inBit, MuxShield muxShieldOut, int outRow, int outBit) :
_muxShieldIn(muxShieldIn),
_muxShieldOut(muxShieldOut),
_inRow(inRow),
_inBit(inBit),
_outRow(outRow),
_outBit(outBit)
{
    _state = 0;
    _previous = 0;
    _reading;

    _time = 0;
    _debounce = 100;
}

void ToggleMux::listen() {
    _reading = _muxShieldIn.digitalReadMS(_inRow, _inBit);
    _state = _muxShieldOut.digitalReadMS(_outRow, _outBit);

    if (_reading == 1 && _previous == 0 && millis() - _time > _debounce) {
        if (_state == 1) {
            _state = 0;
        } else {
            _state = 1;
        }

        _muxShieldOut.digitalWriteMS(_outRow, _outBit, _state);
        _time = millis();
    }

    _previous = _reading;
}

void ToggleMux::on() {
  _state = 1;
  _muxShieldOut.digitalWriteMS(_outRow, _outBit, 1);
}

void ToggleMux::off() {
  _state = 0;
  _muxShieldOut.digitalWriteMS(_outRow, _outBit, 0);
}

And this is the MuxShield 2 library:

/*
 MuxShield.cpp - Library for using Mayhew Labs' Mux Shield.
 Created by Mark Mayhew, December 29, 2012.
 Released into the public domain.
 */

#include "Arduino.h"
#include "MuxShield.h"
#include "BitBool.h"

int _shiftReg1[16] = {0};
int _shiftReg2[16] = {0};
int _shiftReg3[16] = {0};

MuxShield::MuxShield(int S0, int S1, int S2, int S3, int OUTMD,int IOS1, int IOS2, int IOS3, int IO1, int IO2, int IO3)
{
    _S0 = S0;
    _S1 = S1;
    _S2 = S2;
    _S3 = S3;
    _OUTMD = OUTMD;
    _IOS1 = IOS1;
    _IOS2 = IOS2;
    _IOS3 = IOS3;
    _IO1 = IO1;
    _IO2 = IO2;
    _IO3 = IO3;

    pinMode(_S0,OUTPUT);
    pinMode(_S1,OUTPUT);
    pinMode(_S2,OUTPUT);
    pinMode(_S3,OUTPUT);
    pinMode(_OUTMD,OUTPUT);
    digitalWrite(_OUTMD,LOW);
    pinMode(_IOS1,OUTPUT);
    pinMode(_IOS2,OUTPUT);
    pinMode(_IOS3,OUTPUT);
}

MuxShield::MuxShield()
{
    _S0 = 2;
    _S1 = 4;
    _S2 = 6;
    _S3 = 7;
    _OUTMD = 8;
    _IOS1 = 10;
    _IOS2 = 11;
    _IOS3 = 12;
    _IO1 = A0;
    _IO2 = A1;
    _IO3 = A2;

    pinMode(_S0,OUTPUT);
    pinMode(_S1,OUTPUT);
    pinMode(_S2,OUTPUT);
    pinMode(_S3,OUTPUT);
    pinMode(_OUTMD,OUTPUT);
    digitalWrite(_OUTMD,LOW);
    pinMode(_IOS1,OUTPUT);
    pinMode(_IOS2,OUTPUT);
    pinMode(_IOS3,OUTPUT);
}

void MuxShield::setMode(int mux, int mode)
{
    switch (mux) {
        case 1:
            switch (mode) {
                case DIGITAL_IN:
                    pinMode(_IO1,INPUT);
                    digitalWrite(_IOS1,LOW);
                    break;
                case DIGITAL_IN_PULLUP:
                    pinMode(_IO1,INPUT_PULLUP);
                    digitalWrite(_IOS1,LOW);
                    break;
                case DIGITAL_OUT:
                    pinMode(_IO1,OUTPUT);
                    digitalWrite(_IOS1,HIGH);
                    break;
                case ANALOG_IN:
                    digitalWrite(_IOS1,LOW);
                    break;
                default:
                    break;
            }
            break;
        case 2:
            switch (mode) {
                case DIGITAL_IN:
                    pinMode(_IO2,INPUT);
                    digitalWrite(_IOS2,LOW);
                    break;
                case DIGITAL_IN_PULLUP:
                    pinMode(_IO2,INPUT_PULLUP);
                    digitalWrite(_IOS2,LOW);
                    break;
                case DIGITAL_OUT:
                    pinMode(_IO2,OUTPUT);
                    digitalWrite(_IOS2,HIGH);
                    break;
                case ANALOG_IN:
                    digitalWrite(_IOS2,LOW);
                    break;
                default:
                    break;
            }
            break;
        case 3:
            switch (mode) {
                case DIGITAL_IN:
                    pinMode(_IO3,INPUT);
                    digitalWrite(_IOS3,LOW);
                    break;
                case DIGITAL_IN_PULLUP:
                    pinMode(_IO3,INPUT_PULLUP);
                    digitalWrite(_IOS3,LOW);
                    break;
                case DIGITAL_OUT:
                    pinMode(_IO3,OUTPUT);
                    digitalWrite(_IOS3,HIGH);
                    break;
                case ANALOG_IN:
                    digitalWrite(_IOS3,LOW);
                    break;
                default:
                    break;
            }
            break;
        default:
            break;
    }

}

void MuxShield::digitalWriteMS(int mux, int chan, int val)
{
    int i;

    digitalWrite(_S3,LOW);                              //S3 here is LCLK
    digitalWrite(_OUTMD,HIGH);                          //set to output mode
    switch (mux) {
        case 1:
            _shiftReg1[chan] = val;                     //store value until updated again

            for (i=15; i>=0; i--) {
                digitalWrite(_S0,LOW);                  //S0 here is i/o1 _sclk
                digitalWrite(_IO1,_shiftReg1[i]);       //put value
                digitalWrite(_S0,HIGH);                 //lactch in value
            }
            break;
        case 2:
            _shiftReg2[chan] = val;                     //store value until updated again

            for (i=15; i>=0; i--) {
                digitalWrite(_S1,LOW);                  //S1 here is i/o2 _sclk
                digitalWrite(_IO2,_shiftReg2[i]);       //put value
                digitalWrite(_S1,HIGH);                 //lactch in value
            }
            break;
        case 3:
            _shiftReg3[chan] = val;                     //store value until updated again

            for (i=15; i>=0; i--) {
                digitalWrite(_S2,LOW);                  //S2 here is i/o3 _sclk
                digitalWrite(_IO3,_shiftReg3[i]);       //put value
                digitalWrite(_S2,HIGH);                 //lactch in value
            }
            break;
        default:
            break;
    }
    digitalWrite(_S3,HIGH);                     //latch in ALL values
    digitalWrite(_OUTMD,LOW);                   //Exit output mode

}

int MuxShield::digitalReadMS(int mux, int chan)
{
    digitalWrite(_OUTMD,LOW);   //Set outmode off (i.e. set as input mode)
    int val;
    switch (mux) {
        case 1:
            digitalWrite(_S0, (chan&1));
            digitalWrite(_S1, (chan&3)>>1);
            digitalWrite(_S2, (chan&7)>>2);
            digitalWrite(_S3, (chan&15)>>3);

            val = digitalRead(_IO1);
            break;
        case 2:
            digitalWrite(_S0, (chan&1));
            digitalWrite(_S1, (chan&3)>>1);
            digitalWrite(_S2, (chan&7)>>2);
            digitalWrite(_S3, (chan&15)>>3);

            val = digitalRead(_IO2);
            break;
        case 3:
            digitalWrite(_S0, (chan&1));
            digitalWrite(_S1, (chan&3)>>1);
            digitalWrite(_S2, (chan&7)>>2);
            digitalWrite(_S3, (chan&15)>>3);

            val = digitalRead(_IO3);
            break;
        default:
            break;
    }
    return val;
}

int MuxShield::analogReadMS(int mux, int chan)
{
    digitalWrite(_OUTMD,LOW);
    int val;

    digitalWrite(_S0, (chan&1));
    digitalWrite(_S1, (chan&3)>>1);
    digitalWrite(_S2, (chan&7)>>2);
    digitalWrite(_S3, (chan&15)>>3);

    switch (mux) {
        case 1:
            val = analogRead(_IO1);
            break;
        case 2:
            val = analogRead(_IO2);
            break;
        case 3:
            val = analogRead(_IO3);
            break;
        default:
            break;
    }
    return val;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.