comparing an array of inputs

What I am trying to do is use an array to store the high/low values of 8 digital input pins. Then after a short time, say 250mS, check those pins again and see if they match. My goal is to make a mat that determines movement. I have several sensors that will operate like switches giving me 5V when inactive and 0V when activated. I am going to bring those values using digital read into an array and store them. Then wait the designated amount of time and compare them again. Any ideas on how i can do this?

I think you just have to save the values in two arrays do 8 compares (in a loop). Or, you can read the 8 pins directly and compare to the 8 values in the array.

And if you are just looking for any-difference or no-difference, you can break-out of the loop as soon as you find a mismatch, since there's no point in checking the remainder of the array once a difference is found.

There might be an easier way if you use a C++ vector, instead of a C-style array... But, it's been awhile since Ive done any "real C++".

Since they are digital inputs, you could use a bit field. If you use PORT programming and wire them to the right inputs, you can read all 8 pins at the same time. And compare them in one instruction. If they are different, an exclusive or tells you which bits have changed.

What TH posted only with more details:

You can keep the status of those 8 pins in a bit array, otherwise known as a byte.

You can use bitRead(), bitWrite(), bitSet() and bitClear() to work with the bits and/or the bitwise operators, the shifts and logic operations. All those are found here:

If you have a pattern 11111011 that changes to 11110111 then XOR the two and get 00001100 showing the bits that changed (the 1's in the result) and work it from there.

If you arrange which parts of the mat match which bits then bit position might be something you can use in your algorithm, relating spatial movement to bit movement.

Yes it requires knowing or learning bits and bit logic. Is using a variable-per-sensor array going to be easier because you don't have to learn bits? Well there's not all that much to bits and bit logic and by using those you can compare all 8 sensors in one operation while using arrays will require looping and extra variables.

If you are using an UNO then you can read all 8 sensors in 2 direct Port reads (search on Port Manipulation). All UNO Ports have some pins tied up by default. The MEGA2560 has some ports with all 8 pins (bits) open for use, you can read the whole mat in one operation.

Do some studying and ask questions before you choose a path, and you will be better prepared either way.

I made a mistake earlier, I actually need 16 inputs. can I still use the byte format? I am using a mega2560. I was hoping I could Just digital read all the inputs, subtract the two arrays, and then if the value was >0 increment a value. Im not a great programmer, and my education is in electronics not programming. Its just a final project before I graduate. I got everything done but the arrays. I seen this code and thought it would be good to use but can’t get it to work. This is what I was Trying. No need to laugh when you see it :smiley:

void sensorControlLoop(){
  
  unsigned long sensMillis = millis();
  long prevSensMillis = 0;
  long sensInterval = 1000;
  int n;
    int pinArray1[16];
    int pinArray2[16];
    pinArray1[0] = digitalRead(31);
    pinArray1[1] = digitalRead(32);
    pinArray1[2] = digitalRead(33);
    pinArray1[3] = digitalRead(34);
    pinArray1[4] = digitalRead(35);
    pinArray1[5] = digitalRead(36);
    pinArray1[6] = digitalRead(37);
    pinArray1[7] = digitalRead(38);
    pinArray1[8] = digitalRead(39);
    pinArray1[9] = digitalRead(40);
    pinArray1[10] = digitalRead(41);
    pinArray1[11] = digitalRead(42);
    pinArray1[12] = digitalRead(43);
    pinArray1[13] = digitalRead(44);
    pinArray1[14] = digitalRead(45);
    pinArray1[15] = digitalRead(46);
    
    if(sensMillis - prevSensMillis > sensInterval){
      pinArray2[0] = digitalRead(31);
      pinArray2[1] = digitalRead(32);
      pinArray2[2] = digitalRead(33);
      pinArray2[3] = digitalRead(34);
      pinArray2[4] = digitalRead(35);
      pinArray2[5] = digitalRead(36);
      pinArray2[6] = digitalRead(37);
      pinArray2[7] = digitalRead(38);
      pinArray2[8] = digitalRead(39);
      pinArray2[9] = digitalRead(40);
      pinArray2[10] = digitalRead(41);
      pinArray2[11] = digitalRead(42);
      pinArray2[12] = digitalRead(43);
      pinArray2[13] = digitalRead(44);
      pinArray2[14] = digitalRead(45);
      pinArray2[15] = digitalRead(46);
      
      if (array_cmp(pinArray1, pinArray2, 16, 16) == false){
        ++alarmCount;
        if(alarmCount==10){
          digitalWrite(alarmPin, HIGH);
         }
      }
      else{
        alarmCount = 0;
       }     
    }
}
 boolean array_cmp(int *pinArray1, int *pinArray2, int len_a, int len_b){
      int n;

      // if their lengths are different, return false
      if (len_a != len_b) return false;

      // test each element to be the same. if not, return false
      for (n=0;n<len_a;n++) if (pinArray1[n]!=pinArray2[n]) return false;

      //ok, if we have not returned yet, they are equal :)
      return true;
}void sensorControlLoop(){
  
  unsigned long sensMillis = millis();
  long prevSensMillis = 0;
  long sensInterval = 1000;
  int n;
    int pinArray1[16];
    int pinArray2[16];
    pinArray1[0] = digitalRead(31);
    pinArray1[1] = digitalRead(32);
    pinArray1[2] = digitalRead(33);
    pinArray1[3] = digitalRead(34);
    pinArray1[4] = digitalRead(35);
    pinArray1[5] = digitalRead(36);
    pinArray1[6] = digitalRead(37);
    pinArray1[7] = digitalRead(38);
    pinArray1[8] = digitalRead(39);
    pinArray1[9] = digitalRead(40);
    pinArray1[10] = digitalRead(41);
    pinArray1[11] = digitalRead(42);
    pinArray1[12] = digitalRead(43);
    pinArray1[13] = digitalRead(44);
    pinArray1[14] = digitalRead(45);
    pinArray1[15] = digitalRead(46);
    
    if(sensMillis - prevSensMillis > sensInterval){
      pinArray2[0] = digitalRead(31);
      pinArray2[1] = digitalRead(32);
      pinArray2[2] = digitalRead(33);
      pinArray2[3] = digitalRead(34);
      pinArray2[4] = digitalRead(35);
      pinArray2[5] = digitalRead(36);
      pinArray2[6] = digitalRead(37);
      pinArray2[7] = digitalRead(38);
      pinArray2[8] = digitalRead(39);
      pinArray2[9] = digitalRead(40);
      pinArray2[10] = digitalRead(41);
      pinArray2[11] = digitalRead(42);
      pinArray2[12] = digitalRead(43);
      pinArray2[13] = digitalRead(44);
      pinArray2[14] = digitalRead(45);
      pinArray2[15] = digitalRead(46);
      
      if (array_cmp(pinArray1, pinArray2, 16, 16) == false){
        ++alarmCount;
        if(alarmCount==10){
          digitalWrite(alarmPin, HIGH);
         }
      }
      else{
        alarmCount = 0;
       }     
    }
}
 boolean array_cmp(int *pinArray1, int *pinArray2, int len_a, int len_b){
      int n;

      // if their lengths are different, return false
      if (len_a != len_b) return false;

      // test each element to be the same. if not, return false
      for (n=0;n<len_a;n++) if (pinArray1[n]!=pinArray2[n]) return false;

      //ok, if we have not returned yet, they are equal :)
      return true;
}

This is the reference Code I was looking at and the address. http://forum.arduino.cc/index.php/topic,5157.0.html

boolean array_cmp(int *a, int *b, int len_a, int len_b){
      int n;

      // if their lengths are different, return false
      if (len_a != len_b) return false;

      // test each element to be the same. if not, return false
      for (n=0;n<len_a;n++) if (a[n]!=b[n]) return false;

      //ok, if we have not returned yet, they are equal :)
      return true;
}

int arr_a[] = {1, 4, 7, 1, 3};
      int arr_b[] = {1, 4, 7, 2, 3};

      if (array_cmp(arr_a, arr_b, 5, 5) == true){
            // do this if they are equal
      }else{
            // do this if they are different
      }

This is going to be a problem. Actually two problems.

  long prevSensMillis = 0;

Local variables get initialized every time the function is called. If you really want that value to persist between function calls, you have to declare it static. And, you might want to set prevSensMillis at some other point as well.

pwrbildr:
I made a mistake earlier, I actually need 16 inputs. can I still use the byte format? I am using a mega2560. I was hoping I could Just digital read all the inputs, subtract the two arrays, and then if the value was >0 increment a value. Im not a great programmer, and my education is in electronics not programming. Its just a final project before I graduate. I got everything done but the arrays. I seen this code and thought it would be good to use but can’t get it to work. This is what I was Trying. No need to laugh when you see it :smiley:

void sensorControlLoop(){

unsigned long sensMillis = millis();
 long prevSensMillis = 0;
 long sensInterval = 1000;
 int n;
   int pinArray1[16];
   int pinArray2[16];
   pinArray1[0] = digitalRead(31);
   pinArray1[1] = digitalRead(32);
   pinArray1[2] = digitalRead(33);
   pinArray1[3] = digitalRead(34);
   pinArray1[4] = digitalRead(35);
   pinArray1[5] = digitalRead(36);
   pinArray1[6] = digitalRead(37);
   pinArray1[7] = digitalRead(38);
   pinArray1[8] = digitalRead(39);
   pinArray1[9] = digitalRead(40);
   pinArray1[10] = digitalRead(41);
   pinArray1[11] = digitalRead(42);
   pinArray1[12] = digitalRead(43);
   pinArray1[13] = digitalRead(44);
   pinArray1[14] = digitalRead(45);
   pinArray1[15] = digitalRead(46);
   
   if(sensMillis - prevSensMillis > sensInterval){
     pinArray2[0] = digitalRead(31);
     pinArray2[1] = digitalRead(32);
     pinArray2[2] = digitalRead(33);
     pinArray2[3] = digitalRead(34);
     pinArray2[4] = digitalRead(35);
     pinArray2[5] = digitalRead(36);
     pinArray2[6] = digitalRead(37);
     pinArray2[7] = digitalRead(38);
     pinArray2[8] = digitalRead(39);
     pinArray2[9] = digitalRead(40);
     pinArray2[10] = digitalRead(41);
     pinArray2[11] = digitalRead(42);
     pinArray2[12] = digitalRead(43);
     pinArray2[13] = digitalRead(44);
     pinArray2[14] = digitalRead(45);
     pinArray2[15] = digitalRead(46);
     
     if (array_cmp(pinArray1, pinArray2, 16, 16) == false){
       ++alarmCount;
       if(alarmCount==10){
         digitalWrite(alarmPin, HIGH);
        }
     }
     else{
       alarmCount = 0;
      }    
   }
}
boolean array_cmp(int *pinArray1, int *pinArray2, int len_a, int len_b){
     int n;

// if their lengths are different, return false
     if (len_a != len_b) return false;

// test each element to be the same. if not, return false
     for (n=0;n<len_a;n++) if (pinArray1[n]!=pinArray2[n]) return false;

//ok, if we have not returned yet, they are equal :slight_smile:
     return true;
}void sensorControlLoop(){
 
 unsigned long sensMillis = millis();
 long prevSensMillis = 0;
 long sensInterval = 1000;
 int n;
   int pinArray1[16];
   int pinArray2[16];
   pinArray1[0] = digitalRead(31);
   pinArray1[1] = digitalRead(32);
   pinArray1[2] = digitalRead(33);
   pinArray1[3] = digitalRead(34);
   pinArray1[4] = digitalRead(35);
   pinArray1[5] = digitalRead(36);
   pinArray1[6] = digitalRead(37);
   pinArray1[7] = digitalRead(38);
   pinArray1[8] = digitalRead(39);
   pinArray1[9] = digitalRead(40);
   pinArray1[10] = digitalRead(41);
   pinArray1[11] = digitalRead(42);
   pinArray1[12] = digitalRead(43);
   pinArray1[13] = digitalRead(44);
   pinArray1[14] = digitalRead(45);
   pinArray1[15] = digitalRead(46);
   
   if(sensMillis - prevSensMillis > sensInterval){
     pinArray2[0] = digitalRead(31);
     pinArray2[1] = digitalRead(32);
     pinArray2[2] = digitalRead(33);
     pinArray2[3] = digitalRead(34);
     pinArray2[4] = digitalRead(35);
     pinArray2[5] = digitalRead(36);
     pinArray2[6] = digitalRead(37);
     pinArray2[7] = digitalRead(38);
     pinArray2[8] = digitalRead(39);
     pinArray2[9] = digitalRead(40);
     pinArray2[10] = digitalRead(41);
     pinArray2[11] = digitalRead(42);
     pinArray2[12] = digitalRead(43);
     pinArray2[13] = digitalRead(44);
     pinArray2[14] = digitalRead(45);
     pinArray2[15] = digitalRead(46);
     
     if (array_cmp(pinArray1, pinArray2, 16, 16) == false){
       ++alarmCount;
       if(alarmCount==10){
         digitalWrite(alarmPin, HIGH);
        }
     }
     else{
       alarmCount = 0;
      }    
   }
}
boolean array_cmp(int *pinArray1, int *pinArray2, int len_a, int len_b){
     int n;

// if their lengths are different, return false
     if (len_a != len_b) return false;

// test each element to be the same. if not, return false
     for (n=0;n<len_a;n++) if (pinArray1[n]!=pinArray2[n]) return false;

//ok, if we have not returned yet, they are equal :slight_smile:
     return true;
}




This is the reference Code I was looking at and the address. http://forum.arduino.cc/index.php/topic,5157.0.html


boolean array_cmp(int *a, int *b, int len_a, int len_b){
      int n;

// if their lengths are different, return false
      if (len_a != len_b) return false;

// test each element to be the same. if not, return false
      for (n=0;n<len_a;n++) if (a[n]!=b[n]) return false;

//ok, if we have not returned yet, they are equal :slight_smile:
      return true;
}

int arr_a = {1, 4, 7, 1, 3};
      int arr_b = {1, 4, 7, 2, 3};

if (array_cmp(arr_a, arr_b, 5, 5) == true){
            // do this if they are equal
      }else{
            // do this if they are different
      }

If you still have reasonable time then not panicking will serve you.

An unsigned int is 16 bits and with a MEGA2560 you can arrange those as the pins on two Ports and read them in two Port reads.

You can compare 2 different times using XOR of two unsigned ints. Unsigned ints because signed ints use the top bit as sign.

My oh my, you have an array compare function that includes the lengths of the arrays with logic on if they differ? But they should never differ in length, should they?

I see that you get as far as comparing arrays and if they are different, light up a led. Is that it? Is that all you need to do? That would be a blessing, just tell IF there was movement and not actually from where to where!

Without using Port reads this:

    pinArray1[0] = digitalRead(31);
    pinArray1[1] = digitalRead(32);
    pinArray1[2] = digitalRead(33);
    pinArray1[3] = digitalRead(34);
    pinArray1[4] = digitalRead(35);
    pinArray1[5] = digitalRead(36);
    pinArray1[6] = digitalRead(37);
    pinArray1[7] = digitalRead(38);
    pinArray1[8] = digitalRead(39);
    pinArray1[9] = digitalRead(40);
    pinArray1[10] = digitalRead(41);
    pinArray1[11] = digitalRead(42);
    pinArray1[12] = digitalRead(43);
    pinArray1[13] = digitalRead(44);
    pinArray1[14] = digitalRead(45);
    pinArray1[15] = digitalRead(46);

can change to this:

// up near the top of the code, declaring 2 global variables
  unsigned int matBits;
  unsigned int lastBits = 0xFFFF; // 0x denotes hexadecimal notation. 0xFFFF is all bits set
....
then we go down into loop() for the reads
....
  for ( byte i = 31; i < 47; i++ ) 
  {
    bitWrite( matBits, i - 31, digitalRead( i ) );
  }

  if ( matBits != lastBits )
  {
    then light the alarm led or compare the bits to find out which changed, etc
  }

  lastBits = matBits;
  delay( 250 );
} // end of loop()

Magic part. You only read the pins once per time through loop. Then you compare that read to the last time through loop. And maybe you check more often than 4 times a second which the delay( 250 ) is for, so perhaps no delay() and get immediate response to all changes which is better BTW.

Coding loop() to handle what is going on NOW with variables holding states determined in PAST executions of loop() affecting how results from NOW are used is how to code for REAL TIME. In PC code this is often done by placing a while-loop in the main code and it is generally referred to as the MAIN LOOP. I go back to the 70’s there but it’s probably as old as operating systems.

You are a EE major? Have you gotten to logic gates yet? The software logical operations are equivalent to logic gates. The bitwise logical operations are equivalent to working with arrays of logic gates which actually on the chip level THEY ARE.

What I am trying to do is compare the two sets of bits and see if there is movement. As long as there is movement its fine. But if no movement is detected over a given period of time, such as 10 seconds, light up the LED. Im not sure I understand what the for loop is doing. Why subtract 31 from k? Doesnt k hold the value of the pins being used?

Here is a for-next loop to read the pins into 16-bit unsigned int matBits.

  for ( byte i = 31; i < 47; i++ ) 
  {
    bitWrite( matBits, i - 31, digitalRead( i ) );
  }

Here is a comparison between the current pins states and the previous states.

  if ( matBits == lastBits )
  {
    then no change... 
    now you only have to figure out how long there has been no change
    and what to do if change occurs or not within a time limit
  }

