Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Sine Wave using a DAC/Microcontroller.

  1. Jun 1, 2009 #1
    Hello everyone. I am working on a present for a girl (hehe) which will play a wav sound from an SD card into headphones. So, I have an SD card connected via SPI to a microcontroller which then connects via SPI to a DAC.

    Right now I connected my DAC and now I am having problems outputting a sine wave. It comes out "fat". I am not sure if it's because I picked bad numbers or what. Please take a look at it and tell me if anything is wrong here. I am basically lost here.


    I have a microproccesor MSP430F2012 (http://focus.ti.com/docs/prod/folders/print/msp430f2012.html").

    Full code attached to this post. I am posting small snippets here.


    Code (Text):
    //Main Loop

      while(1)
      {
        P1OUT |= 0x01; //Turn LED on
       
        for(i=0;i<511;i++)
             spi_send_byte(sinwave[i]); //transfer sine wave down-up
       
        P1OUT &= ~0x01; //Turn LED off
       
        for(i=512;i>1;i--)
             spi_send_byte(sinwave[i]); //transfer sin wave up-down
      }
     
    Code (Text):

    //sindata.h

    #ifndef SINDATA_H_
    #define SINDATA_H_


    const unsigned int sinwave[]={0,201,402,603,804,1005,1206,1407,1608,1809,2010,2211,2412,\
      2613,2814,3015,3216,3417,3617,3818,4019,4219,4420,4621,4821,5022,5222,5422,5623\
      ,5823,6023,6224,6424,6624,6824,7024,7224,7423,7623,7823,8022,8222,8421,8621,\
      8820,9019,9218,9417,9616,9815,10014,10212,10411,10609,10808,11006,11204,11402\
      ,11600,11798,11996,12193,12391,12588,12785,12983,13180,13376,13573,13770,\
      13966,14163,14359,14555,14751,14947,15143,15338,15534,15729,15924,16119,16314\
      ,16508,16703,16897,17091,17285,17479,17673,17867,18060,18253,18446,18639,18832\
      ,19024,19216,19409,19600,19792,19984,20175,20366,20557,20748,20939,21129,21320\
      ,21510,21699,21889,22078,22268,22457,22645,22834,23022,23210,23398,23586,23774\
      ,23961,24148,24335,24521,24708,24894,25080,25265,25451,25636,25821,26005,26190\
      ,26374,26558,26742,26925,27108,27291,27474,27656,27838,28020,28202,\
      28383,28564,28745,28926,29106,29286,29466,29645,29824,30003,30182,30360,\
      30538,30716,30893,31071,31248,31424,31600,31776,31952,32127,32303,32477,32652,\
      32826,33000,33173,33347,33520,33692,33865,34037,34208,34380,34551,34721,34892\
      ,35062,35231,35401,35570,35738,35907,36075,36243,36410,36577,36744,36910,37076\
      ,37241,37407,37572,37736,37900,38064,38228,38391,38554,38716,38878,39040,39201\
     ,39362,39523,39683,39843,40002,40161,40320,40478,40636,40794,40951,41108,41264,\
     41420,41576,41731,41886,42040,42194,42348,42501,42654,42806,42958,43110,43261,\
     43412,43562,43713,43862,44011,44160,44308,44456,44604,44751,44898,45044,45190,\
     45335,45480,45625,45769,45912,46056,46199,46341,46483,46624,46765,46906,47046\
     ,47186,47325,47464,47603,47741,47878,48015,48152,48288,48424,48559,48694,48828\
     ,48962,49095,49228,49361,49493,49624,49756,49886,50016,50146,50275,50404,50532\
     ,50660,50787,50914,51041,51166,51292,51417,51541,51665,51789,51911,52034,52156\
     ,52277,52398,52519,52639,52759,52878,52996,53114,53232,53349,53465,53581,53697\
     ,53812,53926,54040,54154,54267,54379,54491,54603,54714,54824,54934,55043,55152\
     ,55260,55368,55476,55582,55689,55794,55900,56004,56108,56212,56315,56418,56520\
     ,56621,56722,56823,56923,57022,57121,57219,57317,57414,57511,57607,57703,57798\
     ,57892,57986,58079,58172,58265,58356,58448,58538,58628,58718,58807,58896,58983\
     ,59071,59158,59244,59330,59415,59499,59583,59667,59750,59832,59914,59995,60075\
    ,60156,60235,60314,60392,60470,60547,60624,60700,60776,60851,60925,60999,61072\
     ,61145,61217,61288,61359,61429,61499,61568,61637,61705,61772,61839,61906,61971\
     ,62036,62101,62165,62228,62291,62353,62415,62476,62536,62596,62655,62714,62772\
     ,62830,62886,62943,62998,63054,63108,63162,63215,63268,63320,63372,63423,63473\
     ,63523,63572,63621,63668,63716,63763,63809,63854,63899,63944,63987,64031,64073\
     ,64115,64156,64197,64237,64277,64316,64354,64392,64429,64465,64501,64536,64571\
     ,64605,64639,64672,64704,64735,64766,64797,64827,64856,64884,64912,64940,64967\
     ,64993,65018,65043,65067,65091,65114,65137,65159,65180,65200,65220,65240,65259\
     ,65277,65294,65311,65328,65343,65358,65373,65387,65400,65413,65425,65436,65447\
     ,65457,65467,65476,65484,65492,65499,65505,65511,65516,65521,65525,65528,65531,65533,65535,65535};

    #endif /*SINDATA_H_*/
     

    Attached Files:

    Last edited by a moderator: Apr 24, 2017
  2. jcsd
  3. Jun 1, 2009 #2

    vk6kro

    User Avatar
    Science Advisor

    Those figures are a reasonable shape for a quarter of a sinewave.

    I graphed them with Excel.

    But you need to then step down through the same numbers to go from 90 to 180 degrees and then go negative with the same numbers to go from 180 to 270 degrees and then step down through them again as negative numbers to go from 270 to 360 degrees.

    Have you done that? Your display seems to indicate that you haven't done the 180 to 360 degree bit.

    Probably you don't need anywhere near this precision, though, to get a sinewave.

    Your "fat" waveform might be insufficient filtering. Looks like it.
     
  4. Jun 1, 2009 #3
    As vk6kro said, your code is only computing one part of the sine wave. You'll need to fully compute the sine wave (with the trough corresponding to digital 0) and then feed that into the DAC. Then you'll need to remove the DC offset; a capacitor can take care of this. And finally, you'll need a good low pass filter for a variety of reasons: Smooth the waveform, possibly remove fatness, and to present a low output impedance to the headphones (since the cap will be high impedance compared to the headphones).
     
  5. Jun 1, 2009 #4
    In order to graph negative I'd need a negative power supply. Which shouldn't be a problem, but I wanted to get it to be smooth and one line instead of a bunch of up/down waveform.

    Why would I need filtering? Shouldn't the DAC be able to ouput a single point at each of the 16 bits?
    Even if it's off at a couple then shouldn't it be more of a straight line with bad angles?

    But why do I have fatness in the first part? I mean, I went this way to avoid using a low pass filter :(
     
  6. Jun 1, 2009 #5
    This straight line with bad angles is precisely why we need filtering. From Fourier analysis we know that a "bad angle" is really comprised of infinite frequency components. The DAC's output will have these high frequency components in it and they must be filtered out; if not, it will show up in the headphones as a very noticeable hissing sound.
     
  7. Jun 1, 2009 #6

    vk6kro

    User Avatar
    Science Advisor

    The output from that DAC appears to be pulse width modulation. So you need to filter the fast switching component to get the average level.

    For programming convenience, you could calculate all values of your sinewave at 1 degree steps from 0 to 360 degrees and multiply by 65535 to get suitable values for your DAC. This will involve some repetition of numbers but make the programming a lot easier.
    This would involve fewer numbers than you have now and 1 degree steps should still give an excellent sinewave.

    How is a sinewave going to entertain your girl friend?
     
  8. Jun 2, 2009 #7
    Wow! Thank you everyone!
    I figured it out. Apparently in my SPI initialization I needed to set SPIPHC which makes the SPICLK rise at the aqusition level (half phase shift behind the SPIDO) instead of the same time as SPIDO. This means that sometimes I got a random bit shift by one. Now it's all fixed!!!

    I uploaded how it looks now. I gotta make it work faster though.. gotta work out the interrupt version of it.


    Note: She is just a friend-girl ;)
     

    Attached Files:

  9. Jun 2, 2009 #8

    vk6kro

    User Avatar
    Science Advisor

    Not sure what the problem was, but that graph is not a sinewave.
    See attachment.

    To make it go faster, use fewer points and have the whole sinewave already in the program as data.
    I tried 5 degree steps and it still looks like a good sinewave.
    That only takes 72 data values.
     

    Attached Files:

    Last edited: Jun 2, 2009
  10. Jun 2, 2009 #9
    As noted above, you do not yet have a sine wave; what you have is essentially a half rectified sine wave. You'll need to generate the "negative" part of the sine wave. And as I said earlier, this will create a sine wave with a DC component which you'll need to remove otherwise the headphones won't play anything. This "bumped up" sine wave is what you will have to deal with because your DAC only outputs positive voltages.
     
  11. Jun 2, 2009 #10
    I thought that the speaker only requires the signal to be changing in order to hear a sound. Does it truly require negative voltages to be there as well?


    I actually think I might have two or three modules which can do negative voltages. Do i need them?
     
  12. Jun 2, 2009 #11

    vk6kro

    User Avatar
    Science Advisor

    The waveform you have will sound much rougher than a sinewave. A sinewave is a pure sounding note, but a bit boring and irritating after a while.

    You don't need negative voltages. Just take your output through a suitable capacitor.

    You could try the following values for your data. They give a complete sinewave with a peak amplitude of 25000. Should fit into your D to A OK. They graph OK in Excel.

    30000
    32179
    34341
    36470
    38551
    40565
    42500
    44339
    46070
    47678
    49151
    50479
    51651
    52658
    53492
    54148
    54620
    54905
    55000
    54905
    54620
    54148
    53492
    52658
    51651
    50479
    49151
    47678
    46070
    44339
    42500
    40565
    38551
    36470
    34341
    32179
    30000
    27821
    25659
    23530
    21449
    19435
    17500
    15661
    13930
    12322
    10849
    9521
    8349
    7342
    6508
    5852
    5380
    5095
    5000
    5095
    5380
    5852
    6508
    7342
    8349
    9521
    10849
    12322
    13930
    15661
    17500
    19435
    21449
    23530
    25659
    27821
    30000
     
  13. Jun 2, 2009 #12
    Thanks!

    Here's your data. It looks nice, sounds pretty nice. I used a really small capacitor (1u I think) and it looks great!!
    Can you please tell me what affects the size of capacitor has?
     

    Attached Files:

  14. Jun 3, 2009 #13

    vk6kro

    User Avatar
    Science Advisor

    OK.
    That is showing about 40 steps for the sinewave instead of 72 so the steps are coming from the screen resolution. Anyway, glad it worked.

    The reactance of the capacitor should be negligible compared with the impedance after the capacitor.
    So if the frequency was 2000 Hz and the following impedance was 100 K ohms, the reactance of the capacitor would need to be less than 10 % of 100 K ohms.
    Reactance = 1/(2 pi F C) C= 1 /( 6.28 * 2000 * 10000) or about 0.008 uF, but more C is OK.

    If you can add a 1 uS delay before reading each data value, the next frequency after 2145 Hz would be 1858 Hz because this would add a 72 uS increase to the total period. Further delays would drop the frequency more. It may be possible to play tunes by changing this delay.
     
  15. Jun 3, 2009 #14
    I am learning about reactances and impedance next semester ^^.
    I do remember something simple about it.

    I have a bunch of lm741cn. (http://www.national.com/ds/LM/LM741.pdf" [Broken]) Their listed input resistance is typical 2 megaohms.

    For sound I'd need 22 kHz, and if the typical 2megaOhms is actually 2 megaOhms.. 1% of 2 megaOhms = 20k ohms.
    1/(2 pi f C).
    so, 20000 = 1/ (2 * 3.14159 * 22 000 * C).
    2.76460154 × 10^9 = 1/C
    C = 361715779 F or smaller... wow.

    As for tunes, I want to connect it to real headphones and play wav music.

    Now I am not sure if it's possible without some kind of an amplifier. I have a lot of MOSFETs, but I don't think I can really use them.

    Edit: OMG I found a perfect thing! http://kitsrus.com/projects/tda7052.pdf" [Broken]
    How do I know if my headphones are 8 ohm?

    Edit2:
    100k impedence in this amplifying thing. 1% is 1k ohms.
    1000=1/ (2 * 3.14159 * 22 000 * C).
    C=7.2 nanoFarads or smaller... :(
     
    Last edited by a moderator: May 4, 2017
  16. Jun 3, 2009 #15

    vk6kro

    User Avatar
    Science Advisor

    I make that first capacitance 361 pF (pico-Farads ie 10 to the minus 12 Farads.) Pretty small. Anything bigger than that is OK. Just use 0.1 uF.

    You can just measure the resistance of your headphones with a multimeter. 8 ohm speakers and headphones just measure 8 ohms.
     
  17. Jun 4, 2009 #16
    Awesome! Thank you! I got a 0.1F, it works heh.

    I tested one of my speakers, and it draws 0.1 amp (8ohms), how much will that last a battery?
     
  18. Jun 4, 2009 #17
    I'm not sure you're on the right page. Impressing a girl with an audio file is about as effective as piling your rice into a volcano during a dinner date and making explosion noises to show how clever you are. Unless, of course, the audio message indicates some promise on the short-list of what all women want.
     
    Last edited: Jun 4, 2009
  19. Jun 4, 2009 #18
    *boom boom!* *vroooom, boom!* :wink:

    There's no promise in the audio file... I will just be playing "Girl" by Beatles - my personal favorite.

    I guess I am not really doing this for her per say. It's a way of learning something new, saving $30 and seeing if the girl is the right one ;)


    Here's a question though.... Does anyone know where I can get a real SD SPI specifications? So far I only found a 1.0 revision, and a bunch of hobbyist sites which seem to differ for every card.

    Specifically when I give the SD card a multi-byte command, do I pull the CS low for the entire command or can I only do it for each byte?
     
  20. Jun 4, 2009 #19
    Sorry. That was really a rough comment on my part. :redface: It's an unusual girl that has some genuine interest in technology. Good luck to you.
     
  21. Jun 4, 2009 #20

    vk6kro

    User Avatar
    Science Advisor

    I'm not sure you're on the right page. Impressing a girl with an audio file is about as effective as piling your rice into a volcano during a dinner date and making explosion noises to show how clever you are. Unless, of course, the audio message indicates some promise on the short-list of what all women want.

    Still laughing at that one, Phrak. I wondered the same thing.

    What would be far more effective is if you could show you can put up a shelf on a wall, stop a faucett dripping, test torch batteries, fix a flat tyre or cook a chicken (preferably Coq au Vin).
    Then show you can remember her birthday and her parents' first names, but still address them as Mr Smith and Mrs Smith (or whatever hot-chick's surname is).
    About then, you start to become genuinely useful. Just don't talk about D to A converters.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook