Produce exponential steps for assembler code

Tessellated Circuits: Home => Old Home => Exponential steps  

What does this do?:  ± 

This is a little php program that I wrote to produce equally spaced (on a log plot, that is) steps. These progressions can be thought of as generalized Renard numbers . Originally I wrote it to produce look up tables for controlling PWM-driven devices such as LEDs. Exponential increases in intensity are viewed by our eyes as step changes since our eyes respond in a logarithmic manner. The program works by determining the exponent needed to produce the number of steps desired between the start point and the end point, and then using that as a progressive multiplier to generate each point. Really simple math, however a few extras make it useful:

  • The resultant values are rounded to integers (no affect on the precision of the calculations);
  • There is an option to throw out repeated values;
  • There is an option to throw out values below a threshold;
  • The output values are rounded, then converted to hex;
  • The outputs are formatted such that they can be just dropped into an assembler file. One or two bytes are produced as needed. Currently, for a 16-bit output, the bytes are produced in separate tables. (This can be disabled.)

Once I started looking for examples, I was surprised at how many directions I was led. For example I had not heard the term Renard numbers before, that came up when looking at resistor values. See below the form for examples.

How to use:  ± 

  1. Enter the start value in the “Start Value:” box. Zero or negative numbers are replaced by 1;
  2. Similarly, enter the top value* to use in the “End Value:” box. The end value can be lower than the start value, to produce a decreasing step table, but then the “Add a zero...” (point 4 below) option is of no use;
  3. Enter the number of steps. There may be one or two more values produced in the table, depending on the next two options;
  4. If a zero is wanted at the start of the sequence, tick the next box (this will never be removed by either value test, see points 6 and 7);
  5. If the end value is wanted (at the end of the sequence, of course), tick the “Add top value at end?” box;
  6. If it is desired to delete all values below a certain percentage, then tick the “Remove low numbers?” box and enter the desired threshold value. This is used when small value changes would not produce visible illumination changes;
  7. If it is desired to delete superfluous values (at the low end) then tick the “Remove duplicates?” box. This is useful in a PWM situation where you want each step to have at least some change;
  8. If the PWM circuit needs a value that is one less than full scale (e.g. a 16 bit PWM counter will count 0...65,535, but 65536 would have been used as the end value) click the “Decrement top by one?” box;
  9. The last input field of the form is the “Assembler's define byte prefix?” box. This defaults to FCB for Freescale (Motorola) syntax, however DB could be used for other assemblers. If it is blank, then the whole assembler table generation step is skipped.

*Depending on the application this value may or may not be wanted in the output data set: it can be included by selecting the appropriate option (default: off), see #5, above.

Start value:
 
End value:
 
Number of steps?
 
Add a zero at beginning?

Add top value at end?

Remove low numbers?
(Use threshold = %)
Remove duplicates?

Decrement top by one?

Assembler's define byte prefix?
 (If blank, no assembler table produced.)

    
  

Some examples:  ± 

Its remarkable how many of our physical senses have logarithmic response curves. Notably our hearing and eyesight both respond to a doubling of intensity as an increment: this means that 4 times the sound level or illumination is perceived as two steps louder or brighter, not 4 steps. While we are hearing things, frequency, too is perceived logarithmicaly: a musical scale is a doubling of frequency, not some linear progression. This forms the basis of our first example.

Let's hear some music!

Follow the following steps or ... quick link.

  1. Enter 220 and 440 for the start and end values respectively;
  2. Enter 12 for the number of steps.
  3. All the other boxes can remain at their defaults, but you won't need an assembler table so clear out the “define byte prefix” entry;
  4. Hit the “Make the table” button;

The table produced represents the frequencies [in Hz] of the musical notes from the A below middle C to the A above middle C. The 4th value, which should read as 261.6256 [Hz], is middle C .

Notes on notes:

There is a lot of history behind musical notes. One reference stated that a fifth is a ratio of 3/2, or 1.5. This is not exactly the case with the “normal” (tempered) scale, and in fact if you look at the results of this example you will see that coincidentally the 8th rounded number is 330 which is 1.5 times the starting point (the A below middle C). 330 Hz is the E above middle C. You can see that the error from that theoretical ideal is 0.113%. So a fifth is, more or less, a ratio of 27/12.

Interesting that a whole theory (look up the circle of fifths on Wikipedia ) is built on an approximation. But then even for those with “perfect pitch,” I guess our ears are forgiving. What I think this means is that an untempered scale does not have a 2:1 ratio between octaves, but instead would be defined, eg, by a sequence such as 220...495 in 14 steps. In that case, the 13th result, which is (495/220)12/14 = 2.003875... times the start frequency, is very close to double the start.

This use of the table corresponds to my understanding of all 88 of the notes of a piano. The start frequency was calculated by halving the note A4's frequency (440 Hz) 4 times to get A0. The end was calculated by doubling C4's frequency from the previous table (261.6256 Hz) 4 times to reach C8, the last note on the keyboard. 87 steps are used, not 88, since there are 87 spaces between the 88 notes.

A chip check.

The LP3954 , which National Semiconductor (TI now) calls an “Advanced Lighting Management Unit,” uses a 3-bit code and a couple of different curves to control the intensity of the LEDs that it is driving. (They call the control logarithmic when in fact it is exponential, presumably because this is compensating for the eye's logarithmic response.) At the bottom of page 14 of the data sheet (download the pdf from the page linked to above if you want to follow along) we see the two sets of data in both table and graph formats.

To check the data for the LOG=1 mode's table enter 1 and 100 for start and stop and 6 for the number of steps and check the two boxes which add zero and the top value. This produces the sequence [0, 1, 2, 5, 10, 22, 46, 100], which is a very good match for the chip's actual sequence, [0, 1, 2, 4, 10, 21, 46, 100] (differences in bold). In fact, if one truncates instead of rounding, one gets the data sheet sequence. Since we do not know what resolution of PWM counter is used in the chip, and considering the fact that this table is not the code used in the chip, but the resultant percentage, this may well be the best fit.

The other mode, LOG=0, is close to a 14...100, 5 step sequence, ignoring the [0, 7] starting points. This produces [14, 21, 31, 46, 67, 100]. The biggest deviation from the chip's sequence is at the 67, where the chip has 71. This deviation can be seen clearly in the data sheet's graph. (And the linear [0, 7, 14] start can be seen there too.) Again, not knowing how the PWM is implemented one cannot say that they could have done better.

A not so good example.

Resistor (and capacitor and often inductor) values are defined by a set of “E” series; E6, E12, E24 E96 and E192. Each is, at least approximately, a Renard series. Some modifications were made for an unknown reason (unknown to me, at least) to the shorter ones. If you enter 10 and 100 as the start and stop numbers, and 12 as the number of steps, you will get 10, 12, 15, 18, 22, 26, 32, 38, 46, 56, 68, 83 as the series. The bolded numbers are all off (by +/-1) from the usual E12 series, which all Electronic specialists know as the values available in a 10% component tolerance product range. (Does anybody know the historical reason? Perhaps somebody's log table was missing a page?)


If you wish to comment on this application, click on over to my contacts page , and please do so (check the sample apps button there to let me know which aspect of the site you are communicating about).