Speech Recognition on MKR1000 – Wifi impact on ADC Converter

I am using MKR1000, Wifi101 ,SparkFun Microphone and Google Speech API to develop a speech controlled project.

Because the memory of MKR1000 is restricted, I send the sound data (8000HZ,16bit, 4-5 seconds) to Google while the voice is recorded. The program is sending blocks of 500bytes. For ADC Conversion I have “stolen” the code from AudioFrequencyMeter library and adjusted.

Everything is working alone, but all combined the ADC converter is returning wrong values (high peeks) exactly when the data is send via Wifi (see attached audacy image, increasing block to 1000 bytes also increased the amount of wrong values per block).

I can see three possible reasons:

  • Using internal reference voltage for ADC, maybe when using WIFI this is not stable enough
  • The voltage on the microphone is not constant when wifi is used – have used alternative power, no improvement
  • WIFI is triggering an interrupt, while ADC Converter is running – but I have already tried: __disable_irq() during ADC convertion

The MKR1000 is basically two systems (ATWINC1500 & ARM Cortex M0+) that communicate via interrupt and SPI. If the interrupts are handled fine – it should work. Or is my assumption wrong?

I believe the MKR is the perfect device for speech recognition– a lot of cool things can be done - if we get this working. Any help is really appreciated!!!

Latest code - already working with GoogleSpeech API is on GitHub
https://github.com/happychriss/MKR_VoiceRecognition

// Main loop, sending the buffer via WIFI when full
void loop() {
    while (true) {

        delay(1);

        if (b_buffer_send_ready) {
             client.write(send_buffer, BUFFER_SIZE);
            b_buffer_send_ready = false;
            loop_count++;
        }
    }
}


// Interrupt Routine
void TC5_Handler (void)
{

    // Reading Data from A01 and converting to 16bit unsigned for Google
    newData = ADCread();
    int16_t newDataSigned=(int16_t ) newData + 32768; // 2 power 15
    write_buffer[buf_count] = newDataSigned & 0xff;buf_count++;
    write_buffer[buf_count] = newDataSigned >> 8; buf_count++;

    if (buf_count==BUFFER_SIZE) {

        // switching buffer, when b_buffer_send_ready==true, main program will send
        tmp_buffer=write_buffer;write_buffer=send_buffer;send_buffer=tmp_buffer;
        b_buffer_send_ready=true;

        buf_count=0;

        if (loop_count==BUFFER_LOOPS) {
            Serial.println("Done");
            my_speech.end();
            client.stop();
        }
    }

   // Clear interrupt
    TC5->COUNT16.INTFLAG.bit.MC0 = 1;
}


// ADC Read, code from AudioFrequencyMeter
uint16_t ADCread()
{
    uint16_t returnValue;

//    __disable_irq(); // tried this,  no difference

    while (ADCisSyncing());

    ADC->SWTRIG.bit.START = 1;

    while ( ADC->INTFLAG.bit.RESRDY == 0 );   					// Waiting for conversion to complete
    returnValue = ADC->RESULT.reg;            					// Store the value

    while (ADCisSyncing());

    ADC->SWTRIG.bit.START = 0;

//    __enable_irq();

    return returnValue;
}

Update: After some research I found that Wifi (when transmitting data) impacts ADC when measuring at same time (ADC data in the frequency of speech).

I did the full set-up with data sending via Serial and Wifi. Serial is perfect, Wifi has exactly noise when the data is sent.

Could this be a problem of the board layout?

Good news: Sending to Google Speech API and retrieving text response is running fine. As data is send while recording there is no memory limitation. Recognition rate is “just ok” because of above.

See attached - and find out yourself which part was send via Wifi :slight_smile: