Arduino - Type error, help please

Discussion in 'Programmer's Corner' started by flat5, May 6, 2015.

  1. flat5

    Thread Starter Active Member

    Nov 13, 2008
    403
    17
    I've tried various types for 'h' and other ways to get what I need such as String h[1] and String h
    What I need:
    User inputs some characters but is not allowed to repeat any.
    This becomes test_str. This is probably an awkward way to input data but it's the only way I have found. It would be easier to check the string as it is being made, I suspect.

    error is reported on this line "if (h == test_str.substring(t+1))"

    error: no match for 'operator==' (operand types are 'char' and 'String')

    Code (Text):
    1.  
    2. String answers; unsigned int randNumber; String send_char;  String test_str;
    3.   Serial.flush();
    4.   Serial.println("Enter the characters you want sent. Then press Esc to continue");
    5.   Serial.setTimeout(10000);
    6.   test_str.concat(Serial.readStringUntil(27)); // 10 seconds or Esc
    7.   while (test_str.length() > 43)
    8.   {
    9.     Serial.println("Too many characters. Try again. Max:44");
    10.     test_str = "";
    11.     test_str.concat(Serial.readStringUntil(27));
    12.   }
    13. Serial.setTimeout(1000); // reset key timeout to a more reasonable length
    14. test_str.toLowerCase();
    15.   for (unsigned int t = 0; t < test_str.length(); t++)
    16.   {
    17.     char h;
    18.     h = test_str[t];
    19.     if (h == test_str.substring(t+1)) //  <----------------problem
    20.     {
    21.       Serial.println("Do not include the same character more than once.");
    22.     }
    23.   }
    24.  
     
    Last edited: May 6, 2015
  2. DumboFixer

    Active Member

    Feb 10, 2009
    219
    34
    I think your problem is that substring returns a String and not a Char - the error message does point to this.

    I don't know the exact syntax but something like Substring(t+1,1) should return just a single character though it may still be a String. If that's the case then try casting it to a char.
     
  3. flat5

    Thread Starter Active Member

    Nov 13, 2008
    403
    17
    if (h == test_str.substring(t+1,1))

    Thank you, DumboFixer. Same error message.
    I'll Google casting and char
    (not interested in fish right now)
     
  4. djsfantasi

    AAC Fanatic!

    Apr 11, 2010
    2,787
    825
    Or instead of using .substring, use the .charAt() method. It ruturns a single character.

    There is a method which converts a String type to a char type... char(). So you could do something like the following.

    if(h == char(test_str.atChar(t+1))) ...

    The following example sketch compiles.
    Code (Text):
    1. void setup() {
    2. }
    3. void loop() {
    4.   String test_str="abcdefghijklmnopqrstuvwxyz";
    5.   char h = 'j';
    6.   if(h == char(test_str.charAt(10))) {
    7.   }
    8. }
     
    Last edited: May 6, 2015
  5. flat5

    Thread Starter Active Member

    Nov 13, 2008
    403
    17
    I'll play with that, djsfantasi. Thank you for being specific and providing a useful example.
    I'll have time later to play with it.
     
  6. flat5

    Thread Starter Active Member

    Nov 13, 2008
    403
    17
    Did I misunderstand something?
    Code (Text):
    1.  
    2. for (unsigned int t = 0; t < test_str.length(); t++)
    3.   {
    4.     char h;
    5.     h = char(test_str.charAt(t));
    6.     if (h == test_str.substring(t+1,1))  // <-----------error: no match for 'operator==' (operand types are 'char' and 'String')
    7.     {
    8.       Serial.println("Do not repeat a character.");
    9.       subset_test();
    10.     }
    11.   }
    12.  
    Tried h = test_str[t];
    instead of
    h = char(test_str.charAt(t));
    error: no match for 'operator==' (operand types are 'char' and 'String')
    Tried declaring h as String but that brings many error messages.
    This too is useless:
    if (test_str.indexOf(test_str[t]) == test_str.substring(t+1))
     
    Last edited: May 6, 2015
  7. djsfantasi

    AAC Fanatic!

    Apr 11, 2010
    2,787
    825
    In your if statement, you forgot to cast the string to a char. On my phone; working late so I can't provide an example.
     
  8. djsfantasi

    AAC Fanatic!

    Apr 11, 2010
    2,787
    825
    Look at how I coded the test in my example. You need to use a similar construction in yours. I've modifed your code and it successfully compiles. The only modification that I made was to change your "test_str.substring(t+1,1)" to "test_str.charAt(t+1)" and to cast it to type char (to compare to h, which is type char). I used the char() function to do this, "char(test_str.charAt(t+1))"

    Code (Text):
    1. String test_str = "abcdefghiklmnopqrstuvwxyz";
    2.  
    3. void setup() {
    4.   // put your setup code here, to run once:
    5. for (unsigned int t = 0; t < test_str.length(); t++)
    6.   {
    7.     char h;
    8.     h = char(test_str.charAt(t));
    9.     if (h == char(test_str.charAt(t+1))) { // <-------- no error
    10.       Serial.println("Do not repeat a character.");
    11.       //  subset_test();
    12.     }
    13.   }
    14. }
    15.  
    16. void loop() {
    17.   // put your main code here, to run repeatedly:
    18.  
    19. }
     
  9. flat5

    Thread Starter Active Member

    Nov 13, 2008
    403
    17
    Yes! My Googling did not help me to understand 'casting'.
    djsfantasi, your example says it clearly enough for my present needs.
    The goto works well. The prog is not getting stuck in a loop.
    Calling subset_test() did not work well.
    I would like to use more functions but so many variables need to be passed and my attempts have not gone well.
    I need to study how to break some routines into functions when they have to carry a lot of baggage.
    I'm also having trouble with keyboard input. You can see how crudely I'm building test_str.
    If I could test each character as the Serial is read, a few problems could be caught right away.
    Such as a punctuation that is not in the array of characters or double entry of a character.
    The timing kludge and goto could be removed too.
     
  10. flat5

    Thread Starter Active Member

    Nov 13, 2008
    403
    17
    The full program as it was. post #24 is the update
    Code (Text):
    1.  
    2. // send random Morse code ver.2
    3. // by flat5 May-8-2015
    4. // choice of tone/notone or external oscillator.
    5. // Plug speaker to Analog pin8 and gnd. Use a resistor or pot in series if you want to. I used 220 ohm.
    6.  
    7. #include <Arduino.h>
    8. byte signalPin = 13; // will control oscillator speaker
    9. unsigned int wpm = 20;
    10. unsigned int elementWait = 1200 / wpm;
    11. unsigned int row = 43;
    12. unsigned int space = 2; // time between characters. It is good to send the chacters faster than the space between them for practice.
    13. unsigned int pitch = 846; // near a volume peak on my sounder. needed because I'm using a 220 ohm resistor in series.
    14. char* codes[] =
    15. { ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--",
    16.   "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", // 26 letters
    17.   "-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.",     // 10 numbers
    18.   "--..--", ".-.-.-", "..--..", "..--.", "---...", ".-..-.", ".----.", "-...-"                  //  8 punctuation
    19. };
    20. char* code_char[] =
    21. { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
    22.   "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", // 26 letters
    23.   "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",                // 10 numbers
    24.   ",", ".", "?", "!", ":", "\"", "'", "="                          // 8 punctuation, so far - 44 characters
    25. };
    26.  
    27. void setup() {
    28.   pinMode(signalPin, OUTPUT);
    29.   noTone(8);
    30.   Serial.begin(9600); //115200 - 9600
    31.   randomSeed(analogRead(0));
    32.   menu();
    33. }
    34.  
    35. void loop()
    36. {
    37.   parser();
    38. }
    39.  
    40. void menu() {
    41.   Serial.println("Send a random group of characters for Morse practice");
    42.   Serial.println("Press Spacebar [Enter] to start");
    43.   Serial.println("Enter 's'(value) to adjust letter space (1-whatever)");
    44.   Serial.println("Enter 'w'(value) to adjust wpm (Example: w20)");
    45.   Serial.println("Enter 'p'(value) to set tone pitch <p31-24000 or <0 for off");
    46.   Serial.println("Enter 'r'(value) to set how many characters in the row to send (1-88)");
    47.   Serial.println("Enter 't'(characters) to set a select group of characters to send (44 max)");
    48.   Serial.println("Enter 'u' to send just the punctuation characters");
    49.   Serial.println("Enter 'm' to display this menu");
    50.   Serial.println("Enter 'c' to clear screen on real terminals");
    51.   Serial.print("Currently: s:"); Serial.print(space); Serial.print(" w:"); Serial.print(wpm);
    52.   Serial.print(" r:"); Serial.print(row); Serial.print(" P:"); Serial.println(pitch);
    53.   Serial.println();
    54. }
    55.  
    56. void parser()
    57. {
    58.   unsigned int digits;
    59.   unsigned int value = 0;
    60.   do
    61.   {
    62.     digits = Serial.available();
    63.   }
    64.   while (digits < 1);
    65.   char keypress = Serial.read();
    66.   do
    67.   {
    68.     digits = Serial.available();
    69.   }
    70.   while (digits < 0);
    71.   value = Serial.parseInt();
    72.   Serial.flush();
    73.   switch (keypress)
    74.   {
    75.     case 'm': case 'M': case 'h': case 'H': // display menu
    76.       {
    77.         menu();
    78.         break;
    79.       }
    80.     case ' ': // Spacebar. generate code
    81.       {
    82.         random_code();
    83.         break;
    84.       }
    85.     case 't': case 'T': // send a selected group of characters
    86.       {
    87.         subset_test();
    88.         break;
    89.       }
    90.     case 'u': case 'U': // send the punctuation characters
    91.       {
    92.         send_punc();
    93.         break;
    94.       }
    95.     case 's': case 'S': // letter space time length (1 is same time as a dit)
    96.       {
    97.         if (value != 0) space = value;
    98.         Serial.print("Letter space(s) "); Serial.println(space);
    99.         break;
    100.       }
    101.     case 'w': case 'W': // wpm
    102.       {
    103.         if (value != 0) wpm = value;
    104.         elementWait = 1200 / wpm; // dit = 1200 / wpm
    105.         Serial.print("wpm: "); Serial.println(wpm);
    106.         break;
    107.       }
    108.     case 'r': case 'R': // how many to send (a row)
    109.       {
    110.         if (value != 0 && value < 89)
    111.         {
    112.           row = value;
    113.           Serial.print(row); Serial.println(" characters will be sent");
    114.           break;
    115.         }
    116.         else
    117.         { Serial.print("value must be 1-88, presently "); Serial.println(row);
    118.           break;
    119.         }
    120.       }
    121.     case 'c': case 'C':
    122.       {
    123.         refresh_Screen(); // a real terminal is required for this to work
    124.         break;
    125.       }
    126.     case 'p': case 'P':
    127.       {
    128.         pitch = value;
    129.         if (pitch == 0)
    130.         {
    131.           pitch = 0;
    132.           noTone(8);
    133.           Serial.println("Tone echo is now off."); // stare at the led or use an external oscillator triggered by pin D13
    134.           break;
    135.         }
    136.         if (pitch < 31 || pitch > 24000)
    137.         {
    138.           Serial.println("Pitch range is 31-24000");
    139.           break;
    140.         }
    141.         Serial.print("Tone pitch in Hz:"); Serial.println(pitch, DEC);
    142.         tone(8, pitch, 400); // give a sample
    143.         break;
    144.       }
    145.   }
    146. }
    147.  
    148. void refresh_Screen() // not compatable with all terminal programs
    149. {
    150.   Serial.write(27); // ESC
    151.   Serial.write("[2J"); // clear screen
    152.   Serial.write(27); // ESC
    153.   Serial.write("[H"); // cursor to home
    154. }
    155.  
    156. void dit() {
    157.   digitalWrite(signalPin, HIGH);
    158.   if (pitch != 0) tone(8, pitch);
    159.   delay(elementWait);      // milliseconds - one dit
    160.   digitalWrite(signalPin, LOW);
    161.   noTone(8);
    162.   delay(elementWait);
    163. }
    164.  
    165. void dah() {
    166.   digitalWrite(signalPin, HIGH);
    167.   if (pitch != 0) tone(8, pitch);
    168.   delay(elementWait * 3);
    169.   digitalWrite(signalPin, LOW);
    170.   noTone(8);
    171.   delay(elementWait);
    172. }
    173.  
    174. void letter_space() {
    175.   delay(elementWait * space);
    176. }
    177.  
    178. void random_code() { // send a random character's Morse equivlent
    179.   char* code_char[] =
    180.   { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
    181.     "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", // 26 letters
    182.     "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",                // 10 numbers
    183.     ",", ".", "?", "!", ":", "\"", "'", "="                          // 8 punctuation, so far - 44 characters
    184.   };
    185.   String send_char; String answers; String answers2;
    186.   char* send_codes[row]; //array starts at 0. User inputs how many characters in a run (row on screen)
    187.   //unsigned long seed = seedOut(31); randomSeed(seed);
    188.   for (unsigned int t = 0; t < row; t++) // each run will be 'row' characters (+ 'row' spaces) but the last check needs a kludge
    189.   {
    190.     unsigned int randNumber = random(44); // 0 - 43, all characters.
    191.     // see if the randNumber character is in string 'answers' or 'answers2' already.
    192.     if (t < 44)
    193.     {
    194.       if (answers.indexOf(code_char[randNumber]) != -1) t = t - 1; // character already in array. try again
    195.       else
    196.       {
    197.         answers.concat(code_char[randNumber]); answers.concat(" "); // add a space after each character for readability
    198.         send_codes[t] = (codes[randNumber]); // build array of code character strings to be sent
    199.       }
    200.     }
    201.     if (t > 43 )
    202.     {
    203.       if (answers2.indexOf(code_char[randNumber]) != -1) t = t - 1;
    204.       else
    205.       {
    206.         answers2.concat(code_char[randNumber]); answers2.concat(" ");
    207.         send_codes[t] = (codes[randNumber]);
    208.       }
    209.     }
    210.   }
    211.   for (unsigned int t = 0; t < row ; t++)
    212.   {
    213.     send_char = send_codes[t]; // send the code of a character
    214.     for (unsigned int i = 0; i < send_char.length(); i++) // break it down to it's elements
    215.     {
    216.       String x;
    217.       x = send_char.substring(i, i + 1);
    218.       if (x == ".") dit(); else if (x == "-") dah(); // check both. don't send garbage
    219.     }
    220.     letter_space();
    221.   }
    222.   Serial.print(answers); Serial.println(answers2); Serial.println(); // show test answers & answers2, if any
    223. }
    224.  
    225. void subset_test()   // Select characters for study -----------------still working on this one---------------
    226. {
    227.   String answers; unsigned int randNumber; String send_char;
    228. label:
    229.   String test_str;
    230.   Serial.flush();
    231.   Serial.println("Enter the characters you want sent. Then press Esc to continue");
    232.   Serial.setTimeout(10000);
    233.   test_str.concat(Serial.readStringUntil(27)); // 10 seconds or Esc
    234.   if (test_str.length() > 43)
    235.   {
    236.     Serial.println("Too many characters. Try again. Max:44");
    237.     goto label;
    238.   }
    239.   Serial.setTimeout(1000); // reset key timeout to a more reasonable length
    240.   test_str.toLowerCase();
    241.   for (unsigned int t = 0; t < test_str.length(); t++) // test to see if the string has duplicates
    242.   {
    243.     char h; // overcoming the string vs char compile error by CASTING
    244.     h = char(test_str.charAt(t));
    245.     if (h == char(test_str.charAt(t + 1))) //--------------------------
    246.     {
    247.       Serial.println("Do not repeat a character.");
    248.       goto label;
    249.     }
    250.   }
    251.   char* send_codes[test_str.length()];
    252.   for (unsigned int t = 0; t < test_str.length(); t++)
    253.   {
    254.     randNumber = random(test_str.length() + 1);
    255.     if (answers.indexOf(test_str[randNumber]) != -1) t = t - 1; // character already in array. try again
    256.     else
    257.     {
    258.       answers.concat(test_str[randNumber]); answers.concat(" "); // add a space after each character for readability
    259.       for (unsigned int i = 0; i < 44; i++)
    260.       {
    261.         if (test_str.substring(randNumber, randNumber + 1) == code_char[i]) // to index the correct code string
    262.         {
    263.           send_codes[t] = codes[i];
    264.         }
    265.         //else { // Serial.print(test_str.substring(randNumber)); Serial.println(" is not a character in the Morse array.");
    266.         //} // Still working on this
    267.       }
    268.     }
    269.   }
    270.   for (unsigned int t = 0; t < test_str.length(); t++)
    271.   {
    272.     send_char = send_codes[t]; // send the code of a character
    273.     for (unsigned int i = 0; i < send_char.length(); i++) // break it down to it's elements
    274.     {
    275.       String x;
    276.       x = send_char.substring(i, i + 1);
    277.       if (x == ".") dit(); else if (x == "-") dah(); // check both. don't send garbage
    278.     }
    279.     letter_space();
    280.   }
    281.   Serial.println(answers);
    282. }
    283.  
    284. void send_punc() // send just punctuation characters
    285. {
    286.   String punc = (",.?!:\"'="); String answers; unsigned int randNumber; String send_char;
    287.   for (unsigned int t = 0; t < 8; t++)
    288.   {
    289.     randNumber = random(8);
    290.     if (answers.indexOf(punc[randNumber]) != -1)
    291.     {
    292.       t = t - 1; // character already in array. try again
    293.     }
    294.     else
    295.     {
    296.       answers.concat(punc[randNumber]); // build answers string
    297.       answers.concat(" ");              // add a space after each character for readability
    298.       send_char = codes[randNumber + 36]; // build code array to match answers index
    299.       for (unsigned int i = 0; i < send_char.length(); i++) // break it down to it's elements
    300.       {
    301.         String x;
    302.         x = send_char.substring(i, i + 1);
    303.         if (x == ".") dit(); else if (x == "-") dah(); // check both. don't send garbage
    304.       }
    305.     }
    306.     letter_space();
    307.   }
    308.   Serial.println(answers);
    309. }
    310.  
     
    Last edited: May 10, 2015
  11. flat5

    Thread Starter Active Member

    Nov 13, 2008
    403
    17
    Multiple personality code. Yikes!
    Code updated.
    To do: multiple runs of option 't' using same characters.
    That option is a bit of a mess.
    Could use lots of help on that one. (hint hint)
     
  12. djsfantasi

    AAC Fanatic!

    Apr 11, 2010
    2,787
    825
    Not quite clear as to what your new requirement is? Please re-word it, so I can see if I can understand it better.

    By the way, I am curious. What is this for?
     
  13. flat5

    Thread Starter Active Member

    Nov 13, 2008
    403
    17
    djsfantasi, I guess you are not kidding. You programmers always say I'm not clear enough :)
    OK, I wrote this program to improve my Morse code receiving skills. (and programming skills)

    To practice receiving the code characters at any speed
    to be able to send fast but put a long space between characters to think about what I heard
    to practice a group that is giving me trouble
    to practice just the punctuation characters which I am weakest with.

    Doing these exercises can be fatiguing so it's nice to control the row length. Another reason for that option is to try to visualise what I am hearing instead of writing down the characters. Sending 4 or 5 character groups is what I'm mostly doing.

    If you were referring to what I want the 't' option to do:
    That option allows one to select a group of characters for study instead of all characters.
    But it only runs once.
    I want it to be able to run many times but have the characters in a different order each run.
    Presently, one has to input the characters over and over again.
    I also need an elegant way to stop this routine and get back to the parser().
    I am unhappy with the way keyboard input is accomplished in this routine. I have had to work around it.

    If you need further clarification I'll try :)
    and seriously, any help with the code is appreciated! I am working very much alone in my study efforts!

    Edit: about 't'
    The result I want might be to press the Spacebar for the next run or press Esc to quit this routine. I will work on it too. It seems not too difficult but again, my input routine has made this more difficult. At least I think so.
     
    Last edited: May 8, 2015
  14. djsfantasi

    AAC Fanatic!

    Apr 11, 2010
    2,787
    825
    Here are some ideas of making the characters in a different order for each 'run'.

    Code (Text):
    1. Define an array to hold the characters in your group (with a size equal to the most number of characters you exepct to have in a group)
    2. Define an array to hold random numbers, equal in size to the character group array
    3.  
    4. Input into the character group array, the characters in the group you want to practice.
    5.  
    6. Each time you want to change the order ([I]and the first time[/I])...
    7. [INDENT]For each character, insert a random number into the second array.
    8. Sort the second array, swapping the character each time you swap a value in the second array.[/INDENT]
    9.  
    10. When the sort finishes - you'll have a different order of the characters without re-entering them.
    11.  
    Have you gone on the Arduino forum site? ...Or the reference pages? I find that a useful resource
     
  15. flat5

    Thread Starter Active Member

    Nov 13, 2008
    403
    17
    Reference pages are of some help, of course. I'll have to look deeper into the forum to see if that works for me. Hope so.

    Group array
    Define an array to hold the characters in your group
    (with a size equal to the most number of characters you expect to have in a group)

    Index array
    Define an array to hold random numbers, equal in size to the character group array

    Input into the character group array, the characters in the group you want to practice.

    All this confuses me:

    Each time you want to change the order (and the first time)...
    I ? is index?
    /I, no idea
    For each character, insert a random number into the second array.
    Sort the second array, swapping the character each time you swap a value in the second array.​
    When the sort finishes - you'll have a different order of the characters without re-entering them.

    ---
    Just re-entering the routine after the character subset is defined seems like it should work (to my simple mind).
    I have not gotten it to work though. At best it works once or twice and then a reset of the board is required.
    repeat: is the re-entry point but does not work well.
    Code (Text):
    1.  
    2. void subset_test()   // Select characters for study -----------------still working on this one---------------
    3. {
    4.   unsigned int randNumber; String send_char;
    5. label:
    6.   String test_str;
    7.   Serial.flush();
    8.   Serial.println("Enter the characters you want sent. Then press Esc to continue");
    9.   Serial.setTimeout(10000);
    10.   test_str.concat(Serial.readStringUntil(27)); // 10 seconds or Esc
    11.   if (test_str.length() > 43)
    12.   {
    13.     Serial.println("Too many characters. Try again. Max:44");
    14.     goto label;
    15.   }
    16.   Serial.setTimeout(1000); // reset key timeout to a more reasonable length
    17.   test_str.toLowerCase();
    18.   String answers(test_str.length());
    19.   for (unsigned int t = 0; t < test_str.length(); t++) // test to see if the string has duplicates
    20.   {
    21.     char h; // overcoming the string vs char compile error by CASTING
    22.     h = char(test_str.charAt(t));
    23.     if (h == char(test_str.charAt(t + 1))) //-------------------------
    24.     {
    25.       Serial.println("Do not repeat a character."); // "Repeated character not allowed."
    26.       goto label;
    27.     }
    28.   }
    29.   //repeat:
    30.   char* send_codes[test_str.length()];
    31. repeat:
    32.   for (unsigned int t = 0; t < test_str.length(); t++)
    33.   {
    34.     randNumber = random(test_str.length() + 1);
    35.     if (answers.indexOf(test_str[randNumber]) != -1) t = t - 1; // character already in array. try again
    36.     else
    37.     {
    38.       answers.concat(test_str[randNumber]); answers.concat(" "); // add a space after each character for readability
    39.       for (unsigned int i = 0; i < 44; i++)
    40.       {
    41.         if (test_str.substring(randNumber, randNumber + 1) == code_char[i]) // to index the correct code string
    42.         {
    43.           send_codes[t] = codes[i];
    44.         }
    45.         //else { // Serial.print(test_str.substring(randNumber)); Serial.println(" is not a character in the Morse array.");
    46.         //} // Still working on this error trap
    47.       }
    48.     }
    49.   }
    50.   for (unsigned int t = 0; t < test_str.length(); t++)
    51.   {
    52.     send_char = send_codes[t]; // send the code of a character
    53.     for (unsigned int i = 0; i < send_char.length(); i++) // break it down to it's elements
    54.     {
    55.       String x;
    56.       x = send_char.substring(i, i + 1);
    57.       if (x == ".") dit(); else if (x == "-") dah(); // check both. don't send garbage
    58.     }
    59.     letter_space();
    60.   }
    61.   Serial.println(answers);
    62.   Serial.flush();
    63.   while (Serial.available() == 0) // wait for data
    64.   {
    65.     char keypress = Serial.read();
    66.     //Serial.print(keypress);
    67.     if (keypress == 32)
    68.     {
    69.       answers = "";
    70.       goto repeat;
    71.     }
    72.     else
    73.     {
    74.       if (keypress == 27)
    75.       {
    76.         Serial.println("Esc");
    77.         return;
    78.       }
    79.     }
    80.   }
    81. }
    82.  
     
    Last edited: May 8, 2015
  16. djsfantasi

    AAC Fanatic!

    Apr 11, 2010
    2,787
    825
    I didn't label the second array because I didn't want to accidentally make a preconception as to how it works. It is NOT an index... If I were to pick a name, I would call it order. Take a look at the examples below, as I walk through the algorithm.

    1) Fill the first (Char) array with the character group desired:

    Char Order
    G
    H
    O
    P

    2) Fill the second array (Order) with a random number. (It represents the order of the group character):

    Char Order
    G 0.245
    H 0.167
    O 0.679
    P 0.032

    3) Perform a sort on the Order array, moving the corresponding position of the Char array:
    The first step in a bubble sort looks like this:

    Char Order
    H 0.167 <-swap
    G 0.245 <-swap
    O 0.679
    P 0.032

    The final sorted list looks like this:

    Char Order
    P 0.032
    H 0.167
    G 0.245
    O 0.679


    Note the final order is different than the beginning order. By regenerating the random numbers and re-sorting, you'll get a different order.

    I haven't written any code, because I feel its important to understand the algorithm before writing any code. The Arduino Forum contains many example sorting programs. The algorithm I've been describing is also known as a "shuffle" algorithm.
     
  17. flat5

    Thread Starter Active Member

    Nov 13, 2008
    403
    17
    Thank you for spending the time to present that, djsfantasi.
    I will practice that. I'm thinking about why use that approach instead of just using random and checking for duplicates. Perhaps it's faster than looping till a unique number is generated.
     
  18. flat5

    Thread Starter Active Member

    Nov 13, 2008
    403
    17
    Does this work?
    Code (Text):
    1.  
    2. String test_str = "..........................................." ; // trying to protect memory space for the string
    3.  test_str = "" ;
    4.  
     
  19. djsfantasi

    AAC Fanatic!

    Apr 11, 2010
    2,787
    825
    Not necessarily. Memory management of type String is done a little differently than other types. By assigning the null string to your variable, you are freeing the unused space from it's prior value to be used as the program wishes. You have more control of memory with character arrays, but give up the flexibility that String type methods give you. For example, you might have to write your own charAt function or use one from another library.

    In the earlier days, variables of type String caused memory problems. With the latest release of the Arduino IDE the problems have been greatly minimized, if not solved.

    Why are you worried about "memory protection"?
     
  20. flat5

    Thread Starter Active Member

    Nov 13, 2008
    403
    17
    My 't' routine is unstable and I think it's memory corruption.
    The behaviour is not exactly the same each time. Sometimes a character is missing from the answer string.
    Sometimes an unexpected character is on screen.
    Sometimes the routine hangs.
    This can happen on the first run. If I use the goto to make another pass, it often works once and rarely twice and never three times.
    I have over stepped variable memory before and had the same symptoms so...

    Concerning the whole program, I shortened all print statements, meaning less text on screen and found a great trick.
    Serial.print(F("text")); saves a lot of memory. Result is, I have plenty of local variable space at this time.

    BTW, I have searched the Arduino site for 'bubble sort'. No hits! Under string object, no sort is listed! Well, there is this 'String Comparison Operators' and compareTo().
    I'm slowly studying this site:
    http://www.tutorialspoint.com/cplusplus
    Actually learning something.
     
    Last edited: May 9, 2015
Loading...