1

I am wondering what is wrong with my code below. I have 2 issues.

The first issue, I am checking if c equals "hi" and if it does then display said hi. I currently see the output of c when it hits Serial.println(c); but never see the said hi even though Serial.println(c); does say "said hi".

The second issue is that when I start up the Arduino I am sending the AT command using bluetooth.println("AT");, but all it seems to do is display AT on the phone instead of OK as it should.

#include <SoftwareSerial.h>

SoftwareSerial bluetooth(8,9); // RX, TX

void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.println("PC Side Connected");
  bluetooth.begin(9600);
  while (!bluetooth) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  bluetooth.println("Bluetooth Side Connected");
  bluetooth.println("AT"); // just a check
}

void loop() { // run over and over
  String c;
  if (bluetooth.available()) {
    //What is sent back from the BT module
    c = bluetooth.readStringUntil('\n');
    delay(10);
    Serial.println(c);
    if (c.equals('hi')) {
      Serial.println("said hi");
    }
  }
  if (Serial.available()) {
    //Send back data to Bluetooth module
    bluetooth.write(Serial.read());
  }
}

enter image description here

4
  • There’s nothing wrong with reading it just checking the value within the if statement.
    – StealthRT
    Dec 22, 2017 at 0:21
  • @AltAir Why? .read() reads a single char not a string.
    – gre_gor
    Dec 22, 2017 at 1:46
  • Could you edit the question and include the exact output please?
    – Mark Smith
    Dec 22, 2017 at 7:15
  • @MarkSmith picture added in the OP.
    – StealthRT
    Dec 23, 2017 at 0:40

1 Answer 1

1

The first issue, I am checking if c equals "hi" and if it does then display said hi.

This is not how you compare:

  if (c.equals('hi')) {

Single quotes indicate a single (or multi-byte) character. A character string (lower-case) is enclosed by double quotes:

  if (c == "hi") {

But it's better to avoid the String class (more info here).

To eliminate the String class, use char arrays instead (aka "C strings") and accumulate characters until the newline is received. There are many, many C string functions for manipulating and searching. In this specific case, you would use strcmp or strstr for comparison:

#include <AltSoftSerial.h>

AltSoftSerial bluetooth; // pin 8 is RX, pin 9 is TX

char btResponse[ 20 ];
uint8_t count;
const uint8_t BT_MAX = sizeof(btResponse);

void setup() {
  Serial.begin(9600);

  Serial.println("PC Side Connected");
  bluetooth.begin(9600);

  bluetooth.println("Bluetooth Side Connected");
  bluetooth.println("AT"); // just a check
}

void loop()
{
  if (bluetooth.available()) {
    // Read what is sent back from the BT module
    char c = bluetooth.read();

    if (c == '\n') {
      btResponse[ count ] = '\0'; // NUL-terminate the character array

      // Use C string functions to parse the response

      if (strcmp( btResponse, "hi" ) == 0) {
        Serial.println("only said hi");

      } else if (strstr( btResponse, "hi" ) != nullptr) {
        Serial.println("said hi, among other things...");

      }

      // And if there is a comma in there somewhere, display all comma-separated fields
      if (strchr( btResponse, ',' ) != nullptr) {
        uint8_t fieldNumber = 0;

        char *field = strtok( btResponse, "," );
        while (field != nullptr) {

          Serial.print( "Field " );
          Serial.print( fieldNumber );
          Serial.print( " = " );
          Serial.println( field );

          // Some fields might be numbers.  Parse them into integers.
          if ( isdigit( field[0] ) ) {
            int value = atoi( field );
            Serial.print( "  value = " );
            Serial.println( value );
          }

          // get next field
          field = strtok( nullptr, "," );
          fieldNumber++;
        }
      }

      // Reset the counter to receive another response
      count = 0;

    } else if (c >= ' ') {
      // Accumulate another non-control char, if there's room
      if (count < BT_MAX-1) {
        btResponse[ count++ ] = c;
      }
    }
  }

  if (Serial.available()) {
    // Send data to Bluetooth module
    bluetooth.write( Serial.read() );
  }
}

Notice that it shows how to use strtok to break the response string into individual fields, if a comma character is somewhere in the line. For example, entering this:

hi,123,456

... produces this output:

said hi, among other things...
Field 0 = hi
Field 1 = 123
  value = 123
Field 2 = 456
  value = 456

It also uses AltSoftSerial for the BT connection. SoftwareSerial is very inefficient, and it cannot send and receive at the same time. It will lose received data while it is transmitting to the BT. This can also interfere with other parts of your sketch or other libraries.

This answer has a good summary of the alternatives and how to select one. Since you are already using pins 8 & 9, it would be easy to switch to the AltSoftSerial library. All of the mentioned libraries are available from the Arduino IDE Library Manager, under the menu Sketch -> Include Library -> Manage Libraries.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.