and don’t forget to update the lastBits before loop() ends so next time the compare is right

  lastBits = matBits;

If you are not sure how to tell when 10000 milliseconds is up, spend time learning the BlinkWithoutDelay example sketch in your IDE.

How about this strategy?

// untested code

void loop() {
  static byte sensorArray[16];
  static unsigned long lastChangedTimeStamp = millis();
  byte pinState;
  byte i;

  for (i = 0; i < 16; ++i)
  {
    pinState = digitalRead(i + 31);
    if (pinState != sensorArray[i])
    {
      sensorArray[i] = pinState;          // Something changed.  Save the changed state
      lastChangedTimeStamp = millis();    // and update the time stamp
    }
  }

  if (millis() - lastChangedTimeStamp >= 10000)  // Ten seconds since the last difference?
    digitalWrite(alarmPin, HIGH);                // Sound the alarm
}

Im not sure I understand what the for loop is doing. Why subtract 31 from k? Doesnt k hold the value of the pins being used?

digitalRead() only returns 0 or 1. The wire is OFF or ON. 1 bit is enough.

Why go from 0 to 31 or back? Because your first pin is pin 31 and arrays/bits start at zero.

Ok i get the array part of it, but I dont see you using an array. Doesnt the array format consist of brackets...... lastBits looks like you just assigned a hex value and are writing binary data into it to make up a value. I do have education on digital logic gates. And I understand how they work. Just the code end of things is kinda confusing to me. I like math and electronics because for the most part there is a process to follow, however coding seems to have a lot of ways to do the same things, making it more complicated. kinda like writing a research report.

