Hey all. I have a circuit that I'm pretty stumped on. I'm a novice working on a project way over my head (but am so close!)
I'm trying to have a piezo sensor activate an LED strip using an Arduino Mega. My circuit is more complex than what I'm showing above, but I believe this is the problem area. It's really just this circuit repeated a number of times with different arduino pins.
The LED strip takes 12v, and has each set of lights in parallel with resistors built in (I'm showing 100ohm as a placeholder, not sure what it actually is). The current is about 3 amps. The trouble arises only when 12v is connected to the circuit and the LEDs are on. When the 12v is disconnected (and only 5v is connected from the USB), all LEDs are off, and I get a nice consistent reading when I tap the piezo. When I have the 12v connected and the LEDs set to LOW in my program, still nothing out of the ordinary (no readings). As soon as I set the LEDs to any value higher than 0, the Piezo actually starts buzzing quietly and the analog input pin gives me rapid very high readings. It's as if the load from the LEDs is partially sinking through the Piezo and into the analog in! Is this possible?
In an attempt to stop that from happening, I placed a 10uF capacitor between the negative side of the Piezo and ground. Same results.
Is there another component I need in the mix, or a change in my circuit? Any help is greatly appreciated!
Here is my test code in case this helps:
const int redPin = 5;
const int greenPin = 6;
const int bluePin = 7;
const int knockSensor1 = A0; // the piezo is connected to analog pin 0
const int threshold = 150; // threshold value to decide when the detected sound is a knock or not
float r = 0;
float g = 0;
float b = 0;
boolean fireR = false;
boolean fireG = false;
int countdown = 0;
int sensorReading1 = 0; // variable to store the value read from the sensor pin
int c=0;
void setup() {
pinMode(greenPin, OUTPUT);
pinMode(redPin, OUTPUT);
pinMode(bluePin, OUTPUT);
analogWrite(greenPin, 0);
analogWrite(redPin, 0);
analogWrite(bluePin, 0);
Serial.begin(9600); // use the serial port
}
void loop() {
// read the sensor and store it in the variable sensorReading:
sensorReading1 = analogRead(knockSensor1);
///Serial.println(sensorReading);
// if the sensor reading is greater than the threshold:
if (sensorReading1 >= threshold) {
//pick random color
r = random(255);
g = random(255);
b = random(255);
analogWrite(redPin, r);
analogWrite(greenPin, g);
analogWrite(bluePin, b);
Serial.println();
Serial.println();
Serial.println("FIRE! ");
Serial.println(sensorReading1);
Serial.println();
}
delay(5); // delay to avoid overloading the serial port buffer
}
Don't share a ground wire between the piezos and the power supply to the Arduino. Dedicate one of the ground pins on the Arduino for use by the piezo sensors (and the associated 1M resistors, and any other sensors you have), and use a different ground pin for providing power to the Arduino and connecting the output devices.
Keep the wires from the piezos to the analog inputs well away from the LEDs and the rest of the output wiring.
There may also be electromagnetic induction causing interference from the LED circuit to the piezo. PWMing a lot of LEDs
means a lot of EMI unless the circuit is shielded - each time the LEDs are switched on and off the rate-of-change of current
can be 10^8 amps/second or so - this will induce voltages in nearby circuits (as Faraday discovered).
Move the LEDs away from the piezo element.
Don't have open loops - these are bad news as the strength of interference is directly proportional to loop area -
always run your wires in a tight bundle, preferably twisted together (but separate bundles for LEDs and piezo,
of course!).
For instance the two wires from the MOSFET to the LEDs should be a twisted pair. The wires from MOSFET to the 12V supply
should be a twisted pair. There should be decoupling capacitors on the 12V rail right next to the MOSFET (at least 10uF,
100 would be better), to reduce the radiation back up the 12V supply wires. Even though the MOSFET isn't directly
connected to the +12V rail you should run the 12V wire up to it, then away again to the LEDs.
MarkT:
There may also be electromagnetic induction causing interference from the LED circuit to the piezo. PWMing a lot of LEDs
means a lot of EMI unless the circuit is shielded - each time the LEDs are switched on and off the rate-of-change of current
can be 10^8 amps/second or so - this will induce voltages in nearby circuits (as Faraday discovered).
Move the LEDs away from the piezo element.
Don't have open loops - these are bad news as the strength of interference is directly proportional to loop area -
always run your wires in a tight bundle, preferably twisted together (but separate bundles for LEDs and piezo,
of course!).
For instance the two wires from the MOSFET to the LEDs should be a twisted pair. The wires from MOSFET to the 12V supply
should be a twisted pair. There should be decoupling capacitors on the 12V rail right next to the MOSFET (at least 10uF,
100 would be better), to reduce the radiation back up the 12V supply wires. Even though the MOSFET isn't directly
connected to the +12V rail you should run the 12V wire up to it, then away again to the LEDs.
Thank you for your help! I've separated out the 2 wires connecting the Piezo to the board (they were in a 6-conductor cable) and it seems to be working well! This is with everything kind of hacked together, so I'm going to connect everything up in a more stable/permanent way and test it out. It did seem that running the Piezo signal along side an unshielded high amperage PWM signal is what gave me crazy readings. I also found that it was only an issue when my program was outputting a PWM signal (anything other than 0 and 255), which would make sense.