element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Personal Blogs
  • Community Hub
  • More
Personal Blogs
Legacy Personal Blogs Arduino: R-2R: Sine On You Crazy Diamond
  • Blog
  • Documents
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: jc2048
  • Date Created: 13 Apr 2018 11:15 PM Date Created
  • Views 4845 views
  • Likes 12 likes
  • Comments 12 comments
  • arduino_projects
  • r2r
Related
Recommended

Arduino: R-2R: Sine On You Crazy Diamond

jc2048
jc2048
13 Apr 2018

Part one is here:
https://www.element14.com/community/people/jc2048/blog/2018/04/12/arduino-r-2r-experiment

 

I was going to do some hardware next but got sidetracked into playing with software instead.

 

Here's a very well-known waveform being produced by the simple resistor-ladder DAC I built in part one.

 

 

image

 

and here's what it looked like before I got the arithmetic right

 

 

image

 

That's generated by this sketch

 

//
//  --- Sine table - generated by sineTable.exe 
//

unsigned int sineTable[256] = {
   0x0000,0x00c9,0x0192,0x025b,0x0324,0x03ed,0x04b6,0x057f,0x0647,0x0710,0x07d9,0x08a2,0x096a,0x0a33,0x0afb,0x0bc3,
   0x0c8b,0x0d53,0x0e1b,0x0ee3,0x0fab,0x1072,0x1139,0x1201,0x12c8,0x138e,0x1455,0x151b,0x15e2,0x16a8,0x176d,0x1833,
   0x18f8,0x19bd,0x1a82,0x1b47,0x1c0b,0x1ccf,0x1d93,0x1e56,0x1f19,0x1fdc,0x209f,0x2161,0x2223,0x22e5,0x23a6,0x2467,
   0x2528,0x25e8,0x26a8,0x2767,0x2826,0x28e5,0x29a3,0x2a61,0x2b1f,0x2bdc,0x2c98,0x2d55,0x2e11,0x2ecc,0x2f87,0x3041,
   0x30fb,0x31b5,0x326e,0x3326,0x33de,0x3496,0x354d,0x3604,0x36ba,0x376f,0x3824,0x38d8,0x398c,0x3a40,0x3af2,0x3ba5,
   0x3c56,0x3d07,0x3db8,0x3e68,0x3f17,0x3fc5,0x4073,0x4121,0x41ce,0x427a,0x4325,0x43d0,0x447a,0x4524,0x45cd,0x4675,
   0x471c,0x47c3,0x4869,0x490f,0x49b4,0x4a58,0x4afb,0x4b9e,0x4c3f,0x4ce1,0x4d81,0x4e21,0x4ebf,0x4f5e,0x4ffb,0x5097,
   0x5133,0x51ce,0x5269,0x5302,0x539b,0x5433,0x54ca,0x5560,0x55f5,0x568a,0x571d,0x57b0,0x5842,0x58d4,0x5964,0x59f3,
   0x5a82,0x5b10,0x5b9d,0x5c29,0x5cb4,0x5d3e,0x5dc7,0x5e50,0x5ed7,0x5f5e,0x5fe3,0x6068,0x60ec,0x616f,0x61f1,0x6271,
   0x62f2,0x6371,0x63ef,0x646c,0x64e8,0x6563,0x65dd,0x6657,0x66cf,0x6746,0x67bd,0x6832,0x68a6,0x6919,0x698c,0x69fd,
   0x6a6d,0x6adc,0x6b4a,0x6bb8,0x6c24,0x6c8f,0x6cf9,0x6d62,0x6dca,0x6e30,0x6e96,0x6efb,0x6f5f,0x6fc1,0x7023,0x7083,
   0x70e2,0x7141,0x719e,0x71fa,0x7255,0x72af,0x7307,0x735f,0x73b5,0x740b,0x745f,0x74b2,0x7504,0x7555,0x75a5,0x75f4,
   0x7641,0x768e,0x76d9,0x7723,0x776c,0x77b4,0x77fa,0x7840,0x7884,0x78c7,0x7909,0x794a,0x798a,0x79c8,0x7a05,0x7a42,
   0x7a7d,0x7ab6,0x7aef,0x7b26,0x7b5d,0x7b92,0x7bc5,0x7bf8,0x7c29,0x7c5a,0x7c89,0x7cb7,0x7ce3,0x7d0f,0x7d39,0x7d62,
   0x7d8a,0x7db0,0x7dd6,0x7dfa,0x7e1d,0x7e3f,0x7e5f,0x7e7f,0x7e9d,0x7eba,0x7ed5,0x7ef0,0x7f09,0x7f21,0x7f38,0x7f4d,
   0x7f62,0x7f75,0x7f87,0x7f97,0x7fa7,0x7fb5,0x7fc2,0x7fce,0x7fd8,0x7fe1,0x7fe9,0x7ff0,0x7ff6,0x7ffa,0x7ffd,0x7fff};

void setup() {
  // set the digital pin as output:
  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
}

void loop() {
    for(i=0;i<256;i++)
        PORTD = (sineTable[i] + 0x8000) >> 8;
    for(i=255;i>0;i--)
        PORTD = (sineTable[i] + 0x8000) >> 8;
    for(i=0;i<256;i++)
        PORTD = (0x8000 - sineTable[i]) >> 8;
    for(i=255;i>0;i--)
        PORTD = (0x8000 - sineTable[i]) >> 8;
}

 

The sine is done with a look-up table rather than the floating point library in order to save space and because it's much faster. I generated the table (only the first quadrant, to save space) using the following simple C program. That was compiled in Visual C++ on a PC and run simply by double-clicking on the filename (the text file ends up in the same directory and it's quicker than typing into a console window). Then I simply open it with Notepad and copy and paste it into the Arduino sketch. Probably not a very elegant approach, but it works.

 

