measuring the thiele-small characteristics of a speaker

113
University “Politehnica” of Bucharest Faculty of Electronics, Telecommunications and Information Technology Measuring the Thiele-Small characteristics of a speaker Diploma Thesis submitted in partial fulfillment of the requirements for the Degree of Engineer in the domain Electronics and Telecomunications, study program Telecomunication Sistems and Technologies Thesis Advisor Conf. Dr. Ing. Mihnea UDREA Student Ilie GALAN

Upload: vlad-damian

Post on 07-Nov-2015

20 views

Category:

Documents


10 download

DESCRIPTION

Measuring the Thiele-Small Characteristics of a Speaker

TRANSCRIPT

Appendix 3: Board Schematics and LayoutUniversity Politehnica of BucharestFaculty of Electronics, Telecommunications and Information Technology

Measuring the Thiele-Small characteristics of a speaker

Diploma Thesissubmitted in partial fulfillment of the requirements for the Degree of Engineer in the domain Electronics and Telecomunications, study program Telecomunication Sistems and Technologies

Ilie-Iulian GALAN

Thesis AdvisorConf. Dr. Ing. Mihnea UDREAStudentIlie GALAN

2013

Table of ContentsIntroduction15Chapter 1: Theory171.1The Driver171.2Break-in181.3Measuring the electrical resistance 181.4Measuring the Resonance Frequency 191.5Measuring the Driver Impedance at the resonant frequency 201.6Calculating the Driver Quality Factors ()201.7Measuring the Effective Radiation Area of the Driver Cone 221.8Determining the Driver Mechanical Compliance 231.9Calculating the volume of air equal to the driver compliance 241.10Determining the volume of the enclosure that will fit our driver 24Chapter 2: KwikStick-K40272.1CodeWarrior and Processor Expert282.2Periodic Interrupt Timer (PIT)322.3Liquid Chrystal Display (LCD)362.412-bit Digital-to-Analog Converter (DAC)382.516-bit Analog-to-Digital Converter (ADC)492.6Touch sense input (TSI)54Chapter 3: Implementation573.1STAGE 0: Starting up and calibration573.2STAGE 1: Measuring the DC Resistance of the driver 583.3STAGE 2: AC Set-up and calibration593.4STAGE 3: Measuring the Resonance Frequency and the value for the impedance of the driver at resonant frequency 633.5STAGE 4: Measuring the frequencies at which the value of the impedance is the geometric mean between and 643.6STAGE 5: Measuring the Driver Mechanical Compliance 64Conclusions65Bibliography67Appendix 1: KwikStik_SegLCD.c69Appendix 2: Events.c73Appendix 3: Board Schematics and Layout85

List of Figures

Figure 1.1: Driver cross section17Figure 1.2: Measuring the driver Electrical Resistance 18Figure 1.3: Measuring the Resonance Frequency19Figure 1.4: The amplitude and phase variations of a driver simulated in LTSpice19Figure 1.5: Driver frequency variation graph21Figure 1.6: Area of the cone22Figure 2.1: Front Side of KwikStik Development Board [QSGKS]27Figure 2.2: Back Side of KwikStik Development Board [QSGKS]28Figure 2.3: File New Bareboard Project29Figure 2.4: Selecting the board29Figure 2.5: Selecting the connection type29Figure 2.6: Choosing Processor Expert as the Rapid Application Development tool30Figure 2.7: Workspace configuration30Figure 2.8: MK40DX256ZVLQ10 Blocks and Pins Configuration31Figure 2.9: PIT Block diagram [K40RM]32Figure 2.10: Initializing PIT33Figure 2.11: PIT in Components window33Figure 2.12: PIT in Component Inspector window33Figure 2.13: Generate Processor Expert Code for PIT34Figure 2.14: The generated files for PIT (TI1.c)34Figure 2.15: Square waveform at 5.971 kHz35Figure 2.16: Square waveform at 5.974 Hz35Figure 2.17: The LCD segment configuration36Figure 2.18: Add LCD to project36Figure 2.19: LCD component functions37Figure 2.20: Display text "Hello"37Figure 2.21: Display number "22.9"37Figure 2.22: DAC Block Diagram [K40RM]38Figure 2.23: Add DAC to project39Figure 2.24: The output of the DAC (direct implementation)41Figure 2.25: The FFT representation (direct implementation)41Figure 2.26: The difference when making a sine wave, using 10 samples with respect to using 100 samples42Figure 2.27: Sinus function, plotted using the values generated by MatLab42Figure 2.28: 10.01 Hz sinus function (for Freq1=100 or 10Hz)44Figure 2.29: The FFT representation (for Freq1=100 or 10Hz)44Figure 2.30: 100.2 Hz sinus function (for Freq2=1000 or 100Hz)44Figure 2.31: The FFT representation (for Freq2=1000 or 100Hz)44Figure 2.32: 79.43 Hz sinus function (for Freq3=795 or 79.5Hz)45Figure 2.33: The FFT representation (for Freq3=795 or 79.5Hz)45Figure 2.34: Linear interpolation error46Figure 2.35: 79.58 Hz sinus function (using linear interpolation)47Figure 2.36: The FFT representation (using linear interpolation)47Figure 2.37: Rising slope for the 10 Hz sinus wave48Figure 2.38: Rising slope for the 100 Hz sinus wave48Figure 2.39: ADC Block Diagram [K40RM]50Figure 2.40: Add ADC to project51Figure 2.41: Setting the conversion time for the ADC51Figure 2.42: ADC measured value on Display52Figure 2.43: ADC measurement52Figure 2.44: Measured value if we set the DAC at 4095 (MAX)53Figure 2.45: Measured value if we set the DAC at 304353Figure 2.46: Copy the TSI component55Figure 2.47: TSI in Component Inspector window55Figure 2.48: TSI enabled56Figure 2.49: TSI on hold56Figure 3.1: Block diagram for measuring the DC connector cables resistance57Figure 3.2: Block diagram for measuring the electrical resistance of a driver58Figure 3.3: DAC generated sine wave with spikes59Figure 3.4: First order Butterworth low pass filter59Figure 3.5: Sine wave after the LPF60Figure 3.6: First order Butterworth high pass filter60Figure 3.3.7: Sine wave after HPF61Figure 3.3.8: The FFT representation61Figure 3.9: Voltage divider61Figure 3.10: Sine wave after the voltage divider61Figure 3.11: Phase Variation62Figure 3.12: Maximum amplitude at 62Figure 3.13: Inverting summing amplifier62Figure 3.14: Difference between and 62

List of Acronyms

NameMeasuring UnitsDescription

hertz [Hz]Driver free air resonance

ohms []Electrical resistance of the coil measured at constant current

ohms []Driver impedance measured in alternative current at resonant frequency

millihenry [mH]Drivers coil impedance

dimensionlessDriver electrical quality factor

dimensionlessDriver mechanical quality factor

dimensionlessDriver total quality factor

meters/Newton [m/N]Driver mechanical compliance

liters [l]It represents the equivalent air volume, that when pressed with a surface equal to the surface of the driver membrane has the same mechanical compliance (or elasticity) with the mobile system composed of the drivers membrane, mobile coil and suspensions.

millimeters [mm]The maximum possible movement of the driver membrane in one direction (maintaining the same number of windings in the magnetic field generated by the coil)

liters [l]The air volume dispatched by the driver membrane at

tesla [B]Magnetic field intensity in the coil

tesla*meters [B*m]Driver motor strength. It is represented by the product between the magnetic field intensity () and the length of the coil conductor ()

centimeters [cm]Driver membrane diameter

meters [m]Coil conductor length

grams [g]Total cone assembly mass including radiation mass

percentage [%] Energetic efficiency or driver yield

watts [W]Electrical power that can be handled by the driver on long periods of time without damaging itself

liters [l]The volume of the enclosure (box) that will fit our driver to form a speaker

decibels [dB]Sound Pressure Level or acoustic pressure level. It is measured by an SPL-meter placed one meter in front of a driver that radiates a power of 1W

centimeters square [cm^2]Effective radiation area of the driver cone

OP-AmpOperational Amplifier

MCUMultiport Control Unit

USBUniversal Serial Buss

PITPeriodic Interrupt Timer

LCDLiquid-Crystal Display

DACDigital-to-Analog Convertor

ADCAnalog-to-Digital Convertor

hertz [Hz]Sampling Frequency

FFTFast Fourier Transform

DCDirect Current

LPFLow Pass Filter

HPFHigh Pass Filter

Introduction

Measuring a driver is relatively simple and it only requires a scientific calculator, a frequency generator, a couple of really accurate resistors (to form good voltage dividers), a good AC voltmeter and a little patience. Most of the measurement can be made by anyone who knows how to use the devices mentioned before but it can take some time and you have to always be focused on your work; that is why I want to build a single device that performs the measurements quickly and accurately.We can say that drivers behave like a resonant circuit having therefore a resonant frequency , and therefore a maximum impedance . Knowing that resonant frequency and the bandwidth at -3 dB we can compute the values of the quality factors. Also by measuring the driver mechanical compliance we can then calculate the volume of air equal to the driver compliance . By knowing only these parameters and some geometrical characteristics of the driver we can determine the optimum volume for an enclosure that will fit our driver. The reason why I chose to make a device that measures drivers is because not all of them come with a specifications sheet made by the producer or maybe you have found a driver and you wish to make an enclosure for it, therefore you will need to know some of their basic parameters. There are a lot of books written about loudspeakers and drivers, so if you are an audio enthusiast just like me, you will probably want to read a book by Ray Alden, Speaker Building 201 [SB201], which explains very well, at a beginners level, what is a driver, how does it work and what do you have to keep in mind when you want do design a speaker system. If you want to take it to the next level, then I recommend that you read Loudspeaker Design Cookbook by Vance Dickason [LDC7], where you can find just about all there is to know about speakers and drivers, presented in detail for those of us that already have a some broad knowledge on this subject.This paper, that you are going to read, presents at first a small introductive theory about speakers; what they are, what parameters do they have and a glimpse on how to measure or compute them. The theory is far from complete and it does not explain roughly why some formulas where used the way they were but it provides sufficient information to understand what are the tasks needed to be done and how I am going to implement the techniques necessary solve those tasks.Although, if you are not interested in all of this audio stuff, but you like to program microcontrollers, play with DACs, ADCs, LCDs or just build cool electronic circuits, you can find out a lot of useful information further along in the book that will help you get started on a new project or make you improve your current design. The microcontroller that I have used is called the Kwikstick-K40 from Freescale Semiconductor, but the code and the methods that I have used can work for anyone that is panning on using CodeWarrior and Processor Expert as the building platforms for their projects.I have developed this paper to act more as a guide to help anyone who wants to develop an easy way of measuring drivers or act as a tutorial for those who those want to initialize a new component into their CodeWarrior project. Almost all of the procedures explained in Chapter 1: Theory will have their implementation described in Chapter 3: Implementation, with references to the techniques presented in Chapter2: Kwikstick-K40.I consider my device to be necessary because it provides an easy and time efficient way of measuring a driver, increasing the accuracy of the measurements by reducing human error factor that comes along when we are trying to do the measurements by hand. A good and stable measuring device can provide some accurate values for the Thiele/Small parameters of a driver, which will lead to some very good enclosures designs, and a high sound quality for the speaker system.

Ilie-Iulian GALANIntroduction

62

15

Theory

In this chapter I will try to explain the theoretical and practical principles behind measuring the Thiele/Small parameters, principles upon which base my thesis and have constructed the measuring device.This whole chapter is based mainly on chapter eight of the book Loudspeaker Design Cookbook, 7th edition by Vance Dickason. [LDC7]

The DriverDrivers are basically a type of transformers that transform the electrical energy into mechanical energy; therefore they can be decomposed into two parts: the electrical part which includes the coil and the mechanical part which includes the cone and the suspension. An oscillating signal applied at the input of the driver will make the coil move according to the magnitude and polarity of the wave, therefore moving the cone and suspension along with it. In Figure 1.1 you can see a cross section, for a more complete view of the driver and its components:

Figure 1.1: Driver cross section

The part of the driver that produces the sound is composed of the moving block which is usually the cone and the dust cap or a one-piece dome and a suspension system which is made up of the spider and the surround.There is a whole chapter written in the book mentioned above about the driver components and we will explain some of them further along in this paper referring back to this picture. The purpose of my device is to generate a set of parameters that will model the behavior of these mechanical and electrical components. Break-inPrior to testing, all cone speakers should be broken in[footnoteRef:1]. Because most of the drivers are mass-produced, the materials that the suspension system is made from may be a little stiff and that is why we must make sure that when we start measuring the driver, it is operating at its optimum parameters. [1: Break-inorbreaking in, also known asrun-inorrunning in, is the procedure of conditioning a new piece of equipment by giving it an initial period of running, usually under light load, but sometimes under heavy load or normal load. It is generally a process of moving parts wearing against each other to produce the last small bit of size and shape adjustment that will settle them into a stable relationship for the rest of their working life. [WIKI1]]

To do this process you need to let the driver play for a long period (usually for 12 hours) at low frequencies (best at 25 Hz) and with sufficient amplitude (it is recommended to use an amplifier). This process loosens the suspension and it can reveal if the driver had any manufacturing flaws like a broken suspension (poorly glued suspension or spider) or a misalignment (or rubbing) of the voice coil. As you can see, this failure detection part that this system offers can be crucial when choosing a driver to be measured, because if the driver presents some flaws then there is no point in proceeding along with the actual measurements.Measuring the electrical resistance Usually most drivers are built with a fixed value for their electrical resistance, like 4, 8 or 16, to tell the audio amplifier manufacturers a specific value of the load that will be placed at the output of their device, therefore allowing them to design a matched output stage that will ensure a maximum power gain for the audio amplifier, but for most commercial drivers, the value of their electrical resistance may slightly vary from the value specified by the manufacturer that is why it is good to measure it because we will need to use it further along in some equations.The simplest way to measure it is to connect a DC voltmeter directly to the terminals of the driver and read the value from the measuring device.

Figure 1.2: Measuring the driver Electrical Resistance Measuring the Resonance Frequency I want to start by saying that the theory presented here fits the small-signal model for the driver therefore when you will want to use small levels for the input voltage, less than 1V would be preferable. Another known fact is that the driver can pick up some waves that are circulating in the room (its acts like a microphone) that is why it is recommended that we do our measurements outside, in free space, with the driver suspended 2-3 meters above the ground and away from any other obstacle or wall, onto a rigid platform (preferably on a wood platform). You will also need a reliable voltage oscillator, an accurate and known resistance of 1 k and a really good AC voltmeter. You will generate sinusoidal wave with small amplitude and a frequency varying between 10Hz and 100Hz using the signal generator, and with the AC voltmeter you will measure the value for the amplitude across the voltage divider. For a clearer view see the next picture.

Figure 1.3: Measuring the Resonance Frequency

Because the impedance of the driver varies with frequency, the output voltage will also vary. The resonant frequency is the frequency at which the impedance of the driver is maximum; therefore in order to find it we must vary the frequency on the sine wave oscillator until we find a maximum for the output voltage.

Figure 1.4: The amplitude and phase variations of a driver simulated in LTSpiceIn Figure 1.4 you can see the voltage and phase variations of the output voltage taken across a driver at different frequency. You can clearly see that some ware between 10 Hz and 100 Hz there is a peak in the voltage transfer function. We can say that that peak is formed at the resonant frequency because we can observe that the phase deviation at that frequency is 0.

Measuring the Driver Impedance at the resonant frequency To measure the driver maximum impedance you must first find the resonant frequency and keep feeding that frequency to the driver. If you look back at Figure 1.3 you can see that the driver and the resistance R of 1k are forming a voltage divider. By measuring the voltage across the driver, knowing the voltage generated by the signal generator and knowing the other resistance you can then compute the value for the impedance of the driver:

Although you have to keep in mind that you are also measuring the impedance of the wires connecting the driver to the device, therefore you will have to measure them and subtract that value from your result:

Calculating the Driver Quality Factors ()By now we know the values for the electrical resistance of the driver (), the resonant frequency () and the value for the maximum impedance (). The driver can be considered a resonant circuit, and we know that the quality factor for a resonant circuit is the ratio between the resonant frequency () and the bandwidth at -3dB. In this case, to make the measurements to be more exact, we will measure the bandwidth at -6dB. To measure this bandwidth we must first fine the values for the frequencies at 6dB (,).First we will calculate a reference impedance value:

After which we can calculate , the impedance value of the driver at which we will find and :

Now by knowing we just need to set the sine signal generator on the resonant frequency and then gradually lower the frequency until we get the value for the impedance of the driver to be thus finding ; and then setting again the generator on the resonant frequency and this time rising the frequency until we get the same value for the driver impedance thus finding .For a better understanding of the phenomena, I have plotted an approximation of a driver response in frequency using MatLab and represented on that graph the values that were discussed above:

Figure 1.5: Driver frequency variation graph

Finally we can now calculate the values for the quality factors using the following formulas:

Measuring the Effective Radiation Area of the Driver Cone The majority of the drivers have the shape of their cone built in the same manner, and they all resemble the base of a cone. The surface of this king of a shape can be written as the sum between the area of the bases and the lateral area:

For a better understanding please refer to the next figure:

Figure 1.6: Area of the cone

To determine the radiation area of the cone we must now subtract from the value obtained above the area of the big base (it dose net really exists in the construction of a driver) and we must add a third of the area of the suspension. To calculate the area of the suspension we will calculate the whole area from which we will subtract the area of the big base:

or:

Determining the Driver Mechanical Compliance To determine the driver compliance we must first compute the value for the driver mass which can be computed by summing the values for the driver air-mass load and the assembly mass :

The driver air-mass load can be computed using the formula:

To determine the assembly mass we will use the added mass method. For this method we will need some extra weights to add on top of the driver cone. In my case I have used some coins that I have pre-weighted and I have put them on top of the driver.For this method to work we need to measure the resonant frequency of the driver and change the mass of the cone (by adding weights) until the resonant frequency of the driver is lowered with at least 25-30%. When we are happy with the value that we have obtained for the frequency, we will note it on a piece of paper as and then calculate the value for the mass added and note it as .The value for the assembly mass can be then computed using the formula:

Combining all of the formulas above into one we can say that the driver mass is:

By knowing the driver mass we can now compute the driver suspension compliance using the following formula:

where:- is given in meters/newton- is given in kilograms

