Read Serial1 on Serial Mega

Hello,

I am trying to get bluetooth HC-06 chip to work on my mega. I hooked the rx (pin 19) of mega to tx pin of the HC-06 and hooked the tx (pin 18) to 5 1k resistors (i didn't have a 5k) and at the end of that there is a wire, connected to the rx of the HC-06 and a 10k resistor attached to ground, so that it acts as a voltage divider.

I hooked VCC of the HC-06 to 5v output on the mega, and hooked the gwd to gwd. I tried this code, and it sends hello to the serial monitor every second, but when I type something in the serial monitor on lap top2 (for example Led On) to send to the HC-06 that tells the arduino to turn on or off the led, it says

const int ledPin=32;
const int ledPin2=33;
boolean ledState=LOW;
String readString;
unsigned long previousMillis=0;
const int interval=2000;

void setup()  
{
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
  Serial1.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  while (!Serial1) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

pinMode(ledPin,OUTPUT);
pinMode(ledPin2,OUTPUT);
Serial.println("Setup Finished");
}

void loop() // run over and over
{blinkwithoutDelay();
checkBluetooth();
}
void blinkwithoutDelay(){
  unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;   
    ledState=!ledState;
    if (ledState==HIGH)
    Serial1.println(F("led2 is on"));
    else
    Serial1.println(F("led2 is off"));
    digitalWrite(ledPin2, ledState);
  }
}
void checkBluetooth()
{
  if (Serial1.available())
  {
    Serial.println(F("something available"));
    Serial.print(F("Number of bytes available: "));
    Serial.println(Serial1.available());
    Serial.print(F("The first Byte is a: "));
   // Serial.println(Serial1.read());
    char c =Serial1.read();
    readString+=c;
    Serial.write(c);
    Serial.println();
    Serial.print(F("The readString is: "));
    Serial.println(readString);
    Serial.println(F("==========end of this loop============"));
    Serial.println();
    if (readString.endsWith("On"))
    {
      digitalWrite(ledPin,HIGH);
      Serial.println(F("led1 is high"));
    }
    else if (readString.endsWith("Off"))
    { digitalWrite(ledPin,LOW);
      Serial.println(F("led1 is low"));
    }
  } 
}

This is the serial readout from Serial.print on the mega

something available
Number of bytes available: 1
The first Byte is a:

for some reason when i copied the serial monitor, didn't want to paste the whole thing
here is the next part

The readString is:

... that 1 byte must be a '\n' because it did it again when i tried to paste.
Do I need to put in a buffer or anything? Why is it only saying there is one Byte, when there should be 6?

   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  while (!Serial1) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

Is this a Leonardo or a Mega? Did you read the comments there when you pasted this code together.

Serial data comes in WAY slower than the loop turns over. So when you get to the Serial1.available() test, there may well only be one character that has shown up yet. If you want to wait for 6 then make that line:

if (Serial1.available() >= 6)

Or go study @Robin2's Serial Input Basics Thread and learn how to collect your string one character at a time.

   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
    while (!Serial1) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

But, you don't have a Leonardo, so WTF?

Do I need to put in a buffer or anything?

Instead of a String? Yes.

Why is it only saying there is one Byte, when there should be 6?

Because the Arduino can read serial data faster than it arrives.

What is sending the data, and how?

Is this a Leonardo or a Mega? Did you read the comments there when you pasted this code together.

I figured other people might read this in the future, they may have a leonardo so I wanted to make it as easy as possible for anyone to learn from this.

If you want to wait for 6 then make that line:

if (Serial1.available() >= 6)

what if I don't know how many bytes are coming? Wouldn't >0 work?

Instead of a String? Yes.

I love this guy! Here this is how I was going to get it to work once I got the basic String concept working.
global

static byte TempNC = 0;
const int MaxLenghtOfChar=80;
char currentLine[MaxLenghtOfChar];

How to collect data not using String

if (c=='\n'){ // if you got a newline, then clear currentLine:
TempNC=0;
if (TempNC<MaxLenghtOfChar)
{ currentLine[TempNC]='\n';
TempNC++;
}
TempNC=0;

}
else if (c != '\r') // you've gotten a character on the current line
{ if (TempNC<MaxLenghtOfChar)
{
currentLine[TempNC]=c;
if (PaulSsaysEndswithNotUsingStrings("GET /H"))
Serial.println(F("LED ON"));
else if (PaulSsaysEndswithNotUsingStrings("GET /L"))
Serial.println(F("LED OFF"));
TempNC++;
}
}

