Introduction: Building an ISP Shield for Arduino

Picture of Building an ISP Shield for Arduino

This Instructable is for the build instructions for our new AVR ISP Shield Kit for Arduino. Its development owes a great deal to Instructables and our own community (particularly Nick!) and I hope to explain some of that along the way. 

Some astute Instructablites have asked. What does this do? Well essentially this shield can turn your Arduino into a quite capable chip programmer. What's more is that it can allow your Arduino to make more Arduino compatible devices. So with this shield, a bit of code and some some spare chips you can replicate what your Arduino does for a fraction of the cost. Not only using the same chip as your Arduino uses but also some smaller cheaper ones too. Like the ATTiny85. 

Let me start by saying to program an AVR chip with an Arduino you don't need a shield or even a crystal if you're programming Arduino bootloaders. But if you plan on doing it more than once a shield is going to save you some headaches as setting up a breadboard each time and then worrying about debugging is a pain...

The project is open sourced and the PCB files can be found on our Github.
The kit itself on our website at www.phenoptix.com

Step 1: The BOM and Tools

Picture of The BOM and Tools
First things first. You don't need to buy our kit to do this and if you really like the kit you can even build them for yourself / hackspace  / makerspace and sell them! For that you're going to need a bill of materials

The BOM
Tools
Right so you've got the gear. Now plug in that soldering iron!

Step 2: Stick on the Sockets!

Picture of Stick on the Sockets!

Put the sockets into the board from the top side, paying attention to the notches on the sockets and the markings on the PCB. Now I normally load up my soldering iron tip with a great glob of solder and hold the opposite end of the socket and dot one corner in. But it's more sensible just to tape the three sockets in place then flip the board and solder the whole lot at once.

This really is the most boring bit of soldering, think of it as practice. Remember heat the pad and pin and add the solder to the union of the two. You'll want it to look like a lush little cone. Pro tip is to use thin (0.5mm) leaded solder. I started this using some thick lead free solder and you can probably spot the joints where I used it, they're dull and over filled!

Step 3: Insert the LEDs

Picture of Insert the LEDs

LEDs are great. It's how we got started. Solder the red Error LED first, and the appropriate resistor. There's only one of this value (180 Ohm). Push in from the front, lining up the flattened edge of the collar of the LED to the to the flattened part of the circle on the silk screen. Silk screen is the white markings on the board.
Once pushed through bend the legs on the LED and resistor back and solder the joints like before. Heat the union of the pad and pin and apply solder. Once soldered you can clip off the legs. Put your finger on the end of the leg as you clip it. That way you won't have to remove it from your eye ball later...

Now for the blue and green, it's your call, the top LED, where we have the green one is going to be your heartbeat LED. The bottom one will flash merrily as the chips are being programmed. Solder these boys in as well as the resistors and clip off the legs, protecting your eyes once more.

Step 4: Solder the ISP Headers

Picture of Solder the ISP Headers

Now lets solder the headers, these are really useful. You'll find lots of cool products to mess with once you've soldered these on. You can tape them or use the loaded soldering iron trick. Your call really, you've had plenty of soldering practice by now.

Step 5: Solder the Arduino Headers

Picture of Solder the Arduino Headers

Last bit of soldering. To make sure you get the shield straight, grab your Arduino. Insert all of the header pins into it. Yes all of them. Now put the shield over the top. Solder the end of each row and remove the Arduino. Your pins will now be straight and compatible, solder the rest! If you leave it in the Arduino it will act as a heat sink and some of the pins will be hard to solder. You've been warned!

Step 6: Add Arduino, Chips and Code!

Picture of Add Arduino, Chips and Code!
Now all is left is to use your shield! Plonk it on top of your Arduino and fire up the IDE. We use a slightly modified version of William Phelps code.
You can now program Arduino Bootloaders from within the IDE and also the AVR chips listed with AVRDUDE, but I'll explain how to do all that on a less product oriented Instructable.

// this sketch turns the Arduino into a AVRISP
// using the following pins:
// 10: slave reset
// 11: MOSI
// 12: MISO
// 13: SCK

