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.
and here's what it looked like before I got the arithmetic right
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
Top Comments