Sunday, April 26, 2009

Another cool idea for connecting vias for DIY double-sided PCBs

Tony Smith, , of the PICLIST gave me this idea:

Take a long piece of solid strand wire and thread it through all of the vias, like sewing. The wire should obviously be bare (stripped of all insulation). Solder one side, then the other. Do this for all the vias and clip off the excess wire and the interconnecting wire.

It’s fast, easy, cost-effective, and it works.

Saturday, April 25, 2009

Annoyances and solutions for components when top-soldering DIY double-sided PCBs

Most components are very easy to top solder when making double-sided PCBs. However, some can be annoying and hard. The following may be a simple solution for such components:

  • Large capacitors
    • Do not insert completely. Leave space on top and bend capacitor over on its side. This will leave a lot of space for easy top soldering.
  • Male/female pin headers
    • For the male pin headers, use pliers or  a vice & hammer to tap the plastic part further toward the connection end. This will give room for top-soldering.
    • For the female headers: this can get tricky on some types as not enough pin length is left to allow for top-soldering. The best I can think of in this case is to try and raise the header off the PCB slightly anyway and solder the top parts first. Then flip to the other side of the PCB and continue soldering.
  • Switches, piezoelectric speakers, and other seated components.
    • These can also get tricky to top-solder. Again, the solution may be to raise the component off the PCB as much as possible. If this doesn’t work, then the next quickest way is to solder stiff copper wires to them as lead-extensions.

 

If all else fails, it’s always handy to have a few through-hole rivets (as discussed in detail in my previous post). In any case, top-soldering is the quickest and most cost-effective method for DIY double-sided PCB making.

And there’s my thought for today.

Thursday, April 23, 2009

Ubuntu 9.04 Released!

Ubuntu 9.04 Released today!

Tuesday, April 21, 2009

Kubuntu 9.04 RC

I just gave Kubuntu 9.04 RC a try - installed it on my old Dell Inspiron 6000 laptop. Works very well (KDE4.2). It was flawless and did everything I needed. Unfortunately, KDE login/logout is still a bit slow compared to Gnome, but this will improve with time. 9.04 final release is due in two days.

Driving a Piezoelectric Speaker with a PIC

Piezoelectric speakers are really cool. You can get them inexpensively from most hobby electronics stores, take them out of PCs, and so on. You can directly connect them to your microcontroller (resistor recommended) and generate any tone you want.

Simply connect one end of the speaker to an output pin on your PIC and connect the other end to GND for the simplest configuration. You make the speaker “tick” by passing current through it. By rapidly turning the output pin on and off, you generate a tone. Here’s a very simple example program that turns the output pin on and off via software:

#include "main.h"
#define SLEEP 1000

void main() {
    setup_adc_ports(NO_ANALOGS|VSS_VDD);    
    setup_oscillator(OSC_8MHZ);
    setup_uart(9600);
    
    while(true) {
        output_high(PIN_B6);
        output_high(PIN_C0);
        delay_us(SLEEP);
        output_low(PIN_B6);
        output_low(PIN_C0);
        delay_us(SLEEP);
    }
}

Pin B6 (in my case) is the speaker output. Pin C0 is an output to an LED (for testing, it is not needed). You can change the value of the SLEEP define for varying frequency of sound.

However, there is another way that this can be done (more reliably) – using the PIC’s internal PWM (from CCP module). You can generate very precise frequencies that way.

Sunday, April 19, 2009

PICKIT2 Linux GUI – In Progress

I’m working on a Linux GUI for the PICKIT2, it’s in progress – almost done. Stay tuned.

Saturday, April 18, 2009

MAX233A

I just got my MAX233A samples from Maxim. They’re UART RS232 <—> TTL level computers so you can interface your PIC’s UART to your computer’s RS232 port. Makes development a lot quicker since it’s easy to program and view output.

On windows, you can use the termite terminal to communicate via UART on a windows machine. On a Linux machine, you have a lot more options – see Minicom. There are even floppy Linux distributions designed just for this purpose, so you can pull that old 386 out and put it to some use.

The great thing about the MAX233A is that it requires no external capacitors for its internal charge pumps (which are used to boost voltage levels to RS232 specifications). The only thing that’s required is a decoupling capacitor as described in the sample circuit in the datasheet.

I salvaged an old RS232 mouse for its cable. It had all the wires I needed (TX, RX, GND) to fully interface to my microcontroller.

So just go ahead and order some samples of the MAX233A – it’s a great little chip.

If you have a PIC that supports self writes to flash, you can even write (or download) a serial bootloader and development will go even faster as you’ll be able to program your chip directly over UART.

Saturday, April 11, 2009

DIY IPOD Battery Pack