How to compare ends.With without String

boolean PaulSsaysEndswithNotUsingStrings(char holder[])
{
  int i = TempNC-strlen(holder);
  if (i>=0)
  {
    static byte TempNT = 0;
    TempNT=0;
    boolean ok =1;
    while (i<TempNC && ok!=0)
    {
      if (holder[TempNT]!=currentLine[i])
          ok=0;
          TempNT++;
          i++;
        }
        if (ok==1)
        return 1;
        else
        return 0;
      } else return 0;
}

Because the Arduino can read serial data faster than it arrives.

I refuse to use delays, do I need to increase the baud rate to max?

What is sending the data, and how?

Second lap top is sending the data to the HC-06 bluetooth chip using Rx (pin 19) and Tx (pin 18). I loaded the new arduino IDE 1.6.6 on lap top two, and paired the lap top to the HC-06 chip which is set for port 5. I opened the Serial monitor connected to port 5 so I didn't need an arduino connected to actually open the Serial monitor.

I want to eventually get two arduinos to handshake like I did with client and server WiFi code. Right now though, I am trying to type in "Led On" or "Led Off" using laptop two, and that should send the command to the arduino using bluetooth, and I would like that to make arduino turn the led on/off and send the responce "Led is On" or Led is Off" back to the Serial port of lap top 2 in response.

Thomas499:
I figured other people might read this in the future, they may have a leonardo so I wanted to make it as easy as possible for anyone to learn from this.

You want them to learn to leave useless code? At least comment it out.

Thomas499:
I refuse to use delays, do I need to increase the baud rate to max?

No, just don't expect the entire message to be there in one swipe. It may take several iterations of the loop to collect the whole message. It would be nice if you include a special character of some kind to mark the end of the packet so you know when you've got the whole thing.

Have you read that thread I linked you to in the first reply? It's definitely worth a read. The concepts there apply not only to Serial, but also to getting stuff from an ethernet client or a radio or really anything that gives you info one character at a time. If you did read it, it's worth a re-read. Learning what's there will save you (and us) tons of headache in the future.

It would be nice if you include a special character of some kind to mark the end of the packet so you know when you've got the whole thing.

I did that with the wifi example, but found if the server disconnected or power off before the entire message was received it would cause caous. I eventually put in a timeout funtion, but it seems for now, I just want it as simple as possible working.

I diagnosed to problem more and found if I connect the rx tx pins to pin 0 and 1 instead of 18 and 19 and change serial1 to serial and take out the previous serials then it works fine. using Serial1 it sends the information to lap top 2 fine, but doesn't receive the information from lap top 2.

Any ideas?

  while (!Serial1) {
    ; // wait for serial port to connect. Needed for Leonardo only
 }

Not necessary on any board.

It won't happen again. Still can't figure out why it works if I hook it up to pin 0 and 1, but not if I use Serial1 or Serial3

Heres an experiment, if you have a Mega upload this code and hook pin 0 to pin 18 and hook pin 1 to pin 19

boolean printonce=1;
void setup() {
  // initialize both serial ports:
  Serial.begin(9600);
  Serial1.begin(9600);
}

void loop() {
   if (printonce==1) 
   {
      Serial1.println(F("Ready"));
      printonce=0;
  }
  // read from port 1, send to port 0:
  if (Serial1.available()) {
    int inByte = Serial1.read();
    Serial.write(inByte);
  }

  // read from port 0, send to port 1:
  if (Serial.available()) {
    int inByte = Serial.read();
    Serial1.write(inByte);
  }
}

if change Serial1.println(F("Ready")); to Serial.println(F("Ready")); it works as you would expect and continuously prints Ready. However, if you use Serial1.println(F("Ready")); nothing ever prints to the serial monitor... why is that?

I probably should have structured that last post in a more obvious form of a question rather than in the form of an experiment. I am convinced that the solution to the last post will be the solution to getting the Bluetooth HC-06 to work properly.

Can anyone tell me why the last post doesn't work properly?

why is that?

Because you connected the two TX pins and the two RX pins together. You need to connect 0 to 19 and 1 to 18, so Serial sends to Serial1's receive pin, and Serial1 sends to Serial's receive pin.

You need to connect 0 to 19 and 1 to 18, so Serial sends to Serial1's receive pin, and Serial1 sends to Serial's receive pin.

according to the arduino Mega pin layout page

Serial: 0 (RX) and 1 (TX); Serial 1: 19 (RX) and 18 (TX);

