Friday, June 18, 2010

First Attempt at DIY SMT

If you build your own through hole printed circuit boards (PCBs), and you don't have a CNC drill, then like me, you're probably sick of drilling holes. I was curious about using surface mount technology (SMT) components for upcoming PCB projects so I'm exploring a couple of avenues.

First up, is a DIY PCB of a simple circuit--a 3.3V regulator with built in filter capacitors.  I'm using an On-Semi NCP1117 regulator (or equivalent) in an SOT-223 package with two 10uF capacitors (per the data sheet) in 0805 packages.

PCB ready for trimming

I drafted the circuit and board in Eagle (download files here), put everything on the bottom layer, and printed the resulting board layout onto a magazine paper with black and white selected and no mirroring.

Schematic (Eagle has an equivalent Burr Brown REG1117 part)
Board Layout (bottom layer)

I then transferred to the small PCB above applying a clothes iron set on Wool for 45 seconds with little pressure except for the weight of the iron.

The PCB turned out pretty well using thermals and .032 traces between the pads. I used a separate pad for the heat sink tab of the regulator. Though capable of delivering 1A, with the small pad I'd best not run it too hard.

Since I haven't yet built a reflow oven, I had to hand solder. Soldering the components was tough. It required tinning the pads and I used too much solder for that and need to switch to a much thinner diameter solder next time so that I can more easily control the amount of solder I put down.

The soldering iron size was just right, using the smallest tip available for my WES51. Using flux paste to help stick the components in place worked out pretty well.  Even so, I had to use a heat gun set to 850°F to reflow the solder and nudge a couple parts around.

Compare form factor with 7805

Aside from the fact that the end result is hideously ugly, the technique works ok for an ultra simple circuit like this.

Something better is needed for prototyping circuits with a higher component count or with difficult components like tiny TSSOP or TQFP chips. And I hope to tell you more about that soon.

Oh ... in case you were wondering, yes, my little DIY regulator works. :)

Friday, June 4, 2010

Arduino to Arduino I2C

Pokey's "visual cortex" (an Ardweeny interfaced to Game Boy Camera) can detect candles, sure.  But unless Pokey's Orangutan LV168 brain can talk to the Ardweeny, Pokey can't really do diddly-squat with the information.

One could use serial I/O in this instance, but that's reserved for telemetry transmission over Bluetooth. Another option is the ATmega built-in Two-Wire Interface (TWI), Atmel's name for I2C.

For this experiment I used the Arduino IDE not only on the Ardweeny but also on the Orangutan, so that I could use the simple Arduino Wire library on both.

This tutorial on Instructables was a big help in getting the AVRs talking to each other.  The Orangutan is set up as the I2C master and the Ardweeny is the slave.  Pull up resistors on the SDA and SCL lines are 4.7k.

The Slave listens for data in, and sends back a "pong" if the master requests data after sending a "ping".  The Master sends a "ping" to the slave. Then it requests a byte back in response. So far the only way the Slave will accept commands and respond to requests for data is by setting up interrupt handlers.

Here's the Master code.
#include
#include
#include "camCom.h"

int ledPin = 1;                 // LED connected to digital pin 1 (PD1) on Orangutans
OrangutanLCD lcd;

void setup() {
  Wire.begin();
  pinMode(ledPin, OUTPUT);      // sets the digital pin as output
  lcd.clear();
  lcd.gotoXY(0,0);
  lcd.print("Pokey");
}

void loop() {
  char buf[5];
  boolean timeout;
  unsigned char i;
  unsigned char c;
 
  delay(500);
  // tell the Ardweeny "PING"
  Wire.beginTransmission(TWI_CAMERA);
  Wire.send(CAM_COM_PING);
  Wire.endTransmission();
  // get back the response: "PONG"
  blink(2,200);
  delay(500);
  Wire.requestFrom(TWI_CAMERA, 1);
  timeout = true;
  for (i = 0; i < 10; i++) {
    if (Wire.available() > 0) {
      timeout = false;
      c = Wire.receive();
      lcd.gotoXY(0,1);
      lcd.printHex(c);
      break;
    }
    delay(100);
  }
}

void blink(unsigned char n, int pause) {
  unsigned char i;
 
  for (i = 0; i < n; i++) {
    digitalWrite(ledPin, HIGH);   // sets the LED on 
    delay(pause);                  // waits for a second 
    digitalWrite(ledPin, LOW);    // sets the LED off 
    delay(pause);              
  }
 
  return;
}

Here's the Slave code (excerpts).

int dataIn;
int dataOut;
boolean dataReady;
unsigned char reg;


void setup()
{
   Serial.begin(38400);
   Wire.begin(TWI_CAMERA);
   dataReady = false;
   Wire.onReceive(recvByte);
   Wire.onRequest(sendByte);
   pinMode(ledPin, OUTPUT);
   camInit();
}

void loop()
{
  delay(10);
  if (dataReady) {
    delay(200);
    blink(2,200); // same blink() code as above
    dataReady = false;
    Serial.write(dataIn);
    switch (dataIn) {
      case CAM_COM_PING:
        dataOut = CAM_COM_PONG;
        break;
      default:
        break;
    }

  }

}

void recvByte(int howMany) {
   dataIn = Wire.receive();
   dataReady = true;
}


void sendByte(void) {
   Wire.send(dataOut);
}

The code for the vision system has to be refactored a tad so as to accommodate this strange protocol where the Master tells the slave not only what to do but when to send data back and how much.