4067 Multiplexer code question

Final test !

Let’s assume we now want to have 4 (four) input channels.

const byte muxChannel[NUM_INPUTS][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   <——<<<<
};

What needs to be changed throughout the sketch to make this happen ? :thinking:

Make these changes to see if they work.

#define NUM_INPUTS                     4
//log the new value of the selected analog
      switch (muxAddress)
      {
        //****************
        case 0:
          {
            muxValue = map(muxValue, 0, 1023, -70, 6);

            Serial.print("Value at channel ");
            Serial.print(muxAddress);
            Serial.print(" is : ");
            Serial.println(muxValue);
          }
          break;

        //****************
        case 1:
          {
            muxValue = map(muxValue, 0, 1023, 10, 100);

            Serial.print("Value at channel ");
            Serial.print(muxAddress);
            Serial.print(" is : ");
            Serial.println(muxValue);
          }
          break;

        //****************
        case 2:
          {
            muxValue = map(muxValue, 0, 1023, 500, -50);

            Serial.print("Value at channel ");
            Serial.print(muxAddress);
            Serial.print(" is : ");
            Serial.println(muxValue);
          }
          break;
          //****************
        case 3:
          {
            muxValue = map(muxValue, 0, 1023, 0, 1000);

            Serial.print("Value at channel ");
            Serial.print(muxAddress);
            Serial.print(" is : ");
            Serial.println(muxValue);
          }
          break;


      } //END of   switch/case
    }

full code:

//https://forum.arduino.cc/t/4067-multiplexer-code-question/1019084

//********************************************^************************************************
//  XXXXXXXXXXXXXXXXX.ino
//
//
//  Version   YY/MM/DD     Comments
//  =======   ========     ========================================================
//  1.04      22/08/04     Running code
//
//********************************************^************************************************

#define ENABLED                        true
#define DISABLED                       false

#define NUM_INPUTS                     4

//                                     s0 s1  s2  s3
const byte addressPin[]              = {8, 9, 10, 11};

const byte muxChannel[NUM_INPUTS][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
};

const byte heartbeatLED       = 13;

//Mux in "SIG" pin
const byte  SIG_pin           = A0;

boolean sampleFlag            = DISABLED;

byte muxAddress;
byte hysteresis               = 20; //whatever is needed

int muxValue;
int lastValue[NUM_INPUTS];

//timing stuff
unsigned long heartbeatMillis;
unsigned long readMuxMillis;
unsigned long settlingMillis;

//********************************************^************************************************
void setup()
{
  Serial.begin(115200);

  pinMode(heartbeatLED, OUTPUT);

  for (byte x = 0; x <= 3; x++)
  {
    pinMode(addressPin[x], OUTPUT);
    digitalWrite(addressPin[x], LOW);
  }

} //END of   setup()

//********************************************^************************************************
void loop()
{
  checkHeartbeatTIMER();

  checkReadMuxTIMER();

  checkSettlingTIMER();

  //*********************************
  // other non blocking code goes here
  //*********************************

} //END of    loop()


//********************************************^************************************************
void checkHeartbeatTIMER()
{
  //*********************************                                heartbeat TIMER
  //is it time to toggle the heartbeatLED ?
  if (millis() - heartbeatMillis >= 500ul)
  {
    //restart this TIMER
    heartbeatMillis = millis();

    //toggle the heartbeatLED
    digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
  }

} //END of   checkHeartbeatTIMER()


//********************************************^************************************************
void checkReadMuxTIMER()
{
  //*********************************                                readMux TIMER
  //is it time to read the next mux analog ?
  if (millis() - readMuxMillis >= 100ul)
  {
    //restart this TIMER
    readMuxMillis = millis();

    //send the new address to the CD4067 mux
    for (byte i = 0; i < 4; i ++)
    {
      digitalWrite(addressPin[i], muxChannel[muxAddress][i]);
    }

    //enable the analog settling TIMER
    sampleFlag = ENABLED;

    //restart the analog settling TIMER
    settlingMillis = millis();
  }

} //END of   checkReadMuxTIMER()


