template <uint8_t _muxCount, uint8_t _muxChannels, uint8_t _muxPins>
class Rox74HC40XX {
public:
Rox74HC40XX(){}
//****************START VOID begin********************************************
void begin(uint8_t ch1, uint8_t ch2, uint8_t ch3, int8_t ch4=-1){
if(_muxChannels<3 || _muxChannels>4){
delay(1000);
Serial.println("channel must be 3 or 4");
while(1);
}
if(_muxChannels==3 && _muxPins!=8){
delay(1000);
Serial.println("_muxPins must be 8");
while(1);
} else if(_muxChannels==4 && _muxPins!=16){
delay(1000);
Serial.println("_muxPins must be 16");
while(1);
}
channels[0] = ch1;
channels[1] = ch2;
channels[2] = ch3;
if(ch4!=-1 && _muxChannels==4){
channels[3] = ch4;
}
for(uint8_t i = 0 ; i < _muxChannels ; i++){
pinMode(channels[i], OUTPUT);
}
delay(10);
timeout = millis();
}
//****************END VOID begin********************************************
uint16_t getLength(){
return _muxCount*_muxPins;
}
//****************START void setSignalPin********************************************
// @n: the index of the mux
// @pin: the pin on the teensy connected to that mux' signal pin
// this method must be called for each mux
void setSignalPin(uint8_t n, uint8_t pin){
if(n < _muxCount){
signalPin[n] = pin;
pinMode(pin, INPUT);
}
}
//****************END void setSignalPin********************************************
// these analog multiplexers require a small delay between pin read
// so that their capacitor for each pin is charged/discharged
// since we don't want to use an actual delay() we use an elapsedMillis
// you can pass a value to this function in your sketch to change the
// number of milliseconds between each pin read.
bool update(uint8_t readInterval=1){
if(millis()-timeout >= readInterval){
readMux();
timeout = millis();
// return true when the mux has been read
// used for testing and to know when the mux has been read
return true;
}
return false;
}
uint16_t read(uint16_t n){
if(n < (_muxCount * totalPins)){
return values[n];
}
return 0;
}
uint16_t* getValues() {
return values;
}
private:
uint8_t currentChannel = 0;
uint8_t channels[_muxChannels];
uint8_t signalPin[_muxCount];
uint16_t values[_muxCount*_muxPins];
unsigned long timeout;
const uint16_t totalPins = (_muxCount*_muxPins);
//****************START void readMux********************************************
void readMux(){
for(uint8_t i = 0 ; i < _muxCount ; i++){
uint8_t index = (i*_muxPins) + currentChannel;
if(index < totalPins){
values[index] = analogRead(signalPin[i]);
}
}
// go to the next channel
currentChannel++;
if(currentChannel >= _muxPins){
currentChannel = 0;
}
// set the channel pins
for(uint8_t i=0 ; i < _muxChannels ; i++){
digitalWrite(channels[i], bitRead(currentChannel, i));
}
}
//****************END void readMux********************************************
};
template <uint8_t _muxCount>
class Rox74HC4067 : public Rox74HC40XX <_muxCount, 4, 16> {};
template <uint8_t _muxCount>
class Rox74HC4051 : public Rox74HC40XX <_muxCount, 3, 8> {};
template <uint8_t _muxCount>
class RoxANAMUX : public Rox74HC40XX <(_muxCount*2), 4, 16> {};
// MUX_TOTAL is the number of 74HC4067s that you have chained together
// if you have more than 1 then change it to that number.
#define MUX_TOTAL 1
Rox74HC4067 <MUX_TOTAL> mux;
#define PIN_S0 8
#define PIN_S1 9
#define PIN_S2 10
#define PIN_S3 11
#define PIN_SIG0 A0
// this is the pin of the 74HC4067 that we will read
#define PIN_TO_READ 0
// keep track of the previous value, while the library handles 10-bit values
// for this example we'll lower the resolution to 8-bits
// this is to avoid some of the noise since there's no smoothing in the library.
//uint8_t prev[16];
uint8_t prev = 0;
void setup(){
delay(100);
Serial.begin(9600);
Serial.println("Serial.begin");
// being the mux
mux.begin(PIN_S0, PIN_S1, PIN_S2, PIN_S3);
Serial.println("mux.begin");
// set what pin is the signal pin for the first mux
// the first argument is the index of the mux, second is the pin number
mux.setSignalPin(0, PIN_SIG0);
}
void loop(){
// read the mux
// this method should always be in your loop() function
// the update method has an option parameter which is the number of millis
// between each pin read, if you don't pass an argument it will read them
// every 1 millisecond
//mux.update();
// read each pin
// for(uint8_t i=0,n=mux.getLength();i<n;i++){
// // since the Rox74HC4067 doesn't smooth the values it just reads them raw
// // we'll only read one pin on this example
// if(i==PIN_TO_READ){
// uint8_t data = mux.read(i)>>2;
// if(data!=prev){
// prev = data;
// Serial.print("Mux pin ");
// Serial.print(i);
// Serial.print(" = ");
// Serial.print(data);
// }
// }
// // }
// bool upd = mux.update();
// Serial.print(upd);
// if (upd) {
// Serial.print(mux.read(0));
// }
mux.update();
for (byte i = 0; i < MUX_TOTAL; i++) {
// if (pots[i].update(muxes.read(i))) {
// MIDI.sendControlChange(i, pots[i].read(), MIDI_CHANNEL);
// }
Serial.print(mux.read(i));
}
// for (int i=0; i<5; i++) {
// int data = mux.read(i);
// prev[i] = data;
// }
// for (const int &n : prev) {
// Serial.print(n);
// Serial.println();
// }
// for(uint8_t i=0,n=mux.getLength();i<n;i++){
// since the Rox74HC4067 doesn't smooth the values it just reads them raw
// we'll only read one pin on this example
// if(i==PIN_TO_READ){
//uint8_t data = mux.read(i)>>2;
// if(data!=prev){
// prev = data;
// Serial.print("Mux pin ");
// Serial.print(i);
// Serial.print(" = ");
// Serial.println(data);
// }
// }
// for (int i=0; i<3; i++) {
// uint8_t data = mux.read(i);
// if (data!=prev[i]) {
// Serial.print("Ch");
// Serial.print(i);
// Serial.print(":");
// Serial.print(data);
// Serial.print( "prev:");
// Serial.print(prev[i]);
// Serial.println();
// prev[i] = data;
// }
//int valList[] = _values;
//Serial.print(valList[]);
// for (int i=0; i<3; i++) {
// Serial.print("Ch");
// Serial.print(i);
// Serial.print(":");
// Serial.print(mux.read(i));
// Serial.print(" ");
// }
// uint16_t* valList = mux.getValues();
// for (int i=0; i<16; i++) {
// mux.update();
// Serial.print(valList[i]);
// Serial.print(" ");
// }
//delay(50);
// }
// for (int i=0; i<3; i++) {
// mux.update();
// int data = mux.read(i);
// Serial.println(data);
// //if (data!=prev) {
// // prev = data;
// // Serial.print(i);
// // Serial.print(":");
// // Serial.print(data);
// // Serial.print(" ");
// //}
// Serial.println();
delay(50);
// }
}