[SOLVED, sort of} HC05 Bluetooth module works with software serial but not UART?

Hi,

I’m seeing something I don’t understand. Hopefully it makes sense immediately to someone reading this. The two sketches below are supposed to be functionally equivalent, using the serial UART and a software serial port, and reading characters arriving from a HC05 bluetooth module on one and echoing them out on the other. The text is being sent from an android phone running a MIT app inventor app.

In the first one, the serial monitor is on the UART and the bluetooth is on the software serial. The text displayed is precisely what I expect.

#include <SoftwareSerial.h>                                               // comms with display drivers

SoftwareSerial Bluetooth(3, 2);
char c;

void setup() {
  Serial.begin(9600);                                                     // serial monitor via hardware UART
  Bluetooth.begin(38400);                                                 // Bluetooth via software serial
  Bluetooth.listen();

  pinMode(13, OUTPUT);

  Serial.println("Start...");
}

void loop() {
  digitalWrite(13, millis()%1000>750);

  while(Bluetooth.available()) { 
    c = Bluetooth.read();
    Serial.print(int(c));
    Serial.print('\t');
    Serial.println(c);
  }
 
}

But swap these over, and after the text “Start…” which correctly displays in the serial monitor the other text received is gibberish, and the int() version of that is frequently a negative value. A screen cap of the serial monitor with some of this text is attached.

#include <SoftwareSerial.h>                                               // comms with display drivers

SoftwareSerial mySerial(3, 2);
char c;

void setup() {
  Serial.begin(38400);                                                     // Bluetooth via hardware serial
  mySerial.begin(9600);                                                    // serial monitor

  pinMode(13, OUTPUT);

  mySerial.println("Start...");
}

void loop() {
  digitalWrite(13, millis()%1000>750);

  while(Serial.available()) { 
    c = Serial.read();
    mySerial.print(int(c));
    mySerial.print('\t');
    mySerial.println(c);
  }
 
}

The traffic only exists for the short bursts when I tell it to, so it’s not just noise. I’ve tested this on an Arduino Pro Mini and a Duemilanove which I chose because both use the FTDI rather than an inbuild USB. Both worked the first way, but not the second.

Is there something obvious I’m missing? Thanks,
Geoff

They are not functionally equivalent, and running Software serial at 38400 is asking for trouble. It might work, but the fact that it might not is a good enough reason not to do it.

strykeroz:
The two sketches below are supposed to be functionally equivalent,

  Serial.begin(9600);                                                     // serial monitor via hardware UART

Bluetooth.begin(38400);                                                // Bluetooth via software serial




But swap these over, 



Serial.begin(38400);                                                    // Bluetooth via hardware serial
  mySerial.begin(9600);                                                    // serial monitor

And then the monitor on software serial? That has to be a first and I won't ask how or why.

Hi Nick

Thanks for checking my post. Point well made, I'll slow down the UART on the bluetooth module to 9600 and hopefully that will sort this out.

Cheers ! Geoff

LoL. I'm afraid you were too quick and I was just about to delete my message, as I'm, afraid I mis-read yours.

For all that, Software serial @ 38400 IS a bad idea, but I now understand it is not your problem!

It could be that running the monitor on software serial is not only a first but an equally bad idea, even at 9600.

Further, I'm not game ask why you are doing all this, particularly when the real player appears to be an Android, and there must be better ways to get Android to talk to PC. Note that you can have Bluetooth and serial monitor share hardware serial while Arduino talks to Android, but Serial monitor just watches rather than participate. I don't know if that will help.

Okay, changes made. Both serials are at 9600 however result is the same with text from the bluetooth output very similar to the screen cap I posted above. New code :

#include <SoftwareSerial.h>                                               // comms with display drivers

SoftwareSerial mySerial(3, 2);
char c;

void setup() {
  Serial.begin(9600);                                                      // Bluetooth via hardware serial
  mySerial.begin(9600);                                                    // serial monitor

  pinMode(13, OUTPUT);

  mySerial.println("Start...");
}

void loop() {
  digitalWrite(13, millis()%1000>750);

  while(Serial.available()) { 
    c = Serial.read();
    mySerial.print(int(c));
    mySerial.print('\t');
    mySerial.println(c);
  }
 
}

For brevity I’ve only tested it now on the Uno-sized board but there was no improvement.

In my project the output was originally an I2C 20x4 character LCD display where I echoed the inbound serial characters for debugging and first saw this odd behavior. I’ve not previously had the bluetooth module included, but have swapped it into the serial now I’m ready for it.

FWIW the intro on the SoftwareSerial reference page does say that

It is possible to have multiple software serial ports with speeds up to 115200 bps.

Regarding your further comment, there is no PC in this project and I’m using it purely for debugging. I only hooked it up this way to have a serial monitor that I could compare the outputs of, and post here - and to remove the other hardware including the I2C display as potential causes.

There has to be something here that is so obvious we’re missing it though?
Geoff

Are you doing anything like sending and receiving on the software serial at the same time?

You must not ever do that, or you'll get gibberish. That's the nature of the beast with software serial - both sending and receiving a character require 100% of the chip's attention, meaning they can't both be done at the same time.

It is easy to not realize you're doing this. I was fully aware of this and talking about it in a thread while looking at a problem someone else was having and it still took me like an hour and multiple boards (as sanity checks) before I realized that I was trying to send characters while more were still coming.

DrAzzy:
Are you doing anything like sending and receiving on the software serial at the same time?

Hi

There is no reading on the SoftwareSerial line at all - just output - though I’ll have to keep that in mind for the actual project. And the initial println(“Start…”) is without corruption, and there are no additional unexpected noise characters reported in between transmissions down the bluetooth.

The Android app sends multiple text fields that have a ~ to delimit them. Via software serial these arrive as expected, but my code never sees a delimiter when the bluetooth module is on the serial UART. Initially I echoed this to the character LCD but made up this test rig to prove there was something wrong with my project hardware, but am actually seeing the same behavior, so something is wrong with just the code I’ve isolated here somehow.

Attached is a camera phone image of the hardware of the test setup. In the rear is the FTDI adapter hooked up to the software serial pins 2 & 3 and also powering the rig. In the foreground is the HC05 module.

Thanks for sharing some brain cycles on this,
Geoff

This is quite perplexing. So I went back into command mode and set the HC05 back to defaults using AT+ORGL. I'm using a simpler android app that you can enter text into, from this RandomNerdTutorials page. Unlike my project's android app, we can now guarantee the same text sent each time for a true comparison.

Connecting it to software serial on the Uno is working a charm, even at the default 38400 baud.

Start...
104 h
101 e
108 l
108 l
111 o

Swap to the other sketch and connect it to the hardware UART (same string input as above)

Start...
0

There has to be something I'm missing standing so near to the problem...
Geoff

Okay I've got this working, but why is now the question.

I've replicated these results above with another HC05 module, and also confirmed the same occurs with IDE 1.6.6, the old 1.0.6 and this week's new release 1.6.7.

Then I tried it on a Uno with a USB port rather than the FTDI one. And it works (still reading the software serial via an FTDI adapter which also powers the Uno when it's not being programmed.

I then swapped in another of the Uno with FTDI (they're arduino duemilanove but with uno firmware) and it also doesn't work. So my initial choice of swapping in a different board that also shared FTDI for programming appears to have been a poor one.

Still not clear why the Pro Mini (8MHz) nor these other full sized boards are doing what they're doing but I finally am seeing the result I'd hoped to with the HC05 on the hardware serial.

Welcome your thoughts as to why,
Geoff