Set variables depending on user input

Discussion in 'Programmer's Corner' started by mcgyvr, Mar 9, 2015.

  1. mcgyvr

    Thread Starter AAC Fanatic!

    Oct 15, 2009
    4,770
    970
    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 (Text):
    1.  
    2. IF barcode is "apple"
    3. then
    4. A=1
    5. B=2
    6. C=3
    7. D=4
    8.  
    9. IF barcode is "pickle"
    10. then
    11. A=3
    12. B=2
    13. C=4
    14. D=1
    15.  
    16. IF barcode is "dog"
    17. then
    18. A=2
    19. B=3
    20. C=1
    21. D=4
    22.  
     
  2. Papabravo

    Expert

    Feb 24, 2006
    10,144
    1,790
    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.
     
  3. mcgyvr

    Thread Starter AAC Fanatic!

    Oct 15, 2009
    4,770
    970
    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}
     
    ErnieM likes this.
  4. Papabravo

    Expert

    Feb 24, 2006
    10,144
    1,790
    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.
     
  5. mcgyvr

    Thread Starter AAC Fanatic!

    Oct 15, 2009
    4,770
    970
    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];
     
  6. Papabravo

    Expert

    Feb 24, 2006
    10,144
    1,790
    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.
     
  7. mcgyvr

    Thread Starter AAC Fanatic!

    Oct 15, 2009
    4,770
    970
    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 :)
     
  8. mcgyvr

    Thread Starter AAC Fanatic!

    Oct 15, 2009
    4,770
    970
    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 (Text):
    1. int Apple[] = {1,2};
    2. int Orange[] = {3,4};
    3. int A;
    4. int B;
    5. String useArray;
    6.  
    7. // the setup function runs once when you press reset or power the board
    8. void setup() {
    9.  
    10.   Serial.begin(9600);
    11.  
    12.   Serial.println("Would you like Apple or Orange data"); //user would respond "Apple" or "Orange" without quotes
    13.   while (Serial.available()==0) {
    14.   }//wait for answer
    15.   useArray = Serial.readString();
    16.  
    17.   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..
    18.   B = "useArray"[2];
    19.  
    20.   Serial.println(A);//if user said Apple then it would print 1, if Orange then 3
    21.   Serial.println(B); //if user said Apple then it would print 2, if Orange then 4
    22.  
    23. }
    24.  
    25. // the loop function runs over and over again forever
    26. void loop() {
    27.  
    28. }
     
    Last edited: Mar 9, 2015
  9. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,388
    1,605
    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 likes this.
  10. djsfantasi

    AAC Fanatic!

    Apr 11, 2010
    2,808
    834
    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: Mar 9, 2015
  11. mcgyvr

    Thread Starter AAC Fanatic!

    Oct 15, 2009
    4,770
    970
    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..
     
  12. djsfantasi

    AAC Fanatic!

    Apr 11, 2010
    2,808
    834
    Here is some sample code. It compiles for an Arduino, but I haven't tested it.
    Code (Text):
    1.  
    2. #define barcodecount 5
    3.  
    4. String barcode[barcodecount]={"123456",
    5.                   "654321",
    6.                   "342510"
    7.                   "987654",
    8.                   "817263"};
    9.  
    10. int FindIt(String myscanned) {
    11.   int i;
    12.   for (i=0;i<=barcodecount;i++) {
    13.     if (myscanned == barcode[i]) break;
    14.   }
    15.   if (i>barcodecount) i=-1;
    16.   return i;
    17. }
    18.    
    19.  
    20. void setup() {
    21.   // put your setup code here, to run once:
    22.  
    23. }
    24.  
    25. void loop() {
    26.   // put your main code here, to run repeatedly:
    27.   int A[barcodecount]={1,2,3,4,5};
    28.   int B[barcodecount]={1,2,3,4,5};
    29.   int C[barcodecount]={1,2,3,4,5};
    30.   int D[barcodecount]={1,2,3,4,5};
    31.   int myA;
    32.   int myB;
    33.   int myC;
    34.   int myD;
    35.   int index=0;
    36.   String scanned="";
    37.   // input "scanned" barcode
    38.  
    39.   index=FindIt(scanned);
    40.   myA=A[index];
    41.   myB=B[index];
    42.   myC=C[index];
    43.   myD=D[index];
    44. }
    45.  
    46.  
     
  13. Papabravo

    Expert

    Feb 24, 2006
    10,144
    1,790
    I know how to do it in C, but that may be of little help to you
    Code (Text):
    1.  
    2. int * p; //p is a pointer to integers
    3.  
    4. int Apple[] ;
    5. int Orange[]
    6. ...
    7. ...
    8. ...
    9. if (strcmp(useArray, "Apple"))
    10. {
    11.   p = &Apple[0] ; //Set p to the address of the first element in Apple
    12. }
    13. else if(strcmp(useArray,"Orange"))
    14. {
    15.   p = &Orange[0] ; //Set p to the address of the first element in Orange
    16. }
    17. else
    18. {
    19.   //Invalid Input, don't let p have a valid pointer
    20.   p = NULL ;
    21. }
    22. ...
    23. if (p != NULL)
    24. {
    25.   A = *(p + 0) ; //First element of the selected array
    26.   B = *(p + 1) ; //Second element of the selected array
    27. }
    28.  
    I didn't say it would be pretty.
     
  14. djsfantasi

    AAC Fanatic!

    Apr 11, 2010
    2,808
    834
    @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 (Text):
    1.  
    2. // "object" can be one of Apple, Orange, or Pear
    3. input object
    4.  
    5. /// a reference table of parameter values for each object
    6. int refTable={...
    7.  
    8. // the reference table can be accessed directly by the object value
    9. myA=refTable[object][0]
    10. myB=refTable[object][1]
    11. ...
    12.  
    The following code illustrates ErnieM's two dimensional array idea and has compiled on an Arduino.

    Code (Text):
    1. #define barcodecount 5 // zero based
    2. #define parmcount 4
    3.  
    4. String barcode[barcodecount]={
    5.                 "123456",
    6.                 "654321",
    7.                 "342510"
    8.                 "987654",
    9.                 "817263"
    10.                 };
    11.  
    12.  
    13. int FindIt(String myscanned) {
    14.   // simple scan search. Other search algorithms are
    15.   // appropriate for larger list sizes.
    16.   int i;
    17.   for (i=0;i<=barcodecount;i++) {
    18.     if (myscanned == barcode[i]) break;
    19.   }
    20.   if (i>barcodecount) i=-1;
    21.   return i;
    22. }
    23.  
    24.  
    25. void setup() {
    26.   // put your setup code here, to run once:
    27.   Serial.begin(9600);
    28.  
    29. }
    30.  
    31.  
    32. void loop() {
    33.   // put your main code here, to run repeatedly:
    34.   // initialization of local variables
    35.   int refArray[barcodecount][parmcount]= {
    36.              {0, 1, 2, 3},
    37.              {1, 3, 4, 5},
    38.              {2, 4, 5, 6},
    39.              {3, 5, 6, 7},
    40.              {4, 6, 7, 8}
    41.              };
    42.   int myA;
    43.   int myB;
    44.   int myC;
    45.   int myD;
    46.   int index=0;
    47.   String scanned="";
    48.  
    49.   // Start of main logic. Input barcode, locate it in list
    50.   // and assign the parameter values associated with the object
    51.   // input "scanned" barcode code here
    52.   index=FindIt(scanned);
    53.   if (index > 0 ) {
    54.     // actual array references could be used instead of assigning
    55.     // their values to a scalar variable.
    56.     myA=refArray[index][0];
    57.     myB=refArray[index][1];
    58.     myC=refArray[index][2];
    59.     myD=refArray[index][3];
    60.     // ... paramters have been assigned above
    61.   } else {
    62.     // could not findf barcode in list
    63.     Serial.println"Unrecognized barcode");
    64.   }
    65.  
    66. }
    67.  
     
    Last edited: Apr 21, 2015
  15. mcgyvr

    Thread Starter AAC Fanatic!

    Oct 15, 2009
    4,770
    970
    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.
     
    ErnieM likes this.
  16. John P

    AAC Fanatic!

    Oct 14, 2008
    1,634
    224
    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.
     
  17. darrough

    Member

    Jan 18, 2015
    86
    19
    Database is the way to go.

    Without database, keep the data in a sorted, linked list and use binary search to find a match.
     
  18. RRITESH KAKKAR

    Senior Member

    Jun 29, 2010
    2,831
    89
    Hello,
    what this mean in real, your projects?
    IF barcode is "apple"
    then
    A=1
    B=2
    C=3
    D=4
     
Loading...