// Put an LED (with resistor) on the following pins:
//  7: Error - Lights up if something goes wrong (use red if that makes sense)
//  8: Programming - In communication with the slave
//  6: Heartbeat - shows the programmer is running (removed, see notes below)
// Optional - Piezo speaker on pin A3
//
// October 2009 by David A. Mellis
// - Added support for the read signature command
//
// February 2009 by Randall Bohn
// - Added support for writing to EEPROM (what took so long?)
// Windows users should consider WinAVR's avrdude instead of the
// avrdude included with Arduino software.
//
// January 2008 by Randall Bohn
// - Thanks to Amplificar for helping me with the STK500 protocol
// - The AVRISP/STK500 (mk I) protocol is used in the arduino bootloader
// - The SPI functions herein were developed for the AVR910_ARD programmer
// - More information at http://code.google.com/p/mega-isp
//
// March 2012 - William Phelps
// modify to work with Arduino IDE 1.0 which has a shorter serial port receive buffer
// getEOP() now gets entire request before avrisp() is called to process it
// Serial.print((char) xxx) changed to Serial.write(xxx)
// uint8_t changed to byte
// added support for Piezo speaker
// moved Pmode LED to A0
// removed "heartbeat" on pin 6, added short blip of ERROR LED instead
// Why is it that PROG_FLASH and PROG_DATA don't actually do anything???
// Tested with Arduino IDE 22 and 1.0
// IDE 22 - 5148 bytes
// IDE 1.0 - 5524 bytes!

// January 2014 - Ben Gray
// Put the heartbeat LED back and switched around the pins a little for the LEDs.


// SLOW SPEED CHIP ERASE AND FUSE BURNING
//
// Enable LOW_SPEED to allow you to erase chips that would fail otherwise,
// for being running with a clock too slow for the programmer.
//
// This allowed me to recover several ATMega328 that had no boot loader and the
// first instruction was to set the clock to the slowest speed. Usually this
// kind of recovery requires high voltage programming, but this trick will do
// just fine.
//
// How to proceed:
// 1. Enable LOW_SPEED, and load it to the programmer.
// 2. Erase and burn the fuses on the target uC. Example for ATMega328:
//   arduino-1.0.1/hardware/tools/avrdude -Carduino-1.0.1/hardware/tools/avrdude.conf -patmega328p -cstk500v1 -P /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A900cf1Q-if00-port0 -b19200 -e -Ulock:w:0x3F:m -Uefuse:w:0x05:m -Uhfuse:w:0xDA:m -Ulfuse:w:0xF7:m
// 3. Comment LOW_SPEED and load it back to the programmer.
// 4. Program the target uC as usual. Example:
//  arduino-1.0.1/hardware/tools/avrdude -Carduino-1.0.1/hardware/tools/avrdude.conf -patmega328p -cstk500v1 -P /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A900cf1Q-if00-port0 -b19200 -Uflash:w:firmware.hex:i
//
// Note 1: EXTRA_SPI_DELAY was added to let you slow down SPI even more. You can
// play with the value if it does not work with the default.
// Note 2: LOW_SPEED will alow you only to erase the chip and burn the fuses! It
// will fail if you try to program the target uC this way!

//#define LOW_SPEED
#ifdef LOW_SPEED
#define EXTRA_SPI_DELAY 125
#else
#define EXTRA_SPI_DELAY 0
#endif

#include "pins_arduino.h"  // defines SS,MOSI,MISO,SCK
#define RESET SS

#define LED_ERR 7
#define LED_PMODE 8
#define LED_HB 6
//#define PIEZO A3

#define HWVER 2
#define SWMAJ 1
#define SWMIN 18

// STK Definitions
const byte STK_OK = 0x10;
const byte STK_FAILED = 0x11;
const byte STK_UNKNOWN = 0x12;
const byte STK_INSYNC = 0x14;
const byte STK_NOSYNC = 0x15;
const byte CRC_EOP = 0x20; //ok it is a space...

const byte STK_GET_SYNC     = 0x30;
const byte STK_GET_SIGNON   = 0x31;
const byte STK_GET_PARM     = 0x41;
const byte STK_SET_PARM     = 0x42;
const byte STK_SET_PARM_EXT = 0x45;
const byte STK_PMODE_START  = 0x50;
const byte STK_PMODE_END    = 0x51;
const byte STK_SET_ADDR     = 0x55;
const byte STK_UNIVERSAL    = 0x56;
const byte STK_PROG_FLASH   = 0x60;
const byte STK_PROG_DATA    = 0x61;
const byte STK_PROG_PAGE    = 0x64;
const byte STK_READ_PAGE    = 0x74;
const byte STK_READ_SIGN    = 0x75;

