Major jitter on my FHT bars

So I finally got my FHT working and visualizing it using a program kindly provided by someone else, which merely captures the serial data and graphs it.

Problem is, no matter how much I check my electrical connections, these bars jump back and forth a few bins, as though the signal is flaky and being offset by some fixed amount for every bin. I don't know what is causing it. Any ideas? Here's a video:

https://vid.me/EJmJ

If I had to guess - and, without code, schematic, a description of the circuit, a description of the input signal, or even an idea of the devices that you're using, I do have to guess - I'd say that the problem lies between the gizmo that calculates the FHT and the gizmo that displays the FHT. I think that it misses some of the data from time to time, and it omits that data on the display.

That's raw speculation, though. If you want better, you might consider taking the effort to describe your setup and code more clearly.

Software: Using the standard example provided in the FHT library with only very minor output modifications to alter the syntax so the 3rd party program can read it and display the bars. The 3rd party software does no alterations to the output data except to draw bars based on their magnitudes

Electronics: A PDA running a tone generator app, set to 5.1 kHz. A 3.5mm plug is inserted into the headphone jack of the PDA, wires stripped downstream of the plug and alligator clips attached to jumpers that connect to the arduino's A0 and GND pins. That's literally it.

There are videos on youtube demonstrating the same 3rd party visualization software running perfectly so I doubt it's a bug.

tmd3: That's raw speculation, though. If you want better, you might consider taking the effort to describe your setup and code more clearly.

Well judging by the last reply I guess he doesn't want anything more than your guess.

Someone mark this [SOLVED]

I would say that some of the data being sent to the visualization software is being dropped. It would explain why the histogram suddenly shifts to the left and then back again. e.g. this sort of thing is being sent

-----^---^^^--
-----^---^^^--
-----^---^^^--

If the middle line is corrupted and the first two chars are dropped you would see:

-----^---^^^--
---^---^^^--
-----^---^^^--

But need to see your code. And it would help to know exactly what the visualization software is expecting too.

Pete

First, please disconnect your PDA, and don't connect it again until you know how to manage the analog input.

Gahhhrrrlic: Electronics: A PDA running a tone generator app ... A 3.5mm plug ... PDA, wires ... alligator clips ... jumpers that connect to the arduino's A0 and GND pins. That's literally it.

Thanks for sharing that part. It turns out to be an important detail. The PDA delivers both negative and positive voltage to its ouput. You've got it connected directly to the Arduino's analog input. The analog input isn't intended to operate with a negative input. It will read the data incorrectly, and it may sustain permanent damage from exposure to a negative voltage.

I'll recommend that you capacitively couple the PDA signal to A0, and offset it by half-scale. If you're using the FHT example that I suspect, it expects an input signal that's centered around half-scale. If you want help doing that, please say so, and we'll help.

See, you told us something about your setup, and we told you something that matters.

If you want to know more, you'll have to be forthcoming with information. We'll still insist on seeing your code, seeing the display code, knowing what kind of Arduino you're using, knowing which library you're using to do the FHT, and knowing what hardware you're using to display the graph. Because it looks very much like there's erratic performance on the communication channel between the Arduino and the display device, we'll want to know about how those two are connected, too. We'll also insist on knowing how everything else is connected. The best way to describe that is with a schematic. If you want, you can draw one by hand, photograph it, and, after you make sure that the photo is readable, attach it to your post. If you have a handy way of drawing a clearer schematic, so much the better. Unless your setup is extraordinarily neat, a photograph of the actual setup is unlikely to be helpful.

There's little point in troubleshooting more subtle aspects of this project while the analog input isn't working properly. Fix that, tell us what happened, and then we'll look at the rest.

Edit: spelling

I shouldn't have missed a detail like the negative voltage, as I'm already aware of it. I guess it slipped my mind. Luckily, the voltage was about 100 - 500 mV... not too much. Maybe I can use an op amp to apply a DC offset or something. Will provide code and schematics when I'm not at work later on. Thanks for the guidance thus far.

Gahhhrrrlic:
Maybe I can use an op amp to apply a DC offset or something.

For this stage of testing, you needn’t go to the effort of using an op amp. The PDA output is designed for headphones, so it should easily drive a considerably higher impedance. The attached jpg shows the schematic of a ferociously simple interface circuit with an input impedance of 10K, and a theoretical voltage at midscale. The capacitor is selected to give a 3dB rolloff frequency of about 16 Hz. Your frequency of interest is 5100 Hz, so you can use a capacitor as low as 0.01 uF and still pass 5100 Hz almost unmolested.

If you later use a sensor of some kind, its characteristics might require an amplifier. For high-impedance inputs, this circuit will reduce the amplitude of the input.

AnalogInputSchematic.JPG

