20150515.jpeg

I'm continuing with the scope creep exercise.

As a preparation to make my Analog Shield talk to the SAMA5D4, I've been testing the on-board ADC functionality.

I've also measured the AC and DC signal path from signal source to ADC chip in.

 

setup.jpg

 

The Digilent / Texas Instruments Analog Shield ADC circuit

 

Our converter is the Texas Instruments ADS8343 16-Bit, 4-Channel Serial Output Sampling Analog-To-Digital Converter.

 

adc.png

The signal goes through 2 opamps before entering the ADC, and it is set up in such a way that both positive and negative signals can be sampled.

The first opamp, TI's LM837 Low Noise Quad Operational Amplifier.

It has two duties.

It more than halfs the input signal (0.4 amplification).

And it adds a DC component to the signal.

 

Check out the schematics for the Analog Shield for the voltage reference design. The circuit, has been taken from TI's application note "Miro Oljaca and Bonnie Baker - How the

Voltage Reference Affects ADC Performance Part 3 - Analog Applications Journal (4Q 2009)".

 

With my so-so voltmeter I measure a DC out perfectly matching what's sent at the input (2.03V).

The output is balancing around 2.86mV with floating input (this will be the case in my situation, where I have a reasonable high impedance input).

 

I've added a dc blocking cap at the input because the setup with the first opamp would inject DC into the pickup coil of my turntable.

The signal, clamped on positive and negative side by a pair of Schottky diodes (SDM40E20LS) in a single package, is sent to a second opamp buffer: TI's OPA4322 rail-to-rail CMOS opamp.

That one drives the signal, unchanged, to the ADC.

 

Sampling

 

I've used the sampler with the internal power supplies on the analog shield to measure DC capabilities. That's all very easy:

 

I mounted the shield on the Arduino UNO that came with the challenge, and connected each of the voltage outputs of the shield's power supply connector in turn to the ADC0 input of the ADC connector.

 

The sketch was only a few lines of code:

#include <analogShield.h>
#include <SPI.h>

void setup() {
  Serial.begin(9600);
}

void loop() {
  unsigned int sensorValue = analog.read(0);
  Serial.println(sensorValue);
  delay(100);
}




 

All worked fine except for one thing. I imported the Analog Shield library with the new Arduino lybrary manager, and I had to add this line to the if defined(__AVR__) section of the library's header file to get a correct compilation:

 

#include <SPI.h>




 

Arduino IDE's include strategy be darned *%$£§@.

 

As a second exercise I connected my turntable to the input and modded my Digital Light Organ Enchantment to work with the Analog Shield ADC.

There was little to change. As a challenge for myself, I added a simple input range optimizer.

 

In the light organ, the sampled input data is sent to a FFT lib to filter out the highs, mids and lows.

The library range is -128..127. My samples are 0..65535.