//********************************************^************************************************
void checkSettlingTIMER()
{
  //*********************************                                settling TIMER
  //if this TIMER is enabled, has this it expired ?
  if (sampleFlag == ENABLED && millis() - settlingMillis >= 10ul)
  {
    //we are now finished with this analog settling TIMER
    sampleFlag = DISABLED;

    //read the stabilized analog
    muxValue = analogRead(SIG_pin);

    //has analog value changed more than the hysteresis amount ?
    if (abs(lastValue[muxAddress] - muxValue) > hysteresis)
    {
      //update to the new value
      lastValue[muxAddress] = muxValue;

      //log the new value of the selected analog
      switch (muxAddress)
      {
        //****************
        case 0:
          {
            muxValue = map(muxValue, 0, 1023, -70, 6);

            Serial.print("Value at channel ");
            Serial.print(muxAddress);
            Serial.print(" is : ");
            Serial.println(muxValue);
          }
          break;

        //****************
        case 1:
          {
            muxValue = map(muxValue, 0, 1023, 10, 100);

            Serial.print("Value at channel ");
            Serial.print(muxAddress);
            Serial.print(" is : ");
            Serial.println(muxValue);
          }
          break;

        //****************
        case 2:
          {
            muxValue = map(muxValue, 0, 1023, 500, -50);

            Serial.print("Value at channel ");
            Serial.print(muxAddress);
            Serial.print(" is : ");
            Serial.println(muxValue);
          }
          break;
          //****************
        case 3:
          {
            muxValue = map(muxValue, 0, 1023, 0, 1000);

            Serial.print("Value at channel ");
            Serial.print(muxAddress);
            Serial.print(" is : ");
            Serial.println(muxValue);
          }
          break;


      } //END of   switch/case
    }

    //prepare for the new/next mux address
    muxAddress++;

    //have we read all the inputs ?
    if (muxAddress > NUM_INPUTS - 1)
    {
      //back to the first address
      muxAddress = 0;
    }
  }

} //END of   checkSettlingTIMER()


//********************************************^************************************************

If your new code changes worked then you passed !

:+1:

image

On to the next project.
:smiley:

1 Like

worked like a charm!
Thanks for all your help!

2 Likes

Always write your sketches with expandability in mind.

Your switch/case amounts to using code instead of arrays.

muxValue and muxAddress are global variables, so all four cases are basically the same.

Any time you have four blocks of code that are the same except for some constants, you should think about using arrays.

If you made a mistake or changed your or added more channels, you would have only one block of code to search for errors in or to make edits on. And adding a channel just means adding out to the arrays.

I think it makes the code any harder to read - if only because the reader is forced to look at each case to see if there is any difference...

Put these array declarations wherever you want, right before the code that does the work is OK, some would put this, well, elsewhere, global or at the very beginning of the function in which they are needed:

 const int lowEnd[] = {-70, 10, 500, 0};
 const int highEnd[] = {6, 100, -50, 1000};

Then the five lines of code supplant your switch/case.

       muxValue = map(muxValue, 0, 1023, lowEnd[muxAddress], highEnd[muxAddress]);

       Serial.print("Value at channel ");
       Serial.print(muxAddress);
       Serial.print(" is : ");
       Serial.println(muxValue);

HTH

a7

1 Like

Hooray for arrays, however, I’ve found over the years that new users do best learning arrays a bit later in the learning process.


Arrays do have a tendency to hide, from new learners, what is happening.

Yes, I agree that arrays are a big mouthful when they hit.

But @hk_jh was using, or at least being expose to, multi-dimensional arrays and, as far as I could tell, getting it, so.

a7

Assuming I am using all the 16 inputs of the mux and I would like to read another 3 analog inputs not via the multiplexer, rather via the other available analog pins - how can I do so?

edit:

Here is how I changed the code:
It seems to work some how but I'm not sure it is best solution

#define ENABLED                        true
#define DISABLED                       false

#define NUM_INPUTS                     5

//                                     s0 s1  s2  s3
const byte addressPin[]              = {8, 9, 10, 11};

const byte muxChannel[NUM_INPUTS][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
};

// verify non blocking code//
const byte heartbeatLED       = 13;

