alexandros
Well-known member
I'm building a modular synthesizer and I'm using Teensy 3.6 for the control interface. I'm using one 16-channel multiplexer which receives data from various 8-channel multiplexers. Each 8-channel multiplexer receives data from the potentiometers of the respective module. Things were working OK until I put 9 or 10 modules. That's when I started getting weird behavior.
I've broken down the code and below I'm trying to provide everything necessary (the active_modules array is declared in the original code and its values are set in another function that reads connections between modules. Since this feature is working I thought I shouldn't post it cause it will make the whole thing too big. The whole code is around 600 lines):
The problem I'm facing is that when I connect more than two modules, it seems that the middle "slave" multiplexer control pin (digital pin 7) is not responding, and the first potentiometer of each modules write values to the first and third array element, the second potentiometer to the second and fourth, the fifth potentiometer to the fifth and sevent, and the sixth potentiometer to the sixth and eighth. The third, fourth, seventh and eights potentiometers are not functioning at all.
If I use only two modules everything works fine.
This has been driving me crazy. Any help much appreciated.
Note: in the whole setup I'm also using input and output shift registers, one per module (74HC165 and 74HC595). The problem though appears in the multiplexer readings (at least for now...).
I've broken down the code and below I'm trying to provide everything necessary (the active_modules array is declared in the original code and its values are set in another function that reads connections between modules. Since this feature is working I thought I shouldn't post it cause it will make the whole thing too big. The whole code is around 600 lines):
Code:
#define BAUDRATE 57600
// number of control pins the master multiplexers have (no accumulation for more than one mux used)
// for a 16-channel mux it's 4 (2^4 = 16)
const int num_master_ctl_pins = 4;
// the next two arrays will have their elements calculated in the setup function
// and they will be used in the read_pots() function to set the control pins of the master multiplexers
int master_ctl_pins[num_master_ctl_pins];
int master_ctl_values[num_master_ctl_pins];
// number of control pins the slave multiplexers have (no accumulation for more than one mux used)
// for an 8-channel mux it's 3 (2^3 = 8)
const int num_slave_ctl_pins = 3;
// the next two arrays will have their elements calculated in the setup function
// and they will be used in the read_pots() function to set the control pins of the slave multiplexers
int slave_ctl_pins[num_slave_ctl_pins];
int slave_ctl_values[num_slave_ctl_pins];
// variable to hold the total number of potentiometers which will be calculated in the setup function
int total_pots = 0;
// pointer to create an array with values that will be used for smoothing
// its size is calculated in the setup() function and it contains one element per potentiometer
float *smoothedVals;
void setup() {
// find the greatest number of modules between the two master multiplexers
int greatest_num_of_slave_mux = 0;
for(int i = 0; i < num_of_master_mux; i++) greatest_num_of_slave_mux = max(greatest_num_of_slave_mux, num_of_slave_mux[i]);
// total_pots and smoothedVals array
for(int i = 0; i < num_of_master_mux; i++){
for(int j = 0; j < greatest_num_of_slave_mux; j++)
total_pots += num_of_pots[i][j];
}
smoothedVals = new float [total_pots];
// set multiplexers control pins and values
for(int i = 0; i < num_master_ctl_pins; i++){
master_ctl_values[i] = pow(2, (i + 1)) - 1;
// master multiplexers have their control pins wired to digital pins 2 to 5
master_ctl_pins[i] = (num_master_ctl_pins - i) + 1;
pinMode(master_ctl_pins[i], OUTPUT);
}
for(int i = 0; i < num_slave_ctl_pins; i++){
slave_ctl_values[i] = pow(2, (i + 1)) - 1;
// slave multiplexers have their control pins wired to digital pins 6 to 8
slave_ctl_pins[i] = (num_slave_ctl_pins - i) + 5;
pinMode(slave_ctl_pins[i], OUTPUT);
}
// open the serial port
Serial.begin(BAUDRATE);
}
// function to read potentiometers of active modules
void read_pots(){
// set local index to global index's current value
int local_index = ndx;
// set row index for 2D array multiple pots
int pot_index = 0;
int module_index = 0;
//static byte smooth_index = 0;
// run througn all master multiplexers
for(int master_mux = 0; master_mux < num_of_master_mux; master_mux++){
// run through all slave multiplexers
for(int slave_mux = 0; slave_mux < num_of_slave_mux[master_mux]; slave_mux++){
// if this module is active, store its index, the number of bytes to expect
// and a 0 to denote that the following values are potentiometer values
// and route its output to its master multiplexer
// activity of modules is being stored in the check_connections function
if(active_modules[module_index]){
transfer_data[local_index++] = module_index;
transfer_data[local_index++] = (num_of_pots[master_mux][slave_mux] * 2) + 1;
transfer_data[local_index++] = 0;
// set the control pins of the current master multiplexer
for(int i = 0; i < num_master_ctl_pins; i++)
digitalWrite(master_ctl_pins[i], (slave_mux & master_ctl_values[i]) >> i);
}
// run through the pins used on each slave multiplexer
// the active module test needs to be separate here in order to be able
// to increment the row_index variable at every iteration of the loop below
for(int pot = 0; pot < num_of_pots[master_mux][slave_mux]; pot++){
// if this module is active store the values of its potentiometers
if(active_modules[module_index]){
// set the control pins of the current slave multiplexer
for(int i = 0; i < num_slave_ctl_pins; i++)
digitalWrite(slave_ctl_pins[i], (pot & slave_ctl_values[i]) >> i);
// read the corresponding analog pin of the Teensy
int pot_val = analogRead(master_mux);
// smooth out the analog reading
int smoothed = smooth(pot_val, pot_index);
// clip the values for a more unified result
if(smoothed > CLIP) smoothed = CLIP;
// and store the smoothed value to the transfer_data array
transfer_data[local_index++] = smoothed & 0x007f;
transfer_data[local_index++] = smoothed >> 7;
}
pot_index++; // update the 2D array row index anyway
}
// the module index is independent of activity as well, it should always increment
module_index++;
}
}
ndx = local_index;
}
void loop() {
ndx = 1;
check_switches();
// write data to the serial port, if there is any activity
if(ndx > 1) Serial.write(transfer_data, ndx);
}
The problem I'm facing is that when I connect more than two modules, it seems that the middle "slave" multiplexer control pin (digital pin 7) is not responding, and the first potentiometer of each modules write values to the first and third array element, the second potentiometer to the second and fourth, the fifth potentiometer to the fifth and sevent, and the sixth potentiometer to the sixth and eighth. The third, fourth, seventh and eights potentiometers are not functioning at all.
If I use only two modules everything works fine.
This has been driving me crazy. Any help much appreciated.
Note: in the whole setup I'm also using input and output shift registers, one per module (74HC165 and 74HC595). The problem though appears in the multiplexer readings (at least for now...).