sending a word

hi :)

so I've connected my Bluetooth module to the Arduino and my phone and i'm controlling 3 leds by sending A if i want to turn the red led on and B if i want to turn the orange one .. etc.

but now i wand to send a word such Red to turn the red one but i really can't figure out how .. any help please :~

and here's the code :

int led1 = 8; int led2 = 7; int led3 = 4; char state = 0;

void setup () { Serial.begin (9600); pinMode(led1, OUTPUT); pinMode(led2, OUTPUT); pinMode(led3, OUTPUT); }

void loop () { if (Serial.available () > 0) { state = Serial.read (); } if (state == 'A') { digitalWrite (led1, HIGH); digitalWrite (led2, LOW); digitalWrite (led3, LOW); } if (state == 'B') { digitalWrite (led1, LOW); digitalWrite (led2, HIGH); digitalWrite (led3, LOW); } if (state == 'C') { digitalWrite (led1, LOW); digitalWrite (led2, LOW); digitalWrite (led3, HIGH); } }

Arduino can only read one character at a time, so you need an array that can store the characters as they come in:

char myBuffer[10+1]; // Can receive 10 characters plus the null terminator

You also need a variable that keeps track of where in the array the next available slot is:

int myIndex = 0;

Every time you read a byte:

inByte = Serial.read();

You check if it matches a terminating character. This can be anything of your choosing, but a common tactic is to have the serial monitor send a newline, and use that:

if (inByte == '\n')

If this is true, then you can use strcmp() to see if it matches your string:

if (strcmp(myBuffer, "Red") == 0)

And take the action accordingly. You should also clear the buffer:

myBuffer[0] = '\0';
myIndex = 0;

If it does not match the new line character, you stick it into the buffer, increment the index and null terminate the array (required for use with string functions like strcmp()):

myBuffer[myIndex] = inByte; // put byte in buffer
myIndex++; // move to next index
myBuffer[myIndex] = '\0'; // and null terminate the array

If you are looking for the capital letter here:

state = Serial.read ();

Then look for the leading letter in the colour like an 'R' an 'O' or a 'B' for example

your sketch ignores anything that it isn't explicitly looking for

else you have to look at parsing the word

edit:

The code didn't work at all.

There is no advantage in sending 3 characters where one would do, and a lot of disadvantages (as you have discovered). The only reason I can think of for going beyond a single character is if you have more than about 62 options - 26 capitals, 26 lower case + 10 numerals.

I can well understand that the user of the phone might find it easier to type the full colour name rather than remember abbreviations. But computers are great at converting long words into abbreviations to minimize the amount of data that needs to be transmitted.

...R

thx guys ^^ much appreciated :) :)

Very simple serial code that might be of interest.

// zoomkat 8-6-10 serial I/O string test
// type a string in serial monitor. then send or enter
// for IDE 0019 and later

//A very simple example of sending a string of characters 
//from the serial monitor, capturing the individual 
//characters into a String, then evaluating the contents 
//of the String to possibly perform an action (on/off board LED).

int ledPin = 13;
String readString;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT); 
  Serial.println("serial on/off test 0021"); // so I can keep track
}

void loop() {

  while (Serial.available()) {
    delay(3);  
    char c = Serial.read();
    readString += c; 
  }

  if (readString.length() >0) {
    Serial.println(readString);

    if(readString.indexOf("on") >=0)
    {
      digitalWrite(ledPin, HIGH);
    }

    if(readString.indexOf("off") >=0)
    {
      digitalWrite(ledPin, LOW);
    }

    readString="";
  } 
}

It's worth pointing out that unless you're a very fast typist, or the commands are machine-generated, you shouldn't consider using Zoomkat's code with anything but the serial monitor, which sends a stream of characters one immediately after the other when you hit "send".

zoomkat: Very simple serial code that might be of interest.

// zoomkat 8-6-10 serial I/O string test
// type a string in serial monitor. then send or enter
// for IDE 0019 and later

//A very simple example of sending a string of characters //from the serial monitor, capturing the individual //characters into a String, then evaluating the contents //of the String to possibly perform an action (on/off board LED).

int ledPin = 13; String readString;

void setup() {   Serial.begin(9600);   pinMode(ledPin, OUTPUT);   Serial.println("serial on/off test 0021"); // so I can keep track }

void loop() {

  while (Serial.available()) {     delay(3);      char c = Serial.read();     readString += c;   }

  if (readString.length() >0) {     Serial.println(readString);

    if(readString.indexOf("on") >=0)     {       digitalWrite(ledPin, HIGH);     }

    if(readString.indexOf("off") >=0)     {       digitalWrite(ledPin, LOW);     }

    readString="";   } }

Can you please explain this for me.

 if(readString.indexOf("off") >=0)

Why do you use ">=0"? Wouldn't "==1" be sufficient? Why would the count be more than, or equal to 0?

Try this code. I have made a smaller version, but it needs a modified version of the HardwareSerial library to work.

It’s not pretty, but it works.

Edited: Had to add delay(1) back in, to get it to work correctly.

char * strings[] = {
  "RED", "GREEN", "BLUE","ORANGE"};
byte i = 0, j=0;
unsigned long _startMillis = 0;
char data[20];
int index = 0;
boolean search = false, found = false;
#define arrSize(x) sizeof(x)/sizeof(x[0])

void setup()
{
  Serial.begin(115200);
  clear(20);
  Serial.println(arrSize(strings)); // shows 4 to indicate the 4 different colors
}

void loop()
{
  searchBuff(20);
}

void clear(byte samples)
{
  int k = 0;
  while(k < samples)
  {
    data[k] = 0;
    k++;
  }
  search = false;
}

void searchBuff(byte samples) // how many samples you want to collect from the buffer to check
{
 if(Serial.available() > 0) // this collects chars from the buffer to cycle through
  {
    for(int S = 0, tmp; S < samples; S++)
    {
      tmp = Serial.read();
      if(tmp != '\n'  || tmp != '\r' || tmp != -1)
        data[S] = tmp; 
      delay(1);
    }
    search = true;
    found = false;
  }
  index = 0;

  if(search)
  {
    j = 0;
    while(!found)
    {
      for(byte i = 0; i < samples; i++)
      {
        if(data[i] != strings[j][index])
          index = 0; // reset index if any char does not match

        if( data[i] == strings[j][index]) // if a char does match, see if any more match
        {
          if(index == strlen(strings[j])-1) // return true if all chars in the target match
          {
            Serial.print("Found ");
            Serial.println(strings[j]);
            j = 0; // reset strings index
            index = 0; // reset matched char counter
            clear(samples);
            found = true;
            break; 
          }
          index++;
          found = false;
        }
      }
      if( (j >= arrSize(strings)) && !found) // if nothing is found, show "Not found"
      {
        Serial.println("not found");
        j = 0;
        clear(samples);
        break;
      }
      else
        j++;
    }
  } 
}

It's not pretty, but it works.

For some definition of "works". Relying on delay() instead of proper delimiters is a really bad idea.

I added the delay because it wasn't collecting everything.

I edited the code.

I edited the code

Hmmm.

if(Serial.available() > 0) // this collects chars from the buffer to cycle through
  {
    for(int S=0; S < samples; S++)
    {
      tmp = Serial.read();

What now?
The purpose of doing it like this is so the code can have multiple passes through what came in the buffer. Every time you do a Serial.read(), it pops an int out of the buffer until the buffer is empty. If you continue to read from the buffer after it is empty, it will return -1.

It doesn’t really matter what is stored as long as the code has a copy of the buffer, even if it is empty (doesn’t really serve a point if it is empty though).

This one is better, it will search the buffer for all the strings and show which ones it finds. If it doesn’t find anything, it will show “not found”.

char * strings[] = {
  "RED", "GREEN", "BLUE","ORANGE"};
  
byte i = 0, j=0;
unsigned long _startMillis = 0;
char data[20];
int index = 0;
boolean search = false, found = false;
#define arrSize(x) sizeof(x)/sizeof(x[0])

void setup()
{
  Serial.begin(115200);
  clear(20);
  Serial.println(arrSize(strings));
}

void loop()
{
  searchBuff(20);
}

void searchBuff(byte samples)
{
  if(Serial.available() > 0)
  {
    for(int S = 0, tmp; S < samples; S++)
    {
      tmp = Serial.read();
      if(tmp != '\n' || tmp != '\r' || tmp != '\0')
        data[S] = tmp; 
      delay(1);
    }
    search = true;
    found = false;
  }
  index = 0; 

  if(search)
  {
    j = 0;
    while(j < arrSize(strings))
    {
      for(byte i = 0; i < samples; i++)
      {
        if(data[i] != strings[j][index])
          index = 0; // reset index if any char does not match

        if( data[i] == strings[j][index])
        {
          if(index == strlen(strings[j])-1) // is true if all chars in the target match
          {
            Serial.print("Found ");
            Serial.println(strings[j]);
            index = 0;
            found = true;
            break;
          }
          else
            index++;
        }
      }//end of FOR loop
      if(found)
        search = false;
      j++; 
    }// End of WHILE loop
    if(!found)
    {
      Serial.println("not found");
      search = false;
    }
    
    clear(samples);
  }// End of Search
}

void clear(byte samples)
{
  int k = 0;
  while(k < samples)
  {
    data[k] = 0;
    k++;
  }
  search = false;
}