Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // FHT, http://wiki.openmusiclabs.com/wiki/ArduinoFHT
- #define LOG_OUT 1 // use the log output function
- #define LIN_OUT8 1 // use the linear byte output function
- #define FHT_N 256 // set to 256 point fht
- #include <FHT.h> // include the library
- // pins
- #define MicPin A0 // used with analogRead mode only
- // consts
- #define AmpMax (1024 / 2)
- #define MicSamples (1024*2) // Three of these time-weightings have been internationally standardised, 'S' (1 s) originally called Slow, 'F' (125 ms) originally called Fast and 'I' (35 ms) originally called Impulse.
- // modes
- #define Use3.3 // use 3.3 voltage. the 5v voltage from usb is not regulated. this is much more stable.
- #define ADCReClock // switch to higher clock, not needed if we are ok with freq between 0 and 4Khz.
- #define ADCFlow // read data from adc with free-run (not interupt). much better data, dc low. hardcoded for A0.
- #define FreqLog // use log scale for FHT frequencies
- #ifdef FreqLog
- #define FreqOutData fht_log_out
- #define FreqGainFactorBits 0
- #else
- #define FreqOutData fht_lin_out8
- #define FreqGainFactorBits 3
- #endif
- #define FreqSerialBinary
- #define VolumeGainFactorBits 0
- // macros
- // http://yaab-arduino.blogspot.co.il/2015/02/fast-sampling-from-analog-input.html
- #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
- #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
- //#################################################################################################################################
- int enablePin = 11;
- int in1Pin = 10;
- int in2Pin = 9;
- int potPin = 1;
- int potVal = 0;
- int LoopCount = 0;
- boolean reverse = false;
- float RefDbValue;
- //int InitialDbValue = true;
- void setup() {
- // put your setup code here, to run once:
- pinMode(in1Pin, OUTPUT);
- pinMode(in2Pin, OUTPUT);
- pinMode(enablePin, OUTPUT);
- int speed = 255;
- setMotor(0,true);
- delay(1000);
- while(LoopCount < 3){
- switch (LoopCount){
- case 0:
- //reverse = true;
- Serial.println("potPin Value = " + analogRead(potPin));
- while(analogRead(potPin) < 1023){
- setMotor(speed,false);
- }
- setMotor(0,true);
- break;
- case 1:
- //reverse = false;
- Serial.println("potPin Value = " + analogRead(potPin));
- while(analogRead(potPin) > 0){
- setMotor(speed,true);
- }
- setMotor(0,false);
- break;
- case 2:
- //reverse = true;
- Serial.println("potPin Value = " + analogRead(potPin));
- while(analogRead(potPin) < 1023){
- setMotor(speed,false);
- }
- setMotor(0,false);
- break;
- }
- LoopCount++;
- }
- //#############################################################################################################
- //pinMode(MicPin, INPUT); // relevant for digital pins. not relevant for analog. however, don't put into digital OUTPUT mode if going to read analog values.
- #ifdef ADCFlow
- // set the adc to free running mode
- // register explanation: http://maxembedded.com/2011/06/the-adc-of-the-avr/
- // 5 => div 32. sample rate 38.4
- // 7 => switch to divider=128, default 9.6khz sampling
- ADCSRA = 0xe0+7; // "ADC Enable", "ADC Start Conversion", "ADC Auto Trigger Enable" and divider.
- ADMUX = 0x0; // use adc0 (hardcoded, doesn't use MicPin). Use ARef pin for analog reference (same as analogReference(EXTERNAL)).
- #ifndef Use3.3
- ADMUX |= 0x40; // Use Vcc for analog reference.
- #endif
- DIDR0 = 0x01; // turn off the digital input for adc0
- #else
- #ifdef Use3.3
- analogReference(EXTERNAL); // 3.3V to AREF
- #endif
- #endif
- #ifdef ADCReClock // change ADC freq divider. default is div 128 9.6khz (bits 111)
- // http://yaab-arduino.blogspot.co.il/2015/02/fast-sampling-from-analog-input.html
- // 1 0 0 = mode 4 = divider 16 = 76.8khz
- //sbi(ADCSRA, ADPS2);
- //cbi(ADCSRA, ADPS1);
- //cbi(ADCSRA, ADPS0);
- // 1 0 1 = mode 5 = divider 32 = 38.4Khz
- sbi(ADCSRA, ADPS2);
- cbi(ADCSRA, ADPS1);
- sbi(ADCSRA, ADPS0);
- #endif
- // serial
- Serial.begin(9600);
- while (!Serial); // Wait untilSerial is ready - Leonardo
- Serial.println("Starting mic demo");
- //#########################################################################################################################
- MeasureVolume(true,0);
- MeasureVolume(true,0);
- MeasureVolume(true,0);
- MeasureVolume(true,0);
- MeasureVolume(true,0);
- MeasureVolume(true,0);
- MeasureVolume(true,0);
- }
- void loop() {
- // put your main code here, to run repeatedly:
- // int speed = 255;
- // setMotor(speed,reverse);
- //#########################################################################################################################
- potVal = analogRead(potPin);
- Serial.println("PotPin Value = " + potVal);
- MeasureVolume(false,potVal);
- //#########################################################################################################################
- }
- void setMotor(int speed, boolean reverse) {
- analogWrite(enablePin, speed);
- digitalWrite(in1Pin, ! reverse);
- digitalWrite(in2Pin, reverse);
- }
- // calculate volume level of the signal and print to serial and LCD
- void MeasureVolume(boolean InitialDbValue, int ServoPos)
- {
- long soundVolAvg = 0, soundVolMax = 0, soundVolRMS = 0, t0 = millis();
- //cli(); // UDRE interrupt slows this way down on arduino1.0
- for (int i = 0; i < MicSamples; i++)
- {
- #ifdef ADCFlow
- while (!(ADCSRA & /*0x10*/_BV(ADIF))); // wait for adc to be ready (ADIF)
- sbi(ADCSRA, ADIF); // restart adc
- byte m = ADCL; // fetch adc data
- byte j = ADCH;
- int k = ((int)j << 8) | m; // form into an int
- #else
- int k = analogRead(MicPin);
- #endif
- int amp = abs(k - AmpMax);
- amp <<= VolumeGainFactorBits;
- soundVolMax = max(soundVolMax, amp);
- soundVolAvg += amp;
- soundVolRMS += ((long)amp*amp);
- }
- soundVolAvg /= MicSamples;
- soundVolRMS /= MicSamples;
- float soundVolRMSflt = sqrt(soundVolRMS);
- //sei();
- float dB = 20.0*log10(soundVolRMSflt/AmpMax);
- // convert from 0 to 100
- soundVolAvg = 100 * soundVolAvg / AmpMax;
- soundVolMax = 100 * soundVolMax / AmpMax;
- soundVolRMSflt = 100 * soundVolRMSflt / AmpMax;
- soundVolRMS = 10 * soundVolRMSflt / 7; // RMS to estimate peak (RMS is 0.7 of the peak in sin)
- // print
- Serial.print("Time: " + String(millis() - t0));
- Serial.print(" Amp: Max: " + String(soundVolMax));
- Serial.print("% Avg: " + String(soundVolAvg));
- Serial.print("% RMS: " + String(soundVolRMS));
- Serial.println("% dB: " + String(dB,3));
- //Serial.println("% dB: " + String(dB));
- //Serial.println("InitialDbValue: " + String(InitialDbValue));
- if(InitialDbValue == true) {
- RefDbValue = dB;
- Serial.println("RefDbValue = " + String(RefDbValue,3));
- }
- else {
- Serial.println("RefDbValue = " + String(RefDbValue,3));
- Serial.println("abs = " + String(abs(RefDbValue - dB)));
- if(abs(RefDbValue - dB) < 10.00 ){
- //potVal = analogRead(potPin);
- if (ServoPos > 0){
- setMotor(255,true);
- }
- }
- else {
- if(abs(RefDbValue - dB) >= 10.00) {
- //potVal = analogRead(potPin);
- if(ServoPos < 1023){
- setMotor(255,false);
- }
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement