Arduino Crashing when receiving BluetoothData, Serial Data works

Hello,

I am currently building a self driving Arduino which I want to control with my phone via Bluetooth. When the Arduino sends data to my phone, everything is working fine, but as soon as I start sending data from my phone, the Arduino crashes soon after. However, the Arduino uses the first few messages of data just fine, and than randomly crashes. I even tried changing the Sending Interval to 2 seconds, just to make sure there’s no input buffer overflow. The HC-05 Bluetooth is connected to the Serial ports. When I remove it and instead try to send data via the Serial Monitor, everything is working just fine. I cannot recreate the issue there. Here’s my code (I’ve shortened it, since the Post would have been to long):

#include "I2Cdev.h"

const unsigned long READ_PERIOD = 20;
const unsigned long SEND_PERIOD = 200;
long lastTime = 0;
long lastSendTime = 0;

void setup() {
  //8 microsteps
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
  Wire.begin();
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
  Fastwire::setup(400, true);
#endif
  Serial.begin(9600);
  Serial.println("Initializing I2C devices...");

  accelgyro.initialize();
  accelgyro.setDLPFMode(MPU6050_DLPF_BW_5);  //5 Hz DLPF
  accelgyro.setFullScaleGyroRange(MPU6050_GYRO_FS_250);
  accelgyro.setFullScaleAccelRange(MPU6050_ACCEL_FS_2);   // Accel Range of +- 2g

  // verify connection
  Serial.println("Testing device connections...");
  Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");

  //Set the timer to interrupt the program with the Frequency of interruptFreq (50kHz). This enables Pulses of 50kHz or slower which equals a maximum RPM of about 900
  //Once the timer triggers, ISR(TIMER2_COMPA_vect) gets called
  /* TCCR2A = 0;                                                               //Make sure that the TCCR2A register is set to zero
    TCCR2B = 0;                                                               //Make sure that the TCCR2A register is set to zero
    TIMSK2 |= (1 << OCIE2A);                                                  //Set the interupt enable bit OCIE2A in the TIMSK2 register
    TCCR2B |= (1 << CS21);                                                    //Set the CS21 bit in the TCCRB register to set the prescaler to 8
    OCR2A = compare;                                                          //The compare register is set to float compare
    TCCR2A |= (1 << WGM21);     */                                              //Set counter 2 to CTC (clear timer on compare) mode
  // STEPPER MOTORS INITIALIZATION
  // TIMER1 CTC MODE
  TCCR1B &= ~(1 << WGM13);
  TCCR1B |=  (1 << WGM12);
  TCCR1A &= ~(1 << WGM11);
  TCCR1A &= ~(1 << WGM10);

  // output mode = 00 (disconnected)
  TCCR1A &= ~(3 << COM1A0);
  TCCR1A &= ~(3 << COM1B0);

  // Set the timer pre-scaler
  // Generally we use a divider of 8, resulting in a 2MHz timer on 16MHz CPU
  TCCR1B = (TCCR1B & ~(0x07 << CS10)) | (2 << CS10);

  //OCR1A = 125;  // 16Khz
  //OCR1A = 100;  // 20Khz
  OCR1A = compare;   // 25Khz
  TCNT1 = 0;
  TIMSK1 |= (1 << OCIE1A); // Enable Timer1 interrupt
  accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
  kalmanX.setAngle(asin(maptoG(ay) / 9810) * 180 / PI);
  KalmanAngleLast = 0;
  Serial.println("Setup complete");
  timer = micros();
}

