Set variables depending on user input

Thread Starter

mcgyvr

Joined Oct 15, 2009
5,394
Working on an Arduino project and could use some help on how to accomplish my needs..

A barcode will be scanned and depending on what it is, the value of 4 variables need to be set and no mathematical formula is possible to determine them..

This is just a "generic" textual example with 3 different barcodes.. but I could have hundreds.
I know I will have to somehow define what A,B,C,D will be for each word but know there must be a better way than hundreds of if statements.. maybe not
Code:
IF barcode is "apple"
then
A=1
B=2
C=3
D=4

IF barcode is "pickle"
then
A=3
B=2
C=4
D=1

IF barcode is "dog"
then
A=2
B=3
C=1
D=4
 

Papabravo

Joined Feb 24, 2006
21,159
What do you think an alternative might look like?
Contextually a case statement might appear different but underneath is a unique comparison statement for each unique barcode. Now this is exactly the same problem that a compiler has when it is building a table of symbols. In a symbol table application there are a number of techniques that can be applied that serve to reduce the average number of comparison to find a match. Perhaps one of these techniques might be helpful.
 

Thread Starter

mcgyvr

Joined Oct 15, 2009
5,394
What do you think an alternative might look like?
Not exactly sure.. For some reason I'd like to declare the data like this and access it that way.. but not sure how best to do that.

apple[] = {1,2,3,4}
pickle[] = {3,2,4,1}
dog[] = {2,3,1,4}
 

Papabravo

Joined Feb 24, 2006
21,159
There is nothing wrong with declaring data using initializers like that, but your program will need to be recompiled or rebuilt each time there is a change. That still doesn't solve the problem of associating a barcode with the name of an initialized array.
 

Thread Starter

mcgyvr

Joined Oct 15, 2009
5,394
There is nothing wrong with declaring data using initializers like that, but your program will need to be recompiled or rebuilt each time there is a change. That still doesn't solve the problem of associating a barcode with the name of an initialized array.
I will put all data in now so I don't have to/recompile later.
I just don't know how to associate/access that data in an efficient way..

I don't know the proper syntax to do it but I think it would be something like.

//where "barcode" is whats scanned..could be apple or pickle or dog
int A = "barcode"[1];
int B = "barcode"[2];
int C= "barcode"[3];
int D="barcode"[4];
 

Papabravo

Joined Feb 24, 2006
21,159
What I meant was if you ever have to add a new barcode to the set of existing barcodes the whole program will have to be rebuilt. That is usually neither desirable nor efficient.

So you want to somehow map an incoming barcodes to a set of static array names in your program. And we are back to the original paradigm of having a series of if statements that map barcodes to pointers to arrays of integers. You could use a loop to sequence through all the barcodes until a match is found and assign the address of the corresponding static array to a pointer. Then you can proceed as you have indicated. Don't know if the tools you are using will permit it or not.
 

Thread Starter

mcgyvr

Joined Oct 15, 2009
5,394
Having to recompile/reupload IF there ever is a change is not a problem at all.. Don't worry about that :)

The "fake" code I posted in #5 to me seems like it should be possible and all thats needed.. Like I said I just don't know the proper syntax in C/Arduino to take that string from the barcode and automatically stick it where "barcode" is and have it actually work :)
 

Thread Starter

mcgyvr

Joined Oct 15, 2009
5,394
Like this but I don't know how to format the 2 lines where I try to set the values for A and B properly..
Code:
int Apple[] = {1,2};
int Orange[] = {3,4};
int A;
int B;
String useArray;

// the setup function runs once when you press reset or power the board
void setup() {

  Serial.begin(9600);

  Serial.println("Would you like Apple or Orange data"); //user would respond "Apple" or "Orange" without quotes
  while (Serial.available()==0) {
  }//wait for answer
  useArray = Serial.readString();

  A = "useArray"[1]; //this is the part that I don't know how to format correctly..don't have a way to test now..if it actually works I feel silly..
  B = "useArray"[2];

  Serial.println(A);//if user said Apple then it would print 1, if Orange then 3
  Serial.println(B); //if user said Apple then it would print 2, if Orange then 4

}

// the loop function runs over and over again forever
void loop() {

}
 
Last edited:

ErnieM

Joined Apr 24, 2011
8,377
What is a barcode? What sort of data do you get into the computer? Is it a number? How small/how big? What data type will it fit into?

What about A B C and D? How small/how big? What data type will it fit into?

Let's assume barcodes are larger than a character, but A B C and D are all character types. Make an array of barcodes so you can search it from 0 to (sizeof barcode -1). When you find a match you have an index number. Also make a 2 dimensional array of the A B C and D values so you can then take that index and just do:

A = code(I,0);
B = code(I,1);
C = code(I,2);
D = code(I,3);