//// TONES  ==========================================
//// Start by defining the relationship between
////       note, period, &  frequency.
//#define  c     3830    // 261 Hz
//#define  d     3400    // 294 Hz
//#define  e     3038    // 329 Hz
//#define  f     2864    // 349 Hz
//#define  g     2550    // 392 Hz
//#define  a     2272    // 440 Hz
//#define  b     2028    // 493 Hz
//#define  C     1912    // 523 Hz

//void pulse(int pin, int times);

int error=0;
int pmode=0;
// address for reading and writing, set by STK_SET_ADDR command
int _addr;
byte _buffer[256]; // serial port buffer
int pBuffer = 0;  // buffer pointer
int iBuffer = 0;  // buffer index
byte buff[256];  // temporary buffer
boolean EOP_SEEN = false;

void setup() {

  Serial.begin(19200);
//  pinMode(PIEZO, OUTPUT);
//  beep(1700, 40);
  EOP_SEEN = false;
  iBuffer = pBuffer = 0;

  pinMode(LED_PMODE, OUTPUT);
  pulse(LED_PMODE, 2);
  pinMode(LED_ERR, OUTPUT);
  pulse(LED_ERR, 2);
  pinMode(LED_HB, OUTPUT);
  pulse(LED_HB, 2);
 
  pinMode(9, OUTPUT);
  // setup high freq PWM on pin 9 (timer 1)
  // 50% duty cycle -> 8 MHz
  OCR1A = 0;
  ICR1 = 1;
  // OC1A output, fast PWM
  TCCR1A = _BV(WGM11) | _BV(COM1A1);
  TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // no clock prescale
 

}

#define beget16(addr) (*addr * 256 + *(addr+1) )
typedef struct param {
  byte devicecode;
  byte revision;
  byte progtype;
  byte parmode;
  byte polling;
  byte selftimed;
  byte lockbytes;
  byte fusebytes;
  int flashpoll;
  int eeprompoll;
  int pagesize;
  int eepromsize;
  int flashsize;
}
parameter;

parameter param;

// this provides a heartbeat on pin 6, so you can tell the software is running.
byte hbval=128;
int8_t hbdelta=4;
void heartbeat() {
  if (hbval > 192) hbdelta = -hbdelta;
  if (hbval < 32) hbdelta = -hbdelta;
  if (hbval > 250) hbdelta = -hbdelta;
  if (hbval < 10) hbdelta = -hbdelta;
  hbval += hbdelta;
  analogWrite(LED_HB, hbval);
  delay(20);
}
 
void getEOP() {
  int minL = 0;
  byte avrch = 0;
  byte bl = 0;
  while (!EOP_SEEN) {
    while (Serial.available()>0) {
      byte ch = Serial.read();
      _buffer[iBuffer] = ch;
      iBuffer = (++iBuffer)%256;  // increment and wrap
      if (iBuffer == 1)  avrch = ch;  // save command
      if ((avrch == STK_PROG_PAGE) && (iBuffer==3)) {
        minL = 256*_buffer[1] + _buffer[2] + 4;
      }
      if ((iBuffer>minL) && (ch == CRC_EOP)) {
        EOP_SEEN = true;
      }
    }
    if (!EOP_SEEN) {
      heartbeat(); // light the heartbeat LED
//     if (bl == 100) {
//       pulse(LED_ERR,1,10);  // blink the red LED
//       bl = 0;
//     }
      bl++;
      delay(10);
    }
  }
}

// serialEvent not used so sketch would be compatible with older IDE versions
//void serialEvent() {
//  int minL = 0;
//  byte avrch = 0;
//  while (Serial.available()>0)
//  {
//    byte ch = Serial.read();
//    _buffer[iBuffer] = ch;
//    iBuffer = (++iBuffer)%256;  // increment and wrap
//    if (iBuffer == 1)  avrch = ch;  // save command
//    if ((avrch == STK_PROG_PAGE) && (iBuffer==3)) {
//      minL = 256*_buffer[1] + _buffer[2] + 4;
//    }
//    if ((iBuffer>minL) && (ch == CRC_EOP)) {
//      EOP_SEEN = true;
//    }
//  }
//}

void loop(void) {
  // is pmode active?
//  if (pmode) digitalWrite(LED_PMODE, HIGH);
//  else digitalWrite(LED_PMODE, LOW);
  digitalWrite(LED_PMODE, LOW);
  // is there an error?
  if (error) digitalWrite(LED_ERR, HIGH);
  else digitalWrite(LED_ERR, LOW);

  getEOP();
 
  // have we received a complete request?  (ends with CRC_EOP)
  if (EOP_SEEN) {
    digitalWrite(LED_PMODE, HIGH);
    EOP_SEEN = false;
    avrisp();
    iBuffer = pBuffer = 0;  // restart buffer
  }
 
}

