Feedback ANC System

Status
Not open for further replies.

zhifangtan

New member
Hi guys, totally newbie here.

I am attempting to create a feedback active noise cancelling system using Teensy 3.6. So the idea is that I have a microphone as the input and a speaker as an output. The signal from the microphone goes through a series of algorithm and output to the speaker. However, I am currently having trouble to make it work. This is my first teensy project and I am still trying to learn as much as I can. I have spent weeks scavenging information about anything that could help. I was wondering if I could achieve this with Teensy, any help would be greatly appreciated.

Problems/Questions:

1) Should I use the audio library for easier implementation?
2) Is there anyway to accelerate the algorithm part?

Again, I am totally newbie in Teensy and micro-controller. I am not entirely sure if I am going to the right direction. Thanks for any input or suggestion


This is the secondary acoustic path estimation for the ANC system.
Code:
/*
   Feedback Active Noise Cancelling System
   Secondary Path Offline Estimation
*/

#include <arm_math.h>
#include <ADC.h>
#include <DMAChannel.h>


ADC *adc = new ADC();
DMAChannel dma;

const int freq = 10;
const int micPin = A0;
const int speakerPin = A22;
const int32_t taps = 200;
uint16_t samples[1];

int32_t r;
int32_t d;
float32_t mu = 0.0000000005;
float32_t x[taps];
float32_t w[taps];
float32_t muEX[taps];
float32_t y;
float32_t e;
float32_t mue;

void setup() {
  // put your setup code here, to run once:
  //pinMode(micPin, INPUT);

  dmaInit();
  analogWriteResolution(12);
  adc->setAveraging(1);
  adc->setResolution(12);
  adc->setConversionSpeed(ADC_CONVERSION_SPEED::VERY_HIGH_SPEED);
  adc->setSamplingSpeed(ADC_SAMPLING_SPEED::VERY_HIGH_SPEED);
  //adc->adc0->analogRead(micPin);
  adc->adc0->startSingleRead(micPin);
  
  adc->enableDMA(ADC_0);
  adc->adc0->stopPDB();
  adc->adc0->startPDB(freq);
  adc->enableInterrupts(ADC_0);
  
  randomSeed(1);
  while (!Serial); // wait for Arduino serial monitor
  delay(100);
  Serial.begin(9600);


  dmaInit();

}

void loop() {

}

void dmaInit() {
  dma.source(*(uint16_t*) &ADC0_RA);
  dma.destinationBuffer(samples, sizeof(samples));
  dma.attachInterrupt(dma_isr);
  dma.interruptAtCompletion();
  dma.triggerAtHardwareEvent(DMAMUX_SOURCE_ADC0);
  dma.enable();
}

void algorithm() {
  int k = taps;
  while (k > 1)
  {
    x[k - 1] = x[k - 2];
    k--;
  }
  r = random(0, 4096);
  x[0] = r;
  analogWrite(speakerPin, r);

  arm_dot_prod_f32(x, w, taps, &y);

  adc->adc0->analogRead(micPin);
  
  d = samples[0];
  //Serial.println(d - 2048);
  e = d - y;

  mue = mu * e;
  
  arm_scale_f32(x, mue, muEX, taps);

  arm_add_f32(w, muEX, w, taps);
  //Serial.println(w[0],7);
}

void adc0_isr() {
  adc->adc0->readSingle();
  Serial.println(samples[0]);
  //long unsigned current = micros();
  algorithm();
  //Serial.println(micros() - current);
}

void dma_isr() {
  //Serial.println("dma");;
  dma.clearInterrupt();
}

void pdb_isr(void) {
        PDB0_SC &=~PDB_SC_PDBIF; // clear interrupt
        //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
}
 
Last edited:
I think that I see that you're using the Teensy's ADC and DAC, as opposed to using an audio interface (like the Teensy Audio Board). Using the onboard ADC and DAC, you're going to have a limited range of loudness that you're going to be able to cancel. Also, your mic and speaker might not be able to be connected directly to the Teensy without some sort of interfacing electronics.

What is your full hardware setup? What kind of test are you trying to do to demonstrate that your setup works (no doesn't)?

Chip
 
Status
Not open for further replies.
Back
Top