Arduino ICSP Programming Cable

Introduction: Arduino ICSP Programming Cable

About: These Arduinos are driving me up the wall.

Here is how I like to make an Arduino ICSP programming cable, to use for bootloading or programming.

Step 1: Supplies

The supplies are Dupont jumpers, capacitor, glue, and heat shrink tubing.

Step 2: Target End

Start with 6 female-to-female Dupont jumpers that are still in a ribbon, have not been zipped apart. And 1 male-to-male jumper. Work on the target end of the programmer cable. Arrange the connectors into 2 rows of 3 pins each pattern, that will plug into the ICSP header on an Arduino.

D12 MISO 1  .  .  2 VCC
D13  SCK 3  .  .  4 MOSI D11
     RST 5  .  .  6 GND

Put a small dob of glue between the connectors, and put a small piece of heat shrink tubing over the assembly and shrink it. There is not much glue needed for this, just enough to keep the connectors from slipping around after full assembly. After shrinking the tubing, press the connectors flat against the table so there aren't any that are sticking out or uneven.

Step 3: Remove Plastic Shell From Programmer End GND Wire

Look at the target end and the colors used for the GND and RST pins. In this case, purple for RST, and black for GND. On the programmer end, remove the plastic shell from the GND pin, and remove the plastic shell from an extra Dupont wire end. There is a tab on the shell to gently pry, and the shell will come off.

Step 4: Solder Capacitor to Connectors and Re-install Shells

Use locking forceps to clamp wires in place and to act as a heatsink to protect the wire insulation, and solder a capacitor to the connectors. Use a very small amount of solder, to keep it from wicking into the pin receptacle, which would prevent it from sliding onto the ICSP header on the Arduino.

Cut the wire off of the extra Dupont wire connector we are putting the in the RST position of the completed connector end. Push the connectors back into the shells using a pin. This took some extra force to get the shell on, because the solder and capacitor wire made the connector a little thicker. After putting the plastic shells back on, I realize next time I should make the wires on the capacitor slightly longer, by perhaps another 1/8 to 1/4 inch. The + side of the capacitor is connected to the extra pin, which is intended for the RST position of the completed connector. The - side of the capacitor is connected to the black GND pin.

A capacitor of several uF is fine, I used 33uF. 10uF would have been fine, but my 33uF capacitors were smaller than the 10uF capacitors I had on hand.

Step 5: Arrange, Glue, and Heat Shrink Connectors

Arrange the connectors to match color-for-color the target end. The bottom left connector is the reset wire. On the ICSP header this is pin 5. Leave the RST wire that comes from the target side connector out of the arrangement of pins on the programmer side, and replace it with your cut off connector that has the capacitor attached. Glue, heat shrink, and make the pins uniform and even as in the target-end step. Use a slightly longer piece of heat shrink tubing on the programmer end, to partially contain the capacitor.

Step 6: Add Male Jumper Wire Connector for the Reset Signal and Mark Pin 1

Cut a male-to-male jumper and use a solder connection and heat shrink tubing, to attach it onto the reset wire that goes to the target side of the cable.

The upper left pin of each connector is pin 1 of the ICSP header on your Arduino. Mark it with a spot of paint. I used a white Gelly Roll paint pen. That's it, the cable is complete.

Step 7: Plug It In

The programmer Arduino is the one loaded with the Arduino as ISP sketch. It gets the programmer end of the cable, plugged in with pin 1 in the upper left corner. The Arduino also has pin 1 marked with a little dot. The reset wire plugs into D10.

The target end of the cable plugs into the Arduino we are going to bootload or program.

Most Arduinos have a little dot near the ICSP header to mark pin 1. If yours doesn't, or if it is not very obvious, now would be a good time to add a little dot while you have the paint or paint pen handy. Here is a picture of an Arduino of mine where I added the dot. On the ATmega16u2 usb-to-serial chip ICSP header that is arranged horizontally near the upper left corner of UNO or MEGA, pin 1 is in the upper right corner of that connector.

Step 8: Another Programming Cable for Pro Mini and Pro Micro

I also like Pro Mini and Pro Micro quite a lot. Those are boards invented by Sparkfun that are practically pin and footprint compatible. Pro Mini has ATmega328p MCU like the UNO and Pro Micro has ATmega32u4 like the Leonardo. I like to use them as programmers, and to program or bootload them via ICSP. So, here are the supplies for making an ICSP cable: female header, female Dupont jumpers, capacitor, and heat shrink tubing.

