Bluetooth Serial Char array overwrites itself on new loop() iteration

Hello

I am trying to make a system which can control LED strip lights and a bluetooth terminal command can select from pre-written patterns inside the arduino. I am using an HC06 module for bluetooth, using the FastLED library for the striplights and SoftwareSerial to control bluetooth.

I am using Robin2’s “Serial input basics” forum post for the serial capture of a char array. My char variable “command” should hold the command, currently 3 exist, cylon, strobe and off.

Cylon works correctly. Once selected it will properly continue to display the cylon pattern until told otherwise or switched off. Strobe however will only ever strobe once and then the striplights will go off. Upon examining this with debug prints, it shows the variable “command” being cleared when a new loop is reached.

The Serial.println() commands are used for debug to the ctrl shift m console, and the mySerial() commands are to the bluetooth receiver.

The output of the ctrl shift m console when entering “cylon” and pressing send on the phone, then a few seconds later entering “strobe” and pressing send looks as follows:

Command is:
Command is:
Command is:
Command is:
New Command!
Command is:cylon
Command is:cylon
Command is:cylon
Command is:cylon
Command is:cylon
Command is:cylon
New Command!
Command is:strobe
Command is:
Command is:

As you can see there is no “New Command!” indicator after strobe, yet it still erases itself somehow.

This might be an easy fix and maybe just requires a fresh set of eyes, but any help would be much appreciated

Regards

#include "FastLED.h"
#include <EEPROM.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX

#define NUM_LEDS 60
#define DATA_PIN 7


// Define the array of leds
CRGB leds[NUM_LEDS];
String color1;
String color2;
String color3;
int delayflag = 0;
uint8_t gHue = 0; // rotating "base color" used by many of the patterns

const byte numChars = 64;
char receivedChars[numChars];   // an array to store the received data
char command[numChars];
boolean newData = false;


void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
  mySerial.println("resetting");
  LEDS.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS);
  LEDS.setBrightness(84);

}

void loop() {
  memset(receivedChars, 0, sizeof(receivedChars));
  recvWithEndMarker();
  showNewData();

    Serial.print("Command is:");
    Serial.println(command);
  //  Serial.println(strcmp("strobe", command));

  //"cylon" pattern code
  if ( strcmp("cylon", command) == 0) {
    static uint8_t hue = 0;
    // First slide the led in one direction
    for (int i = 0; i < NUM_LEDS; i++) {
      // Set the i'th led to red
      leds[i] = CHSV(hue++, 255, 255);
      // Show the leds
      FastLED.show();
      // now that we've shown the leds, reset the i'th led to black
      // leds[i] = CRGB::Black;
      fadeall();
      delayMicroseconds(5000);
      delayMicroseconds(5000);
    }
  }


  //strobe pattern
  else if ( strcmp("strobe", command) == 0) {

    for (int i = 0 ; i < 61 ; i++) {
      leds[i] = CRGB::White;
    }

    FastLED.show();
    delay(50);

    for (int i = 0 ; i < 61 ; i++) {
      leds[i] = CRGB::Black;
    }

    FastLED.show();
    delay(50);
  }

  //off pattern
  else if ( strcmp("off", command) == 0) {

    for (int i = 0 ; i < 61 ; i++) {
      leds[i] = CRGB::Black;
    }

    FastLED.show();
  }


  else {}

}


void recvWithEndMarker() {
  static byte ndx = 0;
  char endMarker = '\n';
  char rc;
  newData = false;
  while (mySerial.available() > 0 && newData == false) {
    rc = mySerial.read();

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

void showNewData() {
  if (newData == true) {
    mySerial.println(receivedChars);
    Serial.println("New Command!");
    strcpy(command, receivedChars);
    memset(receivedChars, 0, sizeof(receivedChars));
    newData = false;
  }
}

void fadeall() {
  for (int i = 0; i < NUM_LEDS; i++) {
    leds[i].nscale8(250);
  }
}

Your problem is the first three lines of loop. You are clearing out your received characters s then when you call showNewData it copies that to command this clearing it out.

Thanks for the reply. showNewData shouldn't get called again until more bluetooth data is available, as newData will be false, and the only way for newData to be set true is in recvWithEndMarker(). And the only way that is called is if mySerial.available() is > 0, so the only way for it to be called is if theres a new command come from the bluetooth module.

Also we would see showNewData being called again and overwriting with the clear as the ctrl shift m console would show "New Command!"

I have started working on this again and I am really confused. There should be no reason why command is wiping itself, even stripping the code down to its bare minimum

#include "FastLED.h"
#include <EEPROM.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX

#define NUM_LEDS 60
#define DATA_PIN 7


// Define the array of leds
CRGB leds[NUM_LEDS];
String color1;
String color2;
String color3;
int delayflag = 0;
uint8_t gHue = 0; // rotating "base color" used by many of the patterns

const byte numChars = 64;
char receivedChars[numChars];   // an array to store the received data
char command[numChars];
boolean newData = false;

static byte ndx = 0;
char endMarker = '\n';
char rc;


void setup() {
  strcpy(command, "strobe");
  Serial.begin(9600);
  //  mySerial.begin(9600);
  //  mySerial.println("resetting");
  LEDS.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS);
  LEDS.setBrightness(84);

}

void loop() {
  //strobe pattern

  Serial.print("Command is: ");
  Serial.println(command);
  if (strcmp(command, "strobe") == 0) {

    for (int i = 0 ; i < 61 ; i++) {
      leds[i] = CRGB::White;
    }

    FastLED.show();
    delay(50);

    for (int j = 0 ; j < 61 ; j++) {
      leds[j] = CRGB::Black;
    }

    FastLED.show();
    delay(50);
  }
}

The output of the serial monitor (ctrl shift m) will read:

Command is: strobe
Command is: 
Command is: 
Command is: 
Command is: 
Command is: 
Command is: 
Command is: 
Command is: 
Command is: 
Command is: 
Command is: 
Command is: 
Command is: 
Command is: 
Command is: 
Command is: 
Command is: 
Command is: 
Command is:

I dont know why it loses the command. Something to do with strcmp overwriting data?

Ah

I have figured it out. My for loop for selecting all the LED's went up to 61 when actually it should be 60. I guess this was overwriting memory somewhere it shouldn't have been.