//Mux in "SIG" pin
const byte  SIG_pin           = A0;

//Others analog pin inputs
const byte otherSIG_pin[] = {A1, A2, A3};

int sigValue;
int lastValue_other[3];

//mapping values other analog inputs      ch0  ch1 ch2  
const int lowEnd_otherInputs[] = {-70, 10, 500};
const int highEnd_otherInputs[] = {6, 100, -50};


boolean sampleFlag            = DISABLED;

byte muxAddress;
byte filter               = 10; //whatever is needed

int muxValue;
int lastValue[NUM_INPUTS];

//mapping values      ch0  ch1 ch2  ch3 ch4
const int lowEnd[] = {-70, 10, 500, 0, 0};
const int highEnd[] = {6, 100, -50, 1000, 1023};

//timing stuff//
unsigned long heartbeatMillis;
unsigned long readMuxMillis;
unsigned long settlingMillis;
unsigned long readSigMillis;

//********************************************^************************************************
void setup()
{
  Serial.begin(115200);

  pinMode(heartbeatLED, OUTPUT);

  for (byte x = 0; x <= 3; x++)
  {
    pinMode(addressPin[x], OUTPUT);
    digitalWrite(addressPin[x], LOW);
  }

} 

void loop()
{
  checkHeartbeatTIMER();

  checkReadMuxTIMER();

  checkSettlingTIMER();

  otherAnalogInputs();

 

} 


//// functions ////
void checkHeartbeatTIMER()
{
  //*********************************                                heartbeat TIMER
  //is it time to toggle the heartbeatLED ?
  if (millis() - heartbeatMillis >= 500ul)
  {
    //restart this TIMER
    heartbeatMillis = millis();

    //toggle the heartbeatLED
    digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
  }

} //END of   checkHeartbeatTIMER()




void checkReadMuxTIMER()
{
  //*********************************                                readMux TIMER
  //is it time to read the next mux analog ?
  if (millis() - readMuxMillis >= 100ul)
  {
    //restart this TIMER
    readMuxMillis = millis();

    //send the new address to the CD4067 mux
    for (byte i = 0; i < 4; i ++)
    {
      digitalWrite(addressPin[i], muxChannel[muxAddress][i]);
    }

    //enable the analog settling TIMER
    sampleFlag = ENABLED;

    //restart the analog settling TIMER
    settlingMillis = millis();
  }

} //END of   checkReadMuxTIMER()



void checkSettlingTIMER()
{
  //*********************************                                settling TIMER
  //if this TIMER is enabled, has this it expired ?
  if (sampleFlag == ENABLED && millis() - settlingMillis >= 10ul)
  {
    //we are now finished with this analog settling TIMER
    sampleFlag = DISABLED;

    //read the stabilized analog
    muxValue = analogRead(SIG_pin);

    //has analog value changed more than the filter amount ?
    if (abs(lastValue[muxAddress] - muxValue) > filter)
    {
      //update to the new value
      lastValue[muxAddress] = muxValue;

      //log the new value of the selected analog
      muxValue = map(muxValue, 0, 1023, lowEnd[muxAddress], highEnd[muxAddress]);

       Serial.print("Value at channel ");
       Serial.print(muxAddress);
       Serial.print(" is : ");
       Serial.println(muxValue);
    }

    //prepare for the new/next mux address
    muxAddress++;

    //have we read all the inputs ?
    if (muxAddress > NUM_INPUTS - 1)
    {
      //back to the first address
      muxAddress = 0;
    }
  }

} //END of   checkSettlingTIMER()


//********************************************^************************************************


void otherAnalogInputs () {
  for (int i = 0; i < 3; i++){
    
  if (millis() - readSigMillis >= 100ul)
  {
     readSigMillis = millis();
    //read the stabilized analog
    sigValue = analogRead(otherSIG_pin[i]);

    //has analog value changed more than the filter amount ?
    if (abs(lastValue_other[i] - sigValue) > filter)
    {
      //update to the new value
      lastValue_other[i] = sigValue;

      //log the new value of the selected analog
      sigValue = map(sigValue, 0, 1023, lowEnd_otherInputs[i], highEnd_otherInputs[i]);

       Serial.print("Value at channel ");
       Serial.print(i+NUM_INPUTS);
       Serial.print(" is : ");
       Serial.println(sigValue);
    }
}
  }
}

