Robot update

I finally have my final pcb design ready for prototyping. I haven’t had too much free time to work on this project as I’ve been busy with work and school. The solution to the power problem I had discussed previously turned out to be caused by my lack of including decoupling capacitors at the outputs of the motor driver, which was causing a temporary loss of voltage to the micro controller. The circuit seems to run great off of 4xAA batteries without any problems. In my redesign, I’ve had to make a couple of sacrifices as I couldn’t find a good way to break out 2 of the io ports on the uC, but I figure I probably won’t need those anyway, and I’ve made up for it by including breakout ports for all of the pins on the xbee module that I will eventually be installing. So for my final design, I have the ATMega328 micro driving 2 motors through a SN754410 dual H-bridge motor controller, serial communication over RS-232 with a max232 chip handling all of the voltage levels, and an Xbee wireless module to provide wireless serial communication and about a million other features. I was able to break out 14 I/O pins, so I should be able to rapidly prototype added functionality at a later date such as sensors and other outputs. When it’s all said and done, I will have spent about $102US on this project including shipping costs, making this my most complex, expensive and fulfilling project to date.

quick robot update

just ran my first series of tests on the control unit and motors. Learned a lot!!! the 2 motors together running at full speed with no load draw a current of over 780 mA.
this means that at no load, I’m using 3.9W of power. (this also lead to my discovery of NEVER touch the LM7805 voltage regulator, and that I need to invest in a heat sink)
I also learned that a 9V battery does not provide nearly enough current, even for bread boarding purposes, and running the motor controller IC off of one powersupply did not give the desired results, it seems the motor controller wasn’t getting the power it needed to drive the motors and the uC. I breadboarded it up with the 2 voltage sources (one for the uC, one for the motors) as the datasheet for the SN754410 suggested (datasheets don’t lie!) and things worked out magnificently. I’ve still got to do some speed tests on each motor so I can nail down the rate and timing to get accurate turns, but I’ve made definite progress. I’m still working to figure out my battery issue before I can finally finalize a design. right now it’s looking like this project is going to work best with the two power supply system I described above, but I’m going to do some research and see if I can come up with something a little better…

I should have video of some more of my tests coming tommorow.

Setting up Breadboard and Initial tests for robot.

Here’s my current progress on the robot project. First of all, I managed to get the chassis, gear box, and tank tread assembly put together correctly on my first try. This took a little bit of guess work as the directions for assembly are primarily in Japanese. I soldered on some really long leads to each motor for testing purposes(so they can reach the bread board).
Chassis
Chassis2

I’ve breadboarded the important parts of the main control board. I’ve got the ATMega328P at the middle clocked to 16MHz, with a motor control subcircuit using the SN754410 motor controller as an H-Bridge voltage controlled current source for the motors. and a MAX232 subcircuit for serial communication with the computer
(very handy for debugging and issuing test commands to the uC)

here’s a link to the Schematic
This schematic is a working rough draft, I’m still refining it, but it gives a general idea of what I’m working with at least.

BreadBoard

This weekend I will have some code written up so i can perform a series of tests on the circuitry, mostly what I’m concerned with is the current draw from each of the motors. This is important because I still haven’t picked a battery configuration for the final unit, but I’m thinking 4AA batteries would be the best balance of voltage, current, and size/weight. I also plan on getting more data on motor speed in the forward and reverse directions so that I can make some calculations for the software in regards to turning the unit.

All in all, I’ve made good progress over the last day or so.

Screw LED Matrices (for now), It's time to talk ROBOTS

So as I’m sure you’ve probably noticed by my previous entries on my blog, I am easily distracted by new fun things, and I’m heavily limited by my hobby budget (about $50/mo and it’s the first thing to get cut when my family needs money).  It’s been said before that time is money. For me, money is time!  I have plenty of time to invest in playing with all of the toys I buy, but since money is tight I sometimes have to make careful consideration in what toys I invest my money in.

So I was thinking. led matrixes are cool and all, but do I really want to invest my money in a new circuit that is only KIND OF COOL?  Heck no.  Thus I have back-burnered my blinky lights in lieu of something way more awesome.  A robot.

My plan with this robot is to focus on simplicity and flexibility in design.  Stage one is going to be building the wheels, transmission, and chassis since these are the base of the robot and probably the most significant parts.  For this I’ve chosen the following components from sparkfun.com