byte getch() {
  if (pBuffer == iBuffer) {  // spin until data available ???
    pulse(LED_ERR, 1);
//    beep(1700, 20);
    error++;
    return -1;
  }
  byte ch = _buffer[pBuffer];  // get next char
  pBuffer = (++pBuffer)%256;  // increment and wrap
  return ch;
}

void readbytes(int n) {
  for (int x = 0; x < n; x++) {
    buff[x] = getch();
  }
}

//#define PTIME 20
void pulse(int pin, int times, int ptime) {
  do {
    digitalWrite(pin, HIGH);
    delay(ptime);
    digitalWrite(pin, LOW);
    delay(ptime);
    times--;
  }
  while (times > 0);
}
void pulse(int pin, int times) {
  pulse(pin, times, 50);
}

void spi_init() {
  byte x;
  SPCR = 0x53;
#ifdef LOW_SPEED
SPCR=SPCR|B00000011;
#endif
  x=SPSR;
  x=SPDR;
}

void spi_wait() {
  do {
  }
  while (!(SPSR & (1 << SPIF)));
}

byte spi_send(byte b) {
  byte reply;
#ifdef LOW_SPEED
    cli();
    CLKPR=B10000000;
    CLKPR=B00000011;
    sei();
#endif
  SPDR=b;
  spi_wait();
  reply = SPDR;
#ifdef LOW_SPEED
    cli();
    CLKPR=B10000000;
    CLKPR=B00000000;
   sei();
#endif
    return reply;
}

byte spi_transaction(byte a, byte b, byte c, byte d) {
  byte n;
  spi_send(a);
  n=spi_send(b);
  //if (n != a) error = -1;
  n=spi_send(c);
  return spi_send(d);
}

void replyOK() {
//  if (EOP_SEEN == true) {
  if (CRC_EOP == getch()) {  // EOP should be next char
    Serial.write(STK_INSYNC);
    Serial.write(STK_OK);
  }
  else {
    pulse(LED_ERR, 2);
    Serial.write(STK_NOSYNC);
    error++;
  }
}

void breply(byte b) {
  if (CRC_EOP == getch()) {  // EOP should be next char
    Serial.write(STK_INSYNC);
    Serial.write(b);
    Serial.write(STK_OK);
  }
  else {
    Serial.write(STK_NOSYNC);
    error++;
  }
}

void get_parameter(byte c) {
  switch(c) {
  case 0x80:
    breply(HWVER);
    break;
  case 0x81:
    breply(SWMAJ);
    break;
  case 0x82:
    breply(SWMIN);
    break;
  case 0x93:
    breply('S'); // serial programmer
    break;
  default:
    breply(0);
  }
}

void set_parameters() {
  // call this after reading paramter packet into buff[]
  param.devicecode = buff[0];
  param.revision = buff[1];
  param.progtype = buff[2];
  param.parmode = buff[3];
  param.polling = buff[4];
  param.selftimed = buff[5];
  param.lockbytes = buff[6];
  param.fusebytes = buff[7];
  param.flashpoll = buff[8];
  // ignore buff[9] (= buff[8])
  //getch(); // discard second value
 
  // WARNING: not sure about the byte order of the following
  // following are 16 bits (big endian)
  param.eeprompoll = beget16(&buff[10]);
  param.pagesize = beget16(&buff[12]);
  param.eepromsize = beget16(&buff[14]);

  // 32 bits flashsize (big endian)
  param.flashsize = buff[16] * 0x01000000
    + buff[17] * 0x00010000
    + buff[18] * 0x00000100
    + buff[19];

}

void start_pmode() {
  spi_init();
  // following delays may not work on all targets...
  pinMode(RESET, OUTPUT);
  digitalWrite(RESET, HIGH);
  pinMode(SCK, OUTPUT);
  digitalWrite(SCK, LOW);
  delay(50+EXTRA_SPI_DELAY);
  digitalWrite(RESET, LOW);
  delay(50+EXTRA_SPI_DELAY);
  pinMode(MISO, INPUT);
  pinMode(MOSI, OUTPUT);
  spi_transaction(0xAC, 0x53, 0x00, 0x00);
  pmode = 1;
}

void end_pmode() {
  pinMode(MISO, INPUT);
  pinMode(MOSI, INPUT);
  pinMode(SCK, INPUT);
  pinMode(RESET, INPUT);
  pmode = 0;
}

