Inconsistent serial communications

Hello,

I'm having issues with serial communications between my computer and the arduino (Uno R3 in this case, however it's the same for my Mega and Due). Right now I'm just working on getting the sketch to ID different headers. I'm working with this as test code:

boolean state = true;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(13, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  /*if (Serial.available()) {
    if (Serial.find("a")) {
      digitalWrite(13, state);
      state = !state;
    }*/
  if (Serial.available() > 0) {
    if (Serial.find("B")) {
      Serial.println("test");
    }
    if (Serial.find("V")) {
      Serial.println("Why does this work?");
    }
    if (Serial.find("C")) {
      Serial.println("Hope this works");
    }
    return;
  }
}

As you can see I commented out the LED toggling, and I'm just having it echo when it receives different characters.

The issue is that sometimes it responds, but most of the time i get nothing back. I can see the RX line blink everytime I send, but only maybe 1 in 10 times does it respond. Can anyone show me what I'm doing wrong?

If this helps I'm on OSX Maverics, just updated Arduino to 1.6.4

I don't even know what Serial.find( ) is, I would suggest not using it, it doesn't seem to be very popular.

Do you know the difference between a single char and a string ? Perhaps you should use Serial.find('B') instead of Serial.find("B") ? But really, I wouldn't use it at all.

Try this

while ( Serial.available() > 0 )
{
    char c = Serial.read() ;
    if ( c == 'B' ) Serial.println("Got B");
    else if ( c == 'V')  Serial.println("Got V");
    else Serial.println("Got something else");
}

i am not recommending the use of Serial.find() But can we use Serial.find() to a char?

Serial.find() reads data from the serial buffer until the target string of given length is found. The function returns true if target string is found, false if it times out.

Spaceheater: The issue is that sometimes it responds, but most of the time i get nothing back. I can see the RX line blink everytime I send, but only maybe 1 in 10 times does it respond.

may be due to return... what's the use of return in the code?

The functionality of that serial.find( ) does not seem to be very well defined.

If you look through the serial buffer for the string "B", and don't find it, what then ? If you then ask for Serial.find("C"), does it start all over again ? Or start from where it gave up looking for "B" ?

It doesn't make a lot of sense when your loop( ) function will be running much faster than the characters are coming in.

Also, if the plan of Serial.find( ) is to leave the characters in the buffer and search through them, without removing them from the buffer, then what is actually going to remove characters from the buffer ? Nothing, probably. The buffer will overflow.

Most of these functions created with the intention of helping stupid people, haven't been well thought through and don't work very well. Avoid them.

The return keyword in your code is not useful, but it won't make any difference to the flow of your code, the way you have used it.

Try running this and see if it's easier to follow than your code.

#define LED    13
boolean state = true;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(LED, OUTPUT);
}

void loop() 
{
  char chr;
  
  if (Serial.available() > 0) {
    chr = toupper(Serial.read());     
    switch (chr) {
      case 'A':
        digitalWrite(13, state);
        state = !state;
        break;
      case 'B':
        Serial.println("test");
        break;
      case 'C':
        Serial.println("Hope this works");
        break;
      case 'V':
        Serial.println("Why does this work?");
        break;
      default:
        Serial.print("Shouldn't be here. chr = ");
        Serial.println(chr, HEX);
        break; 
     }
  }
}

michinyon: Do you know the difference between a single char and a string ? Perhaps you should use Serial.find('B') instead of Serial.find("B") ?

Yes, I know the difference. The actual tags I'm using in the code are strings, hence the "". The code I posted was just the simplest possible that reproduced the error.

michinyon: The functionality of that serial.find( ) does not seem to be very well defined.

If you look through the serial buffer for the string "B", and don't find it, what then ? If you then ask for Serial.find("C"), does it start all over again ? Or start from where it gave up looking for "B" ?

It doesn't make a lot of sense when your loop( ) function will be running much faster than the characters are coming in.

Also, if the plan of Serial.find( ) is to leave the characters in the buffer and search through them, without removing them from the buffer, then what is actually going to remove characters from the buffer ? Nothing, probably. The buffer will overflow.

Most of these functions created with the intention of helping stupid people, haven't been well thought through and don't work very well. Avoid them.

The return keyword in your code is not useful, but it won't make any difference to the flow of your code, the way you have used it.

I agree that the documentation is lacking, to put it nicely. I was under the impression that it would do just that, search the buffer for the target without clearing, which I deal with elsewhere. I haven't had any overflow issues. It seems to clear the buffer once the target is found, though, otherwise it would keep sending on each loop. Either way it's too much of a pain to deal with. I was hoping to leave things in the buffer, retrieving and clearing them when needed, but it's not that important.

As far as the return; that's just a leftover from copy/paste. These aren't the droids you're looking for.

michinyon:
Most of these functions created with the intention of helping stupid people,

or someone who never used a micro controller before and got no idea how it works.

If you are planning to sit there with the serial monitor connected to the serial, and type B or V to make your toy robot go forwards and backwards, or whatever you are planning to do, then you might need to consider that there will be carriage return and/or linefeed characters in your serial stream.

michinyon: If you are planning to sit there with the serial monitor connected to the serial, and type B or V to make your toy robot go forwards and backwards, or whatever you are planning to do, then you might need to consider that there will be carriage return and/or linefeed characters in your serial stream.

Thank you for assuming that my project is a toy, I'm stupid, I can't read the documentation, and I have no idea what I'm doing. It makes me feel good knowing that the internet is still full of people like you.

The examples in serial input basics are simple reliable non-blocking ways to receive data.

Thank you for assuming that my project is a toy, I'm stupid, I can't read the documentation, and I have no idea what I'm doing. It makes me feel good knowing that the internet is still full of people like you.

@michinyon may have been mistaken in thinking your project is to control a toy robot but nothing in his Post suggests that he thinks you are stupid, or are incapable of reading documention. I think you owe an apology.

All he has done is point out something you need to take into account.

And I don't think you had told us your project is NOT a toy robot so I think his assumption was perfectly reasonable.

...R

Thank you for assuming that my project is a toy, I'm stupid, I can't read the documentation, and I have no idea what I'm doing. It makes me feel good knowing that the internet is still full of people like you.

You will notice this forum has participants who appear to have been born with a broom stick in their ass. That being said, you might need to expand on just what you want to do. Below is simple serial code that looks for specific characters in a captured String. There are other String functions that perform actions with the contents of the captured Strings.

// 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);
      Serial.println("LED ON");
    }

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

    readString="";
  } 
}