void loop() {
  //ensure stability running with a fixed samplerate of 20ms
  if (millis() - lastTime >= READ_PERIOD) {
    calcRPM = calcRPM + calcACC * READ_PERIOD / 1000 + 1;    lastTime += READ_PERIOD;
    accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz); // Hier: Drehung um X -> ay, gx interessant
    double dt = (double)(micros() - timer) / 1000000; // Calculate delta time
    timer = micros();
    float angle = atan2(maptoG(ay), maptoG(az)) * 180 / PI;
    KalmanAngle = kalmanX.getAngle(angle, gx / 131.0, dt);
    if (abs(KalmanAngle) > 37.5) {
      emergency = true;
    }
    arel =  (KalmanAngle - KalmanAngleLast) / dt;
    int deadzone = 2;
    // RPM/s
    calcACC = (P * KalmanAngle + D * (KalmanAngle - KalmanAngleLast) / dt);
    KalmanAngleLast = KalmanAngle;

    // AdjustSpeed via following formula: pulseFreq = RPM/60*200*Microsteps;
    pulseFreq = (-calcRPM / 60) * 200 * Microsteps ;
    if (abs(KalmanAngle) < 0 || emergency) {
      SpeedToTimerCount = 0;
    }
    else {
      if (pulseFreq != 0) {
        SpeedToTimerCountTemp = interruptFreq / (2 * pulseFreq);
      }
      if ((abs(SpeedToTimerCount) == 1000 && abs(SpeedToTimerCountTemp) < 950) || SpeedToTimerCount < 1000) {
        //Calculate how many Interrupts are needed until the desired Pulse Length is reached

        if (SpeedToTimerCountTemp < 5 && SpeedToTimerCountTemp >= 0) {
          SpeedToTimerCount = 5;
        }
        else if (SpeedToTimerCountTemp > -5 && SpeedToTimerCountTemp <= 0) {
          SpeedToTimerCount = -5;
        }
        else if (abs(SpeedToTimerCountTemp) > 1000) {
          if (SpeedToTimerCountTemp > 0) {
            SpeedToTimerCount = 1000;
          }
          else if (SpeedToTimerCountTemp < 0) {
            SpeedToTimerCount = -1000;
          }
        }
        else {
          SpeedToTimerCount = SpeedToTimerCountTemp ;
        }

      }
    }
    if (sample_count < NUM_SAMPLES) {
      sum += analogRead(A2);
      sample_count++;
    }
    else {
      voltage = ((float)sum / (float)NUM_SAMPLES * 5.0) / 1024.0;
      sample_count = 0;
      sum = 0;
    }
    recvWithStartEndMarkers();
    if (newData == true) {
      VRead = atoi(receivedChars);
      Serial.print("VRead");
      Serial.print(";");
      Serial.println(KalmanAngle);
      newData = false;
    }

  }
}
float mapfloat(long x, long in_min, long in_max, long out_min, long out_max)
{
  return (float)(x - in_min) * (out_max - out_min) / (float)(in_max - in_min) + out_min;
}

ISR(TIMER1_COMPA_vect) {
  counter++;
  if (counter >= abs(SpeedToTimerCountMemory)) {
    SpeedToTimerCountMemory = SpeedToTimerCount;
    counter = 0;
    if (SpeedToTimerCountMemory < 0) {
      PORTB &= 0b11111101;
      PORTD |= 0b00100000;
    }
    else {
      PORTB |= 0b00000010;
      PORTD &= 0b11011111;
    }
  }
  else if (counter == 1) {
    PORTB |= 0b00000100;
    PORTD |= 0b01000000;

  }
  else if (counter == 2) {
    PORTB &= 0b11111011;
    PORTD &= 0b10111111;
  }

}
int maptoG (int16_t value) {
  int returnV = map(value, -32768, +32767, -2 * 9810, +2 * 9810);
  return returnV;
}

void recvWithStartEndMarkers() {

  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;

  if (Serial.available() > 0 && newData == false) {
    while (Serial.available() > 15 &&  recvInProgress == false) {
      for (int i = 0; i < 7; i++) {
        Serial.read();
      }
    }
    rc = Serial.read();

    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
      }
      else {
        receivedChars[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        ndx = 0;
        newData = true;
      }
    }

    else if (rc == startMarker) {
      recvInProgress = true;
    }
  }
}

I’m using an Arduino Nano and the HC-05 Bluetooth Module.
Any help is greatly appreciated!

EDIT: I updated the Serial.begin(9600) which is the way I used it.

HC-05 Bluetooth is connected to the Serial ports.

It is generally not a good idea to connect a device to the Serial port, pins 0 and 1, particularly as you are printing to the Serial monitor via those pins. Consider using SoftwareSerial to communicate with the HC-05 on two different pins

Well I am using those pins to communicate via Bluetooth, and when I need the Serial Monitor I just unplug the HC-05. Even though I am aware that using softwareserial is generally spoken better, I am quite sure, that this is not causing the issue. Any other ideas?

Do you have any external devices draw power from the arduino?

No, all other devices are supplied externally

I couldn't see it: Where is receivedChars defined?

when I need the Serial Monitor I just unplug the HC-05

But your program writes to Serial whether or not you "need" it

Try SoftwareSerial even if you want to use hardware Serial in the long run

@Blackfin I deleted it since the Post would have been to long.
@UKHeliBob I’ll try.

The advise to use SoftwareSerial instead of HardwareSerial does not make sense to me.

The only problem with Bluetooth on the hardware serial port is during upload.

One thing to research is if the HC05 supports 115200; I have no idea.

And SoftwareSerial is unreliable at that speed.

MJLennox:
Well I am using those pins to communicate via Bluetooth, and when I need the Serial Monitor I just unplug the HC-05. Even though I am aware that using softwareserial is generally spoken better,

You're dead right there, it's the way to go at a time like this, and there is no "better" to be spoken of software serial. It is just something that sometimes has to be used under sufference, is quite unwarranted here, and while I don't know if you really need 115200, using that rate under software serial is usually fatal.

When I remove it and instead try to send data via the Serial Monitor, everything is working just fine.

