Please help me code an if statement in 'C' for Arduino

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

  1. flat5

    Thread Starter Active Member

    Nov 13, 2008
    403
    17
    Idea is to check a string for a character and not concat it if it is already in the string.
    My if statement does not work and I do not have a clue why.
    Code (Text):
    1.  
    2. void random_code() {
    3.   // send a random character's Morse equivlent
    4.   char* code_char[] =
    5.   { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
    6.     "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
    7.     ",", ".", "?", "!", ":", "\"", "'", "="
    8.   };
    9.   char* codes[] =
    10.   { ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--",
    11.     "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", // 26 letters
    12.     "-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.",     // 10 numbers
    13.     "--..--", ".-.-.-", "..--..", "..--.", "---...", ".-..-.", ".----.", "-...-"                  //  8 punctuation
    14.   };
    15.   String send_char; String answers; char* send_codes[row - 1];//array starts at 0. User inputs how many characters in a run (row on screen)
    16.   unsigned long seed = seedOut(31); randomSeed(seed);
    17.   for (unsigned int t = 0; t < row ; t++) // each run will be 'row' characters (+ 'row' spaces)
    18.   {
    19.     unsigned int randNumber = random(43); // 0 - 43, all characters.
    20.     String chkchr = code_char[randNumber]; // the ascii character random has picked
    21.  
    22.  // PROBLEM IS HERE ---------------------------------------------------------------------------------------------------------
    23.  
    24.     if (chkchr == (answers.substring(0))) // see if the randNumber character is in string 'answers'. I will fix this later if a row is > 44
    25.     {
    26.       t = t - 1;
    27.     }
    28.  
    29. //----------------------------------------------------------------------------------------------------------------------------
    30.     else
    31.     {
    32.       answers.concat(code_char[randNumber]); answers.concat(" ");
    33.       send_codes[t] = (codes[randNumber]); // array of code character strings to be sent
    34.     }
    35.   }
    36.    Serial.println(answers); Serial.println();
    37. }
    38.  
     
  2. WBahn

    Moderator

    Mar 31, 2012
    17,715
    4,788
    Is this C or C++?

    Check your random(N) function. Usually these functions return an integer n such that 0 <= n < N.

    What does your substring(K) method do when K=0?
     
  3. flat5

    Thread Starter Active Member

    Nov 13, 2008
    403
    17
    I'm sorry, WBahn. I do not know for sure what you mean by substring(k).
    I guess you did not care to type 'answers.substring(0)'.
    If the random() returns 0 then that would point to the first character in the char* array.

    I'm only asking for help with the if statement. I have done many checks with printing the strings at every point in the code. The characters are correctly returned - not the pointers.

    Anyway, I had tried to use if (answers.indexOf(chkchr) != -1) before but now it works!
    I will test some more but I think the problem is solved.
    It would be nice to know why substring(0) did not work but indexOf(string) does.

    Just for fun I set the row to 45 and the run got caught in the loop :) as it should.
    Now to allow two of a character if the row is between 45-89.
     
    Last edited: May 3, 2015
  4. djsfantasi

    AAC Fanatic!

    Apr 11, 2010
    2,790
    827
    In Arduino C, the substring method when used with only one parameter, returns the sub string from the parameter to the end of the "parent" string". Hence when used with the string "answers", "answers.substring(0)" is the entire string, "answers". You are checking against a single character variable, chkchr, so unless "answers" is a single character, your test for equality will always be false. I don't think that is what you want. Check out this reference

    @WBahn and TS - Arduino's "random" function, random(M), returns a number from 0 inclusive to M exclusive.
     
  5. WBahn

    Moderator

    Mar 31, 2012
    17,715
    4,788
    The reason that I ask if you are using C or C++ is that the dot operator is a structure member dereference in C whereas it is an instance method call in C++. You appear to be using it to call instance methods.

    Having said that, the embedded world has numerous non-conforming C compilers that go off into their own little world with specialized syntax extensions.

    The problem I am trying to point out with random isn't that it will return 0, but that it will, most likely, NOT return 43. It will return one of 43 values, namely 0 through 42. Unless the random() function is very non-standard. Have you ever seen the last character in your strings come up, namely the '='?

    In most string libraries indexOf(k) will return -1 if the character k is not in the string, otherwise it will return the index of the first occurrence of that character within the string.

    When you have: chkchr == (answers.substring(0))

    You are asking if the value returned by answers.substring(0) is exactly equal to the character code that is presently stored in the variable chkchr. What is it that the method substring(0) is supposed to do that would make this a meaningful comparison? That's why I asked what that function returns when passed 0 as an argument. I don't see any reason to expect that to return the character code for any particular character in the string except, possibly, the first. More likely, I would expect it to return a string that starts with the first character of answers and contains all of then characters from that point on. If this is the case, then it is returning a pointer to a string which you can pretty much guarantee will never be equal to the value stored in chkchr, so I would expect this test to virtually always fail.
     
  6. WBahn

    Moderator

    Mar 31, 2012
    17,715
    4,788
    I don't think there would be equality even if "answers" has a single character, because what is returned is going to be a pointer to a string that happens to have one character, not the value of the character.

    And random(M) does just as I expected, which means that random(43) will return values in the range [0, 1, ... 41, 42], which is NOT what the TS wants.
     
  7. flat5

    Thread Starter Active Member

    Nov 13, 2008
    403
    17
    OK. I would have to turn around the check. I did have it that way at first. I did use the reference.
    Thank you, djfantasi!
    if ( answers.substring(0) == chkchr) ...

    Now I'm trying get this correct. first if is ok. Second if does not work. rows come out short.
    Code (Text):
    1.  
    2. if (answers.indexOf(chkchr) != -1  &&  row < 44)
    3.     {
    4.       t = t - 1;
    5.     }
    6.     else if (answers.indexOf(chkchr) != -1  &&  row > 43  &&  row < 89)
    7.     {
    8.      chkAgain = chkAgain+1;
    9.      if (chkAgain == 1) t = t - 1;
    10.     }
    11.     else
    12.     {
    13.       answers.concat(code_char[randNumber]); answers.concat(" ");
    14.       send_codes[t] = (codes[randNumber]); // array of code character strings to be sent
    15.     }
    16.  
     
  8. flat5

    Thread Starter Active Member

    Nov 13, 2008
    403
    17
    WBahn, yes " is found. The string length is 44. 0-43.
    You have to know the 'C' that the Arduino compiler uses.
    I guess there are quirks to it. I am starting here. I have no previous experience with "C".
     
  9. WBahn

    Moderator

    Mar 31, 2012
    17,715
    4,788
    Okay, if you say that random(43) is, in fact, returning 0 through and including 43 then I guess it is. That goes counter to what every random(N) function I have ever seen does, it goes counter to what djsfantasi said that random(M) function in the Arduino language does, and it goes counter to what the Arduino website says that this function does:

    http://www.arduino.cc/en/Reference/random

    It also appears that the Arduino language is neither C nor C++, but is rather based on both (which basically means that it is based on C++) with a bunch of Arduino-specific stuff crammed in.

    But if you are satisfied that using random(43) gets you the values you want, that is all that matters in the end.
     
  10. flat5

    Thread Starter Active Member

    Nov 13, 2008
    403
    17
    No, I did use that page to inform myself. On the page:

    // print a random number from 0 to 299
    randNumber = random(300);
    Serial.println(randNumber);

    Edit: huh? You are correct. I don't know why I'm getting the ".
    I should go to sleep. Now I'm confusing " and =.

    Edit: ok, I changed it to random(44) and am now seeing = and " on the screen.

    Thank you again, WBahn.
    I will try to sleep. It's 3:10 here.
     
    Last edited: May 3, 2015
  11. WBahn

    Moderator

    Mar 31, 2012
    17,715
    4,788
    This has the exact same problem. answers.substring(0) is going to return a pointer to a copy of whatever is in answers. That pointer, which is a memory address, is NOT going to be equal to the value stored in chkchr, which is an ASCII code.

    I'm also concerned about whether you are actually creating an instance of your "answers" string object.

    When you declare a variable such as

    String answers;

    does that invoke the constructor, or does it just allocate memory for the reference variable?

    I've cleaned up your code below:

    It would be really helpful if you told us what you want the code to do instead of expecting us to figure out what you want the code to do based on code that you've indicated does NOT do what you want it to do.
     
    KLillie likes this.
  12. flat5

    Thread Starter Active Member

    Nov 13, 2008
    403
    17
    Here is all the code. (I'll sleep later)
    Code (Text):
    1.  
    2. // send random Morse code
    3. // has improved random seed
    4. // uses tone/notone instead of 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; // a volume peak on my sounder. needed because I'm using a 220 ohm resistor in series.
    14. const int morseOutPin = 13;    // For Morse code output
    15.  
    16. void setup() {
    17.   pinMode(signalPin, OUTPUT);
    18.   pinMode(1, INPUT); // used in random seed routine
    19.   noTone(8);
    20.   pinMode(morseOutPin, OUTPUT);
    21.   Serial.begin(9600);
    22.   menu();
    23. }
    24.  
    25. void loop() {
    26.   parser();
    27. }
    28.  
    29. void menu() {
    30.   //Serial.println();
    31.   Serial.println("Send a random group of characters for Morse practice");
    32.   Serial.println("Press Spacebar [Enter] to start");
    33.   //Serial.println();
    34.   Serial.println("Enter 's'(value) to adjust letter space (1-whatever)");
    35.   //Serial.println();
    36.   Serial.println("Enter 'w'(value) to adjust wpm (Example: w20)");
    37.   //Serial.println();
    38.   Serial.println("Enter 'p'(value) to set tone pitch <p31-24000 or <0 for off");
    39.   //Serial.println();
    40.   Serial.println("Enter 'r'(value) to set how many characters in the row to send (1-89)");
    41.   //Serial.println();
    42.   Serial.println("Enter 'm' to display this menu");
    43.   //Serial.print();
    44.   Serial.println("Enter 'c' to clear screen on real terminals");
    45.   //Serial.print();
    46.   Serial.print("Currently: s:"); Serial.print(space); Serial.print(" w:"); Serial.print(wpm);
    47.   Serial.print(" r:"); Serial.print(row); Serial.print(" P:"); Serial.println(pitch);
    48.   Serial.println();
    49. }
    50.  
    51. void parser()
    52. {
    53.   unsigned int digits;
    54.   unsigned int value = 0;
    55.   do
    56.   {
    57.     digits = Serial.available();
    58.   }
    59.   while (digits < 1);
    60.   char keypress = Serial.read();
    61.   do
    62.   {
    63.     digits = Serial.available();
    64.   }
    65.   while
    66.   (digits < 0);
    67.   value = Serial.parseInt();
    68.   Serial.flush();
    69.   switch (keypress)
    70.   {
    71.     case 'm': case 'M': // display menu
    72.       {
    73.         menu();
    74.         break;
    75.       }
    76.     case ' ': // generate code
    77.       {
    78.         random_code();
    79.         break;
    80.       }
    81.     case 's': case 'S': // letter space length
    82.       {
    83.         if (value != 0) space = value;
    84.         Serial.print("Letter space(s) "); Serial.println(space);
    85.         break;
    86.       }
    87.     case 'w': case 'W': // wpm
    88.       {
    89.         if (value != 0) wpm = value;
    90.         elementWait = 1200 / wpm;
    91.         Serial.print("wpm: "); Serial.println(wpm);
    92.         break;
    93.       }
    94.     case 'r': case 'R': // how many to send (a row)
    95.       {
    96.         if (value != 0)
    97.         {
    98.           row = value;
    99.         }
    100.         Serial.print(row); Serial.println(" characters will be sent");
    101.         break;
    102.       }
    103.     case 'c': case 'C':
    104.       {
    105.         refresh_Screen(); // a real terminal is required for this to work
    106.         break;
    107.       }
    108.     case 'p': case 'P':
    109.       {
    110.         pitch = value;
    111.         if (pitch == 0)
    112.         {
    113.           pitch = 0;
    114.           noTone(8);
    115.           Serial.println("Tone echo is now off."); // stare at the led
    116.           break;
    117.         }
    118.         if (pitch < 31)
    119.         {
    120.           Serial.println("31 is minimum");
    121.           break;
    122.         }
    123.         if (pitch > 24000)
    124.         {
    125.           Serial.print("24000 is max");
    126.           break;
    127.         }
    128.         Serial.print("Tone pitch in Hz:"); Serial.println(pitch, DEC);
    129.         tone(8, pitch, 400);
    130.         break;
    131.       }
    132.   }
    133. }
    134.  
    135. void refresh_Screen()
    136. {
    137.   Serial.write(27); // ESC
    138.   Serial.write("[2J"); // clear screen
    139.   Serial.write(27); // ESC
    140.   Serial.write("[H"); // cursor to home
    141. }
    142.  
    143. void dit() {
    144.   digitalWrite(signalPin, HIGH);
    145.   if (pitch != 0) tone(8, pitch);
    146.   delay(elementWait);      // milliseconds - one dit
    147.   digitalWrite(signalPin, LOW);
    148.   noTone(8);
    149.   delay(elementWait);
    150. }
    151.  
    152. void dah() {
    153.   digitalWrite(signalPin, HIGH);
    154.   if (pitch != 0) tone(8, pitch);
    155.   delay(elementWait * 3);
    156.   digitalWrite(signalPin, LOW);
    157.   noTone(8);
    158.   delay(elementWait);
    159. }
    160.  
    161. void letter_space() {
    162.   delay(elementWait * space);
    163. }
    164.  
    165. void random_code() {
    166.   // send a random character's Morse equivlent
    167.   char* code_char[] =
    168.   { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
    169.     "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
    170.     ",", ".", "?", "!", ":", "\"", "'", "="
    171.   };
    172.   char* codes[] =
    173.   { ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--",
    174.     "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", // 26 letters
    175.     "-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.",     // 10 numbers
    176.     "--..--", ".-.-.-", "..--..", "..--.", "---...", ".-..-.", ".----.", "-...-"                  //  8 punctuation
    177.   };
    178.   String send_char; String answers; char* send_codes[row - 1];//array starts at 0. User inputs how many characters in a run (row on screen)
    179.   unsigned long seed = seedOut(31); randomSeed(seed);
    180.   for (unsigned int t = 0; t < row - 1 ; t++) // each run will be 'row' characters (+ 'row' spaces) but the last check needs a kludge
    181.   {
    182.     unsigned int randNumber = random(44); // 0 - 43, all characters.
    183.     String chkchr = code_char[randNumber]; // the ascii character random has picked
    184.     // see if the randNumber character is in string 'answers'. I remove this check if row > 44
    185.     if (answers.indexOf(chkchr) != -1 && row < 45)
    186.     {
    187.       t = t - 1;
    188.     }
    189.     else
    190.     {
    191.       // I decided I would need another long string to check if a character was repeated more than once.
    192.       // If I want a short run of characters I don't want them to repeat but if the run is >44 it's not so important if they repeat.
    193.       // So I have dropped that check.
    194.       answers.concat(code_char[randNumber]); answers.concat(" ");
    195.       send_codes[t] = (codes[randNumber]); // array of code character strings to be sent
    196.     }
    197.   }
    198.   for (unsigned int t = 0; t < row ; t++)
    199.   {
    200.     send_char = send_codes[t]; // send the code of a character
    201.     for (unsigned int i = 0; i < send_char.length(); i++) // break it down
    202.     {
    203.       String x;
    204.       x = send_char.substring(i, i + 1);
    205.       if (x == ".") dit(); else dah();
    206.     }
    207.     letter_space();
    208.   }
    209.   Serial.println(answers); Serial.println();
    210. }
    211.  
    212. // This code to develop a random seed is from here: http://www.utopiamechanicus.com/article/arduino-better-random-numbers/
    213. // It is much better than the routine that came with the compiler package.
    214. unsigned int bitOut(void)
    215. {
    216.   static unsigned long firstTime = 1, prev = 0;
    217.   unsigned long bit1 = 0, bit0 = 0, x = 0, port = 1, limit = 99;
    218.   if (firstTime)
    219.   {
    220.     firstTime = 0;
    221.     prev = analogRead(port);
    222.   }
    223.   while (limit--)
    224.   {
    225.     x = analogRead(port);
    226.     bit1 = (prev != x ? 1 : 0);
    227.     prev = x;
    228.     x = analogRead(port);
    229.     bit0 = (prev != x ? 1 : 0);
    230.     prev = x;
    231.     if (bit1 != bit0)
    232.       break;
    233.   }
    234.   return bit1;
    235. }
    236.  
    237. unsigned long seedOut(unsigned int noOfBits)
    238. {
    239.   // return value with 'noOfBits' random bits set
    240.   unsigned long seed = 0;
    241.   for (int i = 0; i < noOfBits; ++i)
    242.     seed = (seed << 1) | bitOut();
    243.   return seed;
    244. }
    245.  
    Arduino oscillator circuit.png
    I'm using a 555 osc. so I turn the tone off. option p=0
    I guess I'm happy with this version.
    WBahn, I'll look at your rewrite after I get some sleep.
     
  13. WBahn

    Moderator

    Mar 31, 2012
    17,715
    4,788
    I didn't rewrite anything, just reformatted it a bit to compensate for the lousy way that the forum editor handles pasted test.
     
  14. flat5

    Thread Starter Active Member

    Nov 13, 2008
    403
    17
    I'm still learning how to communicate with experienced programmers :)
    I thought of a much better way to do that function while trying to sleep.

    What I wanted:
    if row is 44 or less, allow no repeats (of a character).
    if a row is greater than 44 and less than 89 allow one repeat.

    I think this is the best way to achieve this.
    build 'answers' til 44 characters
    if a row is > 44 build 'answers2' till 88 characters (or less) using the same check for repeats.
    concat them. 'answers' is now a string of 1 to 88 characters with no more than one repeat of any character.
     
    Last edited: May 4, 2015
  15. djsfantasi

    AAC Fanatic!

    Apr 11, 2010
    2,790
    827
    Strings in Arduino C are different than an array of char in C. The comparison is valid on an Arduino and will succeed if both variables contain the same character value.
     
  16. flat5

    Thread Starter Active Member

    Nov 13, 2008
    403
    17
    This does what I wanted to accomplish in my last post.
    t is not allowed to be > 88
    Code (Text):
    1.  
    2. if (t < 44)
    3.     {
    4.       if (answers.indexOf(chkchr) != -1) t = t - 1;
    5.       else
    6.       {
    7.         answers.concat(code_char[randNumber]); answers.concat(" "); // add a space after each character for readability
    8.         send_codes[t] = (codes[randNumber]); // build array of code character strings to be sent
    9.       }
    10.     }
    11.     if (t > 43)
    12.     {
    13.       if (answers2.indexOf(chkchr) != -1) t = t - 1;
    14.       else
    15.       {
    16.         answers2.concat(code_char[randNumber]); answers2.concat(" ");
    17.         send_codes[t] = (codes[randNumber]);
    18.       }
    19.     }
    20.   .............
    21.   send code
    22.   .............
    23.   Serial.print(answers); Serial.println(answers2); Serial.println();
    24.  
     
    Last edited: May 4, 2015
  17. flat5

    Thread Starter Active Member

    Nov 13, 2008
    403
    17
    Updated full code. If you want the last version note the post edit date/time.
    I will update the code in this post of the thread.
    Code (Text):
    1.  
    2. // send random Morse code
    3. // has improved random seed
    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; // a volume peak on my sounder. needed because I'm using a 220 ohm resistor in series.
    14. const int morseOutPin = 13;    // For Morse code output
    15.  
    16. void setup() {
    17.   pinMode(signalPin, OUTPUT);
    18.   pinMode(1, INPUT); // used in random seed routine
    19.   noTone(8);
    20.   pinMode(morseOutPin, OUTPUT);
    21.   Serial.begin(9600);
    22.   menu();
    23. }
    24.  
    25. void loop() {
    26.   parser();
    27. }
    28.  
    29. void menu() {
    30.   //Serial.println();
    31.   Serial.println("Send a random group of characters for Morse practice");
    32.   Serial.println("Press Spacebar [Enter] to start");
    33.   //Serial.println();
    34.   Serial.println("Enter 's'(value) to adjust letter space (1-whatever)");
    35.   //Serial.println();
    36.   Serial.println("Enter 'w'(value) to adjust wpm (Example: w20)");
    37.   //Serial.println();
    38.   Serial.println("Enter 'p'(value) to set tone pitch <p31-24000 or <0 for off");
    39.   //Serial.println();
    40.   Serial.println("Enter 'r'(value) to set how many characters in the row to send (1-88)");
    41.   //Serial.println();
    42.   Serial.println("Enter 'm' to display this menu");
    43.   //Serial.print();
    44.   Serial.println("Enter 'c' to clear screen on real terminals");
    45.   //Serial.print();
    46.   Serial.print("Currently: s:"); Serial.print(space); Serial.print(" w:"); Serial.print(wpm);
    47.   Serial.print(" r:"); Serial.print(row); Serial.print(" P:"); Serial.println(pitch);
    48.   Serial.println();
    49. }
    50.  
    51. void parser()
    52. {
    53.   unsigned int digits;
    54.   unsigned int value = 0;
    55.   do
    56.   {
    57.     digits = Serial.available();
    58.   }
    59.   while (digits < 1);
    60.   char keypress = Serial.read();
    61.   do
    62.   {
    63.     digits = Serial.available();
    64.   }
    65.   while
    66.   (digits < 0);
    67.   value = Serial.parseInt();
    68.   Serial.flush();
    69.   switch (keypress)
    70.   {
    71.     case 'm': case 'M': // display menu
    72.       {
    73.         menu();
    74.         break;
    75.       }
    76.     case ' ': // generate code
    77.       {
    78.         random_code();
    79.         break;
    80.       }
    81.     case 's': case 'S': // letter space length
    82.       {
    83.         if (value != 0) space = value;
    84.         Serial.print("Letter space(s) "); Serial.println(space);
    85.         break;
    86.       }
    87.     case 'w': case 'W': // wpm
    88.       {
    89.         if (value != 0) wpm = value;
    90.         elementWait = 1200 / wpm;
    91.         Serial.print("wpm: "); Serial.println(wpm);
    92.         break;
    93.       }
    94.     case 'r': case 'R': // how many to send (a row)
    95.       {
    96.         if (value != 0 && value < 89)
    97.         {
    98.           row = value;
    99.    
    100.         Serial.print(row); Serial.println(" characters will be sent");
    101.         break;
    102.         }
    103.         else
    104.         {Serial.println("value must be 1-88");
    105.         break;
    106.         }
    107.       }
    108.     case 'c': case 'C':
    109.       {
    110.         refresh_Screen(); // a real terminal is required for this to work
    111.         break;
    112.       }
    113.     case 'p': case 'P':
    114.       {
    115.         pitch = value;
    116.         if (pitch == 0)
    117.         {
    118.           pitch = 0;
    119.           noTone(8);
    120.           Serial.println("Tone echo is now off."); // stare at the led
    121.           break;
    122.         }
    123.         if (pitch < 31)
    124.         {
    125.           Serial.println("31 is minimum");
    126.           break;
    127.         }
    128.         if (pitch > 24000)
    129.         {
    130.           Serial.print("24000 is max");
    131.           break;
    132.         }
    133.         Serial.print("Tone pitch in Hz:"); Serial.println(pitch, DEC);
    134.         tone(8, pitch, 400);
    135.         break;
    136.       }
    137.   }
    138. }
    139.  
    140. void refresh_Screen()
    141. {
    142.   Serial.write(27); // ESC
    143.   Serial.write("[2J"); // clear screen
    144.   Serial.write(27); // ESC
    145.   Serial.write("[H"); // cursor to home
    146. }
    147.  
    148. void dit() {
    149.   digitalWrite(signalPin, HIGH);
    150.   if (pitch != 0) tone(8, pitch);
    151.   delay(elementWait);      // milliseconds - one dit
    152.   digitalWrite(signalPin, LOW);
    153.   noTone(8);
    154.   delay(elementWait);
    155. }
    156.  
    157. void dah() {
    158.   digitalWrite(signalPin, HIGH);
    159.   if (pitch != 0) tone(8, pitch);
    160.   delay(elementWait * 3);
    161.   digitalWrite(signalPin, LOW);
    162.   noTone(8);
    163.   delay(elementWait);
    164. }
    165.  
    166. void letter_space() {
    167.   delay(elementWait * space);
    168. }
    169.  
    170. void random_code() {
    171.   // send a random character's Morse equivlent
    172.   char* code_char[] =
    173.   { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
    174.     "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
    175.     ",", ".", "?", "!", ":", "\"", "'", "="
    176.   };
    177.   char* codes[] =
    178.   { ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--",
    179.     "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", // 26 letters
    180.     "-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.",     // 10 numbers
    181.     "--..--", ".-.-.-", "..--..", "..--.", "---...", ".-..-.", ".----.", "-...-"                  //  8 punctuation
    182.   };
    183.   String send_char; String answers; String answers2;
    184.   char* send_codes[row]; //array starts at 0. User inputs how many characters in a run (row on screen)
    185.   unsigned long seed = seedOut(31); randomSeed(seed);
    186.   for (unsigned int t=0; t<row; t++) // each run will be 'row' characters (+ 'row' spaces) but the last check needs a kludge
    187.   {
    188.     unsigned int randNumber = random(44); // 0 - 43, all characters.
    189.     String chkchr = code_char[randNumber]; // the ascii character random has picked
    190.     // see if the randNumber character (chkchr) is in string 'answers' already. I remove this check if row > 44
    191.     if (t < 44)
    192.     {
    193.       if (answers.indexOf(chkchr) != -1) t = t - 1;
    194.       else
    195.       {
    196.         answers.concat(code_char[randNumber]); answers.concat(" "); // add a space after each character for readability
    197.         send_codes[t] = (codes[randNumber]); // build array of code character strings to be sent
    198.       }
    199.     }
    200.     if (t > 43 )
    201.     {
    202.       if (answers2.indexOf(chkchr) != -1) t = t - 1;
    203.       else
    204.       {
    205.         answers2.concat(code_char[randNumber]); answers2.concat(" ");
    206.         send_codes[t] = (codes[randNumber]);
    207.       }
    208.     }
    209.   }
    210.   for (unsigned int t = 0; t < row ; t++)
    211.   {
    212.     send_char = send_codes[t]; // send the code of a character
    213.     for (unsigned int i = 0; i < send_char.length(); i++) // break it down
    214.     {
    215.       String x;
    216.       x = send_char.substring(i, i + 1);
    217.       if (x == ".") dit(); else dah();
    218.     }
    219.     letter_space();
    220.   }
    221.   Serial.print(answers); Serial.println(answers2); Serial.println();
    222. }
    223.  
    224. // This code to develop a random seed is from here: http://www.utopiamechanicus.com/article/arduino-better-random-numbers/
    225. // It is much better than the routine that came with the compiler package.
    226. unsigned int bitOut(void)
    227. {
    228.   static unsigned long firstTime = 1, prev = 0;
    229.   unsigned long bit1 = 0, bit0 = 0, x = 0, port = 1, limit = 99;
    230.   if (firstTime)
    231.   {
    232.     firstTime = 0;
    233.     prev = analogRead(port);
    234.   }
    235.   while (limit--)
    236.   {
    237.     x = analogRead(port);
    238.     bit1 = (prev != x ? 1 : 0);
    239.     prev = x;
    240.     x = analogRead(port);
    241.     bit0 = (prev != x ? 1 : 0);
    242.     prev = x;
    243.     if (bit1 != bit0)
    244.       break;
    245.   }
    246.   return bit1;
    247. }
    248.  
    249. unsigned long seedOut(unsigned int noOfBits)
    250. {
    251.   // return value with 'noOfBits' random bits set
    252.   unsigned long seed = 0;
    253.   for (int i = 0; i < noOfBits; ++i)
    254.     seed = (seed << 1) | bitOut();
    255.   return seed;
    256. }
    257. [/code
     
    Last edited: May 5, 2015
  18. WBahn

    Moderator

    Mar 31, 2012
    17,715
    4,788
    So you're saying that myString.substring(5), for instance, returns an ASCII value if myString has six characters but it returns a reference to a string object if it has more than six?
     
  19. djsfantasi

    AAC Fanatic!

    Apr 11, 2010
    2,790
    827
    If you were to execute the line "Serial.print(myString.substring(5))" and myString was "abcdefghij" would you expect a pointer value or "ghij"?

    I'm saying that myString.substring(5), for instance, returns a reference to a string object that consists of one character if myString has six characters and it returns a reference to a string object that consists of multiple characters if it has more than six. Look at the examples in the Arduino reference.
     
  20. flat5

    Thread Starter Active Member

    Nov 13, 2008
    403
    17
    It returns the rest of the string.
    I think it is 0 based so would return "fghij".
     
Loading...