'if the data is the same add it to the array only one time

I have predefined addresses (address1,address2 and address3) and i want to :

  • If each address variables is equal to the first 6 variables of my data then i want to add that data that i have from scanning (scanned_data_buff) to my (list)
  • And i want to do that only one time (if it is the same address again that i've already added to my list) i want to ignore it and move on to the next different address.

I've already made a code prototype below that does the first part but the second part i can't come up with any ideas.

uint8_t *list[10U];
uint8_t scanned_data_buff[30U]={var0,....,var29};/*example: scanned_data[30U]={0x00,0x80,0xE1,0x26,0x9E,0xD9,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}*/
uint8_t address1[6U]={var0,....,var5};/*example: AddressAconeer[6U]={0x00,0x80,0xE1,0x26,0x9E,0xD9}*/
uint8_t address2[6U]={var0,....,var5};/*example: AddressKbeacon[6U]={0xDD,0x34,0x02,0x07,0x54,0xE0}*/
uint8_t address3[6U]={var0,....,var5};
uint8_t counter;
for (counter=0;counter<sizeof(list);counter++)
{
    if (((address1[0U]==scanned_data_buff[0U])&&....&&(address1[6U]==scanned_data_buff[6U]))||/* if(AddressAconeer[0U]==scanned_data[0U]...*/
        ((address2[0U]==scanned_data_buff[0U])&&....&&(address2[6U]==scanned_data_buff[6U]))||
        ((address3[0U]==scanned_data_buff[0U])&&....&&(address3[6U]==scanned_data_buff[6U])))
        {
            list[counter]=scanned_data_buff;/*stock scanned_data into list[0U] and then repeat */
        }
}


Solution 1:[1]

So, you have a list array of size 10, that holds pointers to uint8_t arrays.
You have three uint8_t arrays of length 6, address1, address2, address3. You have an input uint8_t array scanned_data_buff of length 30.

If the first 6 elements of the input array match any of the address arrays, you want to add the pointer to the input array into the list.

That's how I understood the problem.

The question is, you have a for loop going over entire list array. If there is any match of the input buffer to any address, then you will write 10 times the same thing into the list array. I'm really unsure what exactly you are trying to do there.

My idea of placing the address of the input array into the list would be:

uint8_t checkaddress = (1U<<1U) | (1U << 2U) (1U << 3U); //0b00001110 check what addresses could still be a match, bit 1 means address1 is not a fail, bit 2 means address2 is not a fail etc
uint8_t counter = 0x00;
while(counter<6 && checkaddress > 0x00){ //while counter going up and not all checks failed
   if(checkaddress & (1U<<1U)){ //if address 1 could still be a match
       if(address1[counter] !== scanned_data_buff[counter]) checkaddress & ~(1U<<1U); //if no match to the element, address1 is no longer possible, so we won't ever check for match with address 1 anymore
   }
   if(checkaddress & (1U<<2U)){ //if address 2 could still be a match
       if(address2[counter] !== scanned_data_buff[counter]) checkaddress & ~(1U<<2U); //if no match to the element, address2 is no longer possible, so we won't ever check for match with address 2 anymore
   }
if(checkaddress & (1U<<3U)){ //if address 3 could still be a match
       if(address3[counter] !== scanned_data_buff[counter]) checkaddress & ~(1U<<3U); //if no match to the element, address3 is no longer possible, so we won't ever check for match with address 3 anymore
   }
 counter++;
}

So, now if checkaddress has bit 1 set, there is a match to address1, if bit 2 is set, it's a match to address2, if bit 3 is set, it's a match to address3. And if there was some non-match, we didn't keep comparing to that address anymore, saved some processing time. In simple words, it's faster. If the first element doesn't match to address, don't bother checking that address further.

If checkaddress is 0, it means there was no match. If checkaddress is not 0, there was a match. So now you can do with that scanned_data_buff whatever you want. So immediately after that we can do, for instance,

//if address match was found, put a pointer to array ( = pointer to the 1st element) into the list[0]
if(checkaddress > 0x00){ //I just like hex, it's explicit :3
   list[0] = &scanned_data_buff[0];
}

As a side note:

You can have problems with the scope of your input (scan) array, if it's on a stack, it can be overwritten without you even knowing it. You will need in on a heap via malloc or as a global variable, so that memory doesn't get overwritten.

Also, in terms of algo, I would consider turning address1, address2 and address3 into 2D array. It would simplify the code even further, no need to do separate lines of code for each of them.

Also, I haven't obviously tested any of my code. I wrote it right here and haven't even tried to compile it. The idea was to show what kind of algorithm I mean. You can always use 3 variables instead of checkaddress, one for each address (like uint8_t address1match = 1; turn it to 0 if failed), if you don't feel comfortable manipularing individual bits.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ilya