Just use analogRead().

You don't need to

 pinMode(A2, INPUT);

as that is the default, and then

 int reading = analogRead(A2);

Ppl like to give pins meaningful names

const byte voltageInputPin = A2;

and use voltageInputPin instead of A2.

Your code is already using

const byte  SIG_pin           = A0; 

for the multiplexer.

a7

To give some small credit, 'A0' is a more meaningful name than '0'.

Pet peeve.

What's wrong with my updated code at post #49

Is the fact I've added a new function to read the data from the other Analog inputs is the wrong way?

That you updated it. Please don't do that. It makes trash of the thread.

New code, new post. All the code.

a7

Ok, sorry.
I made a new post

That's good, but you actually made a new thread.

I have asked the moderator to fix our mistake.

a7

This is a following post to my previous post regarding using multiplexer

In addition to the reading from the 4067 multiplexer I would like to read another 3 or 4 analog inputs.

Here is the original code from the previous post using 4067 multiplexer:

//https://forum.arduino.cc/t/4067-multiplexer-code-question/1019084

//********************************************^************************************************
//  XXXXXXXXXXXXXXXXX.ino
//
//
//  Version   YY/MM/DD     Comments
//  =======   ========     ========================================================
//  1.04      22/08/04     Running code
//
//********************************************^************************************************

#define ENABLED                        true
#define DISABLED                       false

#define NUM_INPUTS                     3

//                                     s0 s1  s2  s3
const byte addressPin[]              = {8, 9, 10, 11};

const byte muxChannel[NUM_INPUTS][4] =
{
  {0, 0, 0, 0}, //channel 0
  {1, 0, 0, 0}, //channel 1
  {0, 1, 0, 0}, //channel 2
};

const byte heartbeatLED       = 13;

//Mux in "SIG" pin
const byte  SIG_pin           = A0;

boolean sampleFlag            = DISABLED;

byte muxAddress;
byte hysteresis               = 20; //whatever is needed

int muxValue;
int lastValue[NUM_INPUTS];

//timing stuff
unsigned long heartbeatMillis;
unsigned long readMuxMillis;
unsigned long settlingMillis;

//********************************************^************************************************
void setup()
{
  Serial.begin(115200);

  pinMode(heartbeatLED, OUTPUT);

  for (byte x = 0; x <= 3; x++)
  {
    pinMode(addressPin[x], OUTPUT);
    digitalWrite(addressPin[x], LOW);
  }

} //END of   setup()

//********************************************^************************************************
void loop()
{
  checkHeartbeatTIMER();

  checkReadMuxTIMER();

  checkSettlingTIMER();

  //*********************************
  // other non blocking code goes here
  //*********************************

} //END of    loop()


//********************************************^************************************************
void checkHeartbeatTIMER()
{
  //*********************************                                heartbeat TIMER
  //is it time to toggle the heartbeatLED ?
  if (millis() - heartbeatMillis >= 500ul)
  {
    //restart this TIMER
    heartbeatMillis = millis();

    //toggle the heartbeatLED
    digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
  }

} //END of   checkHeartbeatTIMER()


//********************************************^************************************************
void checkReadMuxTIMER()
{
  //*********************************                                readMux TIMER
  //is it time to read the next mux analog ?
  if (millis() - readMuxMillis >= 1000ul)
  {
    //restart this TIMER
    readMuxMillis = millis();

    //send the new address to the CD4067 mux
    for (byte i = 0; i < 4; i ++)
    {
      digitalWrite(addressPin[i], muxChannel[muxAddress][i]);
    }

    //enable the analog settling TIMER
    sampleFlag = ENABLED;

    //restart the analog settling TIMER
    settlingMillis = millis();
  }

} //END of   checkReadMuxTIMER()


//********************************************^************************************************
void checkSettlingTIMER()
{
  //*********************************                                settling TIMER
  //if this TIMER is enabled, has this it expired ?
  if (sampleFlag == ENABLED && millis() - settlingMillis >= 10ul)
  {
    //we are now finished with this analog settling TIMER
    sampleFlag = DISABLED;

    //read the stabilized analog
    muxValue = analogRead(SIG_pin);

    //has analog value changed more than the hysteresis amount ?
    if (abs(lastValue[muxAddress] - muxValue) > hysteresis)
    {
      //update to the new value
      lastValue[muxAddress] = muxValue;

      //log the new value of the selected analog
      switch (muxAddress)
      {
        //****************
        case 0:
          {
            muxValue = map(muxValue, 0, 1023, -70, 6);

            Serial.print("Value at channel ");
            Serial.print(muxAddress);
            Serial.print(" is : ");
            Serial.println(muxValue);
          }
          break;

        //****************
        case 1:
          {
            muxValue = map(muxValue, 0, 1023, 10, 100);

            Serial.print("Value at channel ");
            Serial.print(muxAddress);
            Serial.print(" is : ");
            Serial.println(muxValue);
          }
          break;

        //****************
        case 2:
          {
            muxValue = map(muxValue, 0, 1023, 500, -50);

            Serial.print("Value at channel ");
            Serial.print(muxAddress);
            Serial.print(" is : ");
            Serial.println(muxValue);
          }
          break;

      } //END of   switch/case
    }

    //prepare for the new/next mux address
    muxAddress++;

    //have we read all the inputs ?
    if (muxAddress > NUM_INPUTS - 1)
    {
      //back to the first address
      muxAddress = 0;
    }
  }

} //END of   checkSettlingTIMER()


//********************************************^************************************************

and here is my failure try to add non blocking reading from another 3 analog inputs in addition to the multiplexer:

#define ENABLED                        true
#define DISABLED                       false

#define NUM_INPUTS                     5

//                                     s0 s1  s2  s3
const byte addressPin[]              = {8, 9, 10, 11};

const byte muxChannel[NUM_INPUTS][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
};

// verify non blocking code//
const byte heartbeatLED       = 13;

//Mux in "SIG" pin
const byte  SIG_pin           = A0;

//Others analog pin inputs
const byte otherSIG_pin[] = {A1, A2, A3};

int sigValue;
int lastValue_other[3];

//mapping values other analog inputs      ch0  ch1 ch2  
const int lowEnd_otherInputs[] = {-70, 10, 500};
const int highEnd_otherInputs[] = {6, 100, -50};


boolean sampleFlag            = DISABLED;

byte muxAddress;
byte filter               = 10; //whatever is needed

int muxValue;
int lastValue[NUM_INPUTS];

//mapping values      ch0  ch1 ch2  ch3 ch4
const int lowEnd[] = {-70, 10, 500, 0, 0};
const int highEnd[] = {6, 100, -50, 1000, 1023};

//timing stuff//
unsigned long heartbeatMillis;
unsigned long readMuxMillis;
unsigned long settlingMillis;
unsigned long readSigMillis;

//********************************************^************************************************
void setup()
{
  Serial.begin(115200);

  pinMode(heartbeatLED, OUTPUT);

  for (byte x = 0; x <= 3; x++)
  {
    pinMode(addressPin[x], OUTPUT);
    digitalWrite(addressPin[x], LOW);
  }

} 

void loop()
{
  checkHeartbeatTIMER();

  checkReadMuxTIMER();

  checkSettlingTIMER();

  otherAnalogInputs();

 

} 


//// functions ////
void checkHeartbeatTIMER()
{
  //*********************************                                heartbeat TIMER
  //is it time to toggle the heartbeatLED ?
  if (millis() - heartbeatMillis >= 500ul)
  {
    //restart this TIMER
    heartbeatMillis = millis();

    //toggle the heartbeatLED
    digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
  }

} //END of   checkHeartbeatTIMER()




void checkReadMuxTIMER()
{
  //*********************************                                readMux TIMER
  //is it time to read the next mux analog ?
  if (millis() - readMuxMillis >= 100ul)
  {
    //restart this TIMER
    readMuxMillis = millis();

    //send the new address to the CD4067 mux
    for (byte i = 0; i < 4; i ++)
    {
      digitalWrite(addressPin[i], muxChannel[muxAddress][i]);
    }

    //enable the analog settling TIMER
    sampleFlag = ENABLED;

    //restart the analog settling TIMER
    settlingMillis = millis();
  }

} //END of   checkReadMuxTIMER()



