OrBlink

I got an email this morning from someone named Hadley Rich from NZ. He’s made a kit based upon the same design I made my USB Cube that I made a few years ago.

He reused the code I wrote and he has blogged about the OrBlink on his site.

Posted in Uncategorized | 1 Comment

TrayServiceControl

I’ve made a little tool to help me when I’m developing Windows Services. It’s an icon that sits in the Notification area/System tray and allows you to start, stop and debug services. I find Services.msc a bit of a pain; it has a really long list of services making the one you’re interested in hard to find. This tool allows you to filter down to what you’re interested in. Debugging services can also be inconvenient; the executable names can be the same (for example, svchost.exe is listed thirteen times in my system) making it difficult to find which one you’re looking for.

The code and executable are available on Google Code.

Posted in Debugging, Development, Software | 1 Comment

Yet another USB RGB LED

ThingM, are launching a new product, the blink(1). It looks like it has gone well through the kickstarter goal with $42,535 pledged at the time of writing. There are no details of the design yet, but I would bet the design is pretty similar to my Mail Notifier cube. At $45 shipped its a bit expensive – particularly as my design is less than £2, even buying the components individually.

ThingM have another LED controller project, the BlinkM, that might make a cheaper alternative. It could easily be converted to USB controlled as it uses the same microcontroller (ATTiny) as my Mail Notifier. The firmware I made should be compatible and you only need three components: two zener diodes and a USB connector.

Wire the zener diodes in series to connect from USB V+ to V+ on the BlinkM. Connect the i2c data pin that goes to pin 7 to D+ and the other one to D-. Finally, connect the PWR – on the Blink M to the USB ground pin.

Posted in Uncategorized | Leave a comment

Upgrading Sheevaplug to Squeeze

I bought a cheap Wifi dongle (Edimax EW-7811UN) that I knew would work on the RaspberryPi and I had hoped that it would work on the Sheevaplug. Unfortunately, I couldn’t get it to install.

Instead of fighting it, I decided to upgrade. The drivers that the dongle needs are included in the linux kernel from 3.0. I decided to upgrade to Debian Squeeze, which is the same OS my Raspberry Pi uses.

Also, the OS, Ubuntu Jaunty, I’m currently using is long past its end of life.

I decided to upgrade using one of the NewIt images using these instructions.

Writing the image seems like its going to take hours. I found a method for checking the progress of dd on OS X: kill -SIGINFO <PID> will make the dd process print its progress.

Edit: This didn’t really work. I’m going to start again.

Posted in Uncategorized | Leave a comment

Raspberry Pi initial software install

I’ve finally received a Raspberry Pi. No doubt it will end with the other junk I don’t use.

I then downloaded Debian Squeeze, as that’s what I’m most familiar with. Installed that on a spare memory card and powered it via USB despite the warnings (I’ve found before that my laptop has over-current protection).

Tried to log in over ssh, and annoyingly discovered it is not running an SSH server. I had to get a keyboard and plug it in. Logged in, the best way to get new software is to install it via the package manager.

Instructions for wifi dongle http://www.raspberrypi.org/phpBB3/viewtopic.php?f=26&t=6256

Update it:
sudo apt-get update
To search for the package:
apt-cache search ssh server | less
Buried in all that, I spotted:
openssh-server - secure shell (SSH) server, for secure access from remote machines
To Install it:
sudo apt-get install openssh-server
Need to sort out the users before putting this on the internet, probably change the certificates too.

Use startx to get the window manager running. The default web browser is Midori. I prefer Chrome, but there is no official build, so I install the Chromium open source version. The package is: chromium-browser and I then remove the default web browser icon.

I also want a web server, Apache is the most obvious choice (package apache2). It installed:


Starting web server: apache2apache2: bad group name www-data
Action 'start' failed.
The Apache error log may have more information.
failed!
invoke-rc.d: initscript apache2, action "start" failed.

Found others have had the same problems. To fix:

sudo groupadd www-data
sudo usermod -a -G www-data www-data

restart apache

sudo apache2ctl restart and now when you point your browser at it you should get the “It Works!” page.

I also disabled overscan to get rid of the big black borders and add the line disable_overscan=1 to /boot/config.txt

Posted in Uncategorized | Tagged , , , | Leave a comment

Sheevaplug

I bought myself a new toy for xmas from NewIt, a Sheevaplug. It’s a low power, ARM linux device. I plan to use it as a network attached storage maybe backup. The SheevaPlug has Ubuntu 9.04 pre-installed. Apparently its only draws 4 watts. I’m adding this to remind me of the basic setup I did if I ever have to do it again.