/****************************************************************/

/* sineTable.c                                                  */

/*           Data values for one-quadrant sine look-up table    */

/*           256 values in int array                            */

/*           Output file is called sineTable.txt                */

/*           13th April 2018    Jon Clift                       */

/*--------------------------------------------------------------*/

/* Rev   Date     Comments                                      */

/* 1.0   13/04/18                                               */

/****************************************************************/

#include 

#include 

#include 

#include 

#include 

#include 

// variables

FILE *handle;

char temp_string[256];

unsigned int sineTable[256];

// main routine

void main(int argc,char *argv[])

{   int i,j;

    /* print banner */

    printf("\n--- sineTable DOS UTILITY PROGRAM V1.0 ---\n");

    printf("Builds sine table for Arduino R-2R experiment blog.\n");

 

    /* generate sine table in array */

   for(i=0;i<256;i++) {

        sineTable[i]=(unsigned int) (((sin((3.1415926/512)*i)) * 32768) + 0);

        }

     /* open output file */

    if((handle=fopen("sineTable.txt","wt"))==NULL) {

        printf("Failed to open output file.\n");

        _fcloseall();

        }

 else {

  /* write file banner */

  fprintf(handle,"//\n");

  fprintf(handle,"//  --- Sine table - generated by sineTable.exe \n");

  fprintf(handle,"//\n");


  fprintf(handle,"unsigned int sineTable[256] = {");

  /* write table to file */

  fprintf(handle,"\n");

  for (i=0;i<16;i++) {

   fprintf(handle,"   ");

   for(j=0;j<16;j++) {

    fprintf(handle,"0x%04x",sineTable[(i*16) + j]);

    if(j<15)

     fprintf(handle,",");

    else {

     if(i==15)

      fprintf(handle,"};\n");

     else

      fprintf(handle,",\n");

     }

    }

   }

  /* close output file */

  fclose(handle);

     printf("Done.\n");

  }

 

 

Part one: Arduino: R-2R Experiment

Part two: Arduino: R-2R: Sine On You Crazy Diamond

Part three: Arduino: R-2R: Buffer, Attenuate, and Filter

Part four: Arduino: R-2R: "We Interrupt This Programme..."

Part five: Arduino: R-2R: "Resistance is..."?

Part six: Arduino: R-2R: Setting the Output Frequency

Part seven: Arduino: R-2R; "A Sweep is as Lucky, as Lucky Can Be..."

Part eight: Arduino: R-2R: Setting the Signal Amplitude

  • Sign in to reply

Top Comments

  • Jan Cumps
    Jan Cumps over 7 years ago in reply to genebren +6
  • dougw
    dougw over 7 years ago +5
    Now I'm thinking - what kind of circuit would produce this concave square wave...... It might be one example where performing a Fourier transform would provide insight into the answer.
  • jc2048
    jc2048 over 7 years ago in reply to shabaz +5
    I don't actually know where I'm going with this. I started with seeing the R-2R ladder in an old databook application note and at the same time Jan introduced us to a free SCPI open-source parser, so I…
Parents
  • shabaz
    shabaz over 7 years ago

    That's really nice!!

    I know it's possibly not the use-case you're probably aiming for, but I guess you could make some really great alert tones now if you wanted to, with ADSR, by scaling the amplitude in software.

    • Cancel
    • Vote Up +3 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • jc2048
    jc2048 over 7 years ago in reply to shabaz

    I don't actually know where I'm going with this. I started with seeing the R-2R ladder in an old databook application note and at the same time Jan introduced us to a free SCPI open-source parser, so I just decided to mash the two together and see what came of it.

     

     

    image

     

    The DAC is much better than I expected (for 15 pence worth of SMD resistors; obviously it doesn't compare with a codec throwing out 24-bit waveforms). At 8 bits it's very marginal for audio but that's the most obvious application because the Arduino isn't really up to doing much more. I was kind of thinking along the lines of an audio test generator, but I'm open to other suggestions. (I'm very tempted at this point to give up on the test equipment and make a music box or a MIDI sound module with it. Hammond organ simulator, anyone?)

     

    Adjusting the amplitude is a puzzle (I'm treading a path I'm not familiar with here). If I scale in software, I rapidly run out of resolution [with only 8 bit to start with, I can't afford to throw much of it away], so I've been wondering about doing a range of about 2:1 in the firmware and an external switched attenuator for the rest. A digital pot would be another possibility, but I was try to keep this as cheap and cheerful as possible with easy-to-obtain, generic components.

    • Cancel
    • Vote Up +5 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • shabaz
    shabaz over 7 years ago in reply to jc2048

    I guess an audio/music effects variant could implement A-law/u-law-style spacing between levels, by having different resistors for a non-linear output based on input code. But you're right, as it stands now, maybe the quality won't be so good with software scaling.

    These are very impressive results you're getting with such a low-cost DAC! As a audio function generator, the external switched attenuator sounds like the way to go.

    • Cancel
    • Vote Up +4 Vote Down
    • Sign in to reply
    • More
    • Cancel
Comment
  • shabaz
    shabaz over 7 years ago in reply to jc2048

    I guess an audio/music effects variant could implement A-law/u-law-style spacing between levels, by having different resistors for a non-linear output based on input code. But you're right, as it stands now, maybe the quality won't be so good with software scaling.

    These are very impressive results you're getting with such a low-cost DAC! As a audio function generator, the external switched attenuator sounds like the way to go.

    • Cancel
    • Vote Up +4 Vote Down
    • Sign in to reply
    • More
    • Cancel
Children
No Data
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube