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

Thread Starter

flat5

Joined Nov 13, 2008
403
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:
void random_code() {
  // send a random character's Morse equivlent
  char* code_char[] =
  { "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",
    "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
    ",", ".", "?", "!", ":", "\"", "'", "="
  };
  char* codes[] =
  { ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--",
    "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", // 26 letters
    "-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.",     // 10 numbers
    "--..--", ".-.-.-", "..--..", "..--.", "---...", ".-..-.", ".----.", "-...-"                  //  8 punctuation
  };
  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)
  unsigned long seed = seedOut(31); randomSeed(seed);
  for (unsigned int t = 0; t < row ; t++) // each run will be 'row' characters (+ 'row' spaces)
  {
    unsigned int randNumber = random(43); // 0 - 43, all characters.
    String chkchr = code_char[randNumber]; // the ascii character random has picked

 // PROBLEM IS HERE ---------------------------------------------------------------------------------------------------------

    if (chkchr == (answers.substring(0))) // see if the randNumber character is in string 'answers'. I will fix this later if a row is > 44
    {
      t = t - 1;
    }

//----------------------------------------------------------------------------------------------------------------------------
    else
    {
      answers.concat(code_char[randNumber]); answers.concat(" ");
      send_codes[t] = (codes[randNumber]); // array of code character strings to be sent
    }
  }
   Serial.println(answers); Serial.println();
}
 

WBahn

Joined Mar 31, 2012
30,082
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?
 

Thread Starter

flat5

Joined Nov 13, 2008
403
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:

djsfantasi

Joined Apr 11, 2010
9,163
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.
 

WBahn

Joined Mar 31, 2012
30,082
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.
 

WBahn

Joined Mar 31, 2012
30,082
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.
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.
 

Thread Starter

flat5

Joined Nov 13, 2008
403
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:
if (answers.indexOf(chkchr) != -1  &&  row < 44)
    {
      t = t - 1;
    }
    else if (answers.indexOf(chkchr) != -1  &&  row > 43  &&  row < 89)
    { 
     chkAgain = chkAgain+1; 
     if (chkAgain == 1) t = t - 1;
    } 
    else
    {
      answers.concat(code_char[randNumber]); answers.concat(" ");
      send_codes[t] = (codes[randNumber]); // array of code character strings to be sent
    }
 

Thread Starter

flat5

Joined Nov 13, 2008
403
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".
 

WBahn

Joined Mar 31, 2012
30,082
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".
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.
 

Thread Starter

flat5

Joined Nov 13, 2008
403
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:

WBahn

Joined Mar 31, 2012
30,082
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) ...
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:

Now I'm trying get this correct. first if is ok. Second if does not work. rows come out short.
Code:
if (answers.indexOf(chkchr) != -1  &&  row < 44)
{
   t = t - 1;
}
else
   if (answers.indexOf(chkchr) != -1  &&  row > 43  &&  row < 89)
   {
      chkAgain = chkAgain+1;
      if (chkAgain == 1)
         t = t - 1;
   }
   else
   {
      answers.concat(code_char[randNumber]); answers.concat(" ");
      send_codes[t] = (codes[randNumber]); // array of code character strings to be sent
   }
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.
 

Thread Starter

flat5

Joined Nov 13, 2008
403
Here is all the code. (I'll sleep later)
Code:
// send random Morse code
// has improved random seed
// uses tone/notone instead of external oscillator.
// Plug speaker to Analog pin8 and gnd. Use a resistor or pot in series if you want to. I used 220 ohm.

#include <Arduino.h>
byte signalPin = 13; // will control oscillator speaker
unsigned int wpm = 20;
unsigned int elementWait = 1200 / wpm;
unsigned int row = 43;
unsigned int space = 2; // time between characters. It is good to send the chacters faster than the space between them for practice.
unsigned int pitch = 846; // a volume peak on my sounder. needed because I'm using a 220 ohm resistor in series.
const int morseOutPin = 13;    // For Morse code output

void setup() {
  pinMode(signalPin, OUTPUT);
  pinMode(1, INPUT); // used in random seed routine
  noTone(8);
  pinMode(morseOutPin, OUTPUT);
  Serial.begin(9600);
  menu();
}

void loop() {
  parser();
}

void menu() {
  //Serial.println();
  Serial.println("Send a random group of characters for Morse practice");
  Serial.println("Press Spacebar [Enter] to start");
  //Serial.println();
  Serial.println("Enter 's'(value) to adjust letter space (1-whatever)");
  //Serial.println();
  Serial.println("Enter 'w'(value) to adjust wpm (Example: w20)");
  //Serial.println();
  Serial.println("Enter 'p'(value) to set tone pitch <p31-24000 or <0 for off");
  //Serial.println();
  Serial.println("Enter 'r'(value) to set how many characters in the row to send (1-89)");
  //Serial.println();
  Serial.println("Enter 'm' to display this menu");
  //Serial.print();
  Serial.println("Enter 'c' to clear screen on real terminals");
  //Serial.print();
  Serial.print("Currently: s:"); Serial.print(space); Serial.print(" w:"); Serial.print(wpm);
  Serial.print(" r:"); Serial.print(row); Serial.print(" P:"); Serial.println(pitch);
  Serial.println();
}

void parser()
{
  unsigned int digits;
  unsigned int value = 0;
  do
  {
    digits = Serial.available();
  }
  while (digits < 1);
  char keypress = Serial.read();
  do
  {
    digits = Serial.available();
  }
  while
  (digits < 0);
  value = Serial.parseInt();
  Serial.flush();
  switch (keypress)
  {
    case 'm': case 'M': // display menu
      {
        menu();
        break;
      }
    case ' ': // generate code
      {
        random_code();
        break;
      }
    case 's': case 'S': // letter space length
      {
        if (value != 0) space = value;
        Serial.print("Letter space(s) "); Serial.println(space);
        break;
      }
    case 'w': case 'W': // wpm
      {
        if (value != 0) wpm = value;
        elementWait = 1200 / wpm;
        Serial.print("wpm: "); Serial.println(wpm);
        break;
      }
    case 'r': case 'R': // how many to send (a row)
      {
        if (value != 0)
        {
          row = value;
        }
        Serial.print(row); Serial.println(" characters will be sent");
        break;
      }
    case 'c': case 'C':
      {
        refresh_Screen(); // a real terminal is required for this to work
        break;
      }
    case 'p': case 'P':
      {
        pitch = value;
        if (pitch == 0)
        {
          pitch = 0;
          noTone(8);
          Serial.println("Tone echo is now off."); // stare at the led
          break;
        }
        if (pitch < 31)
        {
          Serial.println("31 is minimum");
          break;
        }
        if (pitch > 24000)
        {
          Serial.print("24000 is max");
          break;
        }
        Serial.print("Tone pitch in Hz:"); Serial.println(pitch, DEC);
        tone(8, pitch, 400);
        break;
      }
  }
}

void refresh_Screen()
{
  Serial.write(27); // ESC
  Serial.write("[2J"); // clear screen
  Serial.write(27); // ESC
  Serial.write("[H"); // cursor to home
}

void dit() {
  digitalWrite(signalPin, HIGH);
  if (pitch != 0) tone(8, pitch);
  delay(elementWait);      // milliseconds - one dit
  digitalWrite(signalPin, LOW);
  noTone(8);
  delay(elementWait);
}

void dah() {
  digitalWrite(signalPin, HIGH);
  if (pitch != 0) tone(8, pitch);
  delay(elementWait * 3);
  digitalWrite(signalPin, LOW);
  noTone(8);
  delay(elementWait);
}

void letter_space() {
  delay(elementWait * space);
}

void random_code() {
  // send a random character's Morse equivlent
  char* code_char[] =
  { "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",
    "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
    ",", ".", "?", "!", ":", "\"", "'", "="
  };
  char* codes[] =
  { ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--",
    "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", // 26 letters
    "-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.",     // 10 numbers
    "--..--", ".-.-.-", "..--..", "..--.", "---...", ".-..-.", ".----.", "-...-"                  //  8 punctuation
  };
  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)
  unsigned long seed = seedOut(31); randomSeed(seed);
  for (unsigned int t = 0; t < row - 1 ; t++) // each run will be 'row' characters (+ 'row' spaces) but the last check needs a kludge
  {
    unsigned int randNumber = random(44); // 0 - 43, all characters.
    String chkchr = code_char[randNumber]; // the ascii character random has picked
    // see if the randNumber character is in string 'answers'. I remove this check if row > 44
    if (answers.indexOf(chkchr) != -1 && row < 45)
    {
      t = t - 1;
    }
    else
    {
      // I decided I would need another long string to check if a character was repeated more than once.
      // 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.
      // So I have dropped that check.
      answers.concat(code_char[randNumber]); answers.concat(" ");
      send_codes[t] = (codes[randNumber]); // array of code character strings to be sent
    }
  }
  for (unsigned int t = 0; t < row ; t++)
  {
    send_char = send_codes[t]; // send the code of a character
    for (unsigned int i = 0; i < send_char.length(); i++) // break it down
    {
      String x;
      x = send_char.substring(i, i + 1);
      if (x == ".") dit(); else dah();
    }
    letter_space();
  }
  Serial.println(answers); Serial.println();
}