void universal() {
//  int w;
  byte ch;
//  for (w = 0; w < 4; w++) {
//    buff[w] = getch();
//  }
  readbytes(4);
  ch = spi_transaction(buff[0], buff[1], buff[2], buff[3]);
  breply(ch);
}

void flash(byte hilo, int addr, byte data) {
  spi_transaction(0x40+8*hilo, addr>>8 & 0xFF, addr & 0xFF, data);
}
void commit(int addr) {
  spi_transaction(0x4C, (addr >> 8) & 0xFF, addr & 0xFF, 0);
}

//#define _current_page(x) (here & 0xFFFFE0)
int current_page(int addr) {
  if (param.pagesize == 32) return addr & 0xFFFFFFF0;
  if (param.pagesize == 64) return addr & 0xFFFFFFE0;
  if (param.pagesize == 128) return addr & 0xFFFFFFC0;
  if (param.pagesize == 256) return addr & 0xFFFFFF80;
  return addr;
}
byte write_flash(int length) {
  if (param.pagesize < 1) {
    return STK_FAILED;
  }
  //if (param.pagesize != 64) return STK_FAILED;
  int page = current_page(_addr);
  int x = 0;
  while (x < length) {
    if (page != current_page(_addr)) {
      commit(page);
      page = current_page(_addr);
    }
    flash(LOW, _addr, buff[x++]);
    flash(HIGH, _addr, buff[x++]);
    _addr++;
  }
  commit(page);
  return STK_OK;
}

byte write_eeprom(int length) {
  // here is a word address, so we use here*2
  // this writes byte-by-byte,
  // page writing may be faster (4 bytes at a time)
  for (int x = 0; x < length; x++) {
    spi_transaction(0xC0, 0x00, _addr*2+x, buff[x]);
    delay(45);
  }
  return STK_OK;
}

void program_page() {
  byte result = STK_FAILED;
  int length = 256 * getch() + getch();
  if (length > 256) {
      Serial.write(STK_FAILED);
      error++;
      return;
  }
  char memtype = (char)getch();
//  for (int x = 0; x < length; x++) {
//    buff[x] = getch();
//  }
  readbytes(length);
  if (CRC_EOP == getch()) {
    Serial.write(STK_INSYNC);
    switch (memtype) {
      case 'E':
        result = (byte)write_eeprom(length);
        break;
      case 'F':
        result = (byte)write_flash(length);
        break;
    }
    Serial.write(result);
    if (result != STK_OK) {
      error++;
    }
  }
  else {
    Serial.write(STK_NOSYNC);
    error++;
  }
}

byte flash_read(byte hilo, int addr) {
  return spi_transaction(0x20 + hilo * 8,
    (addr >> 8) & 0xFF,
    addr & 0xFF,
    0);
}

char flash_read_page(int length) {
  for (int x = 0; x < length; x+=2) {
    byte low = flash_read(LOW, _addr);
    Serial.write( low);
    byte high = flash_read(HIGH, _addr);
    Serial.write( high);
    _addr++;
  }
  return STK_OK;
}

char eeprom_read_page(int length) {
  // here again we have a word address
  for (int x = 0; x < length; x++) {
    byte ee = spi_transaction(0xA0, 0x00, _addr*2+x, 0xFF);
    Serial.write( ee);
  }
  return STK_OK;
}

void read_page() {
  byte result = (byte)STK_FAILED;
  int length = 256 * getch() + getch();
  char memtype = getch();
  if (CRC_EOP != getch()) {
    Serial.write(STK_NOSYNC);
    return;
  }
  Serial.write(STK_INSYNC);
  if (memtype == 'F') result = flash_read_page(length);
  if (memtype == 'E') result = eeprom_read_page(length);
  Serial.write(result);
  return;
}

void read_signature() {
  if (CRC_EOP != getch()) {
    Serial.write(STK_NOSYNC);
    error++;
    return;
  }
  Serial.write(STK_INSYNC);
  byte high = spi_transaction(0x30, 0x00, 0x00, 0x00);
  Serial.write(high);
  byte middle = spi_transaction(0x30, 0x00, 0x01, 0x00);
  Serial.write(middle);
  byte low = spi_transaction(0x30, 0x00, 0x02, 0x00);
  Serial.write(low);
  Serial.write(STK_OK);
}
//////////////////////////////////////////
//////////////////////////////////////////


////////////////////////////////////
////////////////////////////////////

int avrisp() {
  byte data, low, high;
  byte avrch = getch();
  switch (avrch) {
    case STK_GET_SYNC: // get in sync
      replyOK();
      break;
    case STK_GET_SIGNON:  // get sign on
      if (getch() == CRC_EOP) {
        Serial.write(STK_INSYNC);
        Serial.write("AVR ISP");
        Serial.write(STK_OK);
      }
      break;
    case STK_GET_PARM:  // 0x41
      get_parameter(getch());
      break;
    case STK_SET_PARM:  // 0x42
      readbytes(20);
      set_parameters();
      replyOK();
      break;
    case STK_SET_PARM_EXT: // extended parameters - ignore for now
      readbytes(5);
      replyOK();
      break;
    case STK_PMODE_START:  // 0x50
//     beep(2272, 20);
      start_pmode();
      replyOK();
      break;
    case STK_PMODE_END:  //0x51
//      beep(1912, 50);
      error=0;
      end_pmode();
      replyOK();
      break;
    case STK_SET_ADDR:  // 0x55
      _addr = getch() + 256 * getch();
      replyOK();
      break;
    case STK_UNIVERSAL:  //UNIVERSAL 0x56
      universal();
      break;
    case STK_PROG_FLASH: //STK_PROG_FLASH  ???
      low = getch();
      high = getch();
      replyOK();
      break;
    case STK_PROG_DATA: //STK_PROG_DATA  ???
      data = getch();
      replyOK();
      break;
    case STK_PROG_PAGE:  //STK_PROG_PAGE
//      beep(1912, 20);
      program_page();
      break;
    case STK_READ_PAGE: //STK_READ_PAGE
      read_page();   
      break;
    case STK_READ_SIGN: //STK_READ_SIGN
      read_signature();
      break;
    // expecting a command, not CRC_EOP
    // this is how we can get back in sync
    case CRC_EOP:
      Serial.write(STK_NOSYNC);
      break;
    // anything else we will return STK_UNKNOWN
    default:
      if (CRC_EOP == getch())
        Serial.write(STK_UNKNOWN);
      else
        Serial.write(STK_NOSYNC);
  }
}

// beep without using PWM
//void beep(int tone, long duration){
//  long elapsed = 0;
//  while (elapsed < (duration * 10000)) {
//    digitalWrite(PIEZO, HIGH);
//    delayMicroseconds(tone / 2);
//    digitalWrite(PIEZO, LOW);
//    delayMicroseconds(tone / 2);
    // Keep track of how long we pulsed
//    elapsed += tone;
//  }
//} 

Comments

ArcAiN6 (author)2016-09-29

Recently, there was a change in the "arduinoISP" sketch that swapped a pin, does this reflect this change?

Also,
why kicad instead of eagle? Eagle is easily converted into other PCB
software formats, whereas kicad doesn't really play nice when it comes to being
converted to other softwares. Sure, you could export gerber files, but you lose quite a lot of data, and the schematic.

phenoptix (author)ArcAiN62016-09-29

Not sure on the change as don't make these anymore, would be worth comparing the code linked with the recent code change.

KiCad because it's free for all, for any size. It's a pretty simple board, if you can use Eagle I'm sure you could replicate it in about 20 minutes. Please attribute if you do! ;)

dan3008 (author)2014-12-09

just bought a kit of ebay, and am eagerly awaiting delivery to solder it up, and get it working :D

One quick question. Will this work with the standard arduino isp sketch? or do I have to use yours? I've got both saved, so not an issue either way, just intrested :)

phenoptix (author)dan30082014-12-09

Do you have a link to the kit Dan? Best to use our sketch as there are a few differences, if it's one of our ISP Shields.

dan3008 (author)phenoptix2014-12-10

It was just a bid one, where someone had just the one. Apparently it was an unwanted present. It is one of your kits (arrived today), it has your logo and website and everything, even on a red pcb.

phenoptix (author)dan30082014-12-10

Cool, then yes use our script, you'll get the correct LEDs working that way!

dan3008 (author)dan30082014-12-09

(after changing the LED pins on the standard sketch obviously)

gcarlyle22 (author)2014-09-05

I can not get the files from your site. Can you post them here?

I tried to get the schematic and pcb files but eagle says they aren't eagle files.

jamiejackson (author)2014-05-23

I've taken the liberty of revewing this product on my blog; http://blog.jacobean.net/?p=918. Hope you don't mind & if there's anything factually incorrect, please don't hesitate to contact me.

jamiejackson made it! (author)2014-05-23

Fantastic kit. Quick delivery & great value for money. Resister values weren't as picture on this page but worked just fine (tested before soldering).