So my IPOD Nano 1st G internal battery is dying. I can barely squeeze out a few minutes of play time using the normal Apple firmware. IPOD Linux and Rockbox are awesome; by setting the backlight brightness to a minimum, I can get a whole lot more playtime. One option is to buy a battery and installation kit (they’re pretty inexpensive). However, this method requires you to open up your IPOD (which is really not that big of a deal), but there must be a simpler way of getting the job done – using components you can find around the house.

What I’m talking about is an external power supply/battery pack that can fit onto any IPOD (through the USB cable) - http://www.ladyada.net/make/mintyboost/

But we can make one ourselves – a more versatile one.

The IPOD cable consists of one end that plugs into the device and the other end is a standard USB male connector. The USB connector consists of 4 pins - V+, GND, D+, D-. To supply power to the IPOD, we need to supply exactly 5 volts through the V+/GND pins. The D+ and D- should be tied to V+ via 100k resistors (I think – more on this later). And there you have it – your own power ipod power supply.

The actual circuit, however, can get a bit complicated. What regulator do we chose? The design I’m thinking of will be able to be powered from as little as 2 AA batteries to the 12 V output from your car. We need a regulator that can accept this high range of voltages. Obviously it needs to be a boost/buck (step up/step down) regulator. These tend to get a bit annoying as we need external capacitors and solenoids for the circuit. Take a look at the mintyboost above for inspiration.

Oh, and it would be cool to have it small enough so all of it fits on the back of an IPOD Nano 1st G.

 

Just a thought.

Wednesday, April 8, 2009

DIY Through-Plating for Double-Sided PCBs

Creating your own PCBs can be annoying – especially when trying to make them compact and contain many parts. Routing can be very difficult. Luckily, we can make our own double-sided PCBs just as easily. However, the problem now is finding a way to create vias and plated through holes at home safely, efficiently, effectively, quickly, easily and cheaply. Large chemical through-plating machines are out of the question. There must be an easier way to do it.

I came across a webpage a while back which had a few ideas for tackling this issue: http://www.electricstuff.co.uk/pcbs.html

There are several ways to overcome the vias/plated through-hole problem:

Top-soldering:

  • Easy, quick, cheap, works for most ICs and components. The IC holders can be a bit tricky though, as well as certain capacitors and funny components.
  • Connects one side of the board to the other – like a plated through hole.
  • For vias, a smaller hole can be placed and a wire can be soldered through it on both sides of the PCB. This is slow and annoying.

Linking pins and rivets:

Sunday, April 5, 2009

Salvaging an RS232 serial mouse

I recently got some MAX232A samples from Maxim-IC. These chips convert the TTL RS232 signals from your PIC to the RS232 voltage levels required by your PC. They make it very easy to connect your PIC with your PC. I only needed one more thing: an RS232 serial cable. I noticed I had some old RS232 serial mice lying around. I decided to break one open and remove the cable. Perfect – the cable had all the wires I needed – RX, TX and more. Let’s put this aside.

Next, there were some more interesting components inside the mouse that may come in handy, such as buttons, phototransistors, IR LEDs and so on. The IR LEDs, phototransistors and the gears could be used for something interesting.

I found a site that describes the use of the IC inside the serial mouse to extract movement information: http://www.geocities.com/kellertuberg/telescope/serial_mouse.html

Let’s see where this goes…

Saturday, April 4, 2009

Homebrew CPU

I found some interesting sites on making your own CPU from scratch. Some of them are only made out of 74 series integrated circuits.

http://www.homebrewcpu.com/

That site is part of the homebrew CPU webring. Just scroll to the bottom and you can click “next” through all the sites in the webring.

DS18B20 1-wire Driver for CCS C

I got my hands on a few of these DS18B20 1-wire digital temperature sensors. They’re really awesome. They’re small, easy to work with, and they run on the 1-wire bus which means they can run on a minimum of two wires. However, I found it easier to just run these devices with 3 lines: +5V, GND, Bus – saves a lot of design complexity.

I found a few good 1-wire drivers for CCS C (especially for these devices):

DS18S20 & DS18B20 Codes

One DS18B20 in powered mode

dallas onewire primitives library and ds1822 driver code

I then took ideas from them and made my own little driver. Some of the code is copied, some of it isn’t. Here it is:

main.c

#include "main.h"
#include "1wire.c"
#include "ds1820.c"

float value = 0.0;

void main() {
    setup_adc_ports(NO_ANALOGS|VSS_VDD);
    setup_adc(ADC_OFF);
    setup_spi(SPI_SS_DISABLED);
    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
    setup_timer_1(T1_DISABLED);
    setup_timer_2(T2_DISABLED,0,1);    
    setup_oscillator(OSC_8MHZ);
    setup_uart(9600);
    
    delay_ms(1000);
    
    printf("Starting...\t\n");
    while(TRUE) {        
        value = ds1820_read();
        printf("%f\t\n", value);        
    }
}

main.h

#ifndef MAIN_H
#define MAIN_H

#include <16F690.h>
#device adc=8

#FUSES NOWDT                     //No Watch Dog Timer
#FUSES INTRC_IO                  //Internal RC Osc, no CLKOUT
#FUSES NOPROTECT                 //Code not protected from reading
#FUSES NOBROWNOUT                //No brownout reset
#FUSES NOMCLR                    //Master Clear pin used for I/O
#FUSES NOCPD                     //No EE protection
#FUSES PUT                       //Power Up Timer
#FUSES IESO                      //Internal External Switch Over mode enabled
#FUSES FCMEN                     //Fail-safe clock monitor enabled

#use delay(clock=8000000)
#use rs232(baud=9600, parity=N, UART1, bits=8, stop=1)

#endif /*MAIN_H*/

1wire.c

#ifndef ONE_WIRE_C
#define ONE_WIRE_C

/*
 * One wire (1-wire) driver for CCS C compiler. Suitable for use with devices
 * such as the DS18B20 1-wire digital temperature sensor.
 */

#define ONE_WIRE_PIN PIN_C5

/*
 * onewire_reset()
 * Description: Initiates the one wire bus.
 */
// OK if just using a single permanently connected device
void onewire_reset() {
    output_low(ONE_WIRE_PIN);       // pull the bus low for reset
    delay_us(500);
    output_float(ONE_WIRE_PIN);     // float the bus high
    delay_us(500);                  // wait-out remaining initialisation window
    output_float(ONE_WIRE_PIN);
}


/*
 * onewire_write(int8 data)
 * Arguments: a byte of data.
 * Description: writes a byte of data to the device.
 */
void onewire_write(int8 data) {
    int8 count;

    for(count = 0; count < 8; ++count) {
        output_low(ONE_WIRE_PIN);
        delay_us(2);                // pull 1-wire low to initiate write time-slot.
        output_bit(ONE_WIRE_PIN, shift_right(&data, 1, 0)); // set output bit on 1-wire
        delay_us(60);               // wait until end of write slot.
        output_float(ONE_WIRE_PIN); // set 1-wire high again,
        delay_us(2);                // for more than 1us minimum.
    }
}

/*
 * onewire_read()
 * Description: reads and returns a byte of data from the device.
 */
int onewire_read() {
    int count, data;

    for(count = 0; count < 8; ++count) {
        output_low(ONE_WIRE_PIN);
        delay_us(2);                // pull 1-wire low to initiate read time-slot.
        output_float(ONE_WIRE_PIN); // now let 1-wire float high,
        delay_us(8);                // let device state stabilise,
        shift_right(&data, 1, input(ONE_WIRE_PIN)); // and load result.
        delay_us(120);              // wait until end of read slot.
    }
    return data;
} 

#endif /*ONE_WIRE_C*/

ds1820.c

#ifndef DS1820_C
#define DS1820_C

#include "1wire.c"

float ds1820_read();
void ds1820_configure(int8 TH, int8 TL, int8 config);

/*
 * ds1820_read()
 * Description: reads the ds18x20 device on the 1-wire bus and returns
 *              the temperature
 */
 
float ds1820_read() {
    int8 busy=0, temp1, temp2;
    signed int16 temp3;
    float result;
    
    //ds1820_configure(0x00, 0x00, 0x00);     //9 bit resolution

    onewire_reset();
    onewire_write(0xCC);            //Skip ROM, address all devices
    onewire_write(0x44);            //Start temperature conversion

    while(busy == 0)                //Wait while busy (bus is low)
        busy = onewire_read();

    onewire_reset();
    onewire_write(0xCC);            //Skip ROM, address all devices
    onewire_write(0xBE);            //Read scratchpad
    temp1 = onewire_read();
    temp2 = onewire_read();
    temp3 = make16(temp2, temp1);
 
    //result = (float) temp3 / 2.0;   //Calculation for DS18S20 with 0.5 deg C resolution
    result = (float) temp3 / 16.0;    //Calculation for DS18B20
 
    delay_ms(200);
    return(result);
}

/*
 * ds1820_configure(int8 TH, int8 LH, int8 config)
 * Description: writes configuration data to the DS18x20 device
 * Arguments: alarm trigger high, alarm trigger low, configuration
 */

void ds1820_configure(int8 TH, int8 TL, int8 config) {
    onewire_reset();
    onewire_write(0xCC);            //Skip ROM, address all devices
    onewire_write(0x4E);            //Write to scratchpad
    onewire_write(TH);
    onewire_write(TL);
    onewire_write(config);
}

#endif /*DS1820_C*/

All you have to do is set the define to the appropriate pin you’re using for the 1-wire bus. Remember to attach a 4.7k pullup resistor on the bus to VDD. The value of the pullup resistor is not critical. If I remember correctly, I tested resistors anywhere from 1k to 10k and they worked fine. If not, just stick with the 4.7k pullup as recommended in the DS18B20 datasheet.