1

I currently connected 5 sensor via a multiplexer (I must connect them to a multiplexer because they are I2C devices but they cannot been allocate more then 2 addresses so I use a multiplexer to solve the addressing problem).

However the sample rate is a shame , it is about 6.5Hz . I wish I could improve the sample rate by using some tricks. In my loop() function, multiplexer will loop through channel 0-4 , and read each of these channel's sensor value and print it by using Serial.print()

Is there any tricks I could use to improve my sampling rate faster ? Thanks...

Here is my multiplexer class :

class MUX {
public:
//mux control pins:
int s0 = 22;
int s1 = 24;
int s2 = 26;
int s3 = 28;

//SIG pin (not necessary WHEN sig is connect to 5V)
//int SIG_pin = 0;

//array to store channel :: muxChannel[channel numbers ][4 digit channel representation]
int muxChannel[16][4] = {
  {0, 0, 0, 0}, //channel 0
  {1, 0, 0, 0}, //channel 1
  {0, 1, 0, 0}, //channel 2
  {1, 1, 0, 0}, //channel 3
  {0, 0, 1, 0}, //channel 4
  {1, 0, 1, 0}, //channel 5
  {0, 1, 1, 0}, //channel 6
  {1, 1, 1, 0}, //channel 7
  {0, 0, 0, 1}, //channel 8
  {1, 0, 0, 1}, //channel 9
  {0, 1, 0, 1}, //channel 10
  {1, 1, 0, 1}, //channel 11
  {0, 0, 1, 1}, //channel 12
  {1, 0, 1, 1}, //channel 13
  {0, 1, 1, 1}, //channel 14
  {1, 1, 1, 1} //channel 15
};

void setupMux() {
  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  pinMode(s3, OUTPUT);

  digitalWrite(s0, LOW);
  digitalWrite(s1, LOW);
  digitalWrite(s2, LOW);
  digitalWrite(s3, LOW);
  Serial.println(F("Multiplexer initialized"));
}

void selectChannel(int channel) {
  int controlPin[] = {s0, s1, s2, s3};
  for (int i = 0; i < 4; i++) {
    digitalWrite(controlPin[i], muxChannel[channel][i]);
  }
}
  • What is the baud rate for the serial interface? Have you considered using millis() to time your code and see where most of the time is spent? – fuenfundachtzig May 9 '15 at 15:07
  • You may consider changing the i2c bus speed. Here is a forum post covering the steps forum.arduino.cc/index.php?topic=16793.0 – portforwardpodcast May 11 '15 at 12:42
  • Thanks guys , I've speed up my baud rate and it really helps , I also use Robert's proposal , help as well :) – Yank May 12 '15 at 0:26
2

It's hard to offer much more than speculation without knowing more about the sensors and your current code, but here is one possibility:

If the bulk of your loop time is the sum of the conversion times, is it possible to cycle through the sensors twice, once to start each conversion (so they will convert nearly simultaneously), wait one conversion-time (or for the first sensor to complete), then cycle through them again to read back each converted value?

for each sensor,
  setup mux;
  send start conversion command;
end

for each sensor,
  setup mux;
  while conversion not done,
    ;  // wait
  read and store value;
end

For 16 sensors and assuming the conversion time the majority of the time spent, that could speed your sample rate to ~100Hz. Expect maybe half of that, since mux-setup and communication times are probably not negligible.

1

The technique suggested by @JRobert (starting all the conversions in one loop, then running another loop to wait for completions and read results) looks reasonable.

Here are a couple of ways to shorten the code shown in the question:

First, instead of four int declarations to set the value of s0 ... s3, use an enum. An enum is used to declare integer constants.

enum { s0 = 22, s1 = 24, s2 = 26, s3 = 28};

Second, don't bother with the lengthy, tedious, and unnecessary muxChannel array. Delete the declaration of muxChannel and replace selectChannel with the following:

void selectChannel(int channel) {
  int controlPin[] = {s0, s1, s2, s3};
  for (int i = 0; i < 4; i++) {
    digitalWrite(controlPin[i], channel & 1);
    channel /= 2;
  }
}

The expression channel & 1 picks off the least-significant-bit of channel. The statement channel /= 2; divides channel by 2, which moves the next bit of channel into place for output. You could instead say channel >>= 1; or channel = channel/2;, etc. if you prefer.

You might also look closely at your sensor boards to see if there is any way to add jumpers to get another bit or two of I2C device addressing, allowing you to avoid multiplexing.

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.