Hi,
I want to trigger an LED either by beat detection or by capacitive sensing.
Both ideas work well separately but not together in one sketch .
First I used “ADCTouch” by martin2250 which had problems as it interfered with 2 other things that are connected to 2 other analog inputs.
After I tried the “CapSense”-library which apparently slows down the sampling of the beat detection algorithm which makes it fail
Any tips for improving?
Thanks in advance
//***********************************************************
// Arduino Beat Detector By Damian Peckett 2015 modified 2017 by Johannes Hofmann
// License: Public Domain.
//***********************************************************
#include <CapacitiveSensor.h>
#include <TimerOne.h>
// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
int LedPin = 12;
int InterruptPin = 11;
//unsigned int pinElTransistor = ;
unsigned int pinPlasmaTransistor = 8;
//unsigned int pinElPoti = 1;
//unsigned int pinPlasmaPoti = 2;
unsigned int pinBeatPoti = 1;
unsigned int pinTouchSensor = 2;
unsigned int sampleIndex = 0;
bool envelopeTrigger = 0;
bool buttonTrigger = 0;
bool beatTrigger = 0;
CapacitiveSensor cs_4_3 = CapacitiveSensor(4,3);
/*******************************************/
/******************* SETUP *****************/
/*******************************************/
void setup() {
Timer1.initialize(200);
Timer1.pwm(InterruptPin, 512);
Timer1.attachInterrupt(setInterruptFlag);
Serial.begin(9600);
// Set ADC to 77khz, max for 10bit
sbi(ADCSRA,ADPS2);
cbi(ADCSRA,ADPS1);
cbi(ADCSRA,ADPS0);
pinMode(LedPin, OUTPUT);
}
void setInterruptFlag(){
if(sampleIndex++ > 200){
envelopeTrigger = 1;
sampleIndex = 0;
}
}
// 20 - 200hz Single Pole Bandpass IIR Filter
float bassFilter(float sample) {
static float xv[3] = {0,0,0}, yv[3] = {0,0,0};
xv[0] = xv[1]; xv[1] = xv[2];
xv[2] = sample / 9.1f;
yv[0] = yv[1]; yv[1] = yv[2];
yv[2] = (xv[2] - xv[0])
+ (-0.7960060012f * yv[0]) + (1.7903124146f * yv[1]);
return yv[2];
}
// 10hz Single Pole Lowpass IIR Filter
float envelopeFilter(float sample) { //10hz low pass
static float xv[2] = {0,0}, yv[2] = {0,0};
xv[0] = xv[1];
xv[1] = sample / 160.f;
yv[0] = yv[1];
yv[1] = (xv[0] + xv[1]) + (0.9875119299f * yv[0]);
return yv[1];
}
// 1.7 - 3.0hz Single Pole Bandpass IIR Filter
float beatFilter(float sample) {
static float xv[3] = {0,0,0}, yv[3] = {0,0,0};
xv[0] = xv[1]; xv[1] = xv[2];
xv[2] = sample / 7.015f;
yv[0] = yv[1]; yv[1] = yv[2];
yv[2] = (xv[2] - xv[0])
+ (-0.7169861741f * yv[0]) + (1.4453653501f * yv[1]);
return yv[2];
}
/*******************************************/
/***************** MAIN LOOP ***************/
/*******************************************/
void loop() {
unsigned long time = micros(); // Used to track rate
static float sample, value, envelope, beat, thresh;
unsigned char i;
// Read ADC and center so +-512
sample = (float)analogRead(0)-503.f;
// Filter only bass component
value = bassFilter(sample);
// Take signal amplitude and filter
if(value < 0)value=-value;
envelope = envelopeFilter(value);
// Every 200 samples (25hz) filter the envelope
if(envelopeTrigger == 1) {
envelopeTrigger = 0; // Reset interrupt flag
beat = beatFilter(envelope); // Filter out repeating bass sounds 100 - 180bpm
thresh = 0.02f * (float)analogRead(pinBeatPoti);// Get threshold based on potentiometer on analog input
// Serial.print("Threshold = ");
// Serial.println(thresh);
// Compare beat with threshold
if(beat > thresh)
beatTrigger = 1;
else
beatTrigger = 0;
}
Serial.println(cs_4_3.capacitiveSensor(10));
delay(200);
/**** Check if sensor was touched ****/
if( cs_4_3.capacitiveSensor(10) > 500 )
buttonTrigger = 1;
else
buttonTrigger = 0;
/**** Enable LED/transistor when beat wass detected or button pressed ****/
if(beatTrigger == 1 || buttonTrigger == 1)
digitalWrite(LedPin, HIGH);
else
digitalWrite(LedPin, LOW);
// Serial.print("Beat-Value = ");
// Serial.println(beat);
// Serial.println();
}
main.ino (3.87 KB)