Cut the headers to the right length to fit on all of the pins on one side of the Pro Mini or Pro Micro. Cut in the middle of the first unused pin of a long header strip. All it takes is a little pressure with some diagonal cutters, and it will break apart. Then use the diagonal cutters to trim the excess plastic from the pin position destroyed when cutting the header. The result is a 12 position header with nice trimmed ends. To get fancy, sand the ends.

Step 9: Remove Plastic Dupont Shells

Remove the plastic shells from the ends of the Dupont jumpers. Notice a little tab on the shell. Pry the tab up gently and pull the plastic shell off.

Step 10: Add Heat Shrink Tubing and Push Connectors on the Female Header in Correct Positions

Slip the heat shrink tubing onto the wires. Push the connectors onto the female header solder pins. This takes a steady hand and dexterity. The wires go from MOSI, MISO, SCK, VCC, and GND on one header to the other header. The reset wire goes from pin 10 on the programmer Arduino, to the reset pin of the target Arduino.

The designers of Pro Micro were clever when they decided the pin layout. Although the pins are arranged

10, 16, 14, 15

and that seems to be nonsense, it happens to correspond to the pin functions of the Pro Mini pins

10, 11, 12, 13

The order is:

reset-sender, MOSI, MISO, SCK, on both Pro Mini and Pro Micro.

So, you will be able to use this cable with a Pro Mini or Pro Micro as the programmer, and with Pro Mini or Pro Micro as the target.

Step 11: Solder the Pins

Use locking forceps to hold the pins steady, evenly spaced, and straight. The forceps also act as a heat sink that prevents the solder heat from traveling up the wire and melting the insulation or prematurely shrinking the heat shrink tubing. Solder each pin quickly, and don't use an overabundance of solder. Use just enough to get the job done.

Add a capacitor between GND and RST on the programmer-side header, to disable reset from the FTDI adapter's DTR pin. Several uF is fine, I used 33uF. 10uF would be fine, but my 33uF capacitors were smaller than the 10uF capacitors I had on hand. Solder the + side of the capacitor as close as possible to the header plastic so the heat shrink tubing covers as much as possible. I made a small slit near the end of the heat shrink tubing for the capacitor's wire to go through.

Finally, slide the heat shrink tubing up the wire onto the connector until it meets the header plastic, and shrink the tubing with a heat gun.

Step 12: Done

Here is the finished cable. Use a label maker to mark which end of the cable is for the programmer and which end is for the target. And mark which end of the header should point towards the USB side of the Pro Mini's FTDI adapter or the built-in USB of the Pro Micro.