"You can now program Arduino Bootloaders from within the IDE and also the AVR chips listed with AVRDUDE, but I'll explain how to do all that on a less product oriented Instructable.". Is this Instructable on how to program avaible?

batkin made it! (author)2014-03-10

I spaghetti faced it and I'm not even ashamed. I'm not quite into etching yet but it's starting to be clear that it's probably not much more work in the long run and looks quite a bit nicer.

phenoptix (author)batkin2014-03-24

That's super amazing! I love it!

matsk (author)2014-02-12

Nice work.

Any thought on using ZIF sockets instead of normal IC sockets ?
phenoptix (author)matsk2014-03-03

Yes, but the idea with this shield was to keep it cheap for beginners. I'm working on an update with a ZIF at the moment.

Iceberg86300 (author)2014-01-30

Good instructable!

Just a tip for the novice solderers out there: always tin your iron. You don't need a glob on there, just enough so the liquid solder contacts the pins and pads. Doing this greatly increases the heat transfer compared to a dry iron because the heat travels through the solder which covers a lot more surface area on the component instead of just a point contact between the component and iron. This greatly reduces the time the iron needs to be touching the pins and pads, decreasing the chance of lifting a trace because things got too hot while trying to get a good joint.

With some practice you will find the perfect amount of solder to make the connection so you won't need to feed solder into the joint and you won't have a big glob to deal with. (this applies to the first pin, after that the iron will retain some solder from feeding, with practice you'll find the perfect amount of solder to feed at each joint to get a nice shiny joint (or dull if using lead free. Tip: lead free requires a higher temp which in turn needs more heat transfer which requires a pencil iron with more power or better yet an adjustable temp iron. I picked up a hakko from fry's for pretty cheap) while retaining just enough to get good heat transfer at the next joint)

This is a rather simple soldering job with just sockets and pins, but if you are soldering a thru hole component it is a good idea to jump back and forth across a DIP as well as up and down a row to prevent heat buildup in the component. I usually do one corner, jump across and up to the opposite corner, down the row to the pin across from the first, then jump across and up to the opposite corner. All 4 corners should now be done, then go to the pin next to the first and repeat the sequence until finished.

phenoptix (author)Iceberg863002014-01-30

wow what a comment! Great soldering advise. Just to clarify on my glob of solder method, its specifically for one handed pinning on large multipin items. Otherwise simple tinning as you suggest.

Also do you know Nial? You two could have mammoth email exchanges!

Iceberg86300 (author)phenoptix2014-02-16

Yeah, I tend to go overboard in my comments when it deals with giving advice. Don't know Nial, but I'm sure some epic exchanges could be had.

I tend to be able to talk tech with someone forever, something inherited from my dad.

This happens to be the single biggest problem in technique as far as I'm concerned. I wasn't digging on your 'glob'method, I should have used a different word. I actually do the same thing, a large amount of solar on the Iron (as long as you get to the joint quickly before the flux vaporizes) transfers the heat supporter quick, and then I'll just drag the Iron along a few pins until its time to tin again.

A small glob also works great for surface mount IC's. You can just drag the Iron across the pins and then get rid of any bridges after. That is most effective when using flux on the pads and a board that has been masked, a proto board that isn't masked is a nightmare.

Oh, one more thing, I like to tin the Iron and let the flux burn off or use solder without flux when I'm done for the day so the Iron is protected during storage, just make sure that you let the flux burn off if you're using rosin or acid core so the Iron doesn't get pitted.

ykyk (author)2014-02-05

英文看不懂呀

phenoptix (author)ykyk2014-02-05

这很酷,我可以不写中国

Mrplaser (author)2014-02-01

Nice instuctable, but you might want to add in your intro what exactly an ISP Shield for Arduino does. What is its purpose to those not initiated?

MrArtist (author)Mrplaser2014-02-03

My thought entirely. What on earth is it??!!

phenoptix (author)MrArtist2014-02-03

Good point well made chaps. Have added a paragraph on the first page that should shed some light on that very subject.

MrArtist (author)phenoptix2014-02-03

Thanks for the addition, it helps me try and figure out how much more I still need to learn about!

TSJWang (author)2014-01-28

BLUE LEDS EXIST?

xaenon (author)TSJWang2014-01-28

for several years now. Though technically they are ultraviolet with blue phosphor, just as white LEDs are ulltraviolet with white phosphor.

alzie (author)xaenon2014-01-30

No. There are true UV leds all the way down to 365nm and beyond.