I went with Tamiya parts due to their flexible configuration and simple design.  I decided to go with the tank treads for several reasons including
  • increased surface area contact means more torque transfered to linear power.
  • duh, tank treads are super cool.

Here’s an example of what the chassis, wheels, and motor assembly should look like when completely assembled.

treads chassis and motor example

treads chassis and motor example

For the time being, I’m anxiously clicking the FedEx tracking link. but I should have more to post on this by this weekend when I get the parts.

For phase 2, I’m designing an all purpose control board for the robot. I’m going to put quite a bit of work and research into designing the control board before I get a prototype made because I really only want to do this once.  At the center of the control board will be the ATmega328P microcontroller (my favorite for innumerable reasons) clocked externally at 16MHz via a crystal oscillator and programmable via a 10 pin ICSP.  The board will also contain the power subsystem, which will provide busses at 5V and 3.3V (common power supply for most IC’s), An RS-232 UART subcircuit for debugging and communication with the PC, a breakout for an XBee wireless module(future planned addition), a buzzer, and breakout ports for all of the remaining usable pins.  You might notice that the control board contains no permanent I/O as far as sensors and displays are concerned.  I am trying to keep the main board as simple as possible, but with the ability to add on or remove additional devices as I see fit by designing them externally and interfacing them with the broken out pins on the micro.  This way I can easily add or change any peripherals and continuously learn new things using my robot as a base platform.

Perl, Embedded C, and a little more on the 8×8 LED matrix

So while I’m waiting for funding and time to get my afformentioned 8×8 led matrix parts, I’ve been spending my time working on a basic driver to test the apparatus via a scrolling text marquis. First of all, it’s funny how a quick and dirty chunk of test code can quickly turn into an interesting and in-depth project! I started out by designing a “library” of hexadecimal values that represent each letter, (for example A == 0x1F,0×28,0×48,0×28,0x1F, which is the columnar value that draws an A on the matrix) and then designing a C program that writes the text to the matrix and scrolls it across the screen using the atmega328P’s timers to multiplex and scroll the message (insert link to code here!). Essentially, this algorithm operates by using one timer output compare interrupt to update the display periodically, and another to increment through the message array periodically. This was simple enough (actually more simple than I had anticipated, which excites me). The problem was creating the array of hex values that contained the message was insanely tedious. For each letter in the message, I had to manually input up to 6 hex values which leaves quite a bit of room for error, and sore wrists. So I figured there had to be an easier way to go about this. What I wanted to do was create a program that took a string of text, encoded it into the hex value array, and then plugged the resulting value into the array that was read from. I didn’t want to do this in the main code as micros only have a limited amount of program space and I didn’t want to bog the program down with something that only had to be run once. So I figured that a script would do the trick. I read somewhere once (wikipedia I think) that Perl was originally designed for working with text files, so I figured that it was a natural choice for my needs. I had never used Perl before and was only barely familiar with the syntax and datatypes, but after about an hour of googling and a quick forum post I had successfully designed a script that read a string in from an input file, used a hash to translate the values into the hex strings, and stuck the whole thing in as a properly formatted C array into the code. Basically, thanks to Perl, I can take a string from an input file, properly update and compile my C source file and load it up all in a few keystrokes! Once again, I’m pretty excited. I feel that this is what computer programming is really all about, taking tedious and repetitive tasks and creating new ways to NOT do them.

The Perl Script:

#!/usr/bin/env perl
################################################################################
# marqconv.pl is a perl hack that I threw together to modify the C source file
# marquis.c This script reads a line in from a text file, translates it through
# a hash into an array of hexadecimal values and then writes these array
# elements to the appropriate array in marquis.c
# basically this is the most awesome thing ever written.
################################################################################
use strict;
use warnings;
use Tie::File;

# Hash relating characters to their hex array values for use in the C program.
my %hashkey = (
	" " => "0x00,0x00,0x00,0x00,				/* space */",
	"A" => "0x1F,0x28,0x48,0x28,0x1F,0x00,0x00,		/*   A   */",
	"B" => "0x7F,0x49,0x49,0x36,0x00,0x00,			/*   B   */",
	"C" => "0x3E,0x41,0x41,0x41,0x22,0x00,0x00,		/*   C   */",
	"D" => "0x7F,0x81,0x81,0x3E,0x00,0x00,			/*   D	 */",
	"E" => "0x7F,0x49,0x49,0x49,0x00,0x00,			/*   E   */",
	"F" => "0x7F,0x48,0x48,0x40,0x00,0x00,			/*   F   */",
	"G" => "0x3E,0x41,0x41,0x45,0x26,0x00,0x00,		/*   G   */",
	"H" => "0x7F,0x08,0x08,0x08,0x7F,0x00,0x00,		/*   H	 */",
	"I" => "0x41,0x41,0x7F,0x41,0x41,0x00,0x00,		/*   I	 */",
	"J" => "0x02,0x01,0x01,0x3E,0x00,0x00,			/*   J   */",
	"K" => "0x7F,0x08,0x14,0x22,0x41,0x00,0x00,	        /*   K	 */",
	"L" => "0x7F,0x01,0x01,0x01,0x00,0x00,			/*   L   */",
	"M" => "0x7F,0x20,0x10,0x20,0x7F,0x00,0x00,		/*   M   */",
	"N" => "0x7F,0x20,0x08,0x02,0x7F,0x00,0x00,		/*   N   */",
	"O" => "0x1C,0x22,0x41,0x41,0x22,0x1C,0x00,0x00,	/*   O   */",
	"P" => "0x7F,0x48,0x48,0x60,0x00,0x00,			/*   P   */",
	"Q" => "0x1C,0x22,0x41,0x49,0x22,0x1D,0x00,0x00,	/*   Q   */",
	"R" => "0x7F,0x48,0x4C,0x33,0x00,0x00,			/*   R   */",
	"S" => "0x32,0x49,0x49,0x26,0x00,0x00,			/*   S   */",
	"T" => "0x40,0x40,0x7F,0x40,0x40,0x00,0x00,		/*   T   */",
	"U" => "0x7E,0x01,0x01,0x01,0x7E,0x00,0x00,		/*   U   */",
	"V" => "0x7C,0x02,0x01,0x02,0x7C,0x00,0x00,		/*   V   */",
	"W" => "0x7F,0x02,0x04,0x02,0x7F,0x00,0x00,		/*   W   */",
	"X" => "0x63,0x14,0x08,0x14,0x63,0x00,0x00,		/*   X   */",
	"Y" => "0x40,0x20,0x1F,0x20,0x40,0x00,0x00,		/*   Y   */",
	"Z" => "0x43,0x45,0x49,0x51,0x61,0x00,0x00,		/*   Z   */",
	"." => "0x02,0x00,0x00,					/*   .   */",
	"!" => "0x7C,0x00,0x00,					/*   !   */",
	"?" => "0x5A,0x50,0x70,0x00,0x00,			/*   ?   */",
	"0" => "0x3E,0x43,0x49,0x61,0x3E,0x00,0x00,		/*   0   */",
	"1" => "0x21,0x7F,0x01,0x00,0x00,			/*   1   */",
	"2" => "0x21,0x43,0x45,0x49,0x31,0x00,0x00,		/*   2   */",
	"3" => "0x22,0x14,0x94,0x55,0x22,0x00,0x00,		/*   3   */",
	"4" => "0x18,0x28,0x48,0x7F,0x08,0x00,0x00,		/*   4   */",
	"5" => "0x79,0x49,0x49,0x4F,0x00,0x00,			/*   5   */",
	"6" => "0X3e,0X49,0x,49,0x26,0x00,0x00,			/*   6   */",
	"7" => "0x40,0x47,0x58,0x60,0x00,0x00,			/*   7   */",
	"8" => "0x36,0x49,0x49,0x36,0x00,0x00,			/*   8   */",
	"9" => "0x30,0x48,0x48,0x3F,0x00,0x00,			/*   9   */",
);

# specify file to be edited.
my $codefile = 'marquis.c';

# specify the point in the file to be edited.
my $arraystr = 'volatile const uint8_t marquis[] = {';

# Open up my input files
open(my $in, "<", "string.txt") or die "Cuidado! Piso Mojado: $!";
tie my @code, 'Tie::File', $codefile or die "Cuidado! Piso Mojado: $!";

# Read in the string from the input file and chomp off newline
chomp(my $string = <$in>);

# convert string to upper case to make things easier
$string = uc($string);

# convert string to array of characters
my @line = split('',$string);

# initialize an empty array
my @datalines = ();

# push a leading space into the array
push(@datalines,$hashkey{" "});

# take each character and push it's hex matrix to the array
foreach (@line)
{
	push(@datalines,$hashkey{$_});
}

# add a trailing space with no trailing comma.
push(@datalines,"0x00,0x00,0x00,0x00");

# close all files
close($in);

# calculate the start and length for the splice function.
my $start = (grep {$code[$_] eq $arraystr} 1..$#code)[0]+1;
my $length = (grep {$code[$_] eq '};' and $_>$start} 1..$#code)[0] - $start;

# splice our output into the file to be modified.
splice @code, $start, $length, @datalines;

# close file.
untie @code;

and the C code

/*******************************************************************************
 * File: marquis.c
 * Owner: Cyrus Metcalf (cyrus.metcalf@gmail.com)
 * Date: October 25, 2010
 *
 * Marquis.c is a simple test driver for the atmega328P microcontroller
 * to run a scrolling marquis across an 8x8 LED matrix of my own design.
 *******************************************************************************/

//=====================
//HEADERS
//=====================
#include
#include

//======================
//CONSTANTS
//======================

//#define MAX 77 //length of Marquis, manually calculated.

#define MAX(x) (sizeof(x) / sizeof * (x))

//======================
void ioinit(void);      	//Initializes IO
void timer_0_set_up(void); 	//Initialize Timer 0
void timer_2_set_up(void); 	//Initialize Timer 2
//======================

/* Array autogenerated by marqconv.pl  */
volatile const uint8_t marquis[] = {
0x00,0x00,0x00,0x00,				/* space */
0x7F,0x08,0x08,0x08,0x7F,0x00,0x00,		/*   H	 */
0x7F,0x49,0x49,0x49,0x00,0x00,			/*   E   */
0x7F,0x01,0x01,0x01,0x00,0x00,			/*   L   */
0x7F,0x01,0x01,0x01,0x00,0x00,			/*   L   */
0x1C,0x22,0x41,0x41,0x22,0x1C,0x00,0x00,	/*   O   */
0x00,0x00,0x00,0x00,				/* space */
0x1F,0x28,0x48,0x28,0x1F,0x00,0x00,		/*   A   */
0x7F,0x48,0x4C,0x33,0x00,0x00,			/*   R   */
0x3E,0x41,0x41,0x41,0x22,0x00,0x00,		/*   C   */
0x7F,0x08,0x08,0x08,0x7F,0x00,0x00,		/*   H	 */
0x7F,0x01,0x01,0x01,0x00,0x00,			/*   L   */
0x41,0x41,0x7F,0x41,0x41,0x00,0x00,		/*   I	 */
0x7F,0x20,0x08,0x02,0x7F,0x00,0x00,		/*   N   */
0x7E,0x01,0x01,0x01,0x7E,0x00,0x00,		/*   U   */
0x63,0x14,0x08,0x14,0x63,0x00,0x00,		/*   X   */
0x7C,0x00,0x00,					/*   !   */
0x00,0x00,0x00,0x00
};

volatile uint8_t position = 0;

int main (void)
{
	ioinit();
	timer_0_set_up();
	timer_2_set_up();

	sei();

	while(1)
	{
		//wait for interrupt.
	}

	return(0);
}

void ioinit (void)
{
    //1 = output, 0 = input
    DDRB = 0b11111111; //All outputs
    DDRC = 0b11111111; //All outputs
    DDRD = 0b11111111; //PORTD (RX on PD0)
}

/* Timer 0 output compare interrupt every 18 Hz to scroll Marquis */
void timer_0_set_up(void)
{
	TIMSK0 = _BV(OCF0A); //enable output compare interrupt
	TCCR0A = _BV(WGM01); //enable CTC mode
	TCCR0B = _BV(CS02);  //set prescaler to clk/256
	OCR0A  = 217;	     //increment every 18Hz.
}
/* Timer 2 output compare interrupt every 10Hz to multiplex the display */
void timer_2_set_up(void)
{
	TIMSK2 = _BV(OCF2A); //enable output compare interrupt
	TCCR2A = _BV(WGM01); //enable CTC mode
	TCCR2B = _BV(CS02) | _BV(CS01); //set prescaler to clk/1024
	OCR2A  = 98;	     //increment every 10Hz
}

ISR(TIMER0_COMPA_vect)
{
	/* increment the position to scroll the text */

	if ((position + 7) == MAX(marquis))//prevent array overflow, restart marquis
	{
		position = 0;
	}
	position++;
}
ISR(TIMER2_COMPA_vect)
{

	/* multiplex the LED Matrix and display the value
	 * stored to PortB on the given column*/

	for (uint8_t offset = 0; offset < 8; offset++)
	{
		PORTD = offset;
		PORTB = marquis[position + offset];
	}
}

Scrolling Marquis: more fun with timers

After spending the last week playing around with the timers and interrupts of the AtMega328P Microcontroller (see my previous KITT post!)  I’ve decided it’s time to “move up in Farmville” and build myself a new multi-function prototyping device.  up until now, I’ve been playing with buzzers, 4×7 numeric displays, keypad matrices, and just plain LED’s and I’ve decided my next move is to hack together an 8×8 LED matrix.  LED matrices are double plus awesome because they provide you the flexibility of displaying relatively complex output.  The theory behind them is you create a square (or rectangular) grid of LED’s, tie all of the columns low and all of the rows high, and bam you have X number of uniquely addressable LED’s.  Now, the problem with this layout is if you have an 8×8 matrix, you are going to need 16 IO pins to address all of the LED’s (8 for the columns, 8 for the rows)  this would be the easiest to code together since no multiplexing is involved, however, your design is going to be drawing a ridiculous amount of current and use up a huge number of valuable IO pins on your micro.  So, to work around this problem we use multiplexing.  the theory behind this is that you only turn on one row or column at a time REALLY fast, the human eye cannot discern this at >20Hz! thereby reducing the amount of current drawn but increasing the code complexity.  I considered designing my matrix using double multiplexing between 2 3-8 muxes one for the rows and one for the columns, this would drop the number of IO pins used to address the LEDs to 6, and provide the best performance for power, however the complexity of implementation in code is a little too crazy. why not make things easy on our selves and multiplex the columns and then directly address each row!  it’s the best of both worlds.  So here’s my final prototype for my 8×8 LED Matrix:

matrix pcb

matrix pcb

It’s going to be a little while before I can work with this guy. It’s going to take a month to fab the board and get all of the parts necessary. but I’ve got loads of ideas for working with this device. First of all, I’m designing a scrolling marquis that can be programmed via the serial port, and I’m also working on creating a “snake” game that uses a 2D accelerometer for directional input.

also, this design, and all code for it were designed on an arch linux box using the gEDA design suite, and the gcc-avr compiler, with vim as my text editor and avrdude as my programmer.

more to come when I have a functional prototype (I’m so excited!)

KITT the car micro controller fun.

I was thinking that it’s been a while since I’ve made a post on here. I’ve been really really busy with work/school/kids etc. and I haven’t really had too much “me time” lately to play around with circuits and computers. So, mostly to keep my account on here semi-active, I decided to share my most recent project.

This circuit is commonly known as the Larson Scanner, named for Gary Larson the creator KITT from Knight Rider and the Cylons from BSG. My goal with this project was to learn/play with the various timers and interrupts on my ATMega328P micro controller. I’ve implemented the buzzer on Timer 0 using a simple output compare that toggles the I/O pin at the desired frequency and I added the LED Chaser on timer2 with an output compare interrupt that sweeps through the light sequence. timers and interrupts are awesome in the biblical sense. you wouldn’t believe some of the elaborate programs you can create just using a basic timer setup! well, that’s about all I have time for now.

Apparently WP doesn’t play well with embedded youtube players (or I’m doing something wrong), so here’s a link to the video I was going to post.
AWESOME VIDEO

Source Code Files

Doku: progress so far this week.

Alright, so I’m finally getting around to making a little more progress on my sudoku game.  so I figured I would post a few screenshots and show my progress and discuss what’s left on my todo list.  First of all, here is what I started out with:

nsudoku

This is an image of the program nsudoku which I shamelessly open-sourced from the AUR. I figured nsudoku would be perfect for this exercise in learning ncurses because it already is a perfectly functional sudoku puzzle creator, meaning I don’t have to reinvent the wheel too much. After playing around with nsudoku for a little while, it wasn’t long before I found a laundry list of things I thought needed tweaked and improved on it and I decided to get to hacking. First of all, I can’t stand the color, or that the user is locked into only one color scheme. one of my goals is to implement a feature (whether it be via command line arguments or a menu) that allows the user to specify a variety of color schemes to make things a little easier on the eyes. Another goal that I have in mind is to implement a game clock/best time feature. Basically I want a small clock displayed during the puzzle that keeps track of the amount of time the user spends on the puzzle, and then records this value and the difficulty level to a “best times” file which is displayed at the end of each game. Those are the two major additions I’ve been considering and haven’t quite had the time for yet. Of the progress I’ve made, however, I’ve managed to create a much better looking grid around the puzzle and I’ve also added ‘vim style’ key bindings for cursor movement:

mainscreen

I’ve also created a much more elegant solution to the difficulty selection. In the original nsudoku, the program had to be started with an integer argument between 1 and 80 equal to the number of cells the user wanted to have given initially. I didn’t really like this and decided instead to have a “choose difficulty” menu open at the start of the program, allowing the user to choose from 5 difficulty levels, each level randomly choosing an integer initial value within a small range just to add a little suprise.

here’s what I have so far for the difficulty selection menu:

diffmenu

So far it’s pretty basic, and I still need to implement colors, but for now I think this will work quite nicely.

I think that’s about it for my progress update on Doku, It’s going to be slow going over the next couple of weeks, I’ve got a new addition to the family who is taking up quite a bit of my free time lately, however, I should still be able to find some time to get through this project by the end of summer.

Doku: my new project.

Well, I’m waiting on some more spending money to come in before I can start working on any more interesting electronics projects; so I’ve decided to shift my focus temporarily and concentrate on learning the ins and outs of the ncurses library so that I can make some more robust and fun console based applications. To be honest with you, I HATE working with graphical user interfaces. almost all of my programming thus far has used either a line based user interface, or run in the background without need of a user interface. I think that most graphical user interfaces increase code complexity exponentially to the point where only part of the running code involves the programs functionality and the bulk of it is just there to make things pretty and “user friendly.” This is why my main choice for creating a user interface is ncurses. I use several ncurses based programs on a daily basis and I am very happy with their appearance, ease of use, and general all around simplicity, and now I’d like to learn how to implement some of these features in my own programming projects. The idea to learn ncurses has been a while in the making. With many of my projects (like learning Python and Perl) I start out with the desire to learn the skill, but no TASK to perform with the skill, usually causing me to lose interest in a project rather quickly. Occasionally, however, I derive a task that I want to accomplish, and manage to tie in the opportunity to teach myself a new skill along the way. This is how I came up with the idea for Doku, my new C/ncurses sudoku program. I came up with the idea this morning while doing the puzzles in the daily paper. I was thinking, “man, I love these puzzles, I should install a sudoku program. Hell, I’m a programmer, I bet I could MAKE a sudoku program!” So I went to my PC and started hunting around in the repositories for a nice simple sudoku program I could play around with to get me started. After taking a look at all of the options I settled on nsudoku from the aur. I figured this would be a great starting point because it is simple (written in C in less that 200 lines of code) and it already implements a basic ncurses interface.

So I downloaded the source this morning and immediately started hacking away. I have quite a few ideas for what features I would like to implement and change. here are the ideas I’ve had so far:

  • create a better grid around the puzzle
  • implement VIM key bindings for movement
  • implement a better system for selecting puzzle difficulty
  • implement timing on games, and best times for each difficulty level
  • extend the colors, and provide the option of changing colors
  • I’m also going to be dividing the code up into more manageable chunks to better facilitate code reuse.  Essentially, the original author wrote some great code for generating/solving puzzles, I’m just going to be hacking in a bunch of simple features,  making things a little more elegant, and making an awesome sudoku program that everybody is going to want to play!

    I’m also thinking that when I make some good progress on this project I’m going to be throwing the source on github, cooking up a PKGBUILD, and putting it in the AUR so that everyone else can have a chance to play with it and hack it up a little bit.  but all of that will be a few days/weeks down the road I think.  If anything it will keep me busy in my freetime for a while :)

    Added Some Links

    This is just a quick post, I added a couple more links over to my “Favorite Electronics Sites” section.
    Check out the Electronics Club for loads of information great for getting started with hobby circuitry. This site contains lots of tutorials, guides to parts, and projects. It is British, so expect a few minor differences from American electronics terminology (like Ground = Earth, Antenna = Areal, resistors are rectangles and not squigglies, and the metric system) but regardless, a great great great resource! I’ve also added a Link to The Datasheet Archive which provides component datasheets free of charge! This site is my best friend. If you aren’t familiar with data sheets, they are documents containing all of the technical specifications for any given component (think Man Pages for your parts!) learn to use them! Okay, that’s it for now.