Be the First to Share


    • Halloween Contest

      Halloween Contest
    • Fandom Contest

      Fandom Contest
    • Plywood Contest

      Plywood Contest



    1 year ago

    That's really nice work Mr. Lambert. I've also found that heat shrink tubing is the only way to keep those infernal DuPont connectors from driving me insane.

    I wonder if you have any hints on using the ICSP to "steal" back the extra few hundred bytes occupied by the Arduino bootloader? My current project is very tight on space and while I can easily switch to a Mega (or even a more powerful MCU) cost and practicality remain issues, and not least, building the project (HotStuff) is much easier on a Uno/Mega because it's a simple matter of plugging a screen into the headers.


    Reply 1 year ago

    2 hints for fitting a larger sketch:
    1. Install a 3rd party core for ATmega328p and use it to compile and upload. For example MiniCore has an option to gain back the 512 bytes of flash that would otherwise be used for the bootloader if you upload using programmer.
    2. Post your full sketch and ask for help optimizing your code to save flash space on the forum. Post in the appropriate section, use code tags or attachments as needed in order to give the readers of your post the easiest experience when they try to help you, and be prepared for harsh criticism and rudeness that some members over there give. For a large program you may need to use something like and give a link to the pastebin post.


    Reply 1 year ago

    You can see the code at Github to see why HotStuff (my first 'Ible) is so large but a huge
    amount of the available ram was devoured by the libraries necessary to
    just make the graphics work. It's largely development code so a fair bit of untested/unlinked source remains there. It's not a sketch in traditional terms but a multi-file "epic" that needs Visual Code and Platform IO to be compiled.

    I come from the 4 & 8-bit days
    and although pure C (vs. C++) could be used to shave a little overhead,
    I'm already reasonably well-versed in slimming code down, although,
    naturally I'm facing the optimizations that the compiler already does
    which is why the code isn't minified to the point where it's unreadable.

    I tend to stay out of those forums for the very reason you've observed.

    My feeling with C is because it was written for Teletypes on the PDP11 if memory serves, every byte saved in the language definition was a good one. These days we don't need those optimisations so while I've allowed myself (for example) ternary operators for single line IF...ELSE...ENDIF constructs I eschew a lot of the more usual optimisations at source level you know the sort of thing like this:

    if (something is true) <do something>;
    // code continues here (regardless of the condition)

    Which leads to brittle code because there are no braces to delimit the structure. I'm not a huge advocate of many other similar short-forms because they make code harder to read and generally brittle, even for the original developer(s)!

    The biggest optimisation we can do on 8-bit is to do 8-bit - so only use 8-bits when you only *need* 8 bit rather than lazily declaring an integer (signed 16-bits by default). Even the semaphores I've used to control stuff are operated at the bit level to save a few bytes. I re-coded some of the Adafruit graphics library for this reason and saw a performance improvement that was utterly astonishing. Ultimately though, projects like this are limited by how fast the data can be moved onto the display and how fast the display chip can move that into its own VRAM.

    This is why I designed a couple of "graphic" fonts to simulate simple 7-seg and 16-seg displays. While they lack the slight slant of a true display (and some of the rounding seen on LCDs) it's possible to run three rows of full height numbers across a typical 320x240 LCD and and have them count or produce random values far faster than anything the pre-rendered bitmaps were capable of. I spent more hours than I'd admit trying to improve that routine but a combination of digging a byte a time from flash and then decoding/displaying that a pixel at a time proved fruitless.

    I'm no expert at MCUs, but I suspect that a lot of the people we see commenting on these threads assume that if you cut the source, you cut the final code which is often the reverse of what happens.

    I haven't figured out every "optimization" GCC for ARM does in C++ but quite a few bit me right on the fundament! Passing automatic references (declared as consts) should be more efficient but the overhead proved more costly in terms of flash space which was... a shock.

    Certainly, looking at the compiled machine code using a simulator, it's astonishing some of the optimisations that GCC does even with default settings. Often code doesn't look anything like what one might expect but functions equivalently. ATMel's own (now retired) white paper contains a number of tips just like this.

    One thing that both shocked and amazed me was the sheer speed of some of the floating-point functions. I wrote my own pre-calculated tables using quadrants to deliver a fixed point value which would be finally shifted to the correct accuracy, but in tests I discovered that the real bottleneck was in putting the pixels on the screen - even drawing something simple (but FP calculation intensive) like 30-40 concentric circles proved as effective using the library functions. That was a shocker too.

    I'd be interested to know how efficient (or not) the linker is, but my guess is that library code is only included on a per-function level, although I haven't actually tested that.

    Cheers for the suggestions though.


    Question 2 years ago

    Why do you take the reset from pin 10 on the programmer and use a capacitor instead of the reset pin on the ICSP, why can't you just have all the pins connected the same on both sides?
    If the capacitor is needed on the programmer instead of making a weird longer cable going to pin 10 you could add the capacitor just above the connector on the cable because to my knowledge measuring with my multimeter for continuity on my Arduino UNO pin 10 and the reset pin of the ICSP are connected anyway, those are the same so I don't see the need of making the connector on the programmer weird.
    Please correct me if I'm wrong but I think that you can just use the ICSP connector on both sides.


    Answer 2 years ago

    Q: Why do you take the reset from pin 10 on the programmer, why can't you just have all the pins connected the same on both sides?

    A: This is because during the programming process you bring RESET to ground on the target MCU, and keep it low while sending commands and receiving information using the SPI pins. On the programmer MCU you can't bring RESET to ground because the Arduino as ISP program will stop running. So, use a regular I/O pin such as pin 10 to send the reset signal to the target MCU.

    Q: What is the deal with the capacitor?

    A: The purpose of the capacitor is to prevent the programmer MCU from resetting. When the Arduino program on the PC connects to the programmer Arduino, establishing that serial connection sends a reset to the MCU. This is handy when you want to upload a program because reset starts the bootloader. Once the Arduino as ISP program is loaded onto the programmer Arduino, you don't want the programmer Arduino resetting every time you connect to it because that will interrupt the programming process that you are trying to accomplish with the target MCU.