// This code to develop a random seed is from here: http://www.utopiamechanicus.com/article/arduino-better-random-numbers/
// It is much better than the routine that came with the compiler package.
unsigned int bitOut(void)
{
  static unsigned long firstTime = 1, prev = 0;
  unsigned long bit1 = 0, bit0 = 0, x = 0, port = 1, limit = 99;
  if (firstTime)
  {
    firstTime = 0;
    prev = analogRead(port);
  }
  while (limit--)
  {
    x = analogRead(port);
    bit1 = (prev != x ? 1 : 0);
    prev = x;
    x = analogRead(port);
    bit0 = (prev != x ? 1 : 0);
    prev = x;
    if (bit1 != bit0)
      break;
  }
  return bit1;
}

unsigned long seedOut(unsigned int noOfBits)
{
  // return value with 'noOfBits' random bits set
  unsigned long seed = 0;
  for (int i = 0; i < noOfBits; ++i)
    seed = (seed << 1) | bitOut();
  return seed;
}
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.
 

WBahn

Joined Mar 31, 2012
30,082
I didn't rewrite anything, just reformatted it a bit to compensate for the lousy way that the forum editor handles pasted test.
 

Thread Starter

flat5

Joined Nov 13, 2008
403
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:

djsfantasi

Joined Apr 11, 2010
9,163
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.
 

Thread Starter

flat5

Joined Nov 13, 2008
403
This does what I wanted to accomplish in my last post.
t is not allowed to be > 88
Code:
if (t < 44)
    {
      if (answers.indexOf(chkchr) != -1) t = t - 1;
      else
      {
        answers.concat(code_char[randNumber]); answers.concat(" "); // add a space after each character for readability
        send_codes[t] = (codes[randNumber]); // build array of code character strings to be sent
      }
    }
    if (t > 43)
    {
      if (answers2.indexOf(chkchr) != -1) t = t - 1;
      else
      {
        answers2.concat(code_char[randNumber]); answers2.concat(" ");
        send_codes[t] = (codes[randNumber]);
      }
    }
  .............
  send code
  .............
  Serial.print(answers); Serial.println(answers2); Serial.println();
 
Last edited:

Thread Starter

flat5

Joined Nov 13, 2008
403
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:
// send random Morse code
// has improved random seed
// choice of tone/noTone or external oscillator.
// Plug speaker to Analog pin8 and gnd. Use a resistor or pot in series if you want to. I used 220 ohm.

#include <Arduino.h>
byte signalPin = 13; // will control oscillator speaker
unsigned int wpm = 20;
unsigned int elementWait = 1200 / wpm;
unsigned int row = 43;
unsigned int space = 2; // time between characters. It is good to send the chacters faster than the space between them for practice.
unsigned int pitch = 846; // a volume peak on my sounder. needed because I'm using a 220 ohm resistor in series.
const int morseOutPin = 13;    // For Morse code output

void setup() {
  pinMode(signalPin, OUTPUT);
  pinMode(1, INPUT); // used in random seed routine
  noTone(8);
  pinMode(morseOutPin, OUTPUT);
  Serial.begin(9600);
  menu();
}

void loop() {
  parser();
}

void menu() {
  //Serial.println();
  Serial.println("Send a random group of characters for Morse practice");
  Serial.println("Press Spacebar [Enter] to start");
  //Serial.println();
  Serial.println("Enter 's'(value) to adjust letter space (1-whatever)");
  //Serial.println();
  Serial.println("Enter 'w'(value) to adjust wpm (Example: w20)");
  //Serial.println();
  Serial.println("Enter 'p'(value) to set tone pitch <p31-24000 or <0 for off");
  //Serial.println();
  Serial.println("Enter 'r'(value) to set how many characters in the row to send (1-88)");
  //Serial.println();
  Serial.println("Enter 'm' to display this menu");
  //Serial.print();
  Serial.println("Enter 'c' to clear screen on real terminals");
  //Serial.print();
  Serial.print("Currently: s:"); Serial.print(space); Serial.print(" w:"); Serial.print(wpm);
  Serial.print(" r:"); Serial.print(row); Serial.print(" P:"); Serial.println(pitch);
  Serial.println();
}

void parser()
{
  unsigned int digits;
  unsigned int value = 0;
  do
  {
    digits = Serial.available();
  }
  while (digits < 1);
  char keypress = Serial.read();
  do
  {
    digits = Serial.available();
  }
  while
  (digits < 0);
  value = Serial.parseInt();
  Serial.flush();
  switch (keypress)
  {
    case 'm': case 'M': // display menu
      {
        menu();
        break;
      }
    case ' ': // generate code
      {
        random_code();
        break;
      }
    case 's': case 'S': // letter space length
      {
        if (value != 0) space = value;
        Serial.print("Letter space(s) "); Serial.println(space);
        break;
      }
    case 'w': case 'W': // wpm
      {
        if (value != 0) wpm = value;
        elementWait = 1200 / wpm;
        Serial.print("wpm: "); Serial.println(wpm);
        break;
      }
    case 'r': case 'R': // how many to send (a row)
      {
        if (value != 0 && value < 89)
        {
          row = value;
   
        Serial.print(row); Serial.println(" characters will be sent");
        break;
        }
        else
        {Serial.println("value must be 1-88");
        break;
        }
      }
    case 'c': case 'C':
      {
        refresh_Screen(); // a real terminal is required for this to work
        break;
      }
    case 'p': case 'P':
      {
        pitch = value;
        if (pitch == 0)
        {
          pitch = 0;
          noTone(8);
          Serial.println("Tone echo is now off."); // stare at the led
          break;
        }
        if (pitch < 31)
        {
          Serial.println("31 is minimum");
          break;
        }
        if (pitch > 24000)
        {
          Serial.print("24000 is max");
          break;
        }
        Serial.print("Tone pitch in Hz:"); Serial.println(pitch, DEC);
        tone(8, pitch, 400);
        break;
      }
  }
}