(You could probably do this in a single array of structures, but I'm a mess at defining those offhand.)
 

djsfantasi

Joined Apr 11, 2010
9,156
How many values for barcode are we talking about? Depending on the answer, the algorithm for a search will be different.

Search? I see a list of barcodes matched up with arrays of values. By matched up, I mean the first entry in the barcode list will have its values in the first entry of a set of arrays, A[], B[], C[] and D[].

Then you search the list to find the position or index (write a function for this). Then use that index into the arrays to set the value.

NOTE; missed your excellent post, @ErnieM
 
Last edited:

Thread Starter

mcgyvr

Joined Oct 15, 2009
5,394
Forget the barcode for now.. Just look at the code in post 8... I tried to make it super simple with just 2 arrays for now.. There will be hundreds..
How do I get it so that if the user enters Apple that it looks for Apple[1] and Apple[2] instead of an array called "useArray" where I am trying to assign values to A and B?

In my mind that should be super simple I just don't know how to do that or if its even possible..
It sure would be easy..
 

djsfantasi

Joined Apr 11, 2010
9,156
Here is some sample code. It compiles for an Arduino, but I haven't tested it.
Code:
#define barcodecount 5

String barcode[barcodecount]={"123456",
                  "654321",
                  "342510"
                  "987654",
                  "817263"};

int FindIt(String myscanned) {
  int i;
  for (i=0;i<=barcodecount;i++) {
    if (myscanned == barcode[i]) break;
  }
  if (i>barcodecount) i=-1;
  return i;
}
   

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:
  int A[barcodecount]={1,2,3,4,5};
  int B[barcodecount]={1,2,3,4,5};
  int C[barcodecount]={1,2,3,4,5};
  int D[barcodecount]={1,2,3,4,5};
  int myA;
  int myB;
  int myC;
  int myD;
  int index=0;
  String scanned="";
  // input "scanned" barcode

  index=FindIt(scanned);
  myA=A[index];
  myB=B[index];
  myC=C[index];
  myD=D[index];
}
 

Papabravo

Joined Feb 24, 2006
21,159
I know how to do it in C, but that may be of little help to you
Code:
int * p; //p is a pointer to integers

int Apple[] ;
int Orange[]
...
...
...
if (strcmp(useArray, "Apple"))
{
  p = &Apple[0] ; //Set p to the address of the first element in Apple
}
else if(strcmp(useArray,"Orange"))
{
  p = &Orange[0] ; //Set p to the address of the first element in Orange
}
else
{
  //Invalid Input, don't let p have a valid pointer
  p = NULL ;
}
...
if (p != NULL)
{
  A = *(p + 0) ; //First element of the selected array
  B = *(p + 1) ; //Second element of the selected array
}
I didn't say it would be pretty.
 

djsfantasi

Joined Apr 11, 2010
9,156
Forget the barcode for now.. .
Also make a 2 dimensional array of the A B C and D values so you can then take that index and just do:

A = code(I,0);
B = code(I,1);
C = code(I,2);
D = code(I,3);
@mcgyvr, I asked about the number of barcodes, because what you are searching for and the best way to search for it is dependent on the size of the list. For now forgetting the ordinality of the set of barcodes, my examples use a simple linear scan.

@ErnieM, multi-dimensional arrays on an Arduino are tricky. But it was such a great idea, I modified my example using your idea and compiled it for an Arduino!

There is the concept of a "hash map" or "associative array". but its not native to Arduino C. There is a library that has been developed, that can be added to add this feature, however. It's used similar to the following pseudo-code.

Code:
// "object" can be one of Apple, Orange, or Pear
input object

/// a reference table of parameter values for each object
int refTable={...

// the reference table can be accessed directly by the object value
myA=refTable[object][0]
myB=refTable[object][1]
...
The following code illustrates ErnieM's two dimensional array idea and has compiled on an Arduino.

Code:
#define barcodecount 5 // zero based
#define parmcount 4

String barcode[barcodecount]={
                "123456",
                "654321",
                "342510"
                "987654",
                "817263"
                };


int FindIt(String myscanned) {
  // simple scan search. Other search algorithms are
  // appropriate for larger list sizes.
  int i;
  for (i=0;i<=barcodecount;i++) {
    if (myscanned == barcode[i]) break;
  }
  if (i>barcodecount) i=-1;
  return i;
}
 

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

}


void loop() {
  // put your main code here, to run repeatedly:
  // initialization of local variables
  int refArray[barcodecount][parmcount]= {
             {0, 1, 2, 3},
             {1, 3, 4, 5},
             {2, 4, 5, 6},
             {3, 5, 6, 7},
             {4, 6, 7, 8}
             };
  int myA;
  int myB;
  int myC;
  int myD;
  int index=0;
  String scanned="";

  // Start of main logic. Input barcode, locate it in list
  // and assign the parameter values associated with the object
  // input "scanned" barcode code here
  index=FindIt(scanned);
  if (index > 0 ) {
    // actual array references could be used instead of assigning
    // their values to a scalar variable.
    myA=refArray[index][0];
    myB=refArray[index][1];
    myC=refArray[index][2];
    myD=refArray[index][3];
    // ... paramters have been assigned above
  } else {
    // could not findf barcode in list
    Serial.println"Unrecognized barcode");
  }

}
 
Last edited:

Thread Starter

mcgyvr

Joined Oct 15, 2009
5,394
Thanks for all the help guys.. I appreciate it..
I'm a mostly a "beginner (enough to be dangerous)" at this micro programming stuff so I learned a few good tricks in this post..
BUT
After enough beers last night I said.. "screw it" and decided to add ethernet to my Arduino and then used the mysql connector and just pull what I need directly from a mysql database I've setup to hold all the "barcode" words and their associated "settings" :)

Its better in the end anyways.
 

John P

Joined Oct 14, 2008
2,025
Can you put all your entries in alphabetic (or alphanumerical) order instead of leaving them random? Then you could use an intelligent search routine instead of having to compare with each entry in sequence.
 
Top