Compare USB barcode scans

Hello,

I currently have a USB barcode scanner and its working fine by using sample code from here. I can view the scanned code on the serial monitor with Serial.print(Prs.QRCodeBuffer).

I need to be able to compare the last scanned code with the next scanned code.

So basically I need to store the last scanned code (not quite sure how this can be done, I tried the following)

char *Str1; // this is where Ive tried to store the scanned code

when a button is pressed:

Str1 = Prs.QRCodeBuffer

then when the scanner is used i compare the values:

if (!strcmp(Prs.QRCodeBuffer, Str1))
{

//do something

} else {

//do something else

}

the problem Im having is that Str1 is getting updated every time I scan a code and not when I press the button like it should. I think that because Im using a pointer *Str1 it could be the issue??

Im at my wits end here, hope someone can help :wink:

Anybody understand how I can do this, getting really desperate now.......thanks.

You just need to copy somewhere else the last scan.

Create a buffer large enough to hold the scanned cstring and before going to the next scan, save it

const byte maxScanLength = 50;// whatever size is appropriate
char previousScan[maxScanLength+1] = {0}; 
....

// later in the code when you have a scan
if (!strcmp(Prs.QRCodeBuffer, previousScan)) {
      //do something they are the same
 } else {
      //do something else, they are different
      ....
      strncpy(previousScan, Prs.QRCodeBuffer, maxScanLength);
      previousScan[maxScanLength] = ‘\0’; // just in case you had reached the max length
      // now previousScan holds a copy of the scan (or at least the first maxScanLength characters)
}

Thanks for your reply. I'm getting somewhere now, it works fine but I need a slight alteration.

Once I have scanned a barcode I need to copy this and save it, then compare all other scans to this one that had been saved. Then if the user needs to replace the saved scan they can scan a new code and press a save button (on a tft screen).

The purpose of the project is to interlock a door, the user sets a barcode and this saved barcode will allow the door to open if scanned again, if the user scans another barcode it wont open the interlock.

Thanks.

so instead of having only one barcode saved in memory you need to have a list. You need to study arrays.

Careful as the memory is limited on small arduinos such as a UNO

One way to do this is have an array of previousScans. this can either be a static array of constant size cstrings (you will use too much memory but at least you know how many you can have at max) or an array of pointers to dynamically allocated cstrings from the scans, in which case you'll need to be careful when coding to see if you don't get too close to max available memory.

Given you are a beginner, I'd recommend you start with an array of fixed sized cstrings, that makes things easier.

const maxScanMemory = 10;         // we will remember only 10 badges
const byte maxScanLength = 20;      // whatever size is appropriate
char previousScans[maxScanMemory][maxScanLength+1] = {0}; 
byte currentScanMemoryIndex = 0; // where we are in filling up the array

...

// later you would add a new badge number in the list by doing a 
if (currentScanMemoryIndex < maxScanMemory) { // we still have room in the list
   strncpy(previousScans[currentScanMemoryIndex], Prs.QRCodeBuffer, maxScanLength);
   previousScans[currentScanMemoryIndex][maxScanLength] = '\0'; // just in case you had reached the max length
   currentScanMemoryIndex++; // remember we saved one additional entry
} else {
   // list is full, we can't add a new entry
}

to check if a badge is already in the list, you would have to write a for or while loop going from 0 to currentScanMemoryIndex and compare the incoming badge with each of the valid entries of previousScans

if memory becomes an issue, then you need either a bigger arduino (ESP for example would have more memory) or add some sort of extra storage like an SD card (but then it gets slow when you want to check each entry as you have to scan the file)

Thanks again for the quick reply. This is a little more complicated than I first thought, I thought I could save the scanned code and convert it to an 'unsigned long' or something then compare it with all other scanned barcodes that have been converted.
Seems like I'll have to work a little harder on this :confused:

Just for info Im using a mega.

Regards, Kev

well - is the scanned code an number fitting on an unsigned long? or is it a text string ?

if it's a number, then sure it will take way less memory to save it as such!

This is where Im getting confused, I think its a text string as its built up within the QRCodeBuffer (if Im correct in saying that). But obviously once its stored in the QRCodeBuffer and printed to the serial monitor its just looks like a normal long number. So I thought I could just convert it using 'toInt() function' but its just not having it.

don't use String class, so no toInt() option (and you don't have an int, you have an unsigned long)

Can you show some of the numbers scanned? if they do fit in an unsigned long then you could use [url=http://www.cplusplus.com/reference/cstdlib/atol/]atol()[/url] for example if it fits in a signed long or [url=http://www.cplusplus.com/reference/cstdlib/strtoul/?kw=strtoul]strtoul()[/url] for unsigned long

see that example code:

const char barCodescan[] = "1234567890";
unsigned long barCodeValue;

void setup() {
  Serial.begin(115200);
  barCodeValue = strtoul(barCodescan, NULL, 10); // http://www.cplusplus.com/reference/cstdlib/strtoul/?kw=strtoul
  Serial.print(F("The barcode texte was ["));
  Serial.print(barCodescan);
  Serial.println(F("]"));

  Serial.print(F("The associated unsigned long number is = "));
  Serial.print(barCodeValue);
}

void loop() {}

You should see in the Serial Console (set @115200 bauds) the following:

[color=purple]The barcode texte was [1234567890]
The associated unsigned long number is = 1234567890[/color]

then your array to memorize each badge is just an array of unsigned long... 4 bytes each instead of plenty for a string. the comparison is also easier, just use == with the unsigned long representation and no need for strcmp()

I've sorted it, more luck than knowledge I think :slight_smile:

I created another buffer called 'savedScan' and copied the string into this when the user presses the button. so its always comparing with this saved barcode on each scan.

const byte maxScanLength = 50;
char previousScan[maxScanLength + 1] = {0};
char savedScan[maxScanLength + 1] = {0};


// Routine for set button on TFT

    if (p.x > 739 && p.x < 816 && p.y > 160 && p.y < 260)
    {

      strncpy(savedScan, previousScan, maxScanLength);
      savedScan[maxScanLength] = '\0';
      Serial.print(savedScan);
delay(500);

    }




if (!strcmp(Prs.QRCodeBuffer, savedScan))
    {

      Serial.print("Saved scan: ");
      Serial.println(savedScan);

    } else {

      Serial.println("wrong code");

      strncpy(previousScan, Prs.QRCodeBuffer, maxScanLength);
      previousScan[maxScanLength] = '\0'; 

    }

    Prs.resetString();

heres part of the code.

Thanks for yor help as it got me thinking on the right path. Onwards and upwards :slight_smile: