How to use V-USB on an attiny85

V-USB is a project from the company Objective Development Software GmbH to bring basic USB support to any micro controller. This is what they say about it:

V-USB is a software-only implementation of a low-speed USB device for Atmel’s AVR® microcontrollers, making it possible to build USB hardware with almost any AVR® microcontroller, not requiring any additional chip.

And the best thing: It’s opensource. The code is fully available under the GPL. If you want to use it commercially, you can buy a licence. Its a very well documented project and it has a good forum.

I started to use it on an attiny85 as a replacement to parallel port I/O operations. There are many examples and reference designs at the above linked website.

There is just one small issue: The last released code is from 2010. Thats ok, but most of the example projects are back from 2009 and 2008. Since then, the API has quite a bit changed and most of the examples will not work anymore out of the box. (They might work with other micro controllers, but not with an attiny85).

To give it a start, I suggest to build the EasyLogger. Its code worked out of the box for me. Then, when you know your hardware works, download the main core from www.obdev.at/products/vusb/download.html. The version I used was vusb-20100715.

hid-mouse

To get the hid-mouse example working, I had to modify some files as described here. The files are also available for download below. I explain it on a Linux system with all requirements (gcc, ..) already installed. How ever it also should work on Windows.

1. Download and extract the vusb-20100715 files
2. Copy the folder libs-device to examples/hid-mouse/
3. Go into the folder examples/hid-mouse/
4. In the file Makefile, replace

DEVICE  = atmega168
F_CPU   = 16000000    # in Hz
FUSE_L  = # see below for fuse values for particular devices
FUSE_H  =
AVRDUDE = avrdude -c usbasp -p $(DEVICE) # edit this line for your programmer

with

DEVICE=attiny85
F_CPU   = 16500000    # in Hz
FUSE_L  = 0xE1
FUSE_H  = 0xDD
AVRDUDE = avrdude -c stk500v2 -P /dev/ttyUSB0 -p $(DEVICE)

You also will have to tell the compiler to use the files in libs-device:

Replace

CFLAGS  = -Iusbdrv -I. -DDEBUG_LEVEL=0
OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o

with

CFLAGS  = -Iusbdrv -I. -Ilibs-device -DDEBUG_LEVEL=0
OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o libs-device/osccal.o

and further down replace

rm -f main.hex main.lst main.obj main.cof main.list main.map main.eep.hex main.elf *.o usbdrv/*.o main.s usbdrv/oddebug.s usbdrv/usbdrv.s

with

rm -f main.hex main.lst main.obj main.cof main.list main.map main.eep.hex main.elf *.o usbdrv/*.o main.s usbdrv/oddebug.s usbdrv/usbdrv.s  libs-device/osccal.o

5. Next, open the file usbconf.h and change the following:

#define USB_CFG_IOPORTNAME      D

to

#define USB_CFG_IOPORTNAME      B

and

#define USB_CFG_DMINUS_BIT      4

to

#define USB_CFG_DMINUS_BIT      0

Note: If you have another hardware configuration, just adapt it here!

Further down, replace

#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH   0

with

#if USB_CFG_CLOCK_KHZ==16500
#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH   1
#include "osccal.h"
#else
#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH   0
#endif

This was needed for me as the attiny85  clock was wrong or not good enough.

6. Now go into the folder libs-device and open the file osccal.h and change the following:

Uncomment the following lines:

#ifndef __ASSEMBLER__
#include <avr/interrupt.h>  // for sei()
extern void calibrateOscillator(void);
#endif
#define USB_RESET_HOOK(resetStarts)  if(!resetStarts){cli(); calibrateOscillator(); sei();}

(add a */ before it and a /* after it).

And  further down, comment out this line as it is already defined above:

void    calibrateOscillator(void);

7. Now we should be ready to compile the project. To program it, power up the device and connect your SPI programmer. (Note: I couldn’t program it while the USB was plugged in, so I had to power it externally!)
In a terminal, run the following commands:

cd examples/hid-mouse/firmware
make hex
make flash
make fuse

This will compile it and download it and also set the fuses correctly.

Now you should be able to plug into your USB port.
After a second or so the mouse pointer should start moving around.

If you run the comand dmesg, it will show something like the following:

usb 1-1.1.3: new low speed USB device using ehci_hcd and address 17
input: obdev.at Mouse as /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/1-1.1.3/1-1.1.3:1.0/input/input8
generic-usb 0003:16C0:03E8.0008: input,hidraw3: USB HID v1.01 Mouse [obdev.at Mouse] on usb-0000:00:1a.0-1.1.3/input0

If you instead get a message like this:

usb 1-1.1.3: new low speed USB device using ehci_hcd and address 19
usb 1-1.1.3: device descriptor read/64, error -32

then you have most likely a problem with the attiny85 clock and the timing is wrong.

Download

V-USB for attiny85
V-USB for attiny85
vusb_attiny85_20110701.zip
486.4 KiB
84 Downloads
Details...
Posted in Electronics, Linux, Programming | Leave a comment

Graphical LCD controlled by only 2 wires

Graphical display controlled with only 2 wires

Programming a micro controller is much easier if you can do debugging. How ever this is often not available or only very limited. I usually debug my applications with a display. This way I can easily output numbers and strings in real time. The example below shows how to control a graphical 128×64 pixel display on only 2 signal wires. This can be useful if you have only 2 output pins left on your micro controller. I tested a MG12064E-SRY1 as well as a LXG128X64STY, but it should work with most graphic displays.

The data is clocked out serially and moved into a shift register. This then converts the data into a parallel signal which can be understood by the display. It took me a while to get a way to tell the display when the data is ready.It appeared that there has to be a little delay between getting the data ready and rising the display enable line. To solve this, I use an RC-Network. Usually a clock pulse is only about 250 ns long. To trigger the enable signal, I extend the pulse to 2.5 us. The complete time to transmit one byte is around 22 us:

Visualisation on an oscilloscope: Clock signal (yellow) and data signal (green)

To send a character you will need around 5 bytes, depending on the font map you are using. The source code which I provide below currently only supports a 8×5 font and some basic letters of a smaller font (to save program memory). Other font maps and graphic functions can easily be added. There are many complete libraries available on the web, i.e. on www.mugui.de (german).

Hardware

All you need is a display,  serial shift register ic’s (74595), an inverter 7404 and a few resistors and capacitor:

Schematics

Download

The schematic (eagle file) as well as an example software code can be downloaded here:

Controll a graphic display with only 2 wires
31.4 KiB
47 Downloads
Details...

Posted in Electronics, Programming | 2 Comments

Linux, the Sandy-Bridge CPU and the HD3000 GPU

For all those who are wondering how great the Linux support with the new Sandy-Bridge CPUs are, I can let you know, It works great!

As the guys from Phoronix already showed in www.phoronix.com/scan.php?page=article&item=intel_sandy_speed&num=1 Linux runs quite well, as long as you connect the right hardware together. In my case, I put myself a new PC together with the following main components:

  • Intel Mainboard DH67GD
  • Intel Sandy-Bridge CPU i5 2500K, 3.3GHz, 4 Core

I tested it with Kubuntu 10.10 (Maverick) as well as Kubuntu 11.04 beta1 (Natty).
Instead of additional graphic cards I am using the new HD3000 Graphics Processing Core which is directly build into the Sandy-Bridge processor. In both OS’s I updated to the latest graphic card drivers and kernel.

In both tested Linux, the graphics looked good out of the box. Only the context menus got distorted. A bug report and a solution is already shown in bugs.launchpad.net/ubuntu/natty/+source/xserver-xorg-video-intel/+bug/732304. You will have to create a xorg.conf file and add the option “shadow”:

Section "Device"
Identifier      "Sandybridge"
Driver          "intel"
Option "Shadow" "true"
Option          "DRI"   "false"
EndSection

This might disable the 3d acceleration, but makes the GPU work correctly. I am sure there will be a better solution soon. As for new the Sandy-Bridge CPUs are still new and not yet very much used.

Update (13. April 2011):
With the latest kernel (2.6.38-8-generic) this hack is not needed anymore!

In Kubuntu 11.04 even some of the Compiz effects work. Not all of them, but some nice ones like transparency work very well.

As I also prefer to work with more than one monitor, I had a look into dual screen options. In Kubuntu 10.10 I could only get it working when I removed the “shadow” option in the xorg.conf file. In Kubuntu 11.04 however it worked with the “shadow” option enabled. Like I already mentioned in one of my earlier posts (Kubuntu 10.10 and dual screen) that Kubuntu always resets the dual screen option on a restart of the X server. This again can be solved with some command lines in the file /etc/kde4/kdm/Xsetup:

xrandr --output HDMI1 --primary

xrandr --output HDMI1 --mode 1920x1080
xrandr --output HDMI3 --mode 1280x1024

xrandr --output HDMI3 --left-of HDMI1

Of course you will have to adjust the names of the devices. After that the X server should start directly with dual screen support and no menu distortion.

Posted in Linux | Tagged , , , | 2 Comments

How to sync egroupware with a tablet N900 with syncevolution.

Until now, I was using googles address book and calendar service to sync my phones address book and calendar with my PC. As I don’t like to share my personal data with google, I always was looking for an alternative. Important at the same time was the ability to also include it into my KDE address book and calendar. I will explain how to do that in a later post. Here I want to show how to add an egroupware account to syncevolution.

I mainly followed Rene Mayerhofer’s explanations at www.mayrhofer.eu.org/n900-syncevolution . The used versions are as shown below:

Since Rene wrote his guide, syncevolution got changed and some files are in new places. But else his guide is still valid. The file structure is now as following:

/home/user/.config/syncevolution
 |-default
 |---peers
 |-----SERVICENAME
 |-------peers
 |-------sources
 |---------addressbook
 |---------calendar
 |---------calendar+todo
 |---------memo
 |---------todo
 |---sources
 |-----addressbook
 |-----calendar
 |-----calendar+todo
 |-----memo
 |-----todo

BTW, to show this this folder tree, I used this command:

ls -R | grep ":$" | sed -e 's/:$//' -e 's/[^-][^\/]*\//--/g' -e 's/^/   /' -e 's/-/|/'

Now, hot to start?
On your N900, start the SyncEvolution frontend and add a new service. For the template, choose Mobical!  Then add your username and password of your egroupware account. Be aware that Maemo automatically writes the first letter as a capital letter, also in the password!

Now the easy part is done.  Optimally you now could edit the service in this frontend, but it seems to be broken (the done button has no action), so we will have to do it in the terminal. To edit the files, use your editor of choice. I personally prefer Nano (maemo.org/packages/view/nano/).

All the files we have to edit are in /home/user/.config/syncevolution/default/peers/SERVICENAME where SERVICENAME stands for the name yopu choose.

In config.ini, change the following options (I show the options I needed for my egroupware server):

  • syncURL = http://www.ruinelli.ch/egroupware/rpc.php
  • SSLVerifyServer = 0
  • WebURL = http://www.ruinelli.ch/egroupware

In sources/todo/config.ini:

  • uri = ./tasks

In sources/memo/config.ini:

  • uri = ./notes

In sources/calendar/config.ini:

  • uri = calendar

In sources/addressbook/config.ini:

  • uri = ./contacts

Now we are ready to give it a test run. Even you will be able to run the sync in the frontend, I prefer to do it for now in the terminal. This helps in case something goes wrong.

In the terminal, run (as user):

syncevolution --sync slow SERVICENAME calendar

and

syncevolution --sync slow SERVICENAME addressbook

Similar for the other services. (Please note that I did not test them) myself).

If everything is right, it should do a first sync. If evrything goes well, you from now on can do a normal sync (without the “–sync slow” option) or use the frontend.

In case you do not have an egroupware account, I might be able to help out. I have one running and would be willing to give you a free account. Just keep in mind that I do it in my free time and might not be able to give a quick help in case it stops working.

Posted in Linux, Maemo | Tagged , , , , , , | 1 Comment

New SleepAnalyser

Recording options
Once again I could move a new version of my SleepAnalyser into the stable tree of the Maemo repositories.

Beside small changes and bugfixes it also has many new features:

  • Lucid dream music option
  • Wake up music option
  • Alarm is now triggered by blue sleep graph instead yellow movement bars. This should trigger it only when you move more
  • Time bars at bottom of graph have new functionality: they now show in which sleep phase you are
  • Rearanged buttons for easier interactions
  • UI racts now smoother
  • Improved settings
  • New documentation
  • Added bug report dialog
  • Supports now UTF8 for file names
  • Various bugfixes

For more information about it, have a look on this page.

Posted in Maemo, Programming | Leave a comment

Förderverein Generation+

Soeben habe ich die Webseite www.gplus-ilef.ch des Fördervereins Generation+ aufgeschalten.
Der Verein hat die Funktion, finanzielle Mittel zu sammeln, um die Jugendarbeit der reformierten Kirchgemeinde Illnau-Effretikon (www.ref-ilef.ch) auszubauen.

Posted in Various | Leave a comment

SleepAnalyser in new stable version

SleepAnalyser with new features
I am pleased to announce a new stable version (1.8-105) of SleepAnalyser. Compared to the last stable version a lot has changed. Beside a cleanup of the graphical user interface also a big part of the program code got rewritten and many new features where added.

  • Your sleep pattern is now visualized with an easier to understand graph.
  • It has now language support. Currently English, German, French and Dutch are included, more languages will follow.
  • Also it is now faster and responds better to user interactions.
  • The help got overworked and should give newcomers an easier start.
  • And much more

For more information see here.

Posted in Maemo, Programming | Leave a comment

Convert RGB to HSV and back with a micro controller

It took me a while to find code examples how to convert an RGB color value into the equivalent HSV color space and back. Also it took me quite a while to adapt the code for my micro controller.

For the reference, here the examples, written in ANSI C. First of all I created some useful structs to store the values:

struct RGB_set {
 unsigned char r;
 unsigned char g;
 unsigned char b;
} RGB_set;

struct HSV_set {
 signed int h;
 unsigned char s;
 unsigned char v;
} HSV_set;

Here the first function:

/*******************************************************************************
 * Function RGB2HSV
 * Description: Converts an RGB color value into its equivalen in the HSV color space.
 * Copyright 2010 by George Ruinelli
 * The code I used as a source is from http://www.cs.rit.edu/~ncs/color/t_convert.html
 * Parameters:
 *   1. struct with RGB color (source)
 *   2. pointer to struct HSV color (target)
 * Notes:
 *   - r, g, b values are from 0..255
 *   - h = [0,360], s = [0,255], v = [0,255]
 *   - NB: if s == 0, then h = 0 (undefined)
 ******************************************************************************/
void RGB2HSV(struct RGB_set RGB, struct HSV_set *HSV){
 unsigned char min, max, delta;

 if(RGB.r<RGB.g)min=RGB.r; else min=RGB.g;
 if(RGB.b<min)min=RGB.b;

 if(RGB.r>RGB.g)max=RGB.r; else max=RGB.g;
 if(RGB.b>max)max=RGB.b;

 HSV->v = max;                // v, 0..255

 delta = max - min;                      // 0..255, < v

 if( max != 0 )
 HSV->s = (int)(delta)*255 / max;        // s, 0..255
 else {
 // r = g = b = 0        // s = 0, v is undefined
 HSV->s = 0;
 HSV->h = 0;
 return;
 }

 if( RGB.r == max )
 HSV->h = (RGB.g - RGB.b)*60/delta;        // between yellow & magenta
 else if( RGB.g == max )
 HSV->h = 120 + (RGB.b - RGB.r)*60/delta;    // between cyan & yellow
 else
 HSV->h = 240 + (RGB.r - RGB.g)*60/delta;    // between magenta & cyan

 if( HSV->h < 0 )
 HSV->h += 360;
}

And its contrary function:

/*******************************************************************************
 * Function HSV2RGB
 * Description: Converts an HSV color value into its equivalen in the RGB color space.
 * Copyright 2010 by George Ruinelli
 * The code I used as a source is from http://www.cs.rit.edu/~ncs/color/t_convert.html
 * Parameters:
 *   1. struct with HSV color (source)
 *   2. pointer to struct RGB color (target)
 * Notes:
 *   - r, g, b values are from 0..255
 *   - h = [0,360], s = [0,255], v = [0,255]
 *   - NB: if s == 0, then h = 0 (undefined)
 ******************************************************************************/
void HSV2RGB(struct HSV_set HSV, struct RGB_set *RGB){
 int i;
 float f, p, q, t, h, s, v;

 h=(float)HSV.h;
 s=(float)HSV.s;
 v=(float)HSV.v;

 s /=255;

 if( s == 0 ) { // achromatic (grey)
 RGB->r = RGB->g = RGB->b = v;
 return;
 }

 h /= 60;            // sector 0 to 5
 i = floor( h );
 f = h - i;            // factorial part of h
 p = (unsigned char)(v * ( 1 - s ));
 q = (unsigned char)(v * ( 1 - s * f ));
 t = (unsigned char)(v * ( 1 - s * ( 1 - f ) ));

 switch( i ) {
 case 0:
 RGB->r = v;
 RGB->g = t;
 RGB->b = p;
 break;
 case 1:
 RGB->r = q;
 RGB->g = v;
 RGB->b = p;
 break;
 case 2:
 RGB->r = p;
 RGB->g = v;
 RGB->b = t;
 break;
 case 3:
 RGB->r = p;
 RGB->g = q;
 RGB->b = v;
 break;
 case 4:
 RGB->r = t;
 RGB->g = p;
 RGB->b = v;
 break;
 default:        // case 5:
 RGB->r = v;
 RGB->g = p;
 RGB->b = q;
 break;
 }
}