Calculating the volume of air equal to the driver compliance To calculate the driver compliance we just need to input the data obtained above into to following formula:

There are some other methods for calculating but I have chosen the one above for its simplicity.

Determining the volume of the enclosure that will fit our driver The purpose of all these measurements is to find out the parameters of a driver and to design the best enclosure that will fit that driver to form a speaker system.There are whole books written about designing and building a speaker and I am not going to go very hard into this matter. If you are really interested in designing your own speaker system you can read the book Speaker Building 201 by Ray Alden [SB201].There are mainly two types of enclosures; the closed enclosure and the vented enclosure. To see what kind of box is recommended for your driver you can first calculate the efficiency bandwidth product or EBP:

if EBP 50 then the driver is best suited in a closed boxif EBP > 50 then the driver is best suited in a vented boxThis is not a rigid design rule but it only gives us a guideline for what to expect from our driver.If you decide on building a closed box then the volume of the enclosure should be:

where: - is a value that describes the transient response of a box. You will want to take this value to be 0.5 or 0.71 to avoid the ringing effect that a box can produce. For more information please research the transient response curves of a speaker.- is given in liters If you decided on building a vented box speaker then the volume of the box should be:

For the vented box you will need to find the tuning frequency

And now to calculate the length of the port that will tune the box to this frequency:

where: - is the length of the port- is the radius of the portIt is possible to use two or more ports, which combine will form the equivalent of a larger diameter port:

It is good to know that there some rations for the dimensions of the box that are widely spread among the speaker designers. The first one it scaled the acoustic ratio:

and the second one is called the golden ratio (found in mathematics and nature):

There are is a whole lot more to be discussed on this manner but I believe that with the information presented above anyone can succeed at designing and building its very own speaker system that will provide a good sound quality.

Ilie-Iulian GALANChapter1: Theory

61

KwikStick-K40

An ultra-low-cost, all-in-one development tool for evaluating, developing and debugging Kinetis MCUs features the K40X256VLQ100 (144LQFP) MCU with USB, touch-sensing and segment LCD functionality. It comes pre-flashed with demonstration software to exercise a small portion of the capabilities of the Kinetis K40X256 device and the KwikStik hardware. The on-board Segger J-Link debug interface allows the user to evaluate the features of the on-board K40 MCU or to develop, debug and program their own target hardware based on any Kinetis MCU.The KWIKSTIK-K40 can be combined and used with several peripheral modules in the Tower System; it can also be operated as a standalone debug tool.

Features: K40X256 in 144 LQFP (256 KB flash, 256 KB FlexMemory, ultra-low-power, precision mixed-signal) LCD display with 306 segments 3.5 mm audio output jack and two micro USB connectors Omni-directional microphone and a buzzer On-board J-Link USB programmer Infrared communications Micro SD card slot Capacitive touch-sensing interface General purpose Tower plug-in (TWRPI) socket Manganese lithium rechargeable battery [WWW2.1]

Figure 2.1: Front Side of KwikStik Development Board [QSGKS]

Figure 2.2: Back Side of KwikStik Development Board [QSGKS]

I have chosen this development board because it has a very good Digital-to-Analog Convertor (DAC) to generate sinusoidal waveforms, a very good Analog-to-Digital Convertor (ADC) to measure the output after connecting the driver, an Liquid-Crystal Display (LCD) to show the results of the measurements, a really good operating frequency to conduct the calculus and it is easy to learn more about by researching it the internet.All of the following code examples apply to this development board.

CodeWarrior and Processor ExpertCodeWarrior is the name of the software provided by Freescale Semiconductor to be used to build, debug and upload software applications for their line of microcontrollers. Or as stated on their website: CodeWarrior Development Studio is a complete Integrated Development Environment (IDE) that provides a highly visual and automated framework to accelerate development of the most complex embedded applications [WWW2.1.1] .Processor Expert technology is a development system to create, configure, optimize, migrate, and deliver software components for Freescale silicon. This technology is integrated into Freescales CodeWarrior products supporting S08/RS08, S12(X), Coldfire, Coldfire+, Kinetis, DSC 56800/E, and some Power Architecture processors.Processor Expert technology makes it much easier for you to deal with the low level intricacies of a hardware platform in an optimal manner. You do not have to accept generic one-size-fits-all drivers. You design custom peripheral drivers ideally suited to your needs, without having to know everything about the hardware. Additional components are available online at the Freescale Component Store.

Features: Extensive and comprehensive knowledgebase of all supported silicon encapsulating all pins, registers, etc. System on a Chip (SoC) resource conflicts flagged at design time, allowing early correction Simple creation of optimized peripheral drivers without reading massive documentation Enables straightforward migration (wizard assisted) to new hardware Enables creation of arbitrary custom components encapsulating any software Can configure, package, and deliver components to your team Fully integrated into CodeWarrior for Microcontrollers [WWW2.1.2]Chapter 2: KwikStick-K40

For additional information on CodeWarrior and Processor Expert software please contact the freescale website: www.freescale.com.Setting up CodeWarrior and Processor Expert

First you need to start the CodeWarrior software and create a new Bareboard project: (File New Bareboard Project). This will open a new window that will ask you to insert a name for your project (any name will do but you have to keep in mind that you cannot use the same name twice).

Figure 2.3: File New Bareboard Project

After that you need to select your device or board that you are going to use in your project (in my case is the Kinetis PK40X256 microprocessor). You can either type some characters from the name of your device in the searching dialog box or you can search manually for it by clicking the dropdown menu. Once you have found your board, click next.

Figure 2.4: Selecting the board

Now you have to specify how your computer will communicate with the programmable board. For that you need to look up your type of connector in your boards reference guide under the section named Programing the MC. In my case I have selected the Segger J-Link and clicked next.

Figure 2.5: Selecting the connection type

You can also click next to the following panel and at the last panel you have to choose Processor Expert as your Rapid Application Development tool. Processor Expert can generate for you all the device initialization code and it includes many low level drivers. Now you can click finish and wait for the software to configure itself.

Figure 2.6: Choosing Processor Expert as the Rapid Application Development toolNow you have finished configuring your software to work on your specific microprocessor. You should have your workspace almost like in the following image, for which I will now start to explain the use of every window.

Figure 2.7: Workspace configuration

On the upper left side of the screen we have the CodeWarrior Projects window, which displays all the folders, subfolders and files that make your project. This window displays what is actually written on our hard drive when we work on a project. When you chose to delete something from this window it will be deleted from your hard drive as well so be careful. Now you should find there a folder with the name of your project, click on it and it will expand and display some more information. You should find a folder that says Sources, this is the folder that holds the main files of your software design, where you will add your code, after which you compile, debug and write them onto your microcontroller. The file that holds the main() function is called ProcessorExpert.c, and its the file from where you should call most of your secondary functions. There is also another file called Events.c that holds the declarations of all the interrupt functions of your blocks that can be called. You can specify here specific tasks for every one of your interrupt functions.By clicking on one of these files you open up a new window in the middle of your workspace that displays the actual code that is written on that file. From here you can modify the code so it can serve your purpose, but as you can see, these files must obey a specific format that is generated by ProcessorExpert. The format is explained clearly by the text that is generated in the comment lines and it is very important to follow this format in order for the software to work.In the right side of your workspace you should find the Components Library window which holds all of the known features that your MCU can deliver. You can sort them alphabetically or by category and you can add any one of them by right-clicking on it and selecting Add to project. Also, if you need some information on the components you can right-click on it and select Help in component which will open a new window with a lot of useful information on that item.After you added your component, it will show up in the Components window which is located in the lower left side of the workspace, under the components folder. In this window you can tell the software if you want your code to be written in the FLASH or RAM section of the microcontroller memory, and from here you can select one of you added components and modify its parameters. We will talk about this when we will start adding components to our project.

Figure 2.8: MK40DX256ZVLQ10 Blocks and Pins ConfigurationCodeWarrior has a lot of other windows and menus that we can use. One of those windows is the Processor window (you can open it by clicking WindowShow viewProcessor) presented in Figure 2.8, where we can see all of the blocks that we have on the microprocessor, its pins and what block is connected to what pin. We can add a component using this menu as well by right-clicking on the component and then Add to project.Conclusions CodeWarrior and Processor Expert are highly intuitive, easy to work with and you can find a lot of examples on the internet that can help you understand them. Further on I will present some of the components that I added and configured in order for my project to work.

Periodic Interrupt Timer (PIT)The PIT timer module is an array of timers that can be used to raise interrupts and trigger Direct Memory Access (DMA) channels.

Figure 2.9: PIT Block diagram [K40RM]The main features of this component are that timers can generate DMA trigger pulses or generate interrupts which are all maskable. We can also have independent timeout periods for multiple timers.PurposeThe current tendency in microcontroller programing is to work with interrupts. If we want to write something on the DAC, read something from the ADC or call a function at a specific timing, we need to use interrupts. Therefore we will use the PIT in order to generate periodic interrupts with a frequency set by us.

Initialization and setting up

To initialize the PIT in your project you have to search for that component in the Component Library window, right-click on it and select Add to project. Our PIT component is named TimerInt_LLD.

Figure 2.10: Initializing PIT

You can now see that this new component is listed in the Components window (lower left side of the workspace), and a new window has opened in the right side of the screen that says Component Inspect. You can also see that this component has a red x sign on it which warns us that this component needs to be set up (see Figure 2.10). You can set up the component by configuring it as it suit you in the Component Inspect window (see figure 2.11).

Figure 2.11: PIT in Components window

Figure 2.12: PIT in Component Inspector window

To get rid of that warning you just have to insert a value in the Interrupt period field. As you can see in Figure 2.11, I have set my interrupts to be made with a frequency of 10 kHz, but you can insert any value that you want and the software will automatically calculate de division factors that it needs to apply to the primary clock period (PIT clock has a frequency of 50 MHz) in order to get your desired frequency. You can change the name of your component to any value you want and chose an interrupt source (you can have multiple interrupt that operate at different frequencies). I also recommend that you set the Auto initialization field to yes, which will make the software write the code to initialize the component an also set the OnInterupt field to Enabled, which will let you use this timer as a trigger for an interrupt function TI1_OnInterupt. The interrupt function will be prewritten in the Events.c file.After you configured your component you have to press the Generate Processor Expert Code (see Figure 2.12), which will write the files needed to operate this component and place them in the Generated_Code folder located in your main project folder (see Figure 2.13).

You can also see in Figure 2.12 a list of all the functions that Processor Expert has generated and can be used along with the timer component. If you hover over any of those components you will see a description of that function appearing.

Figure 2.13: Generate Processor Expert Code for PIT

Figure 2.14: The generated files for PIT (TI1.c)

For the interrupt timer used in this example, Processor Expert has generated only the TI1.c and TI1.h files and put them in the Generated_Code folder. But in Figure 2.13 you can see that I have several other files generated, which will help me use the ADC, DAC, LCD and many other components needed further in the project. You will have to make the same steps I have presented above every time you want to add and use a new component. Now we are all set to start using this timer and the interrupt function.Generating a square waveform using interruptsIn order to test the interrupt component we will try to generate at the output a square waveform that the values of 0V for the low part and 3V for the high part, and with a frequency equal to half of the interrupt frequency.We will keep the same configuration that we set when we initialized the PIT (see Figure 2.11), which means that we will have an interrupt frequency of 10 kHz.If we open up the Events.c file located in the Sources folder and scroll down a little we will find the declaration of the function TI1_OnInterrupt. This function was generated by Processor Expert and its a function that calls itself with a frequency set by you when you modify the Interrupt period field (in our case is 10 kHz).To generate a square waveform you just have to write the following code:unsigned int i=0;// a variablevoid TI1_OnInterrupt(LDD_TUserData *UserDataPtr){/* 2.2.3Generating a square waveform using interrupts */DA1_SetValue(DA1_DeviceData, i*4090); /* Set converter output */i=(i+1)%2;// a flag which tells us if the function is low or high}The interrupt function first tells the DAC to write something at its output by calling the DA1_SetValue function (this function will be explained in the next section where we present the DAC) and then modifies the flag. By connecting the output of the DAC to an oscilloscope and by changing the interrupt frequency from 10 kHz to 10 Hz we get the following images:

Figure 2.15: Square waveform at 5.971 kHz

Figure 2.16: Square waveform at 5.974 Hz

Because we chose to generate at the output two alternate values every time the interrupt function is called, then we should get a square waveform with a frequency of half the frequency of the interrupt function; therefore the first signal should have a frequency of 5 kHz and the second one should have a frequency of 5 Hz.From Figures 2.14 and 2.15 we notice that the microcontroller is generating the square waveforms with a +19% deviation of the frequency from the desired value. The first thing that came to my mind was to reduce the frequency with which the interrupt function is calling itself by 19%.

If we compensate for this error and insert the new values for the frequencies at the Interrupt period field in the Component Inspector window, the results are perfect.ConclusionsWe can successfully use PIT as an accurate timer or as an interrupt for a specific function within the microcontroller as long as we remember to scale its working frequency by -19%.

Liquid Chrystal Display (LCD)Our KwikStik K40 has an 8x38 = 304 segment LCD integrated in the main development board. Beside those 304 individually configurable segments the LCD has some other predefined figures that can be displayed, as you can see in the following image:

Figure 2.17: The LCD segment configuration

PurposeWe will use the LCD to display some useful information during the test.Initialization and setting up

To initialize the DAC we need to follow the same stapes as initializing the PIT.

In the Components Library window we will search for the SegLCD_LLD, right-click on it and Add to project. You will see that the component is added to the project without any errors and you can start using its functions.

Figure 2.18: Add LCD to project

Displaying a text

As you can see in the Components window, this component has only two functions to work with, one to initialize it and another to select the segments, therefore if we want to write something on the LCD we need to build our own functions.

Figure 2.19: LCD component functions

To do this I have written a new file called KwikStik_SegLCD.c where I have implemented some other functions like lcd_DisplayNumber, lcd_DisplayChar or lcd_DisplayString, ho can display more facile the information on the screen. The code for this function is kind of long but if you are interested you can find it attached in Appendix 1 at the end of this paper.Now if we want to display a text on the LCD, something like Hello, we just have to call the following function:

lcd_DisplayString(SegLCD1_DeviceData, 0, "Hello");

where, the first argument specifies the component to be used, the second number specifies the position where we want to start the display and the last argument is the text that we want to be desplayed.If we want to display a number, lets say 22.9, we will use this function:

lcd_DisplayNumber(SegLCD1_DeviceData, 0, 2, 1, 229);

whereas in the previous case, the first argument specifies the component to be used, the second number specifies the position where we want to start the display, the third number specifies the number of digits ahead of the comma, the forth number specifies the number of digits after the comma and the last number is the number we want to display written with the comma removed (microprocessors perform better if we only work with natural numbers).

Figure 2.20: Display text "Hello"

Figure 2.21: Display number "22.9"

In the figures above you can see how the effect of the functions looks in real life.ConclusionsIt is very useful to have a display when you are working in a project and you want to check and verify the results while you work. I will also use the LCD to make my application more user-friendly with text and information that will guide the user during the measurements.

12-bit Digital-to-Analog Converter (DAC)The KwikStik K40 has a 12-bit low power, general purpose digital-to-analog converter (DAC). The output of this DAC can be placed on an external pin or set as one of the inputs to the analog comparator, OP-Amps, ADC, or other peripherals.

Figure 2.22: DAC Block Diagram [K40RM]

As you can see from its block diagram (Figure 2.17), this is a successive approximation DAC which uses a 4096-level resistive network, selectable thru a 1/4096 multiplexer that is driven by a 12-bit register. We also have a buffer integrated in the circuit to separate the DAC from the other devices that will be put at its output.PurposeWe need this DAC in order to generate a sinusoidal waveform which can have any frequency from 10Hz to 100Hz; that we need in order to test out the driver frequency response and to find the resonant frequency.Initialization and setting upTo initialize the DAC we need to follow the same stapes as initializing the PIT.

In the Components Library window we will search for the DAC_LLD, right-click on it and Add to project. You will see that the component is added to the project without any errors this time and you can start using its functions.

Figure 2.23: Add DAC to project

Although there arent any errors, you can still change some of its proprieties in the Component Inspector window (it should look almost like the one in Figure 2.11) as: the name of the component, which of the two D/A convertor you want to use (DAC0 or DAC1), chose if you want to use the predefined interrupt function that comes with it, which output pin you will use, the resolution and many other. I also recommend setting Low power mode do Disabled if you power your development board by an USB cable instead of its battery and set Auto initialization to yes to make the software write the initialization code for you.To write something on the DAC we just use the DA1_SetValue(DA1_DeviceData, value); function where DA1_SetValue is the name of the function that sets an output value for component DA1, DA1_DeviceData is the component declared by Processor Expert, and value can be any number between 0 and 4095 ( which tells the DAC what value between 0V and 3V to set at its output.Generating a sinusoidal waveform: Direct implementationThe simplest way is to make the processor compute the values for the sinus waveform. The sinus function can be written as:

where: the amplitude - is the peak deviation of the function from zero the ordinary frequency - is the number of oscillations (cycles) that occur each second of time the angular frequency - is the rate of change of the function argument in units of radians per second the phase - specifies (in radians) where in its cycle the oscillation is as To simplify the relation we will take that (the amplitude of the function will be between -1 and 1), (the waveform starts without any phase shift) and (the waveform will have a frequency depending only on the number of computed samples and the frequency of the microprocessor that computes the samples). Therefore we can implement the following formula:

where: a counter - is an integer number that goes from to the number of points in which you want to compute the function - this number determines the fidelity of the resulted waveformNow we have generated a number of values of the sinus function that have values in the interval [-1, 1]. The problem is that our processor cannot work so well with negative values, therefore we will add the value 1 to our result to eliminate this problem. This will make our results be in the range [0, 2], but our 12-bit DAC works with values from 0 to 4095 therefore we will multiply the result with 4095/2:

In code we can write it like this:

/* The direct implementation */#include #define SINUS_LENGTH 1000// the number of samples unsigned int i=0;// a counter float f;// the value for the sin() function

void TI1_OnInterrupt(LDD_TUserData *UserDataPtr){ f=(sin(2*3.14*i/SINUS_LENGTH)+1)*2047;//calculating the valueDA1_SetValue(DA1_DeviceData, f); /* Set converter output */i=(i+1)%SINUS_LENGTH;//incrementing the counter}

In the code above, I have declared a value for the number of samples that I want to compute (1000 samples), two variables for counter and for the value of the sin() function and I have called an interrupt function which computes the value for the amplitude, tells the DAC to write that value at its output and increments the counter. This interrupt function is set to execute itself once every 100s (with a frequency of 10 kHz).I have built and debugged the code, uploaded it the microcontroller and connected the output of the DAC to the oscilloscope. The following picture resulted:

Figure 2.24: The output of the DAC (direct implementation)

Figure 2.25: The FFT representation (direct implementation)

From Figure DAC.1 we can see that the microprocessor is generating a periodic signal which has the frequency of 6.743Hz and the peak-to-peak amplitude of 2.98V, but we can also notice that the waveform is slightly bent to the left. To see how accurate our generated sinusoidal wave is, I have set the oscilloscope to perform the Fast Fourier Transform (FFT) of that signal to see if it has components on other frequencies as well. From Figure DAC.2 we can see that our signal has a DC component and the main frequency set on (which is good because it is the same with what we have measured before), but we can also see that the signal has components on other frequencies as well: and so on, which have significant amplitudes ( is only 20dB below and all the other frequencies are at least 20dB above the amplitude of the noise). Because of those extra spectral components we say that the microprocessor cannot compute accurately the values for the sin() function and we must use a different method of generating the sinusoidal waveform.Generating a sinusoidal waveform: Table search methodTo eliminate the error generated by the microprocessor when computing the sin() function, we will calculate a number of values for the that function using a different software (in my case MatLab) and store there values as an array in the memory of the microprocessor. After having that data we can tell the microprocessor read the values from that array and set the output of the DAC according to that value eliminating the need of excessive computations.I will make MatLab generate 1000 values for the sinus function and have them stored in a file. I chose to generate 1000 values because I plan to use a frequency of 10 kHz (8.4 kHz after we scale it by -19%, as discussed in the interrupt section) as the sampling frequency of the microprocessor and it will result that the microcontroller will be able to give at the output a stable frequency of 10 Hz (F=Fs/N). If we want to generate a higher frequency than 10 Hz, we can define a step that will be incremented with itself and will tell us the position of the next sample, therefore skipping some values (for example, to go from 10 Hz to 100Hz we will define =10 and therefore taking every 10th sample, jumping over the other 9).Figure 2.21 shows us the problems that occur when we chose to jump over values when creating a sinusoidal wave.

Figure 2.26: The difference when making a sine wave, using 10 samples with respect to using 100 samples(taking every 10th sample)

To generate the values I have wrote the following MatLab code:N=999; % the number of samples-1n=0:2*pi()/N:2*pi(); %a vector that goes from 0 to 2*PI with a step of 2*PI/N f=(sin(n)+1)/2; % computing the value of the sine, adding 1 to have only positive values and dividing it by 2 to have the highest value be 1f=round(f*4095); % multiply the result with 4095 (2^12) to increase the range of values from [0,1] to [0,4095] and rounding them to get only integer values that the DAC can work withplot(f) % plots the resultgrid,title('Sinus Wave'),xlabel('Samples'),ylabel('Amplitude')

fid=fopen('sinus.txt','w','b'); % copy the result into a file for further usefprintf(fid,'%d, ',f);fclose(fid);

Figure 2.27: Sinus function, plotted using the values generated by MatLab

Sinus.txt2048, 2060, 2073, 2086, 2099, 2112, 2125, 2138, 2150, 2163, 2176, 2189, 2202, 2215, 2228, 2240, 2253, 2266, 2279, 2292, 2304, 2317, 2330, 2343, 2355, 2368, 2381, 2394, 2406, 2419, 2432, 2444, 2457, 2469, 2482, 2495, 2507, 2520, 2532, 2545, 2557, 2570, 2582, 2595, 2607, 2619, 2632, 2644, 2656, 2669, 2681, 2693, 2705, 2717, 2730, 2742, 2754, 2766, 2778, 2790, 2802, 2814, 2826, 2838, 2850, 2861, 2873, 2885, 2897, 2908, 2920, 2932, 2943, 2955, 2966, 2978, 2989, 3001, 3012, 3023, 3035, 3046, 3057, 3068, 3080, 3091, 3102, 3113, 3124, 3135, 3146, 3156, 3167, 3178, 3189, 3199, 3210, 3221, 3231, 3242, 3252, 3262, 3273, 3283, 3293, 3303, 3314, 3324, 3334, 3344, 3354, 3364, 3373, 3383, 3393, 3403, 3412, 3422, 3431, 3441, 3450, 3460, 3469, 3478, 3487, 3496, 3506, 3515, 3523, 3532, 3541, 3550, 3559, 3567, 3576, 3585, 3593, 3601, 3610, 3618, .....Figure 2.22 shows the sinus function which was generated using the values computed by MatLab, and to the right you can see some samples of those values that were written in the Sinus.txt file.After we have generated the values we have to feed them to the microcontroller. To do that I have defined a static variable that holds the number of values generated by MatLab and declared a new array the size of that static variable which holds the generated values:

/* Table search method */#define SINUS_LENGTH 1000// the number of samplesstatic const LDD_DAC_TData SinusOutputData[SINUS_LENGTH] = {2048, 2060, 2073, 2086, 2099, 2112, 2125, 2138, 2150, 2163, 2176, 2189, ...};// there are 1000 values declared here in the code

unsigned int i=0;//a general purpose variable (in our case a counter)

int Freq=100; //the output frequency (in Hz*10)int Counter_Freq=0; //a counter for the unitary and fractional part of the frequency

void TI1_OnInterrupt(LDD_TUserData *UserDataPtr){ DA1_SetValue(DA1_DeviceData, SinusOutputData[i]); /* Set converter output */ i=(i+Counter_Freq/100)%SINUS_LENGTH;//calculates the position of the next sampleCounter_Freq=Counter_Freq%100+Freq;//calculates the new value for the frequency counter}

Next I have declared 3 new variables; first i which is a counter that indicates the position of the next sample that needs to be sent at the output of the DAC, Freq which is a variable that holds the value of the frequency that we want to obtain at the output and Counter_Freq which is a variable that holds the value for the unitary and fractional part of the frequency and it is incremented with itself. After the declarations I have called an interrupt function that is set to call itself one every 100s. The function first tells the DAC to set at its output the value at the position i from the array declared above, after that the function increments i with the decimal value of the frequency pus 1 if the value of Counter_Freq is above 100 and finally increments Counter_Freq with its initial value.Running and uploading this code to de microprocessor for two different values of Freq (Freq1=100 or 10Hz and Freq2=1000 or 100Hz) results in the following waveforms on the oscilloscope:

Figure 2.28: 10.01 Hz sinus function (for Freq1=100 or 10Hz)

Figure 2.29: The FFT representation (for Freq1=100 or 10Hz)

Figure 2.30: 100.2 Hz sinus function (for Freq2=1000 or 100Hz)

Figure 2.31: The FFT representation (for Freq2=1000 or 100Hz)

We are happy to see that we are able to make the microprocessor produce such an accurate frequency for the sinusoidal wave (with an error 0.5%) and without any other spectral components beside their fundamental frequency.

The code above can tell the microcontroller to change the frequency with a sensitivity of 0.1 Hz therefore I have told the microcontroller to generate a sinusoidal function of 79.5 Hz (Freq3=795) and I have attached the plots for the function and its FFT.

Figure 2.32: 79.43 Hz sinus function (for Freq3=795 or 79.5Hz)

Figure 2.33: The FFT representation (for Freq3=795 or 79.5Hz)

In conclusion, using this method offers good results when we want to generate sinusoidal waveforms with frequencies within the range of 10 Hz up to 100 Hz with a step of only 0.1 Hz and an accuracy of 0.5%.Generating a sinusoidal waveform: Table search and linear interpolation methodI will start by saying that we have obtained a pretty good sinusoidal wave with the previous method but if you have a good microprocessor to make some extra computations and if you want to generate an even better sinusoidal waveform you can apply linear interpolation to the previous method.Linear interpolation is effective if you want to generate a frequency that in not a multiple of 10Hz. Lets say for example that we want to generate a sinusoidal wave that has the frequency of 25Hz. With the previous method we would have taken the samples that are on the positions 0, 2, 5, 7, 10 and so on, therefore jumping at first over 1 value after which we jump over the next 2 values and then repeating the process. This means that we approximate the value that would have been on position 2.5 with the value that is on position 2. To reduce this error (we dont eliminate it completely) we will use linear interpolation between the two nearest points.Linear interpolation method is based on the equation of a straight line:

We will always use two consecutive points therefore:

Now if is not a natural number, but instead it is a fractional number (in our case =2.5), we can divide it by writing separately its natural part and fractional part: (in our case and ). Now if we want to find the value, obtained by linear interpolation, which is placed at position we can apply the following formula: The following picture illustrates this procedure and shows how much we reduced the error.

Figure 2.34: Linear interpolation error

To implement this method I wrote the following code:

#define SINUS_LENGTH 1000// the number of samplesstatic const LDD_DAC_TData SinusOutputData[SINUS_LENGTH] = {2048, 2060, 2073, 2086, 2099, 2112, 2125, 2138, 2150, 2163, 2176, 2189, ... };// there are 1000 values declared here in the actual code

unsigned int i=0;// a counterint Freq=795; //the output frequency (in Hz*10)int Counter_Freq=0; //a counter for the unitary and fractional part of the frequencyint value=0;// a variable used to store the value of the output - in the 'Table search and linear interpolation method'

/* Table search and linear interpolation method */DA1_SetValue(DA1_DeviceData,value); /* Set converter output */if(SinusOutputData[i+1]>SinusOutputData[i]){//the microprocessor value=SinusOutputData[i+1]-SinusOutputData[i]; dosen't operate well}else{with negative valuesvalue= SinusOutputData[i]-SinusOutputData[i+1];therefore we have to see }if the sinus wave is rising or fallingi=(i+Counter_Freq/100)%(SINUS_LENGTH-1);//calculates the position of the next sampleCounter_Freq=Counter_Freq%100+Freq;value=SinusOutputData[i]+value*(Counter_Freq%100)/100;//computes the value of the sample that we want to set at the output

The resulted signal which should have a frequency of 79.5 Hz looks like this:

Figure 2.35: 79.58 Hz sinus function (using linear interpolation)

Figure 2.36: The FFT representation (using linear interpolation)

The figures above look almost the same as Figure DAC.11 and Figure DAC.12 that represent the same 79.5 Hz sinusoidal waveform that was obtained without using linear interpolation. My conclusion is that our microcontroller can generate a good sinusoidal waveform without using linear interpolation. Adding more variables and extra equations will only add more computations that the microprocessor has to evaluate which only adds to the load and complexity of the software. Although, this method can be used if we want to improve the quality of our design. Resolution I want to find out what is the resolution with which our DAC operates. The resolution is the minimum voltage change that the microcontroller can set at its output. Because the DAC works on 12 bits, it can deliver only 4096 () values for the output voltage, and it can operate only within the voltage range of [0, 3] V. Therefore we can say that it has a resolution of:

We have 4096 possible samples but we have declared an array of only 1000 elements, therefore our sinus wave fill not use all of the 4096 samples, instead it will change with a higher step.I have written the following code in MatLab to see which is the maximum difference between the 4096 possible output values.

max=0; % a variable used to store the value for the maximum diference of the numbers in the array for i=2:N+1x=f(i)-f(i-1);% we can say that our sinus has the same rate of change on the rising slope as on the falling slope if (x>max) max=x; endendmax

The code delivered the following result:max = 13This means that the Resolution of our sine wave which has a frequency of 10 Hz is 13 times higher than the resolution of the DAC:

This only happens when the sinus wave has the biggest slope (it ascends or descends rapidly). This effect is not really noticeable at 10 Hz but at 100 Hz you can see it clearly on the oscilloscope. The reason is that at 100 Hz the microprocessor reads every 10th sample and this leads to a higher difference between those 4096 possible outputs. I asked MatLab to compute this difference and it gave the following result:max =129which leads to the following resolution:

Figure 2.37: Rising slope for the 10 Hz sinus wave

Figure 2.38: Rising slope for the 100 Hz sinus wave

In the previous figures you can see clearly how the resolution with which we build the wave affects the shape of the signal. I think that most of the drivers that we are going to measure with this application dont have their resonant frequency above 50 Hz, therefore we can say that the resolution problem wont affect us that much, but to be safe I will implement a simple filter that will be placed at the output of the DAC to eliminate those steps and to smoothen the waveform. This circuit will be discussed in another chapter.ConclusionsOur K40 ARM microprocessor cannot generate on its own a good sinusoidal waveform (I have tried using the #include library to make use of the sin() function but the output resulted in a bent sinusoidal wave that had components on several frequencies). To eliminate this error I have calculated the value for the sin() function on the interval [0, 2] in MatLab and inputted those values in CodeWarrior as an array from which the software can read the values for the sin() function at different time intervals and construct its own wave.Using the table search method offers good results when we want to generate sinusoidal waveforms with frequencies that range from 10Hz up to 100Hz with a step of only 0.1Hz and an accuracy of 0.5%.Although the 12-bit DAC can operate at a resolution of our resulted sinusoidal waves will have other resolutions that will range from at 10 Hz to at 100 Hz. To reduce the effect that this resolution has on the shape of the signal we will filter the output and smoothen the waveform.

16-bit Analog-to-Digital Converter (ADC)The KwikStik K40 has a 16-bit analog-to-digital converter (ADC) which is a successive approximation ADC designed for operation within an integrated microcontroller system-on-chip.Features of the ADC module include: Linear successive approximation algorithm with up to 16-bit resolution Up to 4 pairs of differential and 24 single-ended external analog inputs Output modes: differential 16-bit, 13-bit, 11-bit and 9-bit modes, or single-ended 16-bit, 12-bit, 10-bit and 8-bit modes Output formatted in 2's complement 16-bit sign extended for differential modes Output in right-justified unsigned format for single-ended Single or continuous conversion (automatic return to idle after single conversion) Configurable sample time and conversion speed/power Conversion complete / hardware average complete flag and interrupt Input clock selectable from up to four sources Operation in low power modes for lower noise operation Asynchronous clock source for lower noise operation with option to output the clock Temperature sensor Hardware average function Selectable voltage reference: external or alternate Self-calibration mode Programmable Gain Amplifier (PGA) with up to x64 gain [K40RM]

Figure 2.39: ADC Block Diagram [K40RM]

For more information on the ADC please see the K40 Sub-Family Reference Manual [K40RM], at page 767. PurposeWe plan on using our driver together with a very accurate resistance in a voltage dividing configuration. We will then use the ADC to measure the voltage drop across the driver and knowing the voltage drop across the whole divider (voltage generated by the DAC) we can calculate the value for the impedance of the driver at certain frequencies.Initialization and set-upTo initialize the ADC we need to follow the same stapes as initializing the PIT.

In the Components Library window we will search for the ADC_LLD, right-click on it and Add to project. You will see that the component is added but an error is displayed. To solve that error we need to go to the Component Inspector window and select a Conversion time by double-clicking one of the values predefined there.

Figure 2.40: Add ADC to project

For the Conversion time I have selected the value of 9.615385 s (which is the highest value that I could select). After I chose this parameter the software automatically calculated a set of 5 other values that you can see in Figure 2.36 including the ADC clock which is set to 2.621 MHz.

Figure 2.41: Setting the conversion time for the ADC

Therefore if I generate frequencies between 10 and 100 Hz using the DAC, and I sample them with a frequency of 2.621 MHz then I will have between 262 and 26 thousand samples per period for my reconstructed signal, which are more than enough.You can make your own adjustments just like with the DAC, but I still recommend to enable the Interrupt service/event and set Auto initialization to yes. Also I have selected the PTE24/CAN1_TX/UART4_TX/EWM_OUT_b/ADC0_SE17 as my Input A/D channel (pin). I have chosen this pin because it is conveniently connected to an external pin B42 located on the Primary connector of the board (see Figure 2.1 and 2.2). For more information on how the pins are connected please see the file KWIKSTIK-K40-SCH_V5.pdf, (KWIKSTIK-K40 Schematics), [K40SCH]. Measuring the voltage drop

To measure the voltage drop and testing the accuracy of the ADC we will connect the output of the DAC which will generate a constant voltage to the input of the ADC and read the result.To generate a constant voltage using the DAC we only have to choose what value we want to generate, scale this value to its respective 12-bit number and set this number to the DAC. Lets say that we want to generate the value of 2.2V; we know that the DAC works linearly and 3V is the maximum voltage that can be generated if we feed it with the value of: , therefore we just need to scale this value using the linear approximation method:

To implement this we wrote the following code in the main function:

int main(void) {

DA1_SetValue(DA1_DeviceData, 3003); // Sets the DACs output AD1_SelectSampleGroup(AD1_DeviceData,0);// Selects the ADC for(;;) { AD1_StartSingleMeasurement(AD1_DeviceData); //Starts the ADC measurement } }

The ADC has its own interrupt function in the Events.c file that calls itself every time the measurement is complete. I have set this function to read the value of the measurement and display the result on the LCD(see Figure 2.42) and connected the oscilloscope to get a read on the actual value (see Figure 2.43):

void AD1_OnMeasurementComplete(LDD_TUserData *UserDataPtr){AD1_GetMeasuredValues(AD1_DeviceData,&ADC_Value); lcd_DisplayNumber(SegLCD1_DeviceData, 0, 5, 0, ADC_Value);}

Figure 2.42: ADC measured value on Display

Figure 2.43: ADC measurement

From the LCD we notice that the last two digits arent readable because they change rapidly but we can clearly read the first three digits. Just for the purpose of computations lets make a rough average and say that the value displayed on the LCD is 47550. Knowing that we are working with an 16-bit ACD, tells us that the ADC will yield the value 0 for a voltage of 0V and the value 65535 for 3V. Therefore, if we want to know the voltage value measured by the ADC we just need to make again a linear approximation between these last values.

We can now compute the measuring error:

We have to keep in mind that this error is made mostly because of the noise that affects the circuit and especially the wires.Making an average between the measured valuesWe assume that the noise is a white noise which has the mean 0, that is why we will implement a function that will make an average between all the measured values. To have a clearer view of the result I have set the DAC to give at its output the maximum voltage.

AD1_GetMeasuredValues(AD1_DeviceData,&ADC_Value);avg=ADC_Average(avg, ADC_Value, Nr_Measurements);lcd_DisplayNumber(SegLCD1_DeviceData, 0, 5, 0, avg);if (Nr_Measurements < 255){Nr_Measurements++;}

I chose that the number of measurement should not go above 255 because, in my opinion, the values that we get in the last measurement should influence a lot more the result than the values that were obtained in the first few measurements. The result is encouragingly stable but discouragingly inaccurate:

Figure 2.44: Measured value if we set the DAC at 4095 (MAX)

Figure 2.45: Measured value if we set the DAC at 3043

In Figure 2.44 we see that if we set the DAC to give the maximum voltage (set the value of 4095) and connect the ADC directly to its output, we will read the value of 64664 which correspond to a voltage value of:

which is or lower that what we expected.From now on we will take for granted that the DACs maximum output voltage is and not .To test the accuracy of our averaging function and of our previous approximation, we will set again the DAC to give us a voltage of , supplying a new input value:

The result can be seen in Figure 2.45. The corresponding voltage value is now:

And the resulting error is:

ConclusionsWe can use this 16-bit Analog to Digital Convertor, that is integrated into our KwikStik K40 development board, to make some really accurate voltage measurements with a theoretical error of only .Although we have to keep in mind that if we chose to use the internal DAC as our voltage generator then our maximum voltage value will be and not which will correspond to a 16-bit ADC value of and not (; which should have been its maximum).

Touch sense input (TSI)The touch sensing input (TSI) module provides capacitive touch sensing detection with high sensitivity and enhanced robustness. Each TSI pin implements the capacitive measurement of an electrode having individual programmable detection thresholds and result registers. The TSI module can be functional in several low power modes with ultra-low current adder and waking up the CPU in a touch event. It provides a solid capacitive measurement module for the implementation of touch keypad, rotaries and sliders. [K40RM]PurposeWe will enable the capacitive touch sense input in order to create a menu and, allow the user to select the features that he wants to use from our project. Initialization and set-upAnother method of initializing a component is to copy it from an existing project and insert it into your current project.

To do this just open that past project, and in the Components window right-click on the desired component (in our case the TSI1:TSI_LDD) and then click copy after which open your current project and paste it in the same folder.

Figure 2.46: Copy the TSI component

You should find that the component is preconfigured and you can start using it, but you can still make some changes if you want. In this case it is useful to look in the Component Inspector window and have a look at what is the current configuration and especially you have to know how many pins are allocated and where are they placed. Figure 2.47 shows just an example of my configurations. For more information on the pin configuration please refer to the development board schematics [K40SCH].

Figure 2.47: TSI in Component Inspector window

Test the componentTo test the component I have implemented a simple algorithm that will increment a variable and display it on the LCD as long as I keep my finger on that button.First in the main() function I told the processor to verify the state of the buttons:

int main(void){ for(;;) { TSI1_TriggerSoftwareScan(TSI1_DeviceData); }}

The TSI has its own interrupt function located in the Events.c file that calls itself every time the value of the pin isnt between the threshold values:

int x;void TSI1_OnOutOfRange(LDD_TUserData *UserDataPtr, TSI1_LDD_TSI_PinMask mask){x=(x+1)%10000;lcd_DisplayNumber(SegLCD1_DeviceData, 0, 5, 0, x);}

The result of this function can be seen in the following Figures:

Figure 2.48: TSI enabled

Figure 2.49: TSI on hold

ConclusionsIt is really easy and convenient to implement some buttons in your project that will allow us to add a lot of configurability to our project.And you have to keep in mind that in the software related world there are a lot of free demos and examples that can be redden, understood and then adapted to your current project, so you dont have to invent the wheel all over again.

Implementation

In this chapter I will explain step by step the functionality of my device, the different measuring block diagrams and the code that I used to program the KWIKSTIK-K40 microcontroller. If you skipped directly to this chapter and some ware along it you have some questions on why I implemented a specific process, then please search for that process in Chapter 1: Theory, or if the code doesnt make sense please look for the explications on that specific component in Chapter 2: Kwikstick-K40.I want to avoid inserting any code in this chapter because I want to retain my rights over what I developed, although the code will be added at the end of the paper in the appendixes.

STAGE 0: Starting up and calibrationTo start up the device you just need to plug it into the USB port of your personal computer, to power up the microcontroller and to enable the serial communication between the device and the computer, and plug in the measuring box to power up the analogic part of the system.The system has several operating stages (each stage will be presented further along in this chapter), and by default it will start in STAGE 0 in which a message will appear on the LCD that says ~ DC CAL. This message informs the user that the device needs to be calibrated at first. In order to make the measurements more accurate we must first know the resistance value of the cables connecting the measuring device to the device being measured. To do this we must first connect the cables to the device by inserting one end of the wires into output 1 (which is the DC output) of the measuring device and then connecting the other loose ends together (in a short-circuit configuration).

Figure 3.1: Block diagram for measuring the DC connector cables resistance

The method presented in Figure 1.3 for measuring the resistance is nothing more than just a simple voltage divider made between a known resistance and the resistance of the wires . If we supply a constant known voltage with the DAC (therefore knowing the input voltage ), if we measure the voltage across the wires using the ADC (therefore knowing the output voltage ) and if we know the value of the fixed resistor (which must be a very accurate resistor, with low a tolerance and really small temperature variations), then we can easily calculate the value of the resistance for the connecting cables :

After the user makes all of the connections he must then press the upper left button (which is also marked by a sign on the LCD) that will tell the microcontroller to start calibration. Upon pressing the button the software will start the measurement of the resistance, but it will also make an average of the values measured and display the result on the LCD.After a while, a clock figure will be displayed on the LCD which indicates that the microcontroller has accumulated enough samples and it is waiting for the user to stop the measurement and proceed to the next step. The user can leave the microprocessor measuring the resistance for as long as he wants but after the clock is displayed the changes that can occur arent noticeable. Pressing again the same button that we pressed at first will stop the measurement and the microcontroller will be now calibrated, knowing the resistance of the measurement wires.

STAGE 1: Measuring the DC Resistance of the driver This stage is almost identical to the previous one, the only thing we need to do is to connect the driver to the measuring cables

Figure 3.2: Block diagram for measuring the electrical resistance of a driver

Just as in the previous case, we have a voltage divider formed between the known resistance and the resistance of the wires plus the resistance of the driver . Therefore, we can use exactly the same formula as before to find out the value of , but we have to keep in mind to subtract the resistance of the wires from the actual measurements:

Now back to the microcontroller; a message should have appeared on the screen that tells the user to connect the measuring wires to the driver ~CON DR. After you have connected the wires you can press again the same button to tell the device to start the measurement. The microprocessor already knows the value for the resistance of the wires therefore it will automatically subtract it from the measured values and display on the LCD the actual value for the driver resistance.When you are happy with the value that you obtain you can tell the microprocessor to stop (by clicking the same button) and go to the next measurement.

STAGE 2: AC Set-up and calibrationFirst of all, to measure the resonance frequency, and its respective impedance, you will need a variable sine wave generator. To make this generator we can use the DAC integrated into the microprocessor (for more information on how to make this oscillator please see chapter 2.4: 12-bit Digital-to-Analog Converter). Chapter 3: Implementation

The problem with generating an analogic signal using a digital source is that our signal is bound to have spikes (see Figure 3.3). Spikes are some larger than average voltage outputs that the DAC is generating. Also, at high frequencies, because we chose to generate a sine wave using the table search method the difference in voltages is for each sample are high, therefore the steps tend to form.To get rid of those two effects we will use a first grade Butterworth low pass filter (see Figure 3.4).

Figure 3.3: DAC generated sine wave with spikes

Figure 3.4: First order Butterworth low pass filter

The LPF is formed of the 1 k resistance and the 100 nF capacitor connected to the ground. The value for the cutoff frequency is:

I have designed this LPF to have a cutoff frequency of at least ten times the frequency of the highest frequency that we will be generating using the DAC, in order for our frequency to be situated a decade below the cutoff frequency, therefore it wont be attenuated or affected by the filter.I have also added an operational amplifier to act as a buffer and repeat the filtered signal to the next block separating therefore the LPF from the rest of the circuit.The resulted signal can be seen next in Figure 3.5:

Figure 3.5: Sine wave after the LPF

Figure 3.6: First order Butterworth high pass filter

The resulted signal seen in Figure: 3.5 its a wonderful smooth sinusoidal signal but it still has one problem. The DAC can generate voltages between 0V and 3V, but to measure the driver the signal should have complementary values (the signal should be equally distributed on the positive voltage values as on the negative voltage values). To achieve this we just need to remove the constant current component that this signal has, which will bring our signal 1.5V down, oscillating symmetrically along the 0 V line. A first order Butterworth high pass filter is just what we need (Figure 3.6), which has the cutoff frequency of:

We have to design a filter that has a very low cutoff frequency to allow the minimum frequency that will be generated by the DAC to pass without any attenuation. The actual cutoff frequency of 0.8 Hz is more than a decade below our lowest generated frequency of 10 Hz, therefore the filter will only stop the constant component and will let the pure signal pass.I have also added an operational amplifier here to act as a buffer and repeat the signal to the other blocks in the circuit therefore separating the HPF from the rest of the circuit.The resulted signal can be seen in Figure 3.7; I have also added an FFT plot of the signal in Figure 3.8 to show that the resulted signal has no other spectral components beside its actual frequency.

Figure 3.3.7: Sine wave after HPF

Figure 3.3.8: The FFT representation

Only now we are ready to feed this signal with frequencies between 10 Hz and 100Hz into the voltage divider and see the voltage drop across the driver:

Figure 3.9: Voltage divider

Figure 3.10: Sine wave after the voltage divider

We can clearly see how the amplitude of the resulting wave is changing when the frequency generated by the DAC changes, and if you insert also the input wave into the oscilloscope you can see the phase variations as well:

Figure 3.11: Phase Variation

Figure 3.12: Maximum amplitude at

Now is a good time to start measuring the resonant frequency, but there still is one more problem: the ADC that we are going to use does not operate with negative voltage values therefore we must find a way to get rid of the negative part of the signal. The first thing that comes to mind is to use a rectifying diode, but the diode needs at least 0.6V to open and we dont have that much voltage. Another method is to use an investor amplifier and to add a known voltage to the one that we currently have, therefore rising its minimum value above the 0V threshold.

Figure 3.13: Inverting summing amplifier

Figure 3.14: Difference between and

Only about now we can say that the signal across the driver is ready to be measured.To make the measurements really accurate you will also have to measure with the ADC the value across the whole voltage divider generated by the DAC (point 3 in Figure 3.6 and Figure 3.9). I have observed that every time I change the load of the circuit the top voltage value generated by the DAC changes as well, and furthermore, you cannot trust the DAC to be perfectly linear, therefore it is a good practice to always measure the reference voltage when you want to use it in an equation. I am also measuring the value of the constant voltage used to sum up the signal (point 1V in Figure 3.13), therefore I dont really care about the actual values of the voltage divider; they only need to generate a constant voltage some ware around 1V.For the full view of the schematics please refer to Appendix 3: Board Schematics and Layout at the end of this paper.Therefore, to calibrate the device for the AC we will generate a range of frequencies from 10 Hz to 100 Hz and if we know the reference voltage and the summing voltage we can easily calculate the value for the impedance of the connecting cables using the following formula:

You can find references for the values written above in Appendix 3: Board Schematics.And finally we are ready to implement all that we have said above in the microcontroller. By now a message that says ~AC CAL should have appeared on the LCD; the microcontroller waits for the user to connect the cables together and to start the measurement for the impedance of the cables. The procedure is identical with the one described in the DC section, although, this time two numbers will appear on the screen; the first one tell us how many measurements have been concluded (the number of times that the microprocessor generated values form 10 Hz to 100 Hz) and the second number tells the user the value for the impedance.You can stop this measurement any time you want and finally get to the part where we will measure the maximum impedance of the driver.

STAGE 3: Measuring the Resonance Frequency and the value for the impedance of the driver at resonant frequency This stage is basically the same with the previous stage; the microcontroller first generates a range of frequencies from 10 Hz to 100 Hz and measures the maximum value for the output voltage, therefore finding the resonant frequency. I have also added an improvement to this stage with respect to the previous one; in this stage the microprocessor first generates the frequencies with a step of 1 Hz and finds a preliminary frequency, and then he makes the range of frequencies narrower with a bandwidth of 5 Hz around that frequency, after which he begins to generate frequencies in that range with a step of 0.1Hz, making therefore the measurement more accurate.On the LCD screen you will see the values for the number of measurements concluded, on the left, and the value of the resonant frequency, on the right.Besides measuring the resonant frequency the microcontroller also calculates the value for the maximum impedance of the driver using this simple formula:

STAGE 4: Measuring the frequencies at which the value of the impedance is the geometric mean between and First we have to calculate to calculate the value for at which we will find the frequencies and .

Knowing this value I have programed the microprocessor to start generating the resonant frequency and then gradually lower that frequency until it will find that the value of the impedance of the driver is equal to the value calculated above, therefore finding , after which it will again generate the resonant frequency and this time increase the frequency until it will find that the value of the impedance of the driver is equal to the value calculated above, therefore finding .Knowing these two frequencies allows us to calculate the bandwidth and with the bandwidth we can compute the quality factors.STAGE 5: Measuring the Driver Mechanical Compliance To find the mechanical compliance we will use the added mass method which requires that we lower the resonant frequency of the driver by increasing the mass of the cone.This stage is almost identical to stage 3 where we measure the resonant frequency of the driver but this time we have to keep in mind that we are not allowed to use any long term averaging methods of eliminating the error because we are changing the resonant frequency on purpose. Knowing the value for the new resonant frequency and the value for the mass added we can therefore compute the value for the mechanical compliance, and with it we know all of the main parameters needed to design a good enclosure for a driver making therefore a good overall speaker system.

Conclusions

An automated system that measures drivers is definitely an improvement from the hands on method that requires the user to perform the measurement manually. Every measurement is predisposed to be affected by errors but we can implement using a microcontroller some algorithms that can reduce the error by making at least an average of the values measured or by implementing a couple of filters along the circuit that will improve the quality of the measurements. Using the methods described before I have successfully measured and computed the Thiele/Small parameters of one of my drivers and with that data I was able to design an enclosure for that specific driver, to form a speaker. The consequences for this action are that now my neighbor hates me because when I start playing music on my speaker her dishes tend to fall of from the shelves (I currently live at the dorm so it is easy for that to happen; also you need to have a good amplifier to supply the speaker with enough power).There are also some improvements that I want to make by reducing the noise that appears in the circuit and I also want to eliminate the effect that the impedance of the wires has upon the measurement for the voltages by using a quadripolar configuration (it uses 4 wires instead of 2 to measure the driver). Another thing that I wanted to do and I didnt have time was to make the microcontroller transmit the values that he measured to the PC using a serial configuration and have the computer calculate all of the data and produce some charts necessary for designing a speaker system. I can also design a switching mechanism that will automatically transfer the microcontroller from the DC mode to the AC mode, removing thus the need to switch manually the wires.Designing a good speaker system is more of an art than science, although having accurate data can be a big bonus when tackling the challenge of building a high fidelity speaker system.

Conclusions

Bibliography

[K40SCH]KWIKSTIK-K40-SCH_V5, KWIKSTIK-K40 Schematics (version 5 boards), Rev. 5, Wednesday, April 27, 2011, Source: Freescale Semiconductor, Inc.

[K40RM]K40P144M100SF2RM, K40 Sub-Family Reference Manual, Rev. 3, 4 Nov 2010, Source: Freescale Semiconductor, Inc.

[QSGKS]KWIKSTIKQSG, Quick Start Guide for KwikStik, Rev. 1, Source: Freescale Semiconductor, Inc.

[LDC7]Vance Dickason, Loudspeaker Design Cookbook, 7th edition, Published by Audio Amateur Press, Peterborough, New Hampshire, 2006

[SB201]Ray Alden, Speaker Building 201, First Edition, Audio Amateur Press, Peterborough, New Hampshire, 2004

[WIKI1]http://en.wikipedia.org/wiki/Break-in_(mechanical_run-in) visited on 21 June 2013

[WWW2.1]https://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=KWIKSTIK-K40 visited on 16 June 2013

[WWW2.1.1]http://www.freescale.com/webapp/sps/site/homepage.jsp?code=CW_HOME visited on 16 June 2013

[WWW2.1.2]http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=PROCESSOR-EXPERT visited on 16 June 2013

Bibliography

Appendix 1: KwikStik_SegLCD.c

#include "PE_LDD.h"#include "KwikStik_SegLCD.h"

/* Character table */Appendix 1: KwikStik_SegLCD.c

static const uint8_t CharTable[][5] = {{0x00,0x1C,0x1C,0x1C,0x00}, //0{0x00,0x1C,0x1C,0x1C,0x00}, //1{0x00,0x1C,0x1C,0x1C,0x00}, //2{0x00,0x1C,0x1C,0x1C,0x00}, //3{0x00,0x1C,0x1C,0x1C,0x00}, //4{0x00,0x1C,0x1C,0x1C,0x00}, //5{0x00,0x1C,0x1C,0x1C,0x00}, //6{0x00,0x1C,0x1C,0x1C,0x00}, //7{0x00,0x1C,0x1C,0x1C,0x00}, //8{0x00,0x1C,0x1C,0x1C,0x00}, //9{0x00,0x1C,0x1C,0x1C,0x00}, //10 {0x00,0x1C,0x1C,0x1C,0x00}, //11{0x00,0x1C,0x1C,0x1C,0x00}, //12{0x00,0x1C,0x1C,0x1C,0x00}, //13{0x00,0x1C,0x1C,0x1C,0x00}, //14{0x00,0x1C,0x1C,0x1C,0x00}, //15{0x00,0x1C,0x1C,0x1C,0x00}, //16{0x00,0x1C,0x1C,0x1C,0x00}, //17{0x00,0x1C,0x1C,0x1C,0x00}, //18{0x00,0x1C,0x1C,0x1C,0x00}, //19{0x00,0x1C,0x1C,0x1C,0x00}, //20{0x00,0x1C,0x1C,0x1C,0x00}, //21{0x00,0x1C,0x1C,0x1C,0x00}, //22{0x00,0x1C,0x1C,0x1C,0x00}, //23{0x00,0x1C,0x1C,0x1C,0x00}, //24{0x00