HC-05 Bluetooth module on Serial1 receiving junk when pinMode set

Hi,

I'm having a strange issue with my Arduino Mega receiving data over Bluetooth. I have an Arduino Mega with a Bluetooth HC-05 module wired to Serial1 and serial monitor running over the default Serial channel. The HC-05 is talking to a Bluetooth enabled ELM327 module. I set up my initial code to send a simple AT command to retrieve the voltage from the ELM327 and display it via the serial monitor.

The initial data is received and displayed without issue, so I started to expand to include additional detail, so the RTC was added and time retrieved and displayed to serial monitor. The output was nice and clean:

Starting Serial 2 - OK
Initialising RTC - Success
12.3V
20181116074526,12.3V
12.3V
20181116074528,12.3V
12.3V
20181116074529,12.3V

I then started to code up the SD interface to record the data at which point, the data displayed both in the serial monitor and what was written to the SD card was mangled slightly. See the attached image as cut/paste seems to clean it up.

I trimmed the code back, and it appears to be related to the line:

pinMode(10,OUTPUT);

Without initialising SD, or even changing it to an unused pin in the 30's range, when the pinMode command is issued I get junk back. I've followed several threads in the forums and tried setting the pinMode for Serial1, I've also tried "pulling the pin up" according to a different thread, I've also moved between different Serial interfaces as well, all to no avail. If I use a simple sketch that allows me to send/receive through the monitor to the bluetooth, if I set pinMode, no issues, so I know I'm missing something, but I'm not sure what.

I apologise if this one has been answered before, but I found nothing in my attempts to nut this out.

Please find the full code excerpt below:

/*********************
 * Include libraries *
 *********************/
#include <PCD8544.h>  // LCD library
#include "SD.h"       // SD Card - ADA Fruit library
#include <SPI.h>      // SD Card
#include <RTClib.h>   // Real Time Clock - ADA Fruit library
#include <Wire.h>     // Needed by RTC

/***************************
 * Define global variables *
 ***************************/
#define SerialBaud 9600   // Baud rate of Standard Serial interface
#define Serial1Baud 38400 // Baud rate of secondary serial interface - assumes Mega
String _voltagedata;
RTC_DS1307 rtc; // Real Time Clock

/****************
 * Declare Pins *
 ****************/

/*********************
 * Declare variables *
 *********************/

void setup() {

     //pinMode(10,OUTPUT);
    
    // Set up standard serial
    Serial.begin(SerialBaud);
    Serial.print("Sketch:   ");   Serial.println(__FILE__);
    Serial.print("Uploaded: ");   Serial.println(__DATE__);
    Serial.println(" ");

    // Initialise Bluetooth
    Serial.print("Starting Serial 2 - ");
    Serial2.begin(Serial1Baud);
    Serial2.flush();
    Serial.println("OK");
    
    // initialise RTC
    Serial.print("Initialising RTC");
    if (! rtc.begin())
    {
      Serial.println("Couldnt find RTC");
      while (1);
    }
    else
    {
      Serial.println(" - Success");
    }
}

void loop() {
  
    _voltagedata = GetVoltage();
    String _time = GetTime();
    Serial.print(_time);
    Serial.print(",");
    Serial.println(_voltagedata);

    delay(1000);
}

/*****************
 * Fetch Voltage *
 *****************/
String GetVoltage()
{

  char _receivedchar = ' ';
  char _receiveddata[50];
  int _counter;

  // Send command to bluetooth
  String _command = "atrv\r";

  Serial2.print(_command); 
  Serial2.flush();
  
  // wait for initial data feed  
  while (!Serial2.available());
  _counter=0;
  bool _alldatareceived = false;
  bool _toolong = false;
  unsigned long _time = millis();
  
  while ((!_alldatareceived) && (!_toolong))
  {
      while (Serial2.available())
      {
        _receivedchar = Serial2.read();
        if ((_counter < 20))
        {
          _receiveddata[_counter] = _receivedchar;
        }
        
        _counter=_counter+1;
        if (_receivedchar == 62)
        {
          _alldatareceived = true;
        }
      }
      
      // Check if waiting for data taking too long
      if ((millis() - _time) >= 2000)
      {
        _toolong = true;
      }
  }
  
  // check returned data integrity
  bool _dataok = true;
  for (int i=0;i<_command.length();i++)
  {
    if (_command[i] != _receiveddata[i])
    {
      _dataok = false;
    }
  }

  // Get data
  char _voltage[5];
  if ((_dataok) && (!_toolong))
  {
    _voltage[0] = _receiveddata[5];
    _voltage[1] = _receiveddata[6];
    _voltage[2] = _receiveddata[7];
    _voltage[3] = _receiveddata[8];
    _voltage[4] = _receiveddata[9];
  }
  else
  {
    _voltage[0] = 70;
    _voltage[1] = 65;
    _voltage[2] = 73;
    _voltage[3] = 76;
    _voltage[4] = 33;
  }

  
  // Return data 
  Serial.println(_voltage); 
  return _voltage;
}

/************
 * Get Time *
 ************/
String GetTime()
{
   // Get Time
  DateTime now = rtc.now();
  String currenttime;
  currenttime = String(now.year());
  if (now.month() < 10)
  {
    currenttime = currenttime + "0" + String(now.month());
  }
  else
  {
    currenttime = currenttime + String(now.month());
  }
  if (now.day() < 10)
  {
    currenttime = currenttime + "0" + String(now.day());
  }
  else
  {
    currenttime = currenttime + String(now.day());
  }
  if (now.hour() < 10)
  {
    currenttime = currenttime + "0" + String(now.hour());
  }
  else
  {
    currenttime = currenttime + String(now.hour());
  }
  if (now.minute() < 10)
  {
    currenttime = currenttime + "0" + String(now.minute());
  }
  else
  {
    currenttime = currenttime + String(now.minute());
  }
  if (now.second() < 10)
  {
    currenttime = currenttime + "0" + String(now.second());
  }
  else
  {
    currenttime = currenttime + String(now.second());
  }

  return currenttime;
}

Thanks heaps for your help.

On an Uno you need to set pin 10 as OUTPUT for SPI to work. I assume you need SPI to work with the SD card. The SPI pins are different on a Mega - pin 53 is the equivalent of pin 10.

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with '\0' (NULL).

Using the String class could also be the cause of your problem.

And there is unfortunately no guarantee that different Arduino libraries are compatible with each other.

...R

Thanks heaps for the response Robin2.

Robin2:
On an Uno you need to set pin 10 as OUTPUT for SPI to work. I assume you need SPI to work with the SD card. The SPI pins are different on a Mega - pin 53 is the equivalent of pin 10.

You are right, ultimately pin 10 in this case is for the SD library, the shield I have requires a little mucking around with the adafruit library instead in order to use pin10 on the mega, but it works, but it doesn't matter which pin I set as output, so even with the shield removed, if I set pin 30 as output, the issues repeats.

Robin2:
It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with '\0' (NULL).

Using the String class could also be the cause of your problem.

And there is unfortunately no guarantee that different Arduino libraries are compatible with each other.

...R

I'll take this onboard, I haven't had to program in something resembling pure C in ages, so still coming to grips with a few of these nuances, I'll look to dump the "S"tring. That said, the Serial.println command in the middle of the function is printing a defined char array before it's returned and the junk data exists at that stage. It's just strange.

robmc0:
but it doesn't matter which pin I set as output, so even with the shield removed, if I set pin 30 as output, the issues repeats.

I don't understand.

Can you post the shortest possible program that illustrates the problem together with a sample of the input and the incorrect output.

Is there some significance to your choice of Pin 30?

...R

Hi Robin2,

To clarify, it is the act of calling the pinMode command that is related to the issue. It doesn't matter if I'm trying to set the SPI for the SD card or if I try and just set the Serial ports eg:

pinMode(17,OUTPUT);
pinMode(18,INPUT);

or setting a random pin for an LED

pinMode(30,OUTPUT);

After a lot of tinkering last night, I have narrowed it down to the RTC board and libraries. Multiple RTC libraries all work with the shield, but the act of initiailising the RTC board:

rtc.begin()

is where things go wrong. Tested the shield on both Mega and Uno. Interestingly on the UNO, the RTC doesn't cause issues, but once I initialise the SD card, the problem re-occurs, so there's something strange about the SD shield.

I have a spare SD port around, looks like I might need to order a standalone RTC module to see if the problem still exists.

thanks for your help.

Cheers.