How do I get a bluetooth module and sound sensor to work on the same circuit?

Hello all, got an issue with bluetooth, sound sensors and wiring that I'm hoping you can help me with!

Parts and wiring:
I have an IR module, a Sparkfun Sound Sensor and a HC-05 bluetooth module all powered from the same rails on my breadboard. Additionally there is a strip of WS2012B's with a different power supply that's linked via a ground wire and data wire to the Arduino. Here's a link to how the wiring setup looks (the software I'm using doesn't have an HC-05 module graphic or sound sensor graphic so it's just represented with wires).

The Project:
The Ardunio takes an measurement from the sound sensor, turns that into a usable number which is then used to create patterns on the LED strip. I use an IR sensor/remote to change the pattern mode. The next step is to send that same number to a remote Ardunio via the use of HC-05 modules. This Ardunio makes the same pattern on another strip of LEDs.

The Issue:
I've found that when the bluetooth module is plugged into the breadboard rails it causes the Sound Detector to trigger in a looping pattern, sending incorrect data to my LED strip. It can also cause the IR sensor's input LED to flash as though it's being triggered.

I've done some research and sound sensor looks to be triggering incorrectly because the HC-05 module injects voltage noise into my circuit (I think due to one ground wire being stepped down to 3.3v) and/or is digital and the sound sensor's is analogue. So I think I'm correct in saying that as the voltages base fluctuates on the circuit this causes the voltage reading equipment on the sound sensor to trigger in incorrectly.

What I've done:
Some more research put me in the direction of using capacitors or ferrite beads to reduce circuit noise. I don't have any of the latter though with the former though I've used those small 104 capacitors and a larger 50uF capacitor both at where the power starts on the rail, next to the microphone vin and gnd and the HC-05 vin and gnd all with no positive results.

I've created a common ground, seperated out the grounds. I think I removed potential ground loops and also used a star ground none of which had any effect. I attempted to seperate out the grounds into analogue and digital but I think because there's always a wire bringing sensor data into the Arduino the issue is still present.

I've done a fair amount of research and spent 10's of hours looking up how to solve this issue with no luck. I think now the main issue is the only elecronics I know come from learning and working on this project rather than from an academic background so I simply don't have the experience to figure this issue out.

Things that do work on the project:

  • Both HC-05 IC's work and I've confirmed they can send data from one Ardunio to the other.
  • Both Arduinos work
  • The sound sensor and IR remote work perfectly fine when the HC-05 isn't in the circuit.
  • LEDS work fine.

So my questions are:
How do a I get the HC-05 and the Sound Sensor to work on the same circuit, powered off the same power supply as the Ardunio?

I also have a power supply with 2 USB outputs which I could use to power the HC-05 module and the Arduino with analogue IC's seperatly. Is there an easy way of powering that and sending data to the Ardunio without injecting the noise I think is causing this?

I would use a software serial port for the HC05 so that you can use hardware serial (USB) to follow program flow and monitor variables (debugging).

I have used HC05 modules quite a bit and never have I seen them cause the kind of trouble that you describe.

Post the code that exhibits the behaviour.

groundFungus:
I would use a software serial port for the HC05 so that you can use hardware serial (USB) to follow program flow and monitor variables (debugging).

I looked into using software serial but from what I was reading they use interupts which the FastLED library I'm using disables on my Arduino Uno, so I haven't tested with it. If they don't use interupts then I'll give it a go.

I'll post the relevant code but not all of it as it's a thousand plus lines of mostly colour managment and LCD screen code that I'm not currently using (when I was debugging I simplified the project by removing an LCD screen I had attached). I haven't yet updated the main loop code to work without delay (it's a throwback from when I first started the project) so perhaps that's the issue?.

#include <FastLED.h>
#include <Ewma.h>
#include <Arduino.h>
#include <Math.h>
#include <IRremote.h>
#include <LiquidCrystal.h>
#include <EasyTransfer.h>

#define LED_PIN_1   4
//#define LED_PIN_2   4
#define NUM_LEDS    108
#define PIN_ANALOG_IN A1
#define updateLEDS 2

Ewma adcFilter2(0.1);  // The primary filter for input volume smoothing
Ewma adcFilter3(0.08); // The rainbow smoothing filter

CRGBArray<NUM_LEDS> leds;

EasyTransfer ET;

struct SEND_DATA_STRUCTURE{
  //put your variable definitions here for the data you want to receive
  //THIS MUST BE EXACTLY THE SAME ON THE OTHER ARDUINO
  int16_t rawInputAudioLevel;
  int16_t currentFunctionMode;  
  int16_t currentMode;
  int16_t send_brightness;
};

SEND_DATA_STRUCTURE mydata;

struct color {
  int r;
  int g;
  int b;
};

typedef struct color Color;

int delayAmount = 10;

int maxVolume = 0;

int raw;
int clampedAverageVol;
const int arrayBuffer = 10;
int volumeArray[arrayBuffer];
int arrayCount = 0;
int averageVolume;
int loudnessSpeedSensitivity = 120;

long randNumber;
unsigned long previousMillis = 0;
const long interval = 500;

bool ledDirectionRight = false;

const int minMaxVolume  = 114;
int activeVolumeRange = 108;
int maxVolumeDecaySpeed = 80;
unsigned long maxVolumeLastDecay = 0;

//---------------------\\
//-----MENU SYSTEM-----\\

int functionMode = 0;

//Reactive Effects Menu
int currentReactiveMode = (-1);
int storedReactiveMode;
const int numberOfReactiveModes = 8;

const int REACTIVE_MUSIC_LEFT_MODE = 0;
const int REACTIVE_MUSIC_RIGHT_MODE = 1;
const int REACTIVE_MIDDLE_OUT_MODE = 2;
const int REACTIVE_OUT_IN_MODE = 3;
const int REACTIVE_RAINBOW_MODE = 4;
const int REACTIVE_TOGGLE_MODE = 5;
const int REACTIVE_LENGTH_MODE = 6;
const int REACTIVE_TEST_MODE = 7;

//Chill Effects Menu
int currentChillMode = (-1);
int storedChillMode;
const int numberOfChillModes = 3;

const int CHILL_PULSE_MODE = 0;
const int CHILL_RAINBOW_MODE = 1;
const int CHILL_FADING_COLOURS = 2;

//Tools Menu
int currentSelectedTool = (-1);
int storedSelectedTool;
const int TOOL_SPEED = 0;
const int TOOL_BLUETOOTH = 1;

//Tools Menu Options
bool bluetoothOn = false;

LiquidCrystal lcd(7, 8, 9, 11, 12, 13);
int stripBrightness = 153;

int receiver = 10;
IRrecv irrecv(receiver);
decode_results results;
bool ledsStopped;

int testdata;

void translateIR()
{

  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;

    switch (results.value)
    {      
      case 0xFF30CF: //when the 1 button is pressed
        switch(functionMode)
        {
          case 0: currentReactiveMode = REACTIVE_MUSIC_LEFT_MODE; break;
          case 1: currentChillMode = CHILL_PULSE_MODE; break;
        }        
        break;

//removed most of the switching code for changing modes here, just to keep things short for the post

      default://FastLED disabled interupts which means when I send over an IR code it becomes garbled. Garbled codes trigger this switch case which stops the LEDs from animating and allows for a full IR code to be sent.
        Serial.println("New IR code recieved, stopping loop. Last stored mode is ");
        storedReactiveMode = currentReactiveMode;
        storedChillMode = currentChillMode;
        storedSelectedTool = currentSelectedTool;
        Serial.println (storedReactiveMode);
        Serial.println (storedChillMode);
        Serial.println (storedSelectedTool);        
        currentReactiveMode = -1;
        currentChillMode = -1;
        currentSelectedTool= -1;
        ledsStopped = true;
        
        //Blank out the LEDs so the IR remote can communicate with the Ardunio.
        for(int dot = 0; dot < NUM_LEDS; dot++) 
        { 
          leds[dot] = CRGB::Black;
          FastLED.show();
        }
     }
  }
}