Thanks. That circuit would be very well-behaved. Interim code in the mean-time. I can’t divulge the source code of the 3rd party app without permission. Suffice it to say it is primitive enough to draw bars from the data passed to it via the sketch. You could probably intuit how it works very easily.

/*
fht_adc_serial.pde
guest openmusiclabs.com 7.7.14
example sketch for testing the fht library.
it takes in data on ADC0 (Analog0) and processes them
with the fht. the data is sent out over the serial
port at 115.2kb.
*/

#define LIN_OUT 1 // use the log output function
#define FHT_N 256 // set to 256 point fht

#include <FHT.h> // include the library

void setup() {
  Serial.begin(115200); // use the serial port
  TIMSK0 = 0; // turn off timer0 for lower jitter
  ADCSRA = 0xe6; // set the adc to free running mode
  ADMUX = 0x40; // use adc0
  DIDR0 = 0x01; // turn off the digital input for adc0
}

void loop() {
  while(1) { // reduces jitter
    cli();  // UDRE interrupt slows this way down on arduino1.0
    for (int i = 0 ; i < FHT_N ; i++) { // save 256 samples
      while(!(ADCSRA & 0x10)); // wait for adc to be ready
      ADCSRA = 0xf6; // restart adc
      byte m = ADCL; // fetch adc data
      byte j = ADCH;
      int k = (j << 8) | m; // form into an int
      k -= 0x0200; // form into a signed int
      k <<= 6; // form into a 16b signed int
      fht_input[i] = k; // put real data into bins
    }
    fht_window(); // window the data for better frequency response
    fht_reorder(); // reorder the data before doing the fht
    fht_run(); // process the data in the fht
    fht_mag_lin(); // take the output of the fht
    sei();
        Serial.print("<");
    Serial.print(FHT_N/2);
    Serial.print(":");
    for (int curBin = 0; curBin < FHT_N/2; ++curBin)
    {
      if (curBin > 0)
        Serial.print(",");
      Serial.print(fht_lin_out[curBin]);
    }
    Serial.println(">");

  }
}

I think, but can't verify, that your problem stems from the fact that communication is interrupted right in the middle of the transmission. We don't know what the mystery software does at that point, but it may decide that something has become garbled, and wait for transmission to start again.

The Serial buffer is full of data when execution reaches the end of the wrapping "while" loop. The next thing that happens is that interrupts are disabled, for about 17 milliseconds by my calculations. Then, they're enabled again, and Serial prints the last characters of the previous transmission, and immediately starts transmitting a new data frame.

To test this theory, you might add a Serial.flush() statement right after printing '>', to make the sketch wait until the Serial buffer is empty before disabling interrupts. Or, you might remove the statements cli() and sei() that control interrupts inside loop(), as I don't see that they really help. The Serial buffer will empty before the sketch has finished acquiring the next frame, and it spends most of its time waiting on the ADC. I'd think that task could safely be interrupted for servicing Serial. My experiments don't show a human-noticeable difference in performance when interrupts are enabled.

Edit: delete repeated word

It would appear that the programmatical changes had little effect on the frequency distribution jitter so I am inclined to think that the problem lies elsewhere. Since I have yet to construct a proper test circuit the input waveform is still suspect. Will have to report back when I’ve had time to mock something up that provides the correct ADC input. These negative voltages may be throwing the ADC for a loop and creating this random offset. Occasionally I can get several seconds of clean output but usually no more than 1 or 2 so creating a more solid electrical connection and ensuring only positive voltage seems a necessary first step before further root-cause would be forthcoming.

Gahhhrrrlic:
It would appear that the programmatical changes had little effect

And once again, you didn’t post the code. Sheesh.

How does it work when you send test data?

Try this:

#define FHT_N 256 // set to 256 point fht
uint8_t outData[FHT_N >> 1];

void setup() {
  Serial.begin(115200); // use the serial port
}

void loop() {
  while(1) { // reduces jitter
    for (uint16_t i = 0; i < FHT_N/2; i++) {
      outData[i] = i + random(5);
    }

    Serial.print("<");
    Serial.print(FHT_N/2);
    Serial.print(":");
    for (int curBin = 0; curBin < FHT_N/2; ++curBin)
    {
      if (curBin > 0)
        Serial.print(",");
      Serial.print(outData[curBin]);
    }
    delay(20);
  }
}

Tested with Processing and FXTView from the openmusiclabs site. Naturally, it isn’t tested on the secret display software.

That will keep the output values small enough to fit into a byte. It will eliminate concerns about the ADC, since the ADC isn’t used. With a 20 millisecond delay, it will eliminate concerns about the Serial buffer and transmission timing. You can expect to see increasing bars from left to right, with a bit of ripple to verify that the data is actually being updated. If that works, you can test it with bigger data, with more complicated data, with the FHT library linked and with test data in fht_input, with the ADC running, with interrupts managed, and on until the culprit reveals itself.