So you are saying that I need to connect RX to Rx and Tx to Tx? I thought Rx always connects to Tx and Tx always connects to Rx... when I tried it your way, neither Serial.print or Serial1.print work...

Any other suggestions?

So you are saying that I need to connect RX to Rx and Tx to Tx?

I was going from memory (flawed, apparently) where the RX and TX pin numbers were in increasing order for each SerialN instance. It seems bizarre that Serial uses increasing pin numbers for RX and TX, and the other instances use decreasing pin numbers.

Would you load the sketch into your mega and connect 0 to 18 and 1 to 19 to see if it's just my board? If not, what else could cause the sketch to not work properly?

boolean printonce=1;
void setup() {
  // initialize both serial ports:
  Serial.begin(9600);
  Serial1.begin(9600);
}

void loop() {
   if (printonce==1)
   {
      Serial1.println(F("Ready"));
      printonce=0;
  }
  // read from port 1, send to port 0:
  if (Serial1.available()) {
    int inByte = Serial1.read();
    Serial.write(inByte);
  }

  // read from port 0, send to port 1:
  if (Serial.available()) {
    int inByte = Serial.read();
    Serial1.write(inByte);
  }
}

Would you load the sketch into your mega and connect 0 to 18 and 1 to 19 to see if it's just my board?

I don't have a Mega at work with me. When I get home, if I remember, I will.

I don't have a Mega at work with me. When I get home, if I remember, I will.

I'm looking forward to finding out if its my board.

I was thinking about the analog concept. If you want to read 2 separate analog pins you have to wait 50 or it reads the same as the last analog pin. Does the Serials use the same technology?

I want to be able to use the bluetooth chip for wireless communication, but I don't want to give up my serial monitor debugger. I read that hardware serial is much faster than SPI, and software serial.

Any ideas or suggestions to why the code I posted in the last post isn't working correctly?

Interesting. If you modify the sketch slightly:

boolean printonce = 1;
void setup() {
  // initialize both serial ports:
  Serial.begin(9600);
  Serial1.begin(9600);
  Serial.println(("In setup"));
}

void loop() {
  if (printonce)
  {
    Serial.println(("Ready"));
    printonce = false;
  }

  // read from port 1, send to port 0:
  if (Serial1.available()) {
    int inByte = Serial1.read();
    Serial.write(inByte);
  }

  // read from port 0, send to port 1:
  if (Serial.available()) {
    int inByte = Serial.read();
    Serial1.write(inByte);
  }
}

Now I expect to see "In setup" followed by "Ready" followed by input from my serial monitor, echoed. What I actually see is:

In setup
Ready
In setup
Ready
In setup
Ready
In setup
Ready
In setup
Ready
In setup
Ready
In setup
Ready

If you disconnect the wires connecting the pins, it prints the message once.

What is happening here is that you are printing "Ready" and that is being sent to the other serial port which receives "Ready" which then prints it, it gets received again, and prints it again, and so on. You have set up an infinite loop of echoing back the "Ready" word.

Yes, I got that part working. It's when I modify it from

Serial.println(("Ready"));

to

Serial1.println(("Ready"));

that doesn't work as expected. Can you try it and tell me what results you get?

What I got was:

  • No output at all on the Serial Monitor
  • Constant output on pin 0/18 (on the scope) - it looks like it is looping sending "Ready"

Looking at your code:

boolean printonce=1;
void setup() {
  // initialize both serial ports:
  Serial.begin(9600);
  Serial1.begin(9600);
}

void loop() {
   if (printonce==1)
   {
      Serial1.println(F("Ready"));
      printonce=0;
  }
  // read from port 1, send to port 0:
  if (Serial1.available()) {
    int inByte = Serial1.read();
    Serial.write(inByte);     // <----------- send to serial monitor
  }

  // read from port 0, send to port 1:
  if (Serial.available()) {
    int inByte = Serial.read();
    Serial1.write(inByte);    // <----------- send to Serial input
  }
}

The only way for no output to appear on the serial monitor is if the line marked "send to serial monitor" never sends anything. Thus, there is never anything available on Serial1 input.

And that actually makes sense, if you stare at it long enough.

  • We send "R" to Serial1 (so it goes out on pin 1, and in on pin 19).
  • Because of the wire, that appears on Serial input (pin 0)
  • That is picked up (if Serial.available) and that byte is now written back to Serial1
  • However that is Serial1 output (Tx), not Serial1 input (Rx) so we never receive anything on Serial1.
  • The whole thing repeats indefinitely