void lcdControl()
{
//moved text around on the LCD screen, removed to shorten this
}

void displayBrightnessOnLCD()
{
  lcd.setCursor(0,1);
  lcd.print("Brightness: ");
  lcd.print(stripBrightness);     
}

void setup() 
{
  FastLED.addLeds<WS2812B, LED_PIN_1, GRB>(leds, NUM_LEDS);
  //FastLED.addLeds<WS2812B, LED_PIN_2, GRB>(leds, NUM_LEDS);
  irrecv.enableIRIn(); // Start the receiver
  randomSeed(analogRead(0));
  Serial.begin(9600);//change back to 9600 for the BT modules!
  FastLED.setMaxPowerInVoltsAndMilliamps(5,2400);
  Serial.println("Strip Initilised");
  ET.begin(details(mydata), &Serial);
  lcd.begin(16, 2);
  lcd.print("Strip Initilised");
  lcd.setCursor(0,1);
  lcd.print("v0.7.5.4");
}

void loop()
{    
    if (irrecv.decode(&results))
    {
      translateIR(); 
      lcdControl();
      irrecv.resume(); // Receives the next value from the button pressed
    }

    mydata.rawInputAudioLevel = analogRead(PIN_ANALOG_IN);
    mydata.send_brightness = stripBrightness;
    
    switch(functionMode)
      {        
        case 0:

        switch(currentReactiveMode)
            {
            
            case REACTIVE_MUSIC_LEFT_MODE:
              SetStripBrightness();
              MaxVolumeDecay();
              MusicLeft(); 
              break;
    
            case REACTIVE_MUSIC_RIGHT_MODE:
              SetStripBrightness();
              MaxVolumeDecay();
              MusicRight();    
              break;
    
            case REACTIVE_MIDDLE_OUT_MODE:
              SetStripBrightness();
              MaxVolumeDecay();
              MiddleOut();
              break;
    
            case REACTIVE_OUT_IN_MODE:
              SetStripBrightness();
              MaxVolumeDecay();
              OutIn(); 
              break;  
    
            case REACTIVE_RAINBOW_MODE:
              SetStripBrightness();
              MaxVolumeDecay();
              Rainbow();
              break; 
    
            case REACTIVE_TOGGLE_MODE:
              ToggleMode();
              break;

            case REACTIVE_LENGTH_MODE:
              SetStripBrightness();
              MaxVolumeDecay();              
              ReactiveLength();
              break;               
    
            case REACTIVE_TEST_MODE:
              TestEffect();
              break; 
            }
        break;

      case 1:
        
        switch(currentChillMode)
          {

            mydata.currentMode = currentChillMode;
            
            case CHILL_PULSE_MODE:
              //Serial.println("Chill pulse sudo code");
              break;
    
            case CHILL_RAINBOW_MODE:
              //Serial.println("Chill rainbow sudo code"); 
              break; 
            
            case CHILL_FADING_COLOURS:
              //Serial.println("Chill fading colours sudo code");  
              break;      
          }      
          break;

       case 2:
        switch(currentSelectedTool)
          {
            case TOOL_SPEED:
              //Serial.println("Tool speed sudo code");
              break;  

            case TOOL_BLUETOOTH:
              //Serial.println();
              break;  
          }
          break;
      }
  
  mydata.currentMode = currentReactiveMode;  
  mydata.currentFunctionMode = functionMode;
  ET.sendData();//Send the bluetooth data (originally commented out for debugging)
  
  delay(delayAmount);//this is influenced by the music mode I have on to create speed change effects. Moves between a value of 7-20
  
}

Let me know if this is enough to go on, otherwise if you're fine with it I'll PM you all the code.