But since the range of my audio signal falls roughly between 20000 and 55000 (I sampled the data to check the range, but since my code is dynamically setting it, the actual limits don't really matter), I loose significant resolution if I mix the full range down to -128..127.

To limit the loss in resolution, I calculate the division factor in my code as a function of the effective minimum and maximum.

I set them at he starting limits of 20000 and 50000. If the signal drops below or peaks above, I adjust the range.

I also added a range aging mechanism. The range narrows in each loop of my code. So the upper limit ages towards the lower limit and vice versa.

Only to be pushed back up or down by the signal's peaks.

The aging is there to prevent that a loud part of the signal puts the limits out and spoil the fun any silent part coming later.

 

Here's a few highlights of the code adaption.

 

The preparation and declarations:

 

// http://arduino-guay.blogspot.com.es
// adapted to ti/digilent analog shield jc
//...
#define AUDIO_MINIMUM 20000U
#define AUDIO_MAXIMUM 55000U

void setup() {                
    //...
    // jc removed for analogshield    analogReference(INTERNAL);
    //...
}



 

 

The loop

 

void loop() {
  unsigned int sampleValue = 0U;

  // signal window
  static unsigned int maxi = AUDIO_MINIMUM;
  static unsigned int mini = AUDIO_MAXIMUM;
  unsigned int range = 0U;
  //...



 

 

Range aging:

 

  //...
  // age the signal window. Let the signal range slowly go narrow, so that the signal peaks can drive it to a good range
  if (maxi > AUDIO_MINIMUM) {
    maxi--;
  }
  if (mini < AUDIO_MAXIMUM) {
    mini++;
  }
//...



 

 

Sampling

 

       sampleValue = analog.read(0);



 

 

Range calculation and limits adjust

 

     if(sampleValue>maxi) {
         maxi =  sampleValue;
       }    
       if(sampleValue<mini) {
         mini =  sampleValue;
       }
       range = maxi - mini;



 

 

Down-calculation to -128..127

 

       data[i] = (sampleValue/(range/256)-128);
//...
}



 

As always, the chances for bugs in my calculations are high. Beat me when I goofed up.

 

Photo 15-05-15 19 31 07.jpg

 

 

Table of Contents
Chapter 1: Fix the turntable
1: Perpetuum Ebner Musical 1
2: A Time to Kill and a Time to Heal
3: Preparation for Motor Drive
4: Motor control with Infineon Motor Shield and Arduino UNO
5: Turntable speed sample testbed with Arduino UNO
6: Turntable Speed Sensor design
7: Control Theory - End of Chapter 1
Chapter 2: First Enchantments
8: Digital Light Organ Enchantment
9: Autonomous Servo Lift
10: SMD Time - Solder the IR Speed Sensor PCB
11: Yelp - who can Help me to Compile and Run my First SAMA5D4 C Program
12: Son et Lumiere - End of Chapter 2
Chapter 3: Taming the Board
13: Breakthrough - Run my own C++ Program on the SAMA5D4
14: Digital Light Organ Input Buffer
15: SAMA5D4 Blinky
16: Scope Creep
17: Audio Sampling with 16-bit ADC ADS8343
18: Sending Files to SAMA5D4 over USB
19: Port my Light Organ from Arduino to SAMA5D4
20: Fast Fourier Transform on the SAMA5D4 - End of Chapter 3
Epilogue: Reaching for the Clouds
21: Right-Sizing my Plans
22: My Own C++ Buffered Sampler on the SAMA5D4
Interlude
23: Building In the Motorized Light Organ
24: Up to the Clouds with Yún
25: Publish or Perish
26: Turntable Finished
Stretch & Boni
Bonus 1a: Remote Light Organ with WiFI pt. 1
Bonus 1b: Remote Light Organ with WiFI pt. 2
Grande Finale: Paho MQTT Client on the SAMA5D4
Related blog
Vintage Turntable repair: Can I fix a Perpetuum Ebner from 1958
Review 1: Atmel SMART SAMA5D4 Xplained Ultra Unboxing and First Steps
Review 2: Atmel SMART SAMA5D4 Xplained Ultra - Building the Libraries from Source
Review 3: Digital Continuous Rotation (360°) Servo Part 1
Review 4: Digital Continuous Rotation (360°) Servo Part 2
Review 5: Atmel SMART SAMA5D4 Xplained Ultra - TCP/IP running
Review 6: Atmel SMART SAMA5D4 Xplained Ultra - LINUX Distro with SSH support
poem
Enchanted Objects: Let's work together to tame the ATMEL SMART SAMA5D4 Xplained Ultra kit
17 bis: Off South...
Review 7: Atmel SMART SAMA5D4 Xplained Ultra - C++ ADC Example on Linux
Review 8: Atmel SMART SAMA5D4 Xplained Ultra - Product Review
Review 9a: Atmel SMART SAMA5D4 Xplained Ultra - Set up ADC Buffer with Hardware Trigger Part 1
Review 9b: Atmel SMART SAMA5D4 Xplained Ultra - Set up ADC Buffer with Hardware Trigger Part 2
Review 10: Atmel SMART SAMA5D4 Xplained Ultra - New Content on AT91.com
1958 Turntable from the Black Forest - Summary of the Enchanted Player Story