I have setup a MCP3002 to convert an analog signal to digital signal. When I read it directly through serial and convert it to a wav file, it sounds relative clear. Serial is limited for samples per second though, I can get about 7000 sps.

When I send the signal directly to a server I can reach around 17.500 sps. however when I convert this to a wav file, it also sounds relative clear, but with a slight distortion/'robot voice' through the audio.

Is there a simple way to prevent this, or why is this happening?

The code how I read the SPI is in this question: Reading data from MCP3002

  • Without any code we cannot do much. Having a robot voice sounds like a sampling frequency issue. How do you set a sampling frequency and how did you measure the sample frequency? – chrisl Nov 8 '19 at 9:28
  • Does your ADC reach saturation? You can check whether you have samples with values 0 or 1023. Are you sure your sampling rate is strictly constant? Unless your SPI is clocked from a timer it probably isn't. – Edgar Bonet Nov 8 '19 at 9:30
  • @chrisl the code for reading mcp is added in the link (from another question, where you have also helped me =) ) – Revils Nov 8 '19 at 9:37
  • @EdgarBonet I added the code how I read the code, the ADC is between 100 - 200 so no saturation. My SPI is set at a constant frequency if that is what you mean? – Revils Nov 8 '19 at 9:38
  • And how are you sending the signal directly to a server? That is not in the code of your previous question. That can be very important, since it may screw up your timing, thus producing an unstable measurement frequency. – chrisl Nov 8 '19 at 10:18

From the code you linked to, it appears the SPI port is completely controlled by the software:

void loop() {
    msb = SPI.transfer(cmd);
    lsb = SPI.transfer(0);

This means that the timing of the SPI transaction (when exactly it starts) and, by extension, the timing of the ADC conversion, is dependent on the timing of your code execution. You have no good control on that timing. It depends on what other things may be in your loop, and on the other interrupt sources (timers, network...).

The least you can do is set up a timer interrupt, and run the SPI from the interrupt handler. Your timings should then be more consistent. You will still have some jitter due to the interrupt handler being delayed by some critical sections, including other interrupts. But it may be good enough for your application.

For best results, you would ideally want the timing to be completely controlled by hardware. Maybe there is a way to trigger the SPI port from a timer. This depends on the specific MCU you are using: you will have to dig into the datasheet.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.