Also I wrote a function to split a color string (like they are used in HTML) into its individual RGB color parts:

/*******************************************************************************
 * Function RGB_string2RGB_struct
 * Description: Converts an RGB color tring into the individual color values.
 * Copyright 2010 by George Ruinelli
 * Parameters:
 *   1. pointer string with RGB color (source) without leading # i.e. FF0000 for red.
 *   2. pointer tu struct RGB color struct (target)
 * Notes:
 *   - r, g, b values are from 0..255
 ******************************************************************************/
void RGB_string2RGB_struct(char *tuple, struct RGB_set *RGB){
 char tmp[3];

 strncpy(tmp, tuple, 2); tmp[2]= '\0';
 RGB->r=(unsigned char)(strtoul(tmp, NULL, 16));

 strncpy(tmp, &tuple[2], 2); tmp[2]= '\0';
 RGB->g=(unsigned char)(strtoul(tmp, NULL, 16));

 strncpy(tmp, &tuple[4], 2); tmp[2]= '\0';
 RGB->b=(unsigned char)(strtoul(tmp, NULL, 16));
}

And a little application to test it:

int main (void){
 struct RGB_set RGB;
 struct HSV_set HSV;

 RGB.r=0xFF; RGB.g=0xFF, RGB.b=0x0; //define color "yellow"
 printf ("Yellow in RGB: %X, %X, %X\n", RGB.r, RGB.g, RGB.b);

 RGB2HSV(RGB, &HSV);
 printf ("converted to HSV: %X, %X, %X\n", HSV.h, HSV.s, HSV.v);

 HSV2RGB(HSV, &RGB);
 printf ("converted back to RGB: %X, %X, %X\n", RGB.r, RGB.g, RGB.b);

 char HTML_color[]="FF8000"; //orange
 RGB_string2RGB_struct(HTML_color, &RGB);
 printf ("convert HTML color #FF8000 (orange) to its parts (RGB): %X, %X, %X\n", RGB.r, RGB.g, RGB.b);

 return 0;
}

Some notes:

The functions are written to run on a micro controller. Because of that, RGB2HSV does not use any floating point functions. This can lead to some rounding errors but can usually be ignored. The contrary function HSV2RGB still uses floating point operations. Here some optimizations are possible.

Posted in Programming | Leave a comment

New MAEMO application: Leo

Hi all

As an occasional user of the translation service on  dict.leo.org I got frustrated how time consuming it is, to use it on an embedded device; first you have to start a browser, then type in the url, wait until the page is loaded and then finally you can start your search.

Well, as an user of an opensource operating system, its just normal to think about better solutions.

As many other people already made similar applications or code examples, it was not too hard to create a quickly one for dict.leo.org.

If you are user of MAEMO and occasionally need to translate something from/to German, have a look on my app.

Posted in Maemo, Programming | Leave a comment

SleepAnalyser updated

I just released a new stable version of my SleepAnalyser. SleepAnalyser is a Software for the MAEMO 5 based phone N900. It is able do record and visualise your sleep pattern.
For more informations see here.

SleepAnalyser
Posted in Maemo, Programming | Leave a comment