This was originally posted in Teensy's forum, as I'm using a Teensy in this specific project, but I got no answers there (it's been there for a few days), so though of posting here (the code is 100% Arduino).
I'm trying to eliminate some noise I get in the analog pins of a Teensy 3.1 by writing this code
#define SMOOTH 100
const byte rows = 3;
const byte cols = SMOOTH;
int last_col = SMOOTH - 1;
unsigned int pots[rows][cols];
const byte num_of_data = (rows * 2) + 1;
byte transfer_data[num_of_data];
unsigned int smooth(int row_index)
{
unsigned int smoothed;
unsigned long accumulate;
// accumulate analog readings
for(int i = 0; i < SMOOTH; i++)
accumulate += pots[row_index][i];
// divide readings sum by the number of stored values
smoothed = accumulate / SMOOTH;
return smoothed;
}
void setup()
{
for(int i = 0; i < rows; i++){
for(int j = 0; j < cols; j++){
pots[i][j] = 0;
}
}
analogReadResolution(13);
Serial.begin(115200);
}
void loop()
{
transfer_data[0] = 0xc0;
int index = 1;
for(int i = 0; i < rows; i++){
for(int j = 0; j < last_col; j++) pots[i][j] = pots[i][j + 1];
pots[i][last_col] = analogRead(i);
unsigned int smoothed = smooth(i);
transfer_data[index++] = smoothed & 0x007f;
transfer_data[index++] = smoothed >> 7;
}
Serial.write(transfer_data, num_of_data);
}
which works fine. But when I put it in a greater project (the version above is for testing only), I get the following strange behavior. The first potentiometer is being read fine, but all the rest have their resolution reduced according to the number of samples I take (the SMOOTH macro). If I take 2 samples, the maximum value the pots give is 4095. If I take 3 samples, it's 2730. If I take 4, it's 2047 etc. If I take 1 sample it's 8191, as it should (13-bit resolution).
I have to mention that in the greater project I'm using multiplexers. A main multiplexer is controlling other multiplexers where the pots are wired.
Posting part of the code of the greater project.
Global variables used for the analog pins are the following
#define MASTER_CONTROL0 5
#define MASTER_CONTROL1 4
#define MASTER_CONTROL2 3
#define MASTER_CONTROL3 2
#define SLAVE_CONTROL0 8
#define SLAVE_CONTROL1 7
#define SLAVE_CONTROL2 6
#define SMOOTH 40
// set global variables for multiplexers
// master multiplexers controlling the multiplexers of each module
const byte num_of_master_mux = 1;
// number of slave multiplexers
int num_of_slave_mux[num_of_master_mux] = {3};
// two dimensional array to hold number of pins used on each slave multiplexer
// rows = num_of_master_mux, columns = greatest number in num_of_slave_mux array
int num_of_pots[num_of_master_mux][3] = { { 7, 4, 1 } };
const int total_pots = 12; // sum of elements of num_of_pots
// array to store multiple readings of each knob for smoothing
unsigned int multiple_pots[total_pots][SMOOTH];
// last element index of each row of the two dimensional array
// just so that you don't need to subtract one from SMOOTH in each loop
int last_col = SMOOTH - 1;
The smoothing function is the same. It's this
unsigned int smooth(int row_index)
{
unsigned int smoothed;
unsigned long accumulate;
// accumulate analog readings
for(int i = 0; i < SMOOTH; i++)
accumulate += multiple_pots[row_index][i];
// divide readings sum by the number of stored values
smoothed = accumulate / SMOOTH;
return smoothed;
}
and the for loop inside void loop where I read the pots, is this
transfer_data[0] = 0xc0; // denote start of data stream
int index = 1; // transfer data array index offset
// read potentiometers
int row_index = 0;
// run througn all master multiplexers
for(int master_mux = 0; master_mux < num_of_master_mux; master_mux++){
// first move the elements of current row one position to the left so we can add the new value at the end
for(int i = 0; i < last_col; i++) multiple_pots[row_index][i] = multiple_pots[row_index][i + 1];
// run through all slave multiplexers
for(int slave_mux = 0; slave_mux < num_of_slave_mux[master_mux]; slave_mux++){
digitalWrite(MASTER_CONTROL0, (slave_mux&15)>>3);
digitalWrite(MASTER_CONTROL1, (slave_mux&7)>>2);
digitalWrite(MASTER_CONTROL2, (slave_mux&3)>>1);
digitalWrite(MASTER_CONTROL3, (slave_mux&1));
// run through the pins used on each slave multiplexer
for(int pot = 0; pot < num_of_pots[master_mux][slave_mux]; pot++){
digitalWrite(SLAVE_CONTROL0, (pot&7)>>2);
digitalWrite(SLAVE_CONTROL1, (pot&3)>>1);
digitalWrite(SLAVE_CONTROL2, (pot&1));
// store new reading to the last element of pots row
multiple_pots[row_index][last_col] = analogRead(master_mux);
// call the smoothing function
unsigned int smoothed = smooth(row_index);
// and store the smoothed value to the transfer_data array
transfer_data[index++] = smoothed & 0x007f;
transfer_data[index++] = smoothed >> 7;
row_index++;
}
}
}
And finally I call Serial.write to write that data along with other stuff. Adding delayMicroseconds doesn't change anything. I can't find why is that, can anyone help? I'm getting the data either on OS X 10.8.5 or on an Odroid-U3, in Pd-0.46.
Thanks