To set current limit on an LM317 Regulator in constant current mode. 

AmpLimit, originally published in Sam Goldwasser's LaserFAQ, selects pairs of resistors for LM317 and LM338 regulators for specific currents for diode (or TEC) drive, between 1 mA and 5000 mA. It can compile for Windows with GCC or TCC. Sam's compiled it with GCC for Linux so we know that works too.

AmpLimit.exe, Version 2.0, Size: 7,680 bytes.
CRC32/MD5 codes: C5D39E36/7C97C81BCD2436C182DA933444EBF681.
This is tested and known to work on all 32-bit versions of Windows.
Operation in Win64, and Wine under Linux, has not been tested, but it may work.

The picture below shows why you might want to use the program, but look at the page in Sam's LaserFAQ (linked above, it has been a live link for the best part of twenty years, maybe more), because there are more elaborate and useful variants on this basic schematic which is from the original data sheet. There is one there that will use analog proportional modulation to 1 MHz, but it's still based on the simple method below, and still needs AmpLimit to calculate the safe upper limit for any diode or LED load.

That's a laser diode driven by about 152 mA. It was a cheap diode and the 8.2 ohm resistor was convenient, and adequate. Sometimes you need much better precision, and the required current must dictate the resistance used, not the other way round! In a high current system you also need to know how big the resistor must be to safely get rid of its waste heat. Try this for a much more useful laser diode and LED driver. Like AmpLimit, it was originally published in Sam's LaserFAQ, but if you like coloured HTML pages the local copy will do that.

From my original text on Sam's LaserFAQ entry:

In all the variations of laser diode drivers based on three terminal regulators like the LM317, there is the detail of selecting the series resistor. Standard resistor values rarely match exactly. However, two standard resistors can likely get you to within 1 mA of desired current on a range up to 5 amps, in a parallel or series network. But which two will get closest while remaining under the limit? And how large must they be to handle the current they'll take? AmpLimit is a C program to find the best pairing of available resistors for the selected current at maximum power dissipation. The reasoning behind this is that while many of those drivers will preset or even modulate a current, many people will want to do it within a strict, hardwired upper limit, and sometimes 1.25/I just isn't enough information. The code is free to all, and will likely compile on anything that runs C code in a text-based shell or console window.

Even though the standard resistor ranges like E24 or E12 only cover every possible value at low tolerances, metal film resistors are usually sold as 1% regardless of how small the range is from a supplier. This means the coverage is like a net instead of a cloth. Two resistors are chosen by the program on the assumption of infinitely strict tolerance, but this will still deliver pairings whose current limit is very close to the desired current in almost all cases. Of course, the best thing to do is use 1% resistors. If there is a significant error in some rare case, the comparison of wanted and actual currents will show it. In this case, try some current to see if there is a better match to that. There usually won't be because the program tries all possibilities and gives you its best shot anyway. So use the most precise resistors you can get and bear in mind that for very low currents the regulator, rather than the resistors, will determine how accurate the result will be.

That text might look redundant here, but it's there in case the program ends up without a web page. It's enough to explain why this thing exists and who is responsible for it. Unlike the original version, the C code for this one isn't published, but a Lua script for precise emulation of this new version of AmpLimit can be found here: LuaTools is a hybrid of C and the language Lua (Lua is developed in the university in Rio, Brazil). LuaTools makes separate executable files that run independently of any Lua installation. I have made it available because I think people should be willing and able to make their own tools, so if I can make that easier, I do it.

The image above shows the best parallel selection for the 152 mA specified for the schematic shown earlier. The precision is good, always at or slightly below the requested current. It will NEVER overshoot. If you want more, ask for it. Try series too, it may get closer sometimes. The result may sometimes seem less than precise, but a quick calculation will verify that it's within the 1% tolerance of most high quality resistors that are easily available. If they are NOT easily had, accuracy can suffer, especially if you limit to resistors above 1 ohm when requesting resistors for high currents. The old version would take fractional inputs down to 0.1 mA but this isn't very useful. If you do want that, set an integer current 10 or 100 times higher, then scale up the suggested resistors by the same amount. Bear in mind that very low currents may not be accurate due to the regulator's own noise. 1 mA is a practical low limit.

One way to overcome accuracy limits with pairs of resistors is to use ten of them! This works for the maximum current of 5A, though good ventilation is needed for the standard 0.6W 1% tolerance metal film resistors intended to be used. The board layout in this case is larger, but it is flat, VERY flat, and mounted vertically, can dissipate heat safely and silently by convection, and large lasers or LED arrays can use ganged arrays of this diode driver method in a very compact form that is easy to repair and will always fail safe because if a resistor does burn out, the rest will not be forced to carry more current, and the output is unlikely to be compromised before a repair is made to fix the problem.

AmpLimit will try to maintain close separation in values for an array of 10 resistors. The example above has an unusually wide separation of values, and if a closer separation is needed to get better spreading of the load across them all, try a slightly higher or lower current. In this case, trying 150 mA or 154 mA gets a better selection for load balancing while still being very close to the originally specified current, so always test nearby values to see if they work better for a specific need. Using AmpLimit is always faster than having to do it with a calculator, a web-based ordering system, and a soldering iron!

Additional notes: 3W resistors at 5% tolerance for E24 ranges are made by Panasonic, Vishay and Yageo. At 5mm width and 15 mm length, they will fit onto a standard space that was originally specified for a 1W resistor.

More details of the new Array10 code in the program.... Resistances below 1R are hard to find. It is better to use 0.6W at higher values, ten at a time, for several reasons:
1. Much higher surface area, so ten of them will easily dissipate 6 watts by silent convection even in a tight space.
2. Much easier to source, cheap, widely used. Even high street shops like Maplin and Radio Shack have had good ranges.
3. Low inductance. In low resistance, high power, high speed circuits, a metal film array is better than wirewound.
4. Tight tolerance for accurate current limits. Anything less than 5% is very rare above 0.6W, where 1% is standard.
5. If a resistor fails, the failure of a whole system is much less likely. Maintenance is easier with standard parts.
6. Standard 0.6W metal film resistors cover more possible resistances with E24 and E48 ranges with finer tolerance.
7. An array of ten resistors can use different values for each one, for wide range and high precision with one layout.

Finally, a demonstration of how the program handles input text:

Colour is useful. It is best not to overdo it (this advice coming from a web site that some may see as a colourful glasshouse run by a loony who likes to throw stones), so when showing the status of a program that runs in a text-based console, I like to limit to standard light grey on black, with bright white to indicate headings and output data, low green to indicate input choices a user can select, bright green for accepted input, and bright red for input that the program considers to be an error.

Small rant: I hate FooBar. What IS it with coders and Foo and Bar?! Their activities are rightly curtailed in the example above. No doubt some people would prefer Bleep and Booster. Personally, I prefer ZoodleWurdle, much more fun when testing string functions for difference or similarity, but those won't fit in the example above either. This is probably a good thing. Sometimes text input SHOULD be limited to fit the purpose, as the new code does it. It's one of many ways to make sure a program is protected from malicious input! So there is even a point to this little rant, no?

The original v1.1 code is here: Original AmpLimit.c (5.4 KB)   MD5 checksum for the file: 11250CC067CBB8CBCE25F72085783326

It is unmodified except for the single inclusion of a +1E-9 bias on the main resistance array data to eliminate the original (small) floating point errors that occasionally caused the program to miss an otherwise ideal selection of resistors. This version lacks the text colour and other improved formatting detail in the new one, but it will compile in Linux so may be useful to some people, so it's here to stay, and a lot of the important code in the new one is derived from the old, so it's useful if you want to see how it works.