IF that is true, your software has been proven kosher. There is no need for us to read it, or for you to fiddle with it.

I was going to suggest your signal wiring is suss but now I see

as soon as I start sending data from my phone, the Arduino crashes soon after.

and if that "soon" really is true, your serial wiring is fine, so then I would suggest you go back and check the power. This may be kosher in theory but not in fact - i.e. right connections, wrong supply.

I say this because, when you run your project with serial monitor, you may be getting power from PC but, when you run it with Bluetooth you probably aren't, and you are far from forthcoming about what is actually going on in that arena. The above symptom may actually suggest intermittent supply from a battery which can recover a bit when there is no load. Please don't tell us Arduino, or anything else, is powered by a 9v PP3 battery. You may also be having a problem with running HC-05 on a 5v breakout board with a 3.3v supply - wrong connections, wrong supply.

HC-05 is fine with 115200 - just ignore any admonition about using software serial.

Using software serial is not unreasonable for temporary lashup to configure Bluetooth at 38400 but, other than that, it is usually just a sop for the lazy and incompetent.

The advise to use SoftwareSerial instead of HardwareSerial does not make sense to me.

In this case I think that it is a case of trying it to see whether it works as an indication of the possible underlying problem.

MJLennox:
@Blackfin I deleted it since the Post would have been to long.

You can attach a file with your code in to a post.

n this case I think that it is a case of trying it to see whether it works as an indication of the possible underlying problem.

That really is nonsense.

The code is already proven fine because OP has had the good sense to use hardware serial to do what hardware serial does well - the debugging, including what goes in and out of the serial port.

If you insist on pushing this baloney onto a newbie you might also insist he changes the baud rate to 9600 as well. Otherwise the poor guy is simply going to get into a deeper mess than ever. Running at 115200 with software serial is a seriously bad idea. With five blue stars under your name, you really should be aware of that by now, and it is not as if it hasn’t already been flagged here.

I have a 5V power supply which delivers up to 3 amps. So that can't be the issue, espacially because the motors aren't even turned on and I had no power problems when they were. Wiring is 100% fine.

I am currently trying SoftwareSerial with 9600 Baudrate. Also: When I was using HardwareSerial, I had the BaudRate set to 9600, if that matters.

EDIT: Just to make it clear: I've set the HC-05 Baudrate correctly!

That really is nonsense.

Have it your own way, but the results of trying SoftwareSerial would provide more evidence of a possible problem whether or not it works. Even the act of disconnecting the wires to the HC-05 and plugging them into different pins might be significant. As it happens I think that the result of reducing the baud rate as a test would also be interesting, as would ensuring that the HC-05 is actually set up to use the baud rate of of the serial interface

We are working with little or no evidence here so need all of the feedback we can get. For instance, the OP says that when using Bluetooth the Arduino crashes. In those circumstances I would write a bare minimum sketch to test the Bluetooth connection with no other devices involved

What would your suggestion be for the next step on the part of the OP ?

I have just seen the latest post by the OP and await feedback with interest

The obvious (to me) way to go would be to use a board with multiple hardware serial ports.

I uploaded a sketch with SoftwareSerial, noticed some error in my code, tried uploading a new Sketch and I now get a "not in sync" error when uploading. I tried restarting everything but it somehow doesn't work. The Arduino is alive though, as it behaves normally other than that. HC-05 is not connected so that can't be the issue.

I am at a loss, but I stand by the logic in reply#9, so the last card in the pack is:
Where is the 5v connected to Arduino?
A bit forlorn, as I seem to recall you are using a Nano, so I guess your 5v goes into a USB socket.
Ah, but what about the power to HC-05?

Also

  1. in

as soon as I start sending data from my phone, the Arduino crashes soon after.

are the"soons" exactly the same length of time, every time, as far as you can tell.

  1. are you quite sure that you can use Arduino connected to serial monitor always for longer periods that it takes for it to die when using Bluetooth.

In (1.) above, if the soons are the same, they may be indicating computer operations, which means your code is suss.

If you can really confirm Aduino runs longer with the monitor, rather than just a casual check, then I guess the code is truly kosher.

Also,

  1. what exactly do you mean by "crash" and
  2. how long is "soon".

and, taking, a point from above, I have always assumed that since you get some Bluetooth traffic, Bluetooth has been correctly configured but, the real last card in the pack has to be:
are you sure it has been properly configured to 115200?? (I had to ask)
if not, change your Serial.begin to 9600, and try again.

No, the soosns seem to be random, I just wanted to point out, that the Arduino processes some messages and then crashes.

UPDATE concerning the other issue: I see the Arduino RX Led blinking, TX led isn't blinking at all, and I still can't upload..

I might have missed it but which Arduino are you using?

Did you disconnect everything from pins 0 and 1?

Have you tried pressing and releasing the reset button at the moment that the IDE reports the memory usage? Try with a simple sketch like blink.