No phosphor. See:

http://www.mouser.com/Optoelectronics/_/N-5g5v?Keyword=ultraviolet&FS=True&gclid=CNvcipLoprwCFUHNOgodGX8ADg

xaenon (author)alzie2014-01-30

Yes, but unless I'm misunderstanding this, blue and white LEDs are actually UV LEDs with phosphors to make visible blue or white light.

alzie (author)xaenon2014-01-31

Blue and UV leds are direct emitters, no phosphor.

Only wht leds have an orangish phosphor,

to combine with some leaked blue light to appear white.

A long time ago,

there were some obscure pink and purple (non uv) leds that

were phosphor based. You dont see them any more.

Wyle_E (author)TSJWang2014-01-28

Blue LEDs have been available for years. You can even get ultraviolet LEDs.

TSJWang (author)Wyle_E2014-01-28

lol I would be supprised if they did not exist.
I just have never seen them sold. I've only seen red, yellow, or green tinted LEDs sold usually. Any other colors would not use tint... until I saw this.

Ralphxyz (author)2014-01-30

Could your shield be used without a Arduino?

You have a ICSP header could I connect a AVR programmer?

Might need a power header.

Nice structable thanks.

phenoptix (author)Ralphxyz2014-01-31

It could with some hacking. You can use it as a standard AVR Programmer with the headers though. I have a V2 in the works so to speak that would function as a stand alone programmer. Complete with ZIF socket and external power adapter.

Ralphxyz (author)phenoptix2014-01-31

Now I would like V2, let me know when you make it up.

rhulslander g mail

matstermind (author)2014-01-31

which version of eagle are you using? i am using 6.5.0 and it s give me the error

"Error:

line 1, column 1: Start tag expected."

when opening either file.

phenoptix (author)matstermind2014-01-31

KiCad my good man! This project is Open Source all the way down!

PhilieBlunt (author)2014-01-29

TSJWang, so you have radio shack where you live? they sell all sorts of colors of leds, they have blue and I get uv (blacklight) leds there all the time, I wanna make a led cube with em but at a buck a piece thatd get real expensive real fast lol

phenoptix (author)PhilieBlunt2014-01-31

While everyone is recommending LED suppliers, I can recommend these guys with complete impartiality! http://www.phenoptix.com/collections/leds Admittedly shipping to the states is either expensive or slow though.

xaenon (author)PhilieBlunt2014-01-30

Radio Shack is expensive, period, and personally, I'm not all that impressed with the quality of some of their individual components. Look around at some of the electronics parts houses online, you can get them MUCH cheaper than The Shack if you're going to buy in quantity.

PhilieBlunt (author)xaenon2014-01-30

Thank you, I'll definitely have to look into that! :)

Iceberg86300 (author)PhilieBlunt2014-01-30

Mouser and digikey are good as well and have nearly any component you need. I only give the shack money when I'm in a pinch.

J,R,D, Ltd (author)PhilieBlunt2014-01-30

A buck a piece is a total ripoff! Check out Tayda Electronics http://www.taydaelectronics.com/leds/round-leds.html Prices range from 2-27 Cents each!

matstermind (author)2014-01-30

in github, i can view the .sch and.brd files as text, but i can't figure out how to download the file as .brd and .sch

phenoptix (author)matstermind2014-01-30

You can download the whole thing as a zip on the main page is your best bet, otherwise view as raw and save the page as the file. I'm a bit of a github novice to be honest!

matstermind (author)phenoptix2014-01-30

exactly what i needed to know, apparently i'm even more of a novice than you, thanks!

rpotts2 (author)2014-01-28

I definitely will. I have an EMSL shield and have been sitting on the fence about adding ATTiny support to it. now I dont have too! I just started exploring etching so it's going to be a little while, but I am exxited about this one.

phenoptix (author)rpotts22014-01-28

I'm really pleased and would be stoked to see your board! It's one of the reasons I avoid vias in my boards.

rpotts2 (author)2014-01-28

sweet. my first etch project. Unless you have US distributors... Seriously, that is awesome what you did here. Thank you!

phenoptix (author)rpotts22014-01-28

please go for it!

About This Instructable

70,455views

539favorites

License:

Bio: A member of instructables since 2006 I'm currently cruising at an improving 0.875 instructables a year...
More by phenoptix:MeArm V1.1 - Tiny Open Source Robot ArmMeArm Robot Arm - Your Robot - V1.0Pocket Sized Robot Arm MeArm V0.4
Add instructable to: