Inexpensive USB Keyboard
September 9, 2010
I had done some work recently to show that a quick and easy USB keyboard could be created created with the teensy and found it to be a 1 day project that was easy to implement. There was one problem with this solution, the cost. It was very pricey for something as simple as a USB keyboard. I wanted to keep some of the nice processor functionality so a dumb terminal that translated into USB would not quite cut it.
I stuck with AVR in this case and took a look at v-usb which lets you create simple HID Keyboards and a large number of other projects quickly and easily. The good news is you can do it on small cheap hardware that is still extremely powerful. I choose the attiny85-20pu as my processor going over the 4-key keyboard schematic and found it to be perfect for what I was looking to do. Here is the part list and pricing:
- ATTiny85-20pu – $1.80 from Mouser
- 2x 68 ohm resistors – $0.30
- 1x 1.5k resistor – $0.15
- 2x 1N4148 Diode – $0.04
- 1 ended USB type-A cable – $2.10
- 1x 0.1uF ceramic capacitor – $0.30
Total: $4.69
The same using the teensy was about $32. While the teensy is of course a more powerful device, it all depends on what you intend to do with it.
I will post more later with the rest of the details on the project as it gets finished. I have some boards to etch and some molds to resin.
MicroVGA
May 18, 2010
I got my MicroVGA display circuit today. This lets you output either SVideo or VGA text. The SVideo is in black and white and the VGA is text only and color. This is great to see whats going on and to have some fun ways to display test on tv’s and computer screens without any complications or having to take up a whole avr chip.
There was some issues out of the box, the first thing you should do when you get one is to connect the Arduino Gnd pin to pin 1 on the MicroVGA and 5V pin to pin 2. This will cause the unit to power up and output a display on both the VGA and SVideo outputs. Connect a convenient TV or monitor to one of the outputs and dig out an old PS/2 keyboard. The keyboard provides direct input to the MicroVGA for setup. Once you have this setup there are two contacts on the top of the board by pin 20 labeled “Setup”, put a wire across them and the output on the screen will switch to a menu that can be browsed with the keyboard. Select communications and change the value to SPI. There seems to be a display issue, after selecting SPI if you go back into the communications menu it still lists the wrong value but it is indeed selected. Restart by powering off / on and then you will be ready to setup your Arduino.
Once the SPI is enabled there were a few issues with the default library (the __builtin_avr_delay_cycles method was not defined). I found a nice answer on the Arudino Forums. Just in case there is an issue getting to the site here’s the code that should replace the existing arduino_uvga.c code in the microvga library for the Arduino.
// debugged 25/1/10 by Shaun Ruscoe
// changed 14/03/10 by Copabel for Arduino Mega.
// fixed 16/05/10 by Sh00rGEn
/*
This file implements low-level routines for Arduino MicroVGA-TEXT.
The MicroVGA has to be configured for SPI mode and connected as follows:
1 GND -> Arduino GND
2 +5V -> Arduino 5V
3 +3V3 NOT CONNECTED
4 CS# -> Arduino Digital 10 | Arduino Mega Digital 53
5 SCK -> Arduino Digital 13 | Arduino Mega Digital 52
6 RDY# -> Arduino Digital 8 | Arduino Mega Digital 10
7 MISO -> Arduino Digital 12 | Arduino Mega Digital 50
8 MOSI -> Arduino Digital 11 | Arduino Mega Digital 51
*/
#include "WProgram.h"
#include "conio.h"
#ifndef __builtin_avr_delay_cycles
void __builtin_avr_delay_cycles(unsigned long __n) {
while(__n)
__n--;
}
#endif
#if defined(__AVR_ATmega1280__)
// Arduino Mega Pin definitions
#define DD_SS 0 // PB0 | Arduino Mega Digital 53
#define DD_MOSI 2 // PB2 | Arduino Mega Digital 51
#define DD_MISO 3 // PB3 | Arduino Mega Digital 50
#define DD_SCK 1 // PB1 | Arduino Mega Digital 52
#define DD_RDY 4 // PB4 | Arduino Mega Digital 10
#else
// Arduino Duemilanove pin definitions
#define DD_SS 2 // PB2 | Arduino Digital 10
#define DD_MOSI 3 // PB3 | Arduino Digital 11
#define DD_MISO 4 // PB4 | Arduino Digital 12
#define DD_SCK 5 // PB5 | Arduino Digital 13
#define DD_RDY 0 // PB0 | Arduino Digital 8
#endif
#define DDR_SPI DDRB
void SPI_MasterTransmit(char cData)
{
/* Start transmission */
//SPDR = cData;
SPDR = cData;
/* Wait for transmission complete */
while ( ! (SPSR & (1<<SPIF)));
}
#define KEYBUF_SIZE 10
unsigned char keybuf[KEYBUF_SIZE];
unsigned char khead, ktail;
char kbhit;
int _getch()
{
int key;
while (!_kbhit()) ;
key = keybuf[khead];
khead++;
khead %= KEYBUF_SIZE;
if (key == 0) {
key = 0x100 | keybuf[khead];
khead++;
khead %= KEYBUF_SIZE;
}
return key;
}
int _kbhit()
{
if (khead == ktail)
_putch(0);
if (khead == ktail)
return 0;
if (keybuf[khead] == 0 && ((khead+1)%KEYBUF_SIZE) == ktail) {
_putch(0);
if (keybuf[khead] == 0 && ((khead+1)%KEYBUF_SIZE) == ktail)
return 0;
}
return 1;
}
void _putch(char ch)
{
unsigned char response;
__builtin_avr_delay_cycles(100);
PORTB &= ~(1<<DD_SS); // SS#=0
__builtin_avr_delay_cycles(100);
// wait for RDY signal to go low!
while (PINB & (1<<DD_RDY) );
__builtin_avr_delay_cycles(100);
/* Start transmission */
//SPDR = cData;
SPDR = ch;
__builtin_avr_delay_cycles(100);
/* Wait for transmission complete */
while ( ! (SPSR & (1<<SPIF)));
__builtin_avr_delay_cycles(100);
response = SPDR;
if (response != 0xFF) {
keybuf[ktail] = response;
ktail++;
ktail %= KEYBUF_SIZE;
kbhit = 1;
}
__builtin_avr_delay_cycles(100);
PORTB |= (1<<DD_SS); // SS#=0
}
void microvga_init()
{
kbhit = 0;
khead = 0;
ktail = 0;
/* Set MOSI and SCK output all others input
This agrees to AVR151 Table 1 also */
DDRB = (1<<DD_MOSI) | (1<<DD_SCK) | (1<<DD_SS);
DDRB &= ~(1<<DD_RDY);
DDRB &= ~(1<<DD_MISO); // MISO is always input
/* Enable SPI, Master, set clock rate fck/16 */
SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0) | (1<<CPHA);
}
This should fix the compilation issues. The pin setup for this library is:
1 GND -> Arduino GND
2 +5V -> Arduino 5V
3 +3V3 NOT CONNECTED
4 CS# -> Arduino Digital 10 | Arduino Mega Digital 53
5 SCK -> Arduino Digital 13 | Arduino Mega Digital 52
6 RDY# -> Arduino Digital 8 | Arduino Mega Digital 10
7 MISO -> Arduino Digital 12 | Arduino Mega Digital 50
8 MOSI -> Arduino Digital 11 | Arduino Mega Digital 51
Here’s a couple pics of the board and the first image I got on the screen.
(yes… Exterminate is blinking…)
Scrounging Reveals a Heat Sink
May 15, 2010
A friend gave me some old PC’s he was going to toss out and I set to work taking them apart. Just recently I ordered 5 L293N H-bridges. These are going to be parts for my next motor driver. One thing I was missing was a good heat sink. I was lucky as I found a really nice heat sink that was used in the PC for heat dissipation for 6 Mosfets. The heat sink not only will work great for 4 of my L293N’s but also dissipates the correct amount of heat.
Below are some pics of the 4 L293N attached to the heat sink ready for mounting. I am going to redesign the PCB to match this change in arrangement. I’m currently using Fritzing to do my Schematics and PCB layout so I will post some nice looking results soon. I just submitted my L293N part to the Fritzing part contribution.
No Disassemble!
May 5, 2010
Here’s a pic of me tearing apart a server I got for free. It was quite fun and I got some nice things including a 256K sram chip. No idea if I can make it work yet but there were lots of caps resistors and other components that are just as useful.
Custom PCB Etching
April 25, 2010
Today I picked up the chemicals and parts needed for custom PCB printing. I will be doing a run tomorrow on a single sided PCB (no need to waste a nice double sided on the first try). I found out about an interesting way to reuse the chemicals over many many runs which should reduce the overall waste produced.
Here is the instructable with the method I will be using: http://www.instructables.com/id/How-to-make-a-printed-circuit-board-PCB-using-th/
I won’t be building a UV light since I will be using our saltwater aquarium lights which should do the job about 1000x faster. Here is more information on the chemicals used and why they are a bit more earth friendly: http://www.instructables.com/id/Stop-using-Ferric-Chloride-etchant!–A-better-etc/step4/Chemistry-Break/
Teensy Keyboard
April 15, 2010
A friend wanted to build a cool foot pedal game device. He purchased a teensy 2.0 from http://www.pjrc.com/teensy/ for a very reasonable $18. After about 2 hours I had the breadboard setup and the program put together to act as a USB keyboard. I am still trying to decide how to switch the keys that are assigned to each button later without having to reprogram the device.
A quick video here
To Build a Robot Part 5
April 11, 2010
I found a 15+ year old pre-printed circuit board from Radio shack and found it to fit just right for what needed. It would be nice to have a properly designed circuit board printed out but this will do nicely for now. Later after I decide if this is the best way to arrange the different parts of the robot I will put something together in Eagle and have someone create a cheap board for this.
Here is the finished solder job ( a bit butchered but it works )
The battery and motor connections are done through some nice terminals I picked up for $2 for the 6 pack. The PWM wire connector from the Arduino is a chopped up extension cord selected because it has enough wires to run the 4 PWM lines and the power and ground wire. It is also nicely shielded to keep noise down.
I will be adding a second L293B H-Bridge to this but I haven’t finished the soldering yet. I also need to setup the output for the second motor from the first L293. I left the solder points for the TLC 5940 NT un soldered so later i can setup a series of them to run even more motors. I will likely add a simple connector for the additional boards once i get a bit closer. When complete this board will drive 4 motors with a total of 2 amps at 3V. Due to the gearing it is more than enough. The gear I am using in the video below is a Tamiya 70103 Universal Gearbox. At some point I may change out the H-Bridge for a heavy duty mosfet for something that can withstand 30A of current.
Here’s a video of the motor spinning backward and forward.
Motor Controller
Next up, completion of the soldering on this board and beginning to fabricate the legs.
To Build a Robot Part 4
April 9, 2010
I received my TLC 5940 NT from Texas instruments and immediately set it up to do a quick test with some LEDs which is always fun: LED Video
I was working on the initial setup while I was sick so I missed something very obvious about the design of my circuit. The TLC actually uses the Ground to produce the PWM wave where the Arduino uses the +. This means to have it turn on the H-Bridge you need to do a pull-up resistor so you can feed it with the 5v.
I used 2k resistors for the Pull-up and things worked well, when I went to 10k the motor slowed in reverse (no idea why right now ill investigate later)
Using this setup you can drive a very large number of motors. You can put the TLC5940 chips in series and control hundreds of motors. For the setup I have here you could control 2 motors per H-Bridge if you use the L293B (but get the L293D) like I have here. Since each motor only requires 2 pins you can control a maximum of 8 motors per TLC5940 chip if you also have 4 h-bridges. If you only need the DC Motor to spin in one direction you only need 1 Pin to control it and could then control 16 motors with variable speed.
Keep in mind the amperage when driving motors with the L293 series they all allow up to about 1 amp. Some motors are very powerful and can reach this limit quickly. Choose your H-Bridge wisely.
Docs and Datasheets:
The sketch uses the TLC library for the Arduino available here: TLC5940 Arduino Library
The sketch just spins a motor forward for 1 second then breaks and backward for a second.
#include "Tlc5940.h" boolean forward = false; void setup() { Tlc.init(); } void loop() { Tlc.clear(); forward = !forward; if (forward) { // Brake Tlc.set(1, 0); Tlc.set(2, 0); Tlc.update(); delay(500); // Go Tlc.set(1, 0); Tlc.set(2, 4095); } else { // Brake Tlc.set(1, 0); Tlc.set(2, 0); Tlc.update(); delay(500); // Go Tlc.set(1, 4095); Tlc.set(2, 0); } Tlc.update(); delay(1000); }
Texas Instruments Packaging
April 2, 2010
I picked up a sample of the 5940N to do some motor control as a sample from Texas Instruments. I also picked up a nice MCU at the same time to tinker with for other parts of the bot. The packing came today and was surprisingly overdone. I have a couple pics here showing the packaging and the tiny chip.
VDIP1 USB Host Controller
March 27, 2010
I got my VDIP1 USB Host controller from Saelig today and was able to get it hooked up and reading a Flash drive in a couple hours. Because the Arduino only has one TX / RX serial pin if you connect it using them you cannot communicate with the computer over the built in USB UART on the Arduino. To get around this limitation there are a number of libraries that allow serial communication over non-serial pins.
I chose the NewSoftSerial library to give access to the VDIP1. The first attempt was to use the AFSoftLibrary and it just did not work properly causing some strange looping of the Setup() method. After switching to the NewSoftSerial library everything started working and I had no trouble doing a DIR and creating a new file on the flash drive. I am posting an early version of the sketch just so i can get a good example and a picture / schematic out so expect updates later. Keep reading for the schema, pic and sketch.
Update: I changed the sketch and schematic / pic to include the RTS / CTS flow control.
Click here to see the picture and sketch.
Read the rest of this entry »