Here is how I understood your intent:

Read the states of the 16 pins into and array.
Wait 250 milliseconds.
Read the states of the 16 pins into another array.
Compare the two arrays.
If there has been no change in 10 seconds, sound the alarm.

I wondered if you couldn't simplify the system in a couple of ways. First, why use two arrays? It is just as easy to compare the current state of a pin as it is to compare an array value. Second, why wait 250 milliseconds? It seems easier to me to keep track of a single time stamp than mess with the 250 millisecond / 10 second thing.

So here's how it works. The sensor array keeps track of the state of each pin. Each time the loop() function runs, the for loop checks the state of each pin to see if it is still the same as what it stored in the array last time. If any pins have changed state, it stores the new current state in the array, and updates the time stamp. After it has checked all the pin states, it checks the time stamp against the current time to see if it has been 10 seconds since the last update.

Normally, you don't use a variable or an array without setting it to a known value first. sensorArray will start out with garbage values in each slot. But in this case it really doesn't matter, because the first time the loop() runs, any values that don't match will be replace with the current states of the pins.

You got my intentions right and I'm fine with simplifying things
Im just new to this arduino and seen something I didn't quite understand. So I thought for future reference I'd ask. Now I got it though thanks for the help.

Yes with code we are making up stories but if the stories don't work it's no good and the stories are written in logic which is where being able to do higher math really helps. I did work at the U of D back in 1981 writing chemistry lessons for minimum wage and my job title was 'author'. If they don't pay much, you get a neat job title.

I would suggest that you work through the examples in the IDE that address parts of coding that you aren't sure about. Keep bookmarks to the Arduino Reference page and every other page or site with helpful info, especially references and tutorials. My browser lets me organize bookmarks and I have a wealth of such links. I need them at my age because words just slip away at times and I have to look again to get syntax and order right.

This ain't something you'll learn well in a week but you can get moving and accomplish simple tasks in two weeks if you keep at it. You might not do it the -best- way but as long as it works you're good!