You can use the USB cable it comes with the get tty access, but I couldn’t be bothered, I’m happy enough to use the provided OS filesystems etc. Just plugged it in, waited a couple of minutes and use the standard root password.

The device was called UBUNTU on my routers config.

The forum at NewIt recommends regerating keys.

As I want to use it for a storage I attached my usb hard drive, typed in ls /dev/ expecting to see an entry for a hdd something like sda1. The drive was lighting up; I could hear it spinning up repeatedly.

Nothing there, so I swapped it for a memory stick, which seems to work fine. I’m guessing that the drive is drawing more than the 500ma that USB are supposed to draw. I installed lsusb and checked for the device, which didn’t appear. I added a hub, with external power supply, and attached the USB drive via that and it worked fine. Now its easy to mount the drive (my drive happens to be a WD Passport:

mkdir /media/WDPassport/
sudo mount /dev/disk/by-label/WD\\x20Passport /media/WDPassport/

Added a new user so that I don’t have to log in as root.

adduser daveh

and add to sudoers list to stop me from making stupid mistakes

visudo

annoyingly it uses vi, add the line with i

daveh ALL=(ALL) ALL

then :wq to write the file and exit

Do an apt-get update so that apt has the correct locations to get packages from.

I changed the MOTD for so I know I’m definitely booting from the SD card.

I’d also like to use it to serve my music up, so I’ve installed mt-daap. This was pretty straight forward.

Posted in Uncategorized | 1 Comment

Using LED command line without root

A few of the people who tried to build the LED cube had problems getting it to run. Several people didn’t realise that you needed root. I’ve now had to solve this problem for my self as I’m now trying to use it from my ubuntu plug. I found the solution here and have adapted it for the cube. The solution to this is too use udev, which allows devices to be run from user space.

Create new rule for udev

sudo emacs /etc/udev/rules.d/60-objdev.rules

Edit new rule in emacs and add following:

SUBSYSTEM!=”usb_device”, ACTION!=”add”, GOTO=”objdev_rules_end”

SYSFS{idVendor}==”16c0″, SYSFS{idProduct}==”05df”, GROUP=”users”, MODE=”666″
LABEL=”objdev_rules_end”

For other devices replace the vendor and product id with values you can get from lsusb. For example:

daveh@mbp:~$ lsusb

Bus 001 Device 005: ID 16c0:05df VOTI

Restart udev

sudo /etc/init.d/udev restart

Plug in the cube, and try the command.

Posted in AVR, Electronics, Firmware, Software | Leave a comment

Mail notifier clone

I’ve been a bit slack with blog posts of late. I’ll probably start with more electronics when the weather turns, but for now I’m enjoying the sun.

In the mean time several of the forum members on eeeuser.com have been attempting to build a mail notifier inspired the LED cube that I’ve built. They’ve put their progress in this thread. Forum member posted some pictures to that thread. They’ve gone a bit further than I have by etching their own PCBs and using SMT components.

Here is the completed circuit controlling a mini lava lamp from forum member AlphaCentauri whom has also adapted with Twitter/ICQ/Mail notifier software, dBird to control the cube.

Posted in ATTiny45, AVR, build, Electronics | 9 Comments

AVR Fuse settings

I’ve managed to ‘brick’ two of my ATTiny2313 chips by getting the fuse settings wrong. I’m not sure what I have done but I suspect I’ve set them to use an external oscillator without one. It should be able to get them working if I add an oscillator to my circuit.

Here is a tool that will help calculate the correct values for l/h/e fues.

It is possible to turn off the reset pin. When this happens the only option is to use the HV programmer. When the device is dead you might be able to recover them with this HV Rescue Arduino shield. I’m not planning to buy as I’d like to be able to use it with ATTiny45 which it does not support.

Posted in AVR, Electronics | 2 Comments

ProjectSteve: Cylon attachment

My friend Johnny has brought into work a Roomba clone. Apparently it is not particularly effective at cleaning, so we have decided to hack it. It is named ProjectSteve. He’s already has his vacuum cleaning parts removed and he is pretty good at carrying stuff. When discussing what to build we came up with the idea of building a light strip like KIT or a Cylon. It seems someone else already had the idea of Cylons and has added one to a Roomba.

I have loads of 3mm red LEDs and I’m going to use 25 of them to make this LED strip. I want each LED to be independently addressable so I have decided to configure the LEDs in a matrix. I’ve previously discussed how to use an LED matrix with an Arduino. If you were to wire the LEDs individually you would need 25 pins, one to control each LEDs. Using a matrix can reduce this.

I begin by wiring up the LED matrix. I decided to use 5 groups of 5 Leds

For each group, of LEDs, solder all the cathodes together. I have attached a black wire to this group and this will be used to connect to the MCU.

Close up of the back of the LED strip

Close up of the back of the LED strip

The group’s anodes are then wired together with the corresponding anode from the other groups; the first LED’s anode, from the first group, is wired to the anode of the first LED in each of the other groups. This gives ten wires to control all the LEDs. I’ve soldered each wire to a pin on some PCB header so I should be able to plug it into breadboard, or alternatively a female header when I have made the PCB.

Wiring completed

Wiring completed

The LEDs are mounted in a bent strip of acrylic. I bent this over my kitchen hob but I didn’t get particularly good quality results.

LED strip front

The finished LED strip from the front

As usual I first prototype the design on my Arduino. I’ve connected the ground pins to digital pins 2 to 6 and the positive pins to 7 to 11. I’ve again used Port Manipulation for the Arduino. The Arduino wiki advises against using it because it makes things more complicated, but I feel that it actually makes things simpler in this case. 

Here is the Arduino source. The ‘anim’ array contains the display information. Each byte is used to represent the five LED group. You should be able to see the pattern, 1′s mean LED on 0′s mean LED off.

char anim[][5] = {
{ B00000, B00000, B11111, B00000, B00000},
{ B00000, B00000, B00111, B11000, B00000},
{ B00000, B00000, B00011, B11100, B00000},
{ B00000, B00000, B00000, B11111, B00000},
{ B00000, B00000, B00000, B01111, B10000},
{ B00000, B00000, B00000, B00111, B11000},
{ B00000, B00000, B00000, B00001, B11110},
{ B00000, B00000, B00000, B00000, B11111},
{ B00000, B00000, B00000, B00000, B01111},
{ B00000, B00000, B00000, B00000, B01111},
{ B00000, B00000, B00000, B00000, B00111},
{ B00000, B00000, B00000, B00000, B00111},
{ B00000, B00000, B00000, B00000, B00111},
{ B00000, B00000, B00000, B00000, B00111},
{ B00000, B00000, B00000, B00000, B00111},
{ B00000, B00000, B00000, B00000, B00111},
{ B00000, B00000, B00000, B00000, B01111},
{ B00000, B00000, B00000, B00000, B01111},
{ B00000, B00000, B00000, B00000, B11111},
{ B00000, B00000, B00000, B00001, B11110},
{ B00000, B00000, B00000, B00111, B11000},
{ B00000, B00000, B00000, B01111, B10000},
{ B00000, B00000, B00000, B11111, B00000},
{ B00000, B00000, B00011, B11100, B00000},
{ B00000, B00000, B00111, B11000, B00000},
{ B00000, B00000, B11111, B00000, B00000},
{ B00000, B00011, B11100, B00000, B00000},
{ B00000, B00111, B11000, B00000, B00000},
{ B00000, B11111, B00000, B00000, B00000},
{ B00001, B11110, B00000, B00000, B00000},
{ B00011, B11100, B00000, B00000, B00000},
{ B01111, B10000, B00000, B00000, B00000},
{ B11111, B00000, B00000, B00000, B00000},
{ B11110, B00000, B00000, B00000, B00000},
{ B11110, B00000, B00000, B00000, B00000},
{ B11100, B00000, B00000, B00000, B00000},
{ B11100, B00000, B00000, B00000, B00000},
{ B11100, B00000, B00000, B00000, B00000},
{ B11100, B00000, B00000, B00000, B00000},
{ B11100, B00000, B00000, B00000, B00000},
{ B11100, B00000, B00000, B00000, B00000},
{ B11110, B00000, B00000, B00000, B00000},
{ B11110, B00000, B00000, B00000, B00000},
{ B11111, B00000, B00000, B00000, B00000},
{ B01111, B10000, B00000, B00000, B00000},
{ B00011, B11100, B00000, B00000, B00000},
{ B00001, B11110, B00000, B00000, B00000},
{ B00000, B11111, B00000, B00000, B00000},
{ B00000, B00111, B11000, B00000, B00000},
{ B00000, B00011, B11100, B00000, B00000},
};
void setGnd(int i)
{
  PORTD &= B10000011;
  PORTD |= (~(1 << (i+2))) & B01111100;
}
void clearGnd()
{
  PORTD |= B01111100;
}
void setLeds(unsigned int frame, unsigned int block)
{
  PORTD &= B01111111;
  PORTD |= B10000000 & (anim[frame][4 - block] << 7);
  
  PORTB &= B11110000;
  PORTB |= B00001111 & (anim[frame][4 - block] >> 1);
}
void setup()
{
  DDRD |= B11111100;
  DDRB = B00001111;
}
void loop()
{
  int frames = sizeof(anim) / (5 * sizeof(char));
  unsigned int t = millis();
  unsigned int f = (t / 40) % frames;
  for (int i = 0; i < 5; ++i)
  {
    setGnd(i);
    setLeds(f, i);
    delay(1);
    clearGnd();
  }
}
char anim[][5] = {
	{ B00000, B00000, B11111, B00000, B00000},
	{ B00000, B00000, B00111, B11000, B00000},
	{ B00000, B00000, B00011, B11100, B00000},
	{ B00000, B00000, B00000, B11111, B00000},
	{ B00000, B00000, B00000, B01111, B10000},
	{ B00000, B00000, B00000, B00111, B11000},
	{ B00000, B00000, B00000, B00001, B11110},
	{ B00000, B00000, B00000, B00000, B11111},
	{ B00000, B00000, B00000, B00000, B01111},
	{ B00000, B00000, B00000, B00000, B01111},
	{ B00000, B00000, B00000, B00000, B00111},
	{ B00000, B00000, B00000, B00000, B00111},
	{ B00000, B00000, B00000, B00000, B00111},
	{ B00000, B00000, B00000, B00000, B00111},
	{ B00000, B00000, B00000, B00000, B00111},
	{ B00000, B00000, B00000, B00000, B00111},
	{ B00000, B00000, B00000, B00000, B01111},
	{ B00000, B00000, B00000, B00000, B01111},
	{ B00000, B00000, B00000, B00000, B11111},
	{ B00000, B00000, B00000, B00001, B11110},
	{ B00000, B00000, B00000, B00111, B11000},
	{ B00000, B00000, B00000, B01111, B10000},
	{ B00000, B00000, B00000, B11111, B00000},
	{ B00000, B00000, B00011, B11100, B00000},
	{ B00000, B00000, B00111, B11000, B00000},
	{ B00000, B00000, B11111, B00000, B00000},
	{ B00000, B00011, B11100, B00000, B00000},
	{ B00000, B00111, B11000, B00000, B00000},
	{ B00000, B11111, B00000, B00000, B00000},
	{ B00001, B11110, B00000, B00000, B00000},
	{ B00011, B11100, B00000, B00000, B00000},
	{ B01111, B10000, B00000, B00000, B00000},
	{ B11111, B00000, B00000, B00000, B00000},
	{ B11110, B00000, B00000, B00000, B00000},
	{ B11110, B00000, B00000, B00000, B00000},
	{ B11100, B00000, B00000, B00000, B00000},
	{ B11100, B00000, B00000, B00000, B00000},
	{ B11100, B00000, B00000, B00000, B00000},
	{ B11100, B00000, B00000, B00000, B00000},
	{ B11100, B00000, B00000, B00000, B00000},
	{ B11100, B00000, B00000, B00000, B00000},
	{ B11110, B00000, B00000, B00000, B00000},
	{ B11110, B00000, B00000, B00000, B00000},
	{ B11111, B00000, B00000, B00000, B00000},
	{ B01111, B10000, B00000, B00000, B00000},
	{ B00011, B11100, B00000, B00000, B00000},
	{ B00001, B11110, B00000, B00000, B00000},
	{ B00000, B11111, B00000, B00000, B00000},
	{ B00000, B00111, B11000, B00000, B00000},
	{ B00000, B00011, B11100, B00000, B00000},

};

void setGnd(int i)
{
  PORTD &= B10000011;
  PORTD |= (~(1 << (i+2))) & B01111100;
}

void clearGnd()
{
  PORTD |= B01111100;
}

void setLeds(unsigned int frame, unsigned int block)
{
  PORTD &= B01111111;
  PORTD |= B10000000 & (anim[frame][4 - block] <> 1);
}

void setup()
{
  DDRD |= B11111100;
  DDRB = B00001111;
}

void loop()
{
  int frames = sizeof(anim) / (5 * sizeof(char));
  unsigned int t = millis();
  unsigned int f = (t / 40) % frames;
  for (int i = 0; i < 5; ++i)
  {
    setGnd(i);
    setLeds(f, i);
    delay(1);
    clearGnd();
  }
}

As Arduino has much much than I need  I want to simplify the design. Here is a simple circuit using an ATTiny2313 to control the LEDs. The capacitors and the chip on the right are a voltage regulator. The orange LED is a power indicator. This is the first circuit I’ve made using this chip, so I’ve yet to figure it out how to properly program it. I’ve manage to brick two chips so far, so I’m going to investigate fixing them before I continue with the next stage of this project.

ATTiny2312 LED controller

Breadboard ATTiny2312 LED controller

Posted in ATTiny2313, AVR, Electronics | 1 Comment