void refresh_Screen()
{
  Serial.write(27); // ESC
  Serial.write("[2J"); // clear screen
  Serial.write(27); // ESC
  Serial.write("[H"); // cursor to home
}

void dit() {
  digitalWrite(signalPin, HIGH);
  if (pitch != 0) tone(8, pitch);
  delay(elementWait);      // milliseconds - one dit
  digitalWrite(signalPin, LOW);
  noTone(8);
  delay(elementWait);
}

void dah() {
  digitalWrite(signalPin, HIGH);
  if (pitch != 0) tone(8, pitch);
  delay(elementWait * 3);
  digitalWrite(signalPin, LOW);
  noTone(8);
  delay(elementWait);
}

void letter_space() {
  delay(elementWait * space);
}

void random_code() {
  // send a random character's Morse equivlent
  char* code_char[] =
  { "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",
    "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
    ",", ".", "?", "!", ":", "\"", "'", "="
  };
  char* codes[] =
  { ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--",
    "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", // 26 letters
    "-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.",     // 10 numbers
    "--..--", ".-.-.-", "..--..", "..--.", "---...", ".-..-.", ".----.", "-...-"                  //  8 punctuation
  };
  String send_char; String answers; String answers2;
  char* send_codes[row]; //array starts at 0. User inputs how many characters in a run (row on screen)
  unsigned long seed = seedOut(31); randomSeed(seed);
  for (unsigned int t=0; t<row; t++) // each run will be 'row' characters (+ 'row' spaces) but the last check needs a kludge
  {
    unsigned int randNumber = random(44); // 0 - 43, all characters.
    String chkchr = code_char[randNumber]; // the ascii character random has picked
    // see if the randNumber character (chkchr) is in string 'answers' already. I remove this check if row > 44
    if (t < 44)
    {
      if (answers.indexOf(chkchr) != -1) t = t - 1;
      else
      {
        answers.concat(code_char[randNumber]); answers.concat(" "); // add a space after each character for readability
        send_codes[t] = (codes[randNumber]); // build array of code character strings to be sent
      }
    }
    if (t > 43 )
    {
      if (answers2.indexOf(chkchr) != -1) t = t - 1;
      else
      {
        answers2.concat(code_char[randNumber]); answers2.concat(" ");
        send_codes[t] = (codes[randNumber]);
      }
    }
  }
  for (unsigned int t = 0; t < row ; t++)
  {
    send_char = send_codes[t]; // send the code of a character
    for (unsigned int i = 0; i < send_char.length(); i++) // break it down
    {
      String x;
      x = send_char.substring(i, i + 1);
      if (x == ".") dit(); else dah();
    }
    letter_space();
  }
  Serial.print(answers); Serial.println(answers2); Serial.println();
}

// This code to develop a random seed is from here: http://www.utopiamechanicus.com/article/arduino-better-random-numbers/
// It is much better than the routine that came with the compiler package.
unsigned int bitOut(void)
{
  static unsigned long firstTime = 1, prev = 0;
  unsigned long bit1 = 0, bit0 = 0, x = 0, port = 1, limit = 99;
  if (firstTime)
  {
    firstTime = 0;
    prev = analogRead(port);
  }
  while (limit--)
  {
    x = analogRead(port);
    bit1 = (prev != x ? 1 : 0);
    prev = x;
    x = analogRead(port);
    bit0 = (prev != x ? 1 : 0);
    prev = x;
    if (bit1 != bit0)
      break;
  }
  return bit1;
}

unsigned long seedOut(unsigned int noOfBits)
{
  // return value with 'noOfBits' random bits set
  unsigned long seed = 0;
  for (int i = 0; i < noOfBits; ++i)
    seed = (seed << 1) | bitOut();
  return seed;
}
[/code
 
Last edited:

WBahn

Joined Mar 31, 2012
30,082
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.
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?
 

djsfantasi

Joined Apr 11, 2010
9,163
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.
 
Top