void checkSettlingTIMER()
{
  //*********************************                                settling TIMER
  //if this TIMER is enabled, has this it expired ?
  if (sampleFlag == ENABLED && millis() - settlingMillis >= 10ul)
  {
    //we are now finished with this analog settling TIMER
    sampleFlag = DISABLED;

    //read the stabilized analog
    muxValue = analogRead(SIG_pin);

    //has analog value changed more than the filter amount ?
    if (abs(lastValue[muxAddress] - muxValue) > filter)
    {
      //update to the new value
      lastValue[muxAddress] = muxValue;

      //log the new value of the selected analog
      muxValue = map(muxValue, 0, 1023, lowEnd[muxAddress], highEnd[muxAddress]);

       Serial.print("Value at channel ");
       Serial.print(muxAddress);
       Serial.print(" is : ");
       Serial.println(muxValue);
    }

    //prepare for the new/next mux address
    muxAddress++;

    //have we read all the inputs ?
    if (muxAddress > NUM_INPUTS - 1)
    {
      //back to the first address
      muxAddress = 0;
    }
  }

} //END of   checkSettlingTIMER()


//********************************************^************************************************


void otherAnalogInputs () {
  for (int i = 0; i < 3; i++){
    
  if (millis() - readSigMillis >= 100ul)
  {
     readSigMillis = millis();
    //read the stabilized analog
    sigValue = analogRead(otherSIG_pin[i]);

    //has analog value changed more than the filter amount ?
    if (abs(lastValue_other[i] - sigValue) > filter)
    {
      //update to the new value
      lastValue_other[i] = sigValue;

      //log the new value of the selected analog
      sigValue = map(sigValue, 0, 1023, lowEnd_otherInputs[i], highEnd_otherInputs[i]);

       Serial.print("Value at channel ");
       Serial.print(i+NUM_INPUTS);
       Serial.print(" is : ");
       Serial.println(sigValue);
    }
}
  }
}

Where I'm wrong?

Thanks

I have merged the two topics.

Regards, Per

You've put the de-blocking or timing code within the for loop.

Trace it with your finger - you give the timed code three opportunities to fire, then you leave the function!

Place the for loop within the timing stuff. So the timing code decides whether it is time to read all the inputs, that is to say to run the for loop.

If you meant to have time between the reading of the first, second and third, you'll have to learn a bit more and restructure that function so that each time it is called it sees if it's time to read another input, it selects the next one and does so, and resets to 0 when it reaches the number of inputs you are managing. Three in this case.

HTH

a7

And this is something you can't do in a non-blocking code?

Here is my function for reading the other Analog inputs (this should be a non blocking code):


void otherAnalogInputs () {
  for (int i = 0; i < 3; i++){
    
  if (millis() - readSigMillis >= 100ul)
  {
     readSigMillis = millis();
    //read the stabilized analog
    sigValue = analogRead(otherSIG_pin[i]);

    //has analog value changed more than the filter amount ?
    if (abs(lastValue_other[i] - sigValue) > filter)
    {
      //update to the new value
      lastValue_other[i] = sigValue;

      //log the new value of the selected analog
      sigValue = map(sigValue, 0, 1023, lowEnd_otherInputs[i], highEnd_otherInputs[i]);

       Serial.print("Value at channel ");
       Serial.print(i+NUM_INPUTS);
       Serial.print(" is : ");
       Serial.println(sigValue);
    }
}
  }
}

What do you mean?

like that?

void otherAnalogInputs1 () {   
  if (millis() - readSigMillis >= 100ul)
  {
      for (int i = 0; i < 3; i++){
     readSigMillis = millis();
    //read the stabilized analog
    sigValue = analogRead(otherSIG_pin[i]);

    //has analog value changed more than the filter amount ?
    if (abs(lastValue_other[i] - sigValue) > filter)
    {
      //update to the new value
      lastValue_other[i] = sigValue;

      //log the new value of the selected analog
      sigValue = map(sigValue, 0, 1023, lowEnd_otherInputs[i], highEnd_otherInputs[i]);

       Serial.print("Value at channel ");
       Serial.print(i+NUM_INPUTS);
       Serial.print(" is : ");
       Serial.println(sigValue);
    }
}
  }
}

Can you elaborate on that matter?

Edit: Sry! I see that you had proposed the solution, I'll just not look at it too closely and assume you got it right... I should have put my finger on your post and carefully read it. :wink:

There was no need to post the function in question. All you did was make me waste time checking to see if you had changed anything. You had not. While we are at it, start using the Tools/Auto Format capability of the IDE to put your code into a standard format. Everyone will be able to read the code better, even you. It is good for spotting errors as it gives you code some visual structure.

I don't think you could have put your finger on the function and traced it. Mostly becuase you came back with questions. :expressionless:

You have understood the basic "free running loop" concept, but you have bungled the execution, at least with otherAnalogInputs(). I did not look at the other top level functions being called frequently from loop(). At a glance, it is exemplary.

You want to read three analog inputs periodically.

Let's go with the idea that you want to read all three at once, and do so every 100 milliseconds.

Now watch what happens in otherAnalogInputs() - my finger is on the code!

ENTER the function. This happens very frequently. Let us assume it is time to actually do anything, that is to say millis() has gotten 100 ms ahead of readSigMillis.

first iteration of the loop:

It is time to read otherSIG_pin[0]. Update readSigMillis. Get sigValue and process it.

second iteration of the loop: not time to do anything…

third iteration of the loop: not time to do anything…

EXIT the function.


Now for some good many calls to otherAnalogInputs(), nothing is done in any iteration as it is not yet time, that is to say millis() has not gotten 100 ms ahead of readSigMillis.

Do you see the problem? When that time has elapsed, we basically at the same point, the same thing happens. Result: only one read is ever done.

What I exactly suggest in reply #58 in code:

void otherAnalogInputs ()
{
  if (millis() - readSigMillis >= 100ul) {
    readSigMillis = millis();

    for (int i = 0; i < 3; i++) {

      //read the stabilized analog
      sigValue = analogRead(otherSIG_pin[i]);

      //has analog value changed more than the filter amount ?
      if (abs(lastValue_other[i] - sigValue) > filter) {
        //update to the new value
        lastValue_other[i] = sigValue;

        //log the new value of the selected analog
        sigValue = map(sigValue, 0, 1023, lowEnd_otherInputs[i], highEnd_otherInputs[i]);

        Serial.print("Value at channel ");
        Serial.print(i + NUM_INPUTS);
        Serial.print(" is : ");
        Serial.println(sigValue);
      }
    }
  }
}

Say it: if it is time to, read all three analog inputs.

I like to keep things from going too far off to the right indentation-wise, so in this case we should turn the question upside down, viz:

void otherAnalogInputs()
{
  // is it time to do the readings?
  if (millis() - readSigMillis < 100ul) return; // NO! we outta here

// yes, it is time, so:

  readSigMillis = millis();  //note time of readings

  for (int i = 0; i < 3; i++) {

    //read the stabilized analog
    sigValue = analogRead(otherSIG_pin[i]);

    //has analog value changed more than the filter amount ?
    if (abs(lastValue_other[i] - sigValue) > filter) {
      //update to the new value
      lastValue_other[i] = sigValue;

      //log the new value of the selected analog
      sigValue = map(sigValue, 0, 1023, lowEnd_otherInputs[i], highEnd_otherInputs[i]);

      Serial.print("Value at channel ");
      Serial.print(i + NUM_INPUTS);
      Serial.print(" is : ");
      Serial.println(sigValue);
    }
  }
}

So this will read all three more-or-less at once, at least realitive to being done every 100 ms.

I thought it possible that may have intended to leave 100 ms between the individual readings 0, 1 and 2. Obvsly this could be done in the function by making your own version of a for loop that took one step along 0, 1, 2, 0, 1, 2 &c. for each call of the